Background overlay
952 字
5 分钟
07-Pytorch 构建NN网络实战
2026-04-28
更新中...

一、 神经网络骨架:nn.Module 基础结构#

所有的神经网络模块必须继承 nn.Module。它是封装参数、层逻辑及计算图的核心容器。

1. 结构规范#

  • __init__:定义层结构(如 nn.Conv2d, nn.Linear)。必须首先调用 super().__init__()

  • forward:定义数据流向。调用模型实例时(如 model(input)),会自动触发此方法。

import torch
from torch import nn
class TinyModel(nn.Module):
def __init__(self):
super(TinyModel, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 3)
def forward(self, x):
x = self.conv1(x)
return x

二、 卷积层 (Convolutional Layers)#

卷积层用于提取图像的空间特征。核心类为 nn.Conv2d

1. 核心参数解析#

  • in_channels:输入通道数(如 RGB 图像为 3)。

  • out_channels:输出通道数(卷积核的数量)。

  • kernel_size:卷积核大小(如 3(3, 5))。

  • stride:步长,默认为 1。控制卷积核滑动的频率。

  • padding:填充,在输入边界补零以控制输出尺寸。

  • dilation:空洞卷积系数,用于扩大感受野。

2. 尺寸计算公式#

输出特征图尺寸 HoutH_{out}WW 同理)计算如下:

Hout=Hin+2×paddingdilation×(kernel_size1)1stride+1H_{out} = \lfloor \frac{H_{in} + 2 \times \text{padding} - \text{dilation} \times (\text{kernel\_size} - 1) - 1}{\text{stride}} + 1 \rfloor

# 示例:输入 3 通道,输出 6 通道,5x5 卷积核
conv_layer = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=5, stride=1, padding=0)

三、 池化层 (Pooling Layers)#

池化用于下采样,主要目的是减小数据维度、降低运算量并增强特征的平移不变性。

1. 最大池化 (nn.MaxPool2d)#

  • 核心参数kernel_size (窗口大小), stride (默认等于 kernel_size), ceil_mode

  • ceil_mode:若为 True,则在计算输出尺寸时对结果向上取整,保留边界数据。

  • 特点:池化层不改变通道数,仅改变空间维度(H, W)。

# 示例:2x2 窗口最大池化
pool_layer = nn.MaxPool2d(kernel_size=2, ceil_mode=False)

四、 非线性激活与线性层#

1. 非线性激活 (Activations)#

激活函数为网络引入非线性能力,使其能够拟合复杂函数。

  • nn.ReLUf(x)=max(0,x)f(x) = \max(0, x)。最常用,计算效率高。inplace=True 参数可直接在原内存上修改数据,节省显存。

  • nn.Sigmoid:将输出映射到 (0,1)(0, 1)

2. 线性层 (Linear Layers)#

线性层(全连接层)用于特征的线性组合。

  • 参数in_features, out_features

  • 预处理:在输入线性层前,必须将多维特征图平铺(Flatten)。

# 逻辑:[Batch, 16, 5, 5] -> [Batch, 400] -> [Batch, 10]
flatten = nn.Flatten()
fc = nn.Linear(in_features=400, out_features=10)

五、 模型组装:Sequential 与实战搭建#

nn.Sequential 允许将多个层按顺序包装成一个整体。

1. CIFAR-10 模型示例#

典型的卷积神经网络流程:卷积 -> 激活 -> 池化 -> … -> 平铺 -> 全连接。

class CIFAR10Model(nn.Module):
def __init__(self):
super(CIFAR10Model, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, padding=2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, padding=2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, padding=2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4, 64),
nn.Linear(64, 10)
)
def forward(self, x):
return self.model(x)

六、 损失函数与反向传播#

损失函数用于衡量模型输出与真实值的差异,并为优化提供梯度方向。

1. 常见损失函数#

  • nn.L1Loss / nn.MSELoss:计算绝对差值或均方差。

  • nn.CrossEntropyLoss:适用于多分类。内部集成 Softmax,输入应为原始分数(Logits)。

2. 反向传播逻辑#

通过调用 loss.backward(),计算图中各节点参数的梯度 Lossw\frac{\partial \text{Loss}}{\partial w}

七、 优化器 (Optimizers)#

优化器基于梯度更新参数。

1. 核心流程#

  1. optimizer.zero_grad():清除上一次迭代累积的梯度。

  2. loss.backward():计算当前梯度。

  3. optimizer.step():根据梯度更新参数。

optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 训练过程中:
optimizer.zero_grad()
loss.backward()
optimizer.step()

八、 模型管理与工程技巧#

1. 预训练模型的使用#

利用 torchvision.models 加载现成网络。

  • 修改网络结构:如修改 VGG16 的分类层:vgg16.classifier = nn.Linear(4096, 10)

2. 权重保存与加载#

  • 推荐方式:仅保存状态字典(State Dict)。
# 保存
torch.save(model.state_dict(), "model_weights.pth")
# 加载
model = CIFAR10Model()
model.load_state_dict(torch.load("model_weights.pth"))

3. 测试与评估#

  • model.train() / model.eval():切换模型模式,影响 Dropout 和 BatchNorm。

  • torch.no_grad():在验证集上关闭梯度记录,显著降低内存开销。

model.eval()
with torch.no_grad():
outputs = model(imgs)
# 计算准确率等指标
07-Pytorch 构建NN网络实战
https://icemeow.top/blog/posts/graduate/pytorch-6/
作者
ICEMeow
发布于
2026-04-28
许可协议
CC BY-NC-SA 4.0