共计 2059 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要 CNN?
传统全连接网络处理图像时,参数量会随分辨率暴增。对于一个 28×28 的 MNIST 图像:
- 全连接层输入维度:28×28=784
- 假设隐藏层 500 节点,仅第一层参数就达 784×500=392,000 个
而同样情况下,使用 3×3 卷积核、32 个滤波器的 CNN 层参数仅 32×(3×3+1)=320 个(+ 1 为偏置项)。这种局部连接和权值共享特性,使 CNN 特别适合处理高维空间数据。
卷积操作的本质
-
数学表达:离散卷积运算可表示为
$$(I * K)(i,j) = \sum_{m}\sum_{n} I(i+m,j+n)K(m,n)$$
其中 $I$ 是输入矩阵,$K$ 是卷积核 -
可视化理解:
- 想象一个滑动窗口在图像上逐像素移动
- 每次窗口内进行元素乘加运算
-
最终得到特征响应图(feature map)
-
关键参数:
- Padding:在边缘补零控制输出尺寸
- Stride:滑动步长影响下采样率

PyTorch 实战 MNIST 分类
模型定义
import torch
import torch.nn as nn
model = nn.Sequential(
# 卷积层 1:输入 1 通道,输出 32 通道,3x3 卷积核
nn.Conv2d(1, 32, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2), # 2x2 最大池化
# 卷积层 2:32→64 通道
nn.Conv2d(32, 64, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
# 展平后接全连接层
nn.Flatten(),
nn.Linear(64*7*7, 128), # MNIST 经过两次池化后尺寸 7x7
nn.ReLU(),
nn.Linear(128, 10)
)
训练流程
from torchvision import datasets, transforms
# 数据预处理
transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,)) # MNIST 均值和标准差
])
train_data = datasets.MNIST('../data', train=True, download=True, transform=transform)
# 关键步骤:创建 DataLoader 时设置 pin_memory=True 可加速 GPU 传输
train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
# 训练循环
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
for epoch in range(10):
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward() # 反向传播
optimizer.step() # 参数更新
调参技巧
- 学习率与 batch size:
- 大 batch size 可配合更大学习率(建议比例:lr∝√batch_size)
-
使用学习率预热 (warmup) 避免初期震荡
-
网络结构分析:
from torchsummary import summary summary(model, input_size=(1, 28, 28)) # 输出各层参数统计 -
早停法实现:
best_loss = float('inf') patience = 3 counter = 0 for epoch in range(100): val_loss = validate(model, val_loader) if val_loss < best_loss: best_loss = val_loss counter = 0 torch.save(model.state_dict(), 'best_model.pt') else: counter += 1 if counter >= patience: print('Early stopping!') break
常见问题解决方案
- 维度错误:
- PyTorch 默认 NCHW 格式(批次数×通道数×高×宽)
-
遇到 NHWC 数据时需 permute(0,3,1,2)
-
显存不足:
- 减小 batch size
- 使用混合精度训练(torch.cuda.amp)
-
梯度累积:多次 forward 后统一 backward
-
卷积核设计:
- 小尺寸(3×3)卷积堆叠效果优于大卷积核
- 最后一层特征图尺寸不宜小于 7×7
延伸思考
当处理 4 通道 DICOM 医学影像时:
– 修改第一层 Conv2d 的 in_channels 参数为 4
– 注意预处理时对每个通道单独归一化
– 可能需要增加初始卷积核数量捕捉多通道特征
通过这个实战流程,我们实现了从理论到实践的完整闭环。建议读者尝试调整网络深度、卷积核数量等参数,观察对模型性能的影响。
正文完
发表至: 未分类
四天前
