nn.Sequential
是 PyTorch 中的一个容器模块,它按照模块在构造函数中传入的顺序,依次包含多个子模块(可以是层、激活函数、dropout等)。在nn.Sequential
中,数据会按照定义的顺序依次通过这些子模块。
使用nn.Sequential
时,不需要定义forward
方法,因为数据会自动按照顺序传递给序列中的每个模块。这使得在构建简单的、层与层之间直接连接的网络时,代码更加简洁和清晰。
下面是一个简单的例子,展示了如何使用nn.Sequential
:
import torch
from torch import nn
# 创建一个简单的Sequential模型
model = nn.Sequential(
nn.Linear(784, 128), # 输入层到隐藏层,784个输入节点,128个输出节点
nn.ReLU(), # 激活函数
nn.Linear(128, 10), # 隐藏层到输出层,128个输入节点,10个输出节点(假设有10个类别)
)
# 创建一个随机输入张量,形状为(batch_size, 784),例如(1, 784)
input_tensor = torch.randn(1, 784)
# 通过模型前向传播
output_tensor = model(input_tensor)
# 输出张量的形状现在是(batch_size, 10),例如(1, 10)
print(output_tensor.shape)
在上面的例子中,nn.Sequential
包含了两个nn.Linear
层和一个nn.ReLU
激活函数。输入数据首先通过第一个线性层(全连接层),然后经过ReLU激活函数,最后通过第二个线性层。每个子模块都会按照它们在nn.Sequential
构造函数中的顺序被调用。
nn.Sequential
的参数是一个子模块的列表(或其他可迭代对象)。这些子模块可以是任何继承自nn.Module
的类实例,比如nn.Linear
、nn.Conv2d
、nn.ReLU
、nn.Dropout
等。每个子模块都会按照它们在列表中的顺序被调用,并且数据会在它们之间传递。
需要注意的是,nn.Sequential
不会添加任何额外的层(如池化层或批量归一化层),这些层需要单独添加到模型中。此外,虽然nn.Sequential
使得代码更加简洁,但对于复杂的网络结构(如包含分支或跳跃连接的网络),你可能需要使用nn.Module
来定义自己的模型类,并在其中定义forward
方法。
示意图描述如下:
输入层 (784个节点) ---\
| \
| \-----> 隐藏层 (128个节点,经过ReLU激活)
| /
| /
输出层 (10个节点) ---/
解释:
-
输入层:有784个节点,这通常对应于一个28x28像素的图像(因为28x28=784)。在神经网络的开始,输入数据(如图像)被连接到输入层的每个节点。
-
隐藏层:有128个节点。输入层的数据首先通过一个线性变换(
nn.Linear(784, 128)
)传递到隐藏层,然后经过一个ReLU激活函数(nn.ReLU()
)。ReLU函数会对每个节点的输出应用非线性变换,使得神经网络能够学习复杂的模式。 -
输出层:有10个节点,这通常对应于一个分类任务中的10个不同类别。隐藏层的数据通过一个线性变换(
nn.Linear(128, 10)
)传递到输出层,输出层将产生每个类别的分数或概率。
在实际应用中,每个节点(或神经元)都与其前一层的所有节点以及其后一层的所有节点相连(全连接),并通过权重和偏置参数进行转换。这些权重和偏置参数在训练过程中会被优化,以最小化预测误差。