共计 1854 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点:识别过拟合现象
刚开始接触 BasicCNN 时,我在一个小型图像分类数据集(约 5000 张图片)上训练时发现:虽然训练准确率很快达到 95% 以上,但验证集准确率始终卡在 65% 左右。通过绘制 F1-score 和损失曲线,可以清晰看到过拟合的典型特征:

- 训练损失持续下降,但验证损失在 10 个 epoch 后开始反弹
- 训练集 F1-score 接近 1.0,验证集 F1-score 在 0.7 附近震荡
- 两者差距随时间不断扩大
这种现象说明模型在死记硬背训练数据,却无法泛化到新样本。接下来我将分享解决这个问题的完整方案。
技术方案:三管齐下对抗过拟合
1. 数据增强实战技巧
通过 torchvision.transforms 实现动态数据增强,关键参数设置:
transform_train = transforms.Compose([transforms.RandomHorizontalFlip(p=0.5), # 水平翻转概率
transforms.RandomRotation(15), # 旋转角度范围
transforms.ColorJitter(brightness=0.2), # 亮度变化幅度
transforms.ToTensor()])
- 注意不要过度增强(如旋转 180 度会改变图像语义)
- 验证集必须使用原始预处理,不添加任何随机变换
2. L2 正则化调参实验
在 PyTorch 中实现权重衰减(等效 L2 正则):
optimizer = torch.optim.Adam(model.parameters(),
lr=0.001,
weight_decay=1e-4 # lambda 值
)
通过网格搜索测试不同 lambda 值效果:
| lambda 值 | 验证准确率 | 过拟合程度 |
|---|---|---|
| 0 | 65% | 严重 |
| 1e-5 | 68% | 中等 |
| 1e-4 | 72% | 轻微 |
| 1e-3 | 70% | 可能欠拟合 |
3. Dropout 层最佳实践
在 CNN 架构中合理插入 Dropout 层:
self.features = nn.Sequential(nn.Conv2d(3, 32, 3),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Dropout(0.25), # 推荐初始值
nn.Conv2d(32, 64, 3)
)
- 全连接层前建议使用较高比率(0.5)
- 卷积层后建议使用较低比率(0.1-0.3)
完整训练代码示例
# 训练循环核心代码
for epoch in range(100):
model.train()
for inputs, labels in train_loader:
optimizer.zero_grad()
outputs = model(inputs)
loss = F.cross_entropy(outputs, labels)
loss.backward()
optimizer.step()
# TensorBoard 记录
writer.add_scalar('Loss/train', loss.item(), epoch)
# 验证阶段
model.eval()
with torch.no_grad():
val_loss = 0
correct = 0
for inputs, labels in val_loader:
outputs = model(inputs)
val_loss += F.cross_entropy(outputs, labels).item()
pred = outputs.argmax(dim=1)
correct += pred.eq(labels).sum().item()
val_acc = correct / len(val_loader.dataset)
writer.add_scalar('Accuracy/val', val_acc, epoch)
避坑指南:新手常见误区
- 过早停止训练:看到验证损失上升就停止,可能错过模型自我调整阶段
- Dropout 滥用:在全连接层使用 0.8 等高比率会阻碍有效学习
- 忽略 BatchNorm:未配合使用批量归一化会导致梯度不稳定
实验结果对比
在 CIFAR-10 测试集上的效果提升:
| 方法 | 原始准确率 | 优化后准确率 |
|---|---|---|
| 基础 CNN | 65.2% | – |
| + 数据增强 | – | 71.8% |
| +L2 正则化 | – | 74.3% |
| +Dropout | – | 76.1% |
| 组合方案 | – | 79.4% |
延伸思考
这些技术同样适用于更复杂的架构:
- 在 ResNet 中可以尝试调整各阶段的 Dropout 位置
- 对于 Transformer 模型,attention 层的 dropout 同样关键
- 结合标签平滑 (label smoothing) 能进一步提升效果
建议下一步尝试将这些技巧应用到自定义数据集上,观察不同数据分布下的效果差异。记住:没有放之四海皆准的超参数,持续实验才是王道!
正文完
