Pytorch sequential 和ModuleList学习

Pytorch Sequential() ModuleList()学习

Sequential()

1.建立模型

import torch.nn as nn
import torch
import numpy as np

第一种方法:nn.Sequential()对象.add_module(层名,层class的实例)

net1=nn.Sequential()
net1.add_module('conv',nn.Conv2d(3,3,3))
net1.add_module('batchnorm',nn.BatchNorm2d(3))
net1.add_module('activation_layer',nn.ReLU())

第二种方法:nn.Sequential(多个层class的实例)

net2=nn.Sequential(
    nn.Conv2d(3,3,3),
    nn.BatchNorm2d(3),
    nn.ReLU()
    )

第三种方法:nn.Sequential(OrderedDict([层名,层class的实例]))

from collections import OrderedDict
net3=nn.Sequential(OrderedDict([
    ('conv',nn.Conv2d(3,3,3)),
    ('batchnorm',nn.BatchNorm2d(3)),
    ('activation_layer',nn.ReLU())
]))

2.查看模型

print(net1)
Sequential(
  (conv): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (batchnorm): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (activation_layer): ReLU()
)
print(net2)
Sequential(
  (0): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (1): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU()
)
print(net3)
Sequential(
  (conv): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (batchnorm): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (activation_layer): ReLU()
)

3.提取子module对象

net1.conv
Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
net2[0]
Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
net3.conv
Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))

4.调用模型

可以直接将数据输入网络中,也可以使用上面的Module子对象分别传入输入数据

a=torch.rand(1,3,4,4)
output1=net1(a)
output1.shape
torch.Size([1, 3, 2, 2])
output1=net2(a)
output1.shape
torch.Size([1, 3, 2, 2])
output1=net3(a)
output1.shape
torch.Size([1, 3, 2, 2])
output1=net3.conv(a)
output1.shape
torch.Size([1, 3, 2, 2])

5.查看每层参数

for name,parm in net1.named_parameters():
    print(name,parm)
conv.weight Parameter containing:
tensor([[[[ 0.1248, -0.1676, -0.0221],
          [-0.1005,  0.1782,  0.1286],
          [ 0.1199,  0.1207, -0.1452]],

         [[-0.1085,  0.0304,  0.0343],
          [-0.0180,  0.1129,  0.1154],
          [-0.0113,  0.0513, -0.0662]],

         [[-0.0264, -0.0293,  0.1318],
          [ 0.1089,  0.0927, -0.0658],
          [-0.1722,  0.0948,  0.1745]]],


        [[[ 0.1377,  0.1561,  0.0465],
          [-0.1419, -0.1055, -0.0563],
          [ 0.0818,  0.1034, -0.1776]],

         [[ 0.0144, -0.0388, -0.0545],
          [ 0.1214,  0.1893, -0.1189],
          [ 0.0596, -0.0839, -0.1748]],

         [[ 0.1665,  0.0308, -0.1102],
          [ 0.0777, -0.1707,  0.0012],
          [ 0.1142, -0.0522, -0.0888]]],


        [[[-0.0491, -0.1448, -0.0026],
          [ 0.0584, -0.1670,  0.1772],
          [-0.0135, -0.1363, -0.1036]],

         [[ 0.1768, -0.1662,  0.1386],
          [ 0.1426, -0.1009, -0.0828],
          [ 0.1675,  0.0223, -0.1242]],

         [[-0.1465,  0.0104,  0.1871],
          [-0.1870, -0.1127, -0.1707],
          [ 0.1605, -0.1369,  0.1509]]]])
conv.bias Parameter containing:
tensor(1.00000e-02 *
       [ 4.3432,  9.0630,  6.4161])
batchnorm.weight Parameter containing:
tensor([ 0.1980,  0.8656,  0.5977])
batchnorm.bias Parameter containing:
tensor([ 0.,  0.,  0.])

ModuleList()

​ ModuleList是Module的子类,当在Module中使用它的时候,可以自动识别为子module

  1. 建立模型
modellist=nn.ModuleList([nn.Linear(3,4),nn.ReLU(),nn.Linear(4,2)])
print(modellist)
ModuleList(
  (0): Linear(in_features=3, out_features=4, bias=True)
  (1): ReLU()
  (2): Linear(in_features=4, out_features=2, bias=True)
)
  1. 模型输入
input=torch.rand(1,3)
input
tensor([[ 0.5325,  0.4064,  0.4870]])
for model in modellist:
    input=model(input)
print(input)
tensor([[ 0.5814, -0.0939]])

如下使用方法将报错

output=modellist(input)
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-44-1418d0eaf845> in <module>
----> 1 output=modellist(input)

~/anaconda3/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    489             result = self._slow_forward(*input, **kwargs)
    490         else:
--> 491             result = self.forward(*input, **kwargs)
    492         for hook in self._forward_hooks.values():
    493             hook_result = hook(self, input, result)

~/anaconda3/lib/python3.6/site-packages/torch/nn/modules/module.py in forward(self, *input)
     81             registered hooks while the latter silently ignores them.
     82         """
---> 83         raise NotImplementedError
     84 
     85     def register_buffer(self, name, tensor):

NotImplementedError: 

ModuleList 类似于list,模型中未自动实现forward函数

class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.list = [nn.Linear(3, 4), nn.ReLU()]
        self.module_list = nn.ModuleList([nn.Conv2d(3, 3, 3), nn.ReLU()])
    def forward(self):
        pass
model = MyModule()
print(model)
MyModule(
  (module_list): ModuleList(
    (0): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
    (1): ReLU()
  )
)
for name, parm in model.named_parameters():
    print(name,parm.size())

MyModule(
(module_list): ModuleList(
​ (0): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
​ (1): ReLU()
)
)

module_list.0.weight torch.Size([3, 3, 3, 3])
module_list.0.bias torch.Size([3])

module_list.0.weight torch.Size([3, 3, 3, 3])
module_list.0.bias torch.Size([3])

​ list中的子module并不能被主module所识别,而ModuleList中的子module能够被主module所识别。这意味着如果用list保存子module,将无法调整其参数,因其未加入到主module的参数中。

结论:直接利用Sequential构建网络可以不用定义forward函数,利用ModuleList时需要构建forward函数,构建自己模型常用ModuleList函数建立子模型,建立forward函数实现前向传播;

参考:

https://www.cnblogs.com/hellcat/p/8477195.html

你可能感兴趣的:(PyTorch)