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 是一个高效的深度学习框架,其中nn.modulelist 和 nn.sequential是常用的模块。这两种模块都可以用于创建深度学习网络,并且能够实现自动求导。nn.sequential 是一个有序的容器,其中每个模块按照传入的顺序依次进行计算。nn.modulelist 是一个无序的容器,其中每个模块都可以以列表的形式存储,且没有特定的计算顺序。 nn.sequential 模块的优点是简单易用,并且可以通过一行代码构建和训练网络。例如,要创建一个简单的两层全连接神经网络,可以如下代码实现: ``` model = nn.Sequential(nn.Linear(784, 64), nn.ReLU(), nn.Linear(64, 10), nn.Softmax(dim=1)) ``` 这会定义一个两个全连接层网络以及 ReLU 和softmax 激活函数,输入大小为 784(MNIST 图像大小) ,输出大小为 10(10 个数字)。 nn.modulelist 是一个更加灵活的容器,可以在其中添加任意的子模块。要使用 nn.modulelist,需要先创建一个空的 nn.modulelist,然后手动向其中添加子模块。例如,可以这样创建一个相同的两层全连接网络: ``` model = nn.ModuleList([ nn.Linear(784, 64), nn.ReLU(), nn.Linear(64, 10), nn.Softmax(dim=1) ]) ``` 需要注意的是,nn.modulelist 中的子模块顺序可能会影响计算结果,因为没有特定的训练顺序。因此,在使用 nn.modulelist 时应该尽量保证顺序的准确性。 综上所述,nn.sequential 和 nn.modulelist 都是常用的容器,用于组织神经网络中的子模块,它们在不同场景下具有各自的优势。在简单的前向计算中,nn.sequential 更加容易使用;在需要更好的灵活性时,nn.modulelist 可以更好地实现目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值