Sequential use two ways to build models and Module

Modeled using Sequential mode 

import numpy as np
import torch
from torch import nn

# 定义一个 Sequential 模型
net1 = nn.Sequential(
    nn.Linear(30, 40),
    nn.ReLU(),
    nn.Linear(40, 50),
    nn.ReLU(),
    nn.Linear(50, 10)
)

for layer in net1:
    print(layer)
    if isinstance(layer, nn.Linear): # 判断是否是线性层
        param_shape = layer.weight.shape
        layer.weight.data = torch.from_numpy(np.random.normal(0, 0.5, size=param_shape)) 
        # 定义为均值为 0,方差为 0.5 的正态分布

Output: 

Linear(in_features=30, out_features=40, bias=True)
ReLU()
Linear(in_features=40, out_features=50, bias=True)
ReLU()
Linear(in_features=50, out_features=10, bias=True)

Use Module fashion modeling 

For initialization parameters Module, in fact, very simple, if you want to initialize a layer which can be the same as Sequential redefine it directly Tensor, the only difference is that, if the use of loop access, need to introduce two properties, children and modules, we have the following examples to illustrate

class sim_net(nn.Module):
    def __init__(self):
        super(sim_net, self).__init__()
        self.l1 = nn.Sequential(
            nn.Linear(30, 40),
            nn.ReLU()
        )
        
        self.l1[0].weight.data = torch.randn(40, 30) # 直接对某一层初始化
        
        self.l2 = nn.Sequential(
            nn.Linear(40, 50),
            nn.ReLU()
        )
        
        self.l3 = nn.Sequential(
            nn.Linear(50, 10),
            nn.ReLU()
        )
    
    def forward(self, x):
        x = self.l1(x)
        x =self.l2(x)
        x = self.l3(x)
        return x

i = 0
for layer in net2.modules():
    print(i)
    i = i + 1
    if isinstance(layer, nn.Linear):
        param_shape = layer.weight.shape
        layer.weight.data = torch.from_numpy(np.random.normal(0, 0.5, size=param_shape)) 

i = 0
for layer in net2.children():
    print(i)
    i = i + 1
    if isinstance(layer[0], nn.Linear):
        param_shape = layer[0].weight.shape
        layer[0].weight.data = torch.from_numpy(np.random.normal(0, 0.5, size=param_shape))

Module traversal attribute, the output results are as follows:

0
1
2
3
4
5
6
7
8
9

Traversing children property when the output results are as follows:

0
1
2

Comparing the two outputs, not difficult to find, use the module approach to modeling, we model is traversed from top to bottom, while the use of chidren way can only be traversed on Sequetial model. Here we take a specific look at two different ways to traverse:

# 访问 modules
for i in net2.modules():
    print(i)
sim_net(
  (l1): Sequential(
    (0): Linear(in_features=30, out_features=40)
    (1): ReLU()
  )
  (l2): Sequential(
    (0): Linear(in_features=40, out_features=50)
    (1): ReLU()
  )
  (l3): Sequential(
    (0): Linear(in_features=50, out_features=10)
    (1): ReLU()
  )
)
Sequential(
  (0): Linear(in_features=30, out_features=40)
  (1): ReLU()
)
Linear(in_features=30, out_features=40)
ReLU()
Sequential(
  (0): Linear(in_features=40, out_features=50)
  (1): ReLU()
)
Linear(in_features=40, out_features=50)
ReLU()
Sequential(
  (0): Linear(in_features=50, out_features=10)
  (1): ReLU()
)
Linear(in_features=50, out_features=10)
ReLU()
# 访问 children
for i in net2.children():
    print(i)
Sequential(
  (0): Linear(in_features=30, out_features=40, bias=True)
  (1): ReLU()
)
Sequential(
  (0): Linear(in_features=40, out_features=50, bias=True)
  (1): ReLU()
)
Sequential(
  (0): Linear(in_features=50, out_features=10, bias=True)
  (1): ReLU()
)

 

 

Published 98 original articles · won praise 5 · views 10000 +

Guess you like

Origin blog.csdn.net/chengsilin666/article/details/83502039