pytorch api文档:torch.nn.Sequential()按顺序堆叠神经网络层

作用

torch.nn.Sequential() 是 PyTorch 中用于按顺序堆叠神经网络层的容器,它会把传入的层按顺序封装,前一层的输出会自动作为后一层的输入,无需手动定义前向传播(forward)函数,能极大简化简单网络的编写。

简单来说:Sequential 就是“搭积木”,按顺序把网络层拼起来,自动完成数据的前向传递。

语法

nn.Sequential() 本质是一个类构造函数,有 3种常用语法形式,覆盖不同使用场景:

语法形式 适用场景 示例代码片段
空构造 + 动态添加层 需动态生成层(如循环创建层) model = nn.Sequential() <br> model.add_module('fc1', nn.Linear(10,20))
直接传入层对象(最常用) 静态、简单的串行网络 model = nn.Sequential(nn.Linear(10,20), nn.ReLU())
传入 OrderedDict 需自定义层名称(方便调试/访问) model = nn.Sequential(OrderedDict([('fc1', nn.Linear(10,20)), ('relu', nn.ReLU())]))

空构造 + add_module(动态添加)

import torch.nn as nn

# 空Sequential
model = nn.Sequential()
# 动态添加层:add_module(层名称, 层对象)
model.add_module("fc1", nn.Linear(10, 20))
model.add_module("relu1", nn.ReLU())
model.add_module("fc2", nn.Linear(20, 5))

# 测试
x = torch.randn(2, 10)
print(model(x).shape)  # torch.Size([2, 5])

直接传层对象(极简)

# 语法:nn.Sequential(层1, 层2, 层3, ...)
model = nn.Sequential(
    nn.Conv2d(3, 16, 3),  # 层1:卷积层
    nn.BatchNorm2d(16),   # 层2:归一化层
    nn.MaxPool2d(2)       # 层3:池化层
)

OrderedDict(自定义名称)

from collections import OrderedDict

# 语法:nn.Sequential(OrderedDict([(名称1, 层1), (名称2, 层2), ...]))
model = nn.Sequential(OrderedDict([
    ("conv1", nn.Conv2d(3, 16, 3)),
    ("bn1", nn.BatchNorm2d(16)),
    ("pool1", nn.MaxPool2d(2))
]))

# 可通过名称直接访问层
print(model.conv1)  # 输出:Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1))

注意

传入的必须是 nn.Module 子类

Sequential 只能封装 PyTorch 内置的层(如 nn.Linear、nn.Conv2d、nn.ReLU)或自定义的 nn.Module 子类,不能传入普通函数/张量:

# 错误示例:传入普通函数(如torch.relu)会报错
model = nn.Sequential(
    nn.Linear(10,20),
    torch.relu  # ❌ 不是nn.Module子类,应改用nn.ReLU()
)

# 正确示例:用nn.ReLU()(nn.Module子类)
model = nn.Sequential(
    nn.Linear(10,20),
    nn.ReLU()  # ✅ 合法
)

层的维度必须连续匹配

前一层的输出维度必须等于后一层的输入维度,否则前向传播会报维度不匹配错误:

# 错误示例:Linear(10,20)输出20维,下一层却要求输入15维
model = nn.Sequential(
    nn.Linear(10,20),  # 输出20维
    nn.Linear(15,5)    # ❌ 输入要求15维,维度不匹配
)

# 正确示例:维度连续
model = nn.Sequential(
    nn.Linear(10,20),  # 输出20维
    nn.Linear(20,5)    # ✅ 输入20维,匹配
)

无分支/跳跃逻辑

Sequential 强制按“串行”执行,无法实现分支(如ResNet残差连接)、多输入/多输出,这类场景必须用自定义 nn.Module。

无自动维度调整

比如卷积层输出的4维张量(N,C,H,W)直接接全连接层会报错,需要先用 nn.Flatten() 展平;

与自定义 Module 的区别

  • Sequential 是 nn.Module 的子类,具备 train()、eval()、to(device) 等所有Module的特性;
  • 自定义 nn.Module 需要重写 forward 函数,灵活性更高,Sequential 是简化版。

常用操作语法

操作 语法示例 说明
访问层 model[0] / model.fc1 按索引(默认名)或自定义名称访问层
查看网络结构 print(model) / model.named_parameters() 打印层信息/查看参数名称+值
设备迁移 model.to('cuda') / model.to(torch.device('cpu')) 把整个Sequential移到GPU/CPU
切换训练/评估模式 model.train() / model.eval() 对所有层生效(如BatchNorm、Dropout)

基础使用方法

1. 最简洁的写法(按顺序传层)

适合层的名称无需自定义的场景,PyTorch 会自动给每层分配默认名称(如 0、1、2)。

import torch
import torch.nn as nn

# 定义一个简单的全连接网络:输入→线性层→ReLU→线性层→输出
model = nn.Sequential(
    nn.Linear(10, 20),  # 输入维度10,输出维度20
    nn.ReLU(),          # 激活函数
    nn.Linear(20, 5)    # 输出维度5
)

# 测试前向传播
x = torch.randn(3, 10)  # 批量大小3,输入维度10
output = model(x)
print("输出形状:", output.shape)  # 输出: torch.Size([3, 5])

2. 自定义层名称(OrderedDict 写法)

如果需要给每层起有意义的名字(方便调试/查看网络结构),可以用 OrderedDict 封装:

from collections import OrderedDict

model = nn.Sequential(OrderedDict([
    ('fc1', nn.Linear(10, 20)),  # 命名为fc1
    ('relu1', nn.ReLU()),        # 命名为relu1
    ('fc2', nn.Linear(20, 5))    # 命名为fc2
]))

# 查看网络结构(能看到自定义名称)
print(model)
"""
输出:
Sequential(
  (fc1): Linear(in_features=10, out_features=20, bias=True)
  (relu1): ReLU()
  (fc2): Linear(in_features=20, out_features=5, bias=True)
)
"""

# 通过名称访问特定层
print(model.fc1)  # 输出: Linear(in_features=10, out_features=20, bias=True)

适用场景

1. 适用场景

  • 简单线性网络:层与层之间是“串行”关系,无分支、无跳跃连接(如简单的全连接网络、基础CNN);
  • 快速搭建原型:无需写 forward 函数,几行代码就能完成网络定义;
  • 嵌套使用:可以把一组层封装成 Sequential,再作为一个模块放入更大的 Sequential 中(比如CNN的卷积块)。

2. 不适用场景

  • 复杂网络:有分支(如ResNet的残差连接)、多输入/多输出、需要手动控制前向逻辑的网络(这类场景建议自定义 nn.Module 类);
  • 需要在forward中加额外逻辑:比如中间层输出的复用、动态调整层的执行顺序等。

进阶用法:嵌套 Sequential

实际项目中常把重复的层(如CNN的卷积+激活+池化)封装成 Sequential,再组合成大网络:

# 定义一个CNN网络:卷积块 + 全连接块
cnn_model = nn.Sequential(
    # 卷积块1:卷积→ReLU→池化
    nn.Sequential(
        nn.Conv2d(3, 16, kernel_size=3, padding=1),  # 输入通道3,输出通道16
        nn.ReLU(),
        nn.MaxPool2d(2)  # 池化后尺寸减半
    ),
    # 卷积块2:卷积→ReLU→池化
    nn.Sequential(
        nn.Conv2d(16, 32, kernel_size=3, padding=1),
        nn.ReLU(),
        nn.MaxPool2d(2)
    ),
    # 展平+全连接
    nn.Flatten(),
    nn.Linear(32 * 8 * 8, 10)  # 假设输入是3×32×32的图片,池化两次后是32×8×8
)

# 测试输入(批量大小2,3通道,32×32图片)
x = torch.randn(2, 3, 32, 32)
output = cnn_model(x)
print("CNN输出形状:", output.shape)  # 输出: torch.Size([2, 10])

总结

  1. nn.Sequential() 是 PyTorch 中按顺序堆叠网络层的便捷容器,自动实现前向传播,无需手写 forward;
  2. 有两种写法:直接传层(简洁)、用 OrderedDict 传层+名称(易调试);
  3. 适合搭建线性串行的简单网络,复杂网络(有分支/多输入)建议用自定义 nn.Module;
  4. 使用时核心要保证层的维度匹配,卷积转全连接需用 nn.Flatten() 展平。

原文出处:/show_1GW2e2mYQo9O.html