共计 1499 个字符,预计需要花费 4 分钟才能阅读完成。
过拟合的数学本质
过拟合本质上反映了模型复杂度和数据量之间的失衡。从 VC 维理论 来看,当模型容量($d_{vc}$)远大于训练样本数($N$)时,模型会记住训练数据噪声而非学习泛化规律,导致泛化误差 $\epsilon$ 满足:

$$
\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)
- 划分 10%-20% 验证集
- 监控验证 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 正则(可能过度稀疏化)
- 早停法:验证集需与测试集同分布
思考题
- 当验证 loss 震荡时,如何通过训练 / 验证误差曲线区分欠拟合和过拟合?
- 设计 A / B 测试:同一模型有无 Dropout 时的测试集表现差异
正文完
发表至: 未分类
近一天内
