import torch
from torch import nn #神经网络模块
from d2l import torch as d2l #(drive into deep learning)class Reshape(torch.nn.Module):def forward(self, x):return x.view(-1, 16*3*3)net = torch.nn.Sequential( #序列化神经网络# 2d卷积层、输入通道数1,输出6,卷积核大小5*5,填充2nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),# 2*2 平均池化层,步幅2nn.AvgPool2d(2, stride=2),nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),nn.AvgPool2d(kernel_size=5, stride=2), nn.Flatten(), #扁平化层Reshape(),#重塑层nn.Linear(16*3*3,120), nn.Sigmoid(),nn.Linear(120,84), nn.Sigmoid(),nn.Linear(84,10))# 随机输入张量X
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:X = layer(X)# 打印当前层的类名和输出张量的形状print(layer.__class__.__name__, 'output shape: \t', X.shape)
Conv2d output shape: torch.Size([1, 6, 28, 28])
Sigmoid output shape: torch.Size([1, 6, 28, 28])
AvgPool2d output shape: torch.Size([1, 6, 14, 14])
Conv2d output shape: torch.Size([1, 16, 10, 10])
Sigmoid output shape: torch.Size([1, 16, 10, 10])
AvgPool2d output shape: torch.Size([1, 16, 3, 3])
Flatten output shape: torch.Size([1, 144])
Reshape output shape: torch.Size([1, 144])
Linear output shape: torch.Size([1, 120])
Sigmoid output shape: torch.Size([1, 120])
Linear output shape: torch.Size([1, 84])
Sigmoid output shape: torch.Size([1, 84])
Linear output shape: torch.Size([1, 10])
这段代码是一个简单的神经网络模型,用于对手写数字进行分类。让我逐步解释它:
import torch
: 导入 PyTorch 库。from torch import nn
: 从 PyTorch 库中导入神经网络模块。from d2l import torch as d2l
: 从 D2L(Dive into Deep Learning)库中导入 PyTorch 版本的模块,并使用别名d2l
。class Reshape(torch.nn.Module)
: 创建一个名为Reshape
的类,继承自torch.nn.Module
。这个类用于重塑输入张量的形状。
def forward(self, x)
: 定义了一个前向传播函数,接受输入张量x
,并返回经过重塑后的张量。net = torch.nn.Sequential(...)
:创建一个序列化的神经网络模型net
,其中包含了一系列的神经网络层。
nn.Conv2d(1, 6, kernel_size=5, padding=2)
: 添加一个 2D 卷积层,将输入通道数设为 1,输出通道数设为 6,卷积核大小为 5x5,填充为 2。nn.Sigmoid()
: 添加一个 Sigmoid 激活函数层。nn.AvgPool2d(2, stride=2)
: 添加一个 2x2 的平均池化层,步幅为 2。nn.Conv2d(6, 16, kernel_size=5)
: 添加另一个 2D 卷积层,将输入通道数设为 6,输出通道数设为 16,卷积核大小为 5x5。nn.Sigmoid()
: 添加一个 Sigmoid 激活函数层。nn.AvgPool2d(kernel_size=5, stride=2)
: 添加一个大小为 5x5 的平均池化层,步幅为 2。nn.Flatten()
: 添加一个扁平化层,将多维输入张量展平为一维。Reshape()
: 添加一个自定义的重塑层,用于将输入重塑为合适的形状。nn.Linear(16*3*3, 120)
: 添加一个全连接层,将输入特征数设为 16x3x3,输出特征数设为 120。nn.Sigmoid()
: 添加一个 Sigmoid 激活函数层。nn.Linear(120, 84)
: 添加另一个全连接层,输入特征数为 120,输出特征数为 84。nn.Sigmoid()
: 添加一个 Sigmoid 激活函数层。nn.Linear(84, 10)
: 添加最后一个全连接层,输入特征数为 84,输出特征数为 10(对应于10个类别)。X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
: 创建一个大小为 1x1x28x28 的随机输入张量X
,用于模型的输入。for layer in net:
: 遍历神经网络模型中的每一层。
X = layer(X)
: 将输入张量X
输入到当前层,并将输出赋值给X
,以便将其作为下一层的输入。print(layer.__class__.__name__, 'output shape: \t', X.shape)
: 打印当前层的类名和输出张量的形状。
在上述代码中,通过定义一个神经网络模型,该模型可以接受28x28像素的手写数字图像作为输入,并将其分类为数字0到9中的一个。这是因为该模型的最后一层是一个具有10个输出节点的全连接层,每个节点对应于一个数字类别。
在训练过程中,模型将学习如何从输入图像中提取特征,并通过这些特征对数字进行分类。具体来说,模型的各个层将在训练数据上进行参数优化,以便最小化预测输出与实际标签之间的差距(损失)。通过反向传播算法,模型将根据损失来更新自己的参数,从而逐渐提高对手写数字的分类准确率。
因此,这个模型被设计用于对手写数字进行分类。