什么是过拟合,如何解决?

第4题:什么是过拟合,如何解决?

一、什么是过拟合?

过拟合(Overfitting)指模型在训练数据上表现很好,但在新的、未见过的数据上表现明显变差。

机器学习真正关心的是模型的泛化能力,也就是:

模型在训练过程中没有见过的数据上,能否保持良好的预测性能。

假设训练误差为:

Etrain E_{\text{train}} Etrain

验证误差为:

Eval E_{\text{val}} Eval

如果模型继续训练后:

Etrain↓ E_{\text{train}} \downarrow Etrain

但:

Eval↑ E_{\text{val}} \uparrow Eval

或者训练集与验证集之间的性能差距不断扩大,就需要怀疑出现了过拟合。

可以将泛化差距简单写成:

$$
\text{Generalization Gap}

E_{\text{val}}-E_{\text{train}}
$$

这个差距明显增大,通常意味着模型对训练数据中的特定模式拟合过强。

需要注意:

“训练 loss 继续下降、验证 loss 开始上升”是典型的过拟合现象,但不是唯一的判断方式。

在分类任务中也可能表现为:

  • 训练集 Accuracy 很高;
  • 验证集 Accuracy 明显较低;
  • 训练集 F1 很高;
  • 验证集 F1 明显下降。

核心始终是:

训练数据表现与未见数据表现之间出现明显的泛化差距。


二、为什么会发生过拟合?

常见原因主要有以下几类。

1. 模型容量相对于数据过大

例如:

  • 网络层数过深;
  • 参数数量很多;
  • 特征数量很多;
  • 决策树过深。

模型具有很强的表达能力时,可能把训练数据中的偶然模式和噪声也学习进去。

因此通常需要在:

拟合能力 \text{拟合能力} 拟合能力

和:

泛化能力 \text{泛化能力} 泛化能力

之间取得平衡。


2. 训练数据太少

如果数据量相对于模型复杂度过小,模型很容易记住训练样本中的细节。

例如一个参数量很大的神经网络,只使用很少的样本训练时,可能获得很低的训练误差,但在新数据上表现较差。


3. 训练数据缺乏代表性

即使训练数据数量很多,如果它无法覆盖实际部署环境,也可能产生很大的泛化误差。

例如训练数据全部来自环境 A,而实际部署数据主要来自环境 B。

此时:

Ptrain(X,Y) P_{\text{train}}(X,Y) Ptrain(X,Y)

和真实应用中的:

Preal(X,Y) P_{\text{real}}(X,Y) Preal(X,Y)

存在明显差异。

模型在训练集上表现很好,也不能保证实际效果。


4. 数据中存在噪声或偶然相关性

复杂模型可能学习到与任务目标没有稳定因果关系的模式。

例如:

  • 背景颜色;
  • 文件路径;
  • 数据采集设备;
  • 时间戳;
  • 特定模板;
  • 标签生成过程留下的特征。

这些特征可能在训练数据中与标签高度相关,但换到新的数据后关系消失。


5. 训练时间过长

神经网络训练初期通常先学习较稳定的模式。

继续训练后,模型可能逐渐拟合训练数据中的细节和噪声。

因此可能出现:

Training Loss
持续下降

Validation Loss
先下降
↓
达到最低点
↓
开始上升

这也是 Early Stopping 的主要依据。


三、如何解决过拟合?

处理过拟合时,建议先判断原因,再选择措施。


方法1:先检查数据泄漏

这是实际项目中非常重要的一步。

数据泄漏(Data Leakage)指模型训练过程中使用了预测时本来无法获得的信息。

例如:

  • 测试集参与训练;
  • 在全部数据上计算归一化参数后再划分训练集和测试集;
  • 特征选择时使用了测试集;
  • 同一用户的数据同时出现在训练集和测试集;
  • 同一项目的高度相似样本同时进入训练集和测试集;
  • 时间序列任务中使用未来数据预测过去。

这种情况下可能看到:

Validation Accuracy≈99% \text{Validation Accuracy} \approx 99\% Validation Accuracy99%

但上线后性能突然下降。

因此排查顺序应该首先包括:

  1. 检查训练集、验证集、测试集是否真正隔离;
  2. 检查重复样本;
  3. 检查同源样本;
  4. 检查预处理是否泄漏;
  5. 检查标签是否能够从输入中的某些异常特征直接推断。

数据泄漏属于评测设计错误,需要与模型本身的过拟合分开诊断。


方法2:增加高质量且具有代表性的数据

如果训练数据不足,可以增加训练样本。

通常:

更多有效数据→更难记忆单个训练样本→更容易学习稳定规律 \text{更多有效数据} \rightarrow \text{更难记忆单个训练样本} \rightarrow \text{更容易学习稳定规律} 更多有效数据更难记忆单个训练样本更容易学习稳定规律

这里的关键是“有效”和“具有代表性”。

增加大量重复、错误或分布偏移的数据,可能无法提高泛化能力。


方法3:数据增强

如果无法直接获得更多真实数据,可以使用合理的数据增强。

例如图像任务中:

  • Random Crop;
  • Flip;
  • Rotation;
  • Color Jitter。

数据增强希望在保持标签语义不变的条件下增加输入变化。

可以写成:

(x,y)→(T(x),y) (x,y) \rightarrow (T(x),y) (x,y)(T(x),y)

其中 TTT 是不会改变真实标签的数据变换。

有效的数据增强可以减少模型对单一样本形式的依赖。


方法4:降低模型复杂度

如果模型容量明显超过任务需求,可以减少模型复杂度。

例如:

  • 减少网络层数;
  • 减少隐藏层维度;
  • 减少参数量;
  • 减少无效特征;
  • 限制决策树深度。

目标是降低模型拟合训练噪声的能力。


方法5:L1 / L2 正则化

正则化通过在原始训练目标中加入复杂度惩罚,限制参数自由度。

原始目标可能是:

min⁡θL(θ) \min_\theta L(\theta) θminL(θ)

加入 L2 正则化后:

min⁡θ[L(θ)+λ∥θ∥22] \min_\theta \left[ L(\theta) + \lambda \|\theta\|_2^2 \right] θmin[L(θ)+λθ22]

其中:

  • L(θ)L(\theta)L(θ):原始任务损失;
  • ∣θ∣22|\theta|_2^2θ22:参数平方和;
  • λ\lambdaλ:正则化强度。

λ\lambdaλ 越大,模型受到的参数约束通常越强。

L1 正则化可以写成:

min⁡θ[L(θ)+λ∥θ∥1] \min_\theta \left[ L(\theta) + \lambda \|\theta\|_1 \right] θmin[L(θ)+λθ1]

L1 还具有促进参数稀疏的特点。


方法6:Weight Decay

在深度学习中经常使用 Weight Decay 限制权重增长。

在很多常见优化设置下,它与 L2 正则化具有密切联系。

例如训练时设置:

optimizer = torch.optim.AdamW(
    model.parameters(),
    lr=1e-4,
    weight_decay=1e-2
)

需要注意具体优化器。

AdamW 使用 decoupled weight decay,其更新机制需要与直接在 loss 中添加 L2 penalty 区分理解。


方法7:Dropout

Dropout 是神经网络中常见的正则化方法。

训练过程中随机将部分神经元输出置零:

hi′=mihih'_i=m_i h_ihi=mihi

其中:

mi∼Bernoulli(1−p) m_i \sim \text{Bernoulli}(1-p) miBernoulli(1p)

ppp 是 dropout probability。

例如:

self.dropout = nn.Dropout(p=0.1)

Dropout 会降低神经元之间过强的共同适应,从而提高模型的泛化能力。

需要注意:

Dropout 主要在训练阶段随机丢弃单元。

推理阶段通常使用完整网络,并由框架按照对应规则处理缩放。


方法8:Early Stopping

训练过程中持续监控验证集性能。

例如:

Epoch 1
Validation Loss = 0.50

Epoch 2
Validation Loss = 0.42

Epoch 3
Validation Loss = 0.38   ← 最优

Epoch 4
Validation Loss = 0.40

Epoch 5
Validation Loss = 0.46

此时可以保存 Epoch 3 的模型。

也就是:

t∗=arg⁡min⁡tLval(t)t^*=\arg\min_tL_{\text{val}}(t)t=argmintLval(t)

Early Stopping 可以避免模型在训练后期继续拟合训练数据中的噪声。

实际使用时通常还会设置 patience,例如:

patience = 5

验证性能连续若干轮没有改善后再停止,减少随机波动导致的过早终止。


方法9:合理使用验证集和交叉验证

需要将数据划分为:

Training Set
Validation Set
Test Set

三者作用分别是:

  • Training Set:学习模型参数;
  • Validation Set:选择超参数、模型结构和停止时机;
  • Test Set:在所有设计完成后评估最终泛化性能。

测试集不能反复用于模型选择。

如果数据量有限,还可以使用 K-fold Cross Validation 更稳定地估计模型泛化性能。

交叉验证主要用于:

  • 模型比较;
  • 超参数选择;
  • 泛化性能估计。

它本身不会直接降低一个固定模型的复杂度。


四、实际项目中建议怎样排查?

如果发现:

训练集:98%
验证集:82%

不要立即开始调 Dropout。

建议按照以下顺序处理。

Step 1:检查评测是否合法

先检查:

  • 数据泄漏;
  • 数据重复;
  • 切分方式;
  • 时间泄漏;
  • 用户/项目泄漏;
  • 预处理泄漏。

Step 2:观察学习曲线

同时画:

Ltrain L_{\text{train}} Ltrain

和:

Lval L_{\text{val}} Lval

判断随着 epoch 增加,两条曲线如何变化。


Step 3:判断数据问题

检查:

  • 数据量是否足够;
  • 训练集是否具有代表性;
  • 标签噪声是否严重;
  • train / validation 是否存在分布差异。

Step 4:判断模型容量

如果训练集几乎完全拟合,而验证集明显更差,需要考虑:

  • 减小模型;
  • 减少特征;
  • 增加正则化。

Step 5:加入针对性的正则化

根据模型类型选择:

  • L1;
  • L2;
  • Weight Decay;
  • Dropout;
  • 数据增强;
  • Early Stopping。

Step 6:重新验证

所有超参数都在验证集上确定。

最后固定模型后,再使用测试集进行最终评估。


五、一个常见误区

看到训练集表现明显好于验证集时,需要同时考虑多个原因:

性能差距 \text{性能差距} 性能差距

可能来自:

  • 模型过拟合;
  • 数据分布变化;
  • 数据泄漏导致之前的评测虚高;
  • 验证集规模过小;
  • 标签质量差异;
  • 切分策略错误。

因此,完整的工程判断需要结合数据切分、学习曲线和错误分析。


六、面试时可以这样总结

过拟合指模型在训练数据上表现很好,但在新的未见数据上泛化性能明显下降。典型现象是训练 loss 持续下降,而验证 loss 在下降到一定程度后开始上升,或者训练集和验证集之间出现明显性能差距。

处理时我会先检查数据切分和数据泄漏,因为错误的评测设置会掩盖真实问题。确认评测可靠后,再根据原因处理:数据不足时增加高质量数据或数据增强;模型容量过高时降低复杂度;训练自由度过高时使用 L1/L2、Weight Decay 或 Dropout;训练后期出现过拟合时使用 Early Stopping。所有模型选择都在验证集上完成,测试集只用于最终泛化评估。

来源

[1] Google Machine Learning Crash Course, Overfitting
[2] Google Machine Learning Crash Course, Model Complexity
[3] Google Machine Learning Crash Course, L2 Regularization and Early Stopping
[4] scikit-learn Documentation, Cross-validation: evaluating estimator performance
[5] scikit-learn Documentation, Common pitfalls and recommended practices — Data leakage
[6] Goodfellow, Bengio and Courville, Deep Learning, Chapter 7: Regularization for Deep Learning
[7] Srivastava et al., Dropout: A Simple Way to Prevent Neural Networks from Overfitting, JMLR, 2014

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白羊丨

开始面试题与解析

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值