pytorch小记(二十八):pytorch中`nn.Sequential` 详解
·
pytorch小记(二十八):pytorch中`nn.Sequential` 详解
深入浅出 PyTorch 中的 nn.Sequential —— 简洁高效地串联模型层
在 PyTorch 中,nn.Sequential 是一个非常方便的容器,它能让你像搭积木一样,把多个层(Module)按顺序拼接起来,自动管理子模块的注册和调用。本文将带你从原理到实战,全面了解并掌握 nn.Sequential 的用法与注意事项。
一、nn.Sequential 的核心作用
- 简化模型定义
当网络结构仅是线性堆叠(Conv→ReLU→Pool→FC…),用Sequential可以少写大量forward里的调用语句。 - 自动管理子模块
传入Sequential的每个Module都会被自动注册,你无需再手动在__init__中用self.xxx = …。 - 统一状态切换
调用model.train()或model.eval()时,Sequential会递归地切换所有子模块的训练/推理状态。
二、两种构造方式
方式一:按顺序传入模块实例
import torch.nn as nn
model = nn.Sequential(
nn.Conv2d(3, 16, kernel_size=3, padding=1),
nn.BatchNorm2d(16),
nn.ReLU(inplace=True),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(16*16*16, 10)
)
方式二:使用有序字典,为模块命名
from collections import OrderedDict
import torch.nn as nn
model = nn.Sequential(OrderedDict([
("conv1", nn.Conv2d(3, 16, 3, padding=1)),
("bn1", nn.BatchNorm2d(16)),
("relu1", nn.ReLU()),
("pool", nn.MaxPool2d(2)),
("flat", nn.Flatten()),
("fc", nn.Linear(16*16*16, 10)),
]))
- 按索引访问:
model[0],model[3] - 按名称访问:
model.conv1,model["bn1"]
三、工作原理
调用 output = model(input) 时,Sequential 会依次执行:
x = input
for layer in model:
x = layer(x)
return x
等价于你手动在 forward 中一层层调用,但更简洁。
四、适用场景
- 简单前馈网络
只有单条数据流,没有残差或并行支路。 - 快速原型搭建
调试、试验新想法时,能快速串联层并测试结果。 - 子模块封装
在复杂模型中,将一段“直线”子结构封装成Sequential,便于维护和重用。
五、常见误区与局限
- 不支持分支/跳跃
对于 ResNet 的x + F(x)、Inception 模块的多路径并行,都需自定义nn.Module并在forward中写明逻辑。 - 无法在中间“取特征”
若想在中间层同时获取多个中间输出,需要自己在forward中拆分。
六、与 ModuleList、ModuleDict 区别
| 容器 | 自动调用 | 应用场景 |
|---|---|---|
| Sequential | 是 | 线性堆叠的层,前向一步到位 |
| ModuleList | 否 | 存多组子模块,在 forward 中手动迭代或条件调用 |
| ModuleDict | 否 | 存命名子模块,动态路由或条件分支 |
七、实战示例:小型卷积分类器
import torch
import torch.nn as nn
class SimpleCNN(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
# 特征提取部分
self.features = nn.Sequential(
nn.Conv2d(3, 32, 3, padding=1), # [B,3,32,32] -> [B,32,32,32]
nn.ReLU(),
nn.MaxPool2d(2), # -> [B,32,16,16]
nn.Conv2d(32, 64, 3, padding=1), # -> [B,64,16,16]
nn.ReLU(),
nn.MaxPool2d(2), # -> [B,64,8,8]
)
# 分类器部分也用 Sequential
self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(64*8*8, 256),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(256, num_classes)
)
def forward(self, x):
x = self.features(x)
x = self.classifier(x)
return x
# 测试
model = SimpleCNN(num_classes=100)
print(model)
# 输出:可直接用 model(torch.randn(4,3,32,32)) 得到 [4,100] 的 logits
八、小结
nn.Sequential就是**“顺序容器”**,让你轻松串联层、自动注册子模块、统一切换状态。- 适合线性前馈、快速原型、子模块封装场景;对复杂分支、残差则需自定义
Module。 - 灵活运用,能让你的 PyTorch 代码更简洁、更可读、更易维护。
更多推荐



所有评论(0)