深度学习中的过拟合问题:原理剖析与7大实用解决方案

1次阅读
没有评论

共计 1499 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

过拟合的数学本质

过拟合本质上反映了模型复杂度和数据量之间的失衡。从 VC 维理论 来看,当模型容量($d_{vc}$)远大于训练样本数($N$)时,模型会记住训练数据噪声而非学习泛化规律,导致泛化误差 $\epsilon$ 满足:

深度学习中的过拟合问题:原理剖析与 7 大实用解决方案

$$
\epsilon \leq \sqrt{\frac{d_{vc}(\log(2N/d_{vc})+1)-\log(\eta/4)}{N}}
$$

损失函数曲面 角度,过拟合表现为训练损失陷入局部极低点(下图左),而测试损失开始上升(下图右):

import matplotlib.pyplot as plt
plt.figure(figsize=(10,4))
plt.subplot(121).plot(train_loss, label='Train')
plt.subplot(122).plot(test_loss, label='Test')  # 典型过拟合曲线

7 大解决方案详解

1. Dropout 层

  • 原理:前向传播时随机断开神经元连接(概率 $p$ 通常设 0.2-0.5)
  • PyTorch 实现
    self.drop = nn.Dropout(p=0.3)  # 输入层建议 p 较小
  • 注意 :训练时需显式调用model.train(),预测时用model.eval() 关闭

2. L1/L2 正则化

类型 梯度变化 适用场景
L1 $\text{sign}(w)$ 特征选择
L2 $w$ 平滑权重

3. 早停法(Early Stopping)

  1. 划分 10%-20% 验证集
  2. 监控验证 loss 连续 $k$ 次不下降时终止

4. 数据增强

  • CV:旋转 / 裁剪 / 颜色抖动
    transforms.RandomHorizontalFlip(p=0.5)
  • NLP:同义词替换 / 回译 / 随机插入

5. 批归一化(BatchNorm)

  • 副作用:依赖 batch 统计量,小 batch 时不稳定
  • 改进 LayerNorm 更适合 RNN

6. 模型剪枝

  • 阈值选择:移除权重绝对值 <0.01 的连接
    torch.abs(weight) < threshold  # 结构化剪枝更实用

7. 集成学习

  • Bagging:并行训练多个子模型(如随机森林)
  • 关键:子模型间需要差异性

代码实战:组合防御

import torch.nn as nn

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 512)
        self.drop = nn.Dropout(0.4)  # 隐藏层用较高 dropout 率
        self.fc2 = nn.Linear(512, 10)

    def forward(self, x):
        x = self.drop(torch.relu(self.fc1(x)))
        return self.fc2(x)

# 自定义 L2 正则化
def l2_penalty(params, alpha=0.01):
    return alpha * sum(p.pow(2).sum() for p in params)

# 训练循环示例
for epoch in range(100):
    model.train()
    loss = criterion(outputs, labels) + l2_penalty(model.parameters())

    model.eval()
    with torch.no_grad(): val_loss = criterion(model(val_x), val_y)

生产环境建议

  • 小数据集:优先采用数据增强(成本最低)
  • 高维稀疏特征:避免 L1 正则(可能过度稀疏化)
  • 早停法:验证集需与测试集同分布

思考题

  1. 当验证 loss 震荡时,如何通过训练 / 验证误差曲线区分欠拟合和过拟合?
  2. 设计 A / B 测试:同一模型有无 Dropout 时的测试集表现差异
正文完
 0
评论(没有评论)