nn.moduleList 和Sequential由来、用法和实例 —— 写网络模型

本文详细解析了PyTorch中Sequential和ModuleList的使用方法,包括模型建立、检查与调用,以及两者之间的区别。通过具体示例展示了如何利用这两种工具简化神经网络的构建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于cnn前馈神经网络如果前馈一次写一个forward函数会有些麻烦,在此就有两种简化方式,ModuleList和Sequential。其中Sequential是一个特殊的module,它包含几个子Module,前向传播时会将输入一层接一层的传递下去。ModuleList也是一个特殊的module,可以包含几个子module,可以像用list一样使用它,但不能直接把输入传给ModuleList。下面举例说明。

目录

一、nn.Sequential()对象

1、模型建立方式

第一种写法:

 第二种写法:

第三种写法:

2、检查以及调用模型

查看模型

根据名字或序号提取子Module对象

调用模型

二、nn.ModuleList()对象

为什么有他?

什么时候用?

和list的区别?

1. extend和append方法

2. 建立以及使用方法

3. yolo v3构建网络

一、nn.Sequential()对象
建立nn.Sequential()对象,必须小心确保一个块的输出大小与下一个块的输入大小匹配。基本上,它的行为就像一个nn.Module。

 

1、模型建立方式

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

1

2

3

4

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的实例)

1

2

3

4

5

net2 = nn.Sequential(

        nn.Conv2d(3, 3, 3),

        nn.BatchNorm2d(3),

        nn.ReLU()

        )


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

1

2

3

4

5

6

from collections import OrderedDict

net3= nn.Sequential(OrderedDict([

          ('conv', nn.Conv2d(3, 3, 3)),

          ('batchnorm', nn.BatchNorm2d(3)),

          ('activation_layer', nn.ReLU())

        ]))

 

 

2、检查以及调用模型

查看模型
print对象即可

1

2

3

print('net1:', net1)

print('net2:', net2)

print('net3:', net3)

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

根据名字或序号提取子Module对象
1

2

# 可根据名字或序号取出子module

net1.conv, net2[0], net3.conv

(Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1)),
Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1)),
Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1)))

调用模型
可以直接网络对象(输入数据),也可以使用上面的Module子对象分别传入(input)。

1

2

3

4

5

input = V(t.rand(1, 3, 4, 4))

output = net1(input)

output = net2(input)

output = net3(input)

output = net3.activation_layer(net1.batchnorm(net1.conv(input)))

 

二、nn.ModuleList()对象
为什么有他?
写一个module然后就写foreword函数很麻烦,所以就有了这两个。它被设计用来存储任意数量的nn. module。

什么时候用?
如果在构造函数__init__中用到list、tuple、dict等对象时,一定要思考是否应该用ModuleList或ParameterList代替。

如果你想设计一个神经网络的层数作为输入传递。

和list的区别?
ModuleList是Module的子类,当在Module中使用它的时候,就能自动识别为子module。

当添加 nn.ModuleList 作为 nn.Module 对象的一个成员时(即当我们添加模块到我们的网络时),所有 nn.ModuleList 内部的 nn.Module 的 parameter 也被添加作为 我们的网络的 parameter。

 

class MyModule(nn.Module):
def __init__(self):
super(MyModule, self).__init__()
self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])

def forward(self, x):
# ModuleList can act as an iterable, or be indexed using ints
for i, l in enumerate(self.linears):
x = self.linears[i // 2](x) + l(x)
return x
1. extend和append方法
nn.moduleList定义对象后,有extend和append方法,用法和python中一样,extend是添加另一个modulelist  append是添加另一个module

class LinearNet(nn.Module):
def __init__(self, input_size, num_layers, layers_size, output_size):
super(LinearNet, self).__init__()

self.linears = nn.ModuleList([nn.Linear(input_size, layers_size)])
self.linears.extend([nn.Linear(layers_size, layers_size) for i in range(1, self.num_layers-1)])
self.linears.append(nn.Linear(layers_size, output_size)
2. 建立以及使用方法
建立以及使用方法如下,

1

2

3

4

5

6

modellist = nn.ModuleList([nn.Linear(3,4), nn.ReLU(), nn.Linear(4,2)])

input = V(t.randn(1, 3))

for model in modellist:

    input = model(input)

# 下面会报错,因为modellist没有实现forward方法

# output = modelist(input)

 

和普通list不一样,它和torch的其他机制结合紧密,继承了nn.Module的网络模型class可以使用nn.ModuleList并识别其中的parameters,当然这只是个list,不会自动实现forward方法,

1

2

3

4

5

6

7

8

9

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()
)
)
1

2

for name, param in model.named_parameters():

    print(name, param.size())

('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的参数中。

除ModuleList之外还有ParameterList,其是一个可以包含多个parameter的类list对象。在实际应用中,使用方式与ModuleList类似。

 

3. yolo v3构建网络
首先module_list = nn.ModuleList()

然后 

  for index, x in enumerate(blocks[1:]):#根据不同的block 遍历module

        module = nn.Sequential()

        然后根据cfg读进来的数据,

        module.add_module("batch_norm_{0}".format(index), bn)

        module.add_module("conv_{0}".format(index), conv)

         等等

         module_list.append(module)

 
---------------------
作者:Snoopy_Dream
来源:优快云
原文:https://blog.youkuaiyun.com/e01528/article/details/84397174
版权声明:本文为博主原创文章,转载请附上博文链接!

### PyTorch 中 Layer Module 的区别 在 PyTorch 中,`Layer` 并不是一个正式的类名称;通常所说的 `Layer` 实际上是指那些具体的功能模块,比如线性变换层 (`Linear`) 或卷积层 (`Conv2d`) 等。而 `Module` 是指 `torch.nn.Module` 类及其派生类。 #### 自定义层、块、模型通过继承 `Module` 实现的方式 为了创建更复杂的网络结构或特定功能组件,在实际应用中经常需要自定义新的神经网络单元。这时就可以利用 Python 面向对象编程特性中的继承机制,从 `nn.Module` 基础类派生出自定义的新类[^1]。 下面给出一个简单的例子展示如何定义一个新的全连接多层感知器 (MLP): ```python import torch from torch import nn class MLP(nn.Module): def __init__(self, input_dim=784, hidden_dim=256, output_dim=10): super().__init__() self.fc1 = nn.Linear(input_dim, hidden_dim) self.relu = nn.ReLU() self.fc2 = nn.Linear(hidden_dim, output_dim) def forward(self, x): out = self.fc1(x) out = self.relu(out) out = self.fc2(out) return out ``` 在这个例子中: - 定义了一个名为 `MLP` 的新类,它是 `nn.Module` 的子类; - 初始化函数 `__init__()` 构建了两层线性转换加上激活函数 ReLU 形成的基础架构; - `forward()` 方法描述了数据流经此模型的具体路径[^2]。 #### 使用 `Sequential`, `ModuleList`, `ModuleDict` 方便构建复杂模型 除了直接继承 `nn.Module` 来设计模型外,PyTorch 提供了一些辅助工具帮助简化某些场景下的开发工作。例如: - **Sequential**: 当各层之间顺序排列时非常有用,可以直接按照列表形式传递多个层实例给它构造整个模型[^3]。 ```python model = nn.Sequential( nn.Conv2d(in_channels=1, out_channels=20, kernel_size=(5, 5)), nn.MaxPool2d(kernel_size=(2, 2)) ) ``` - **ModuleList** 及 **ModuleDict**: 对于动态调整层数量或者管理一组具有相同性质但是不同参数设置的层来说特别适用。 综上所述,虽然有时人们习惯把像 `Linear` 这样的基础操作称为 “layer”,但在 PyTorch 文档技术社区讨论中,“module” 更加广泛地用来表示任何由这些基本构件组成的更大规模的对象——无论是单一层还是完整的深度学习模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值