早停法是防止过拟合的动态终止策略,非优化轮数工具;监控指标依任务而定:回归/多分类/噪声数据选val_loss,均衡二分类可选val_accuracy,不平衡或高误判代价场景须用val_f1_score或val_auc;patience反映对验证波动的容忍底线,小数据集建议从3起步。

早停法不是“优化训练轮数”的工具,而是防止过拟合的动态终止策略——它靠验证集信号决定停在哪一轮,而不是预设一个数字。
监控指标选 val_loss 还是 val_accuracy?
选哪个,取决于任务类型和损失函数行为:
- 回归、多分类、带噪声数据,优先用
val_loss:它更平滑,对过拟合更敏感 - 二分类且正负样本均衡时,
val_accuracy可读性高;但类别不平衡时会失效(比如准确率卡在 95%,val_f1_score其实已下滑) - 医疗、金融等误判代价高的场景,必须用
val_f1_score或val_auc,否则早停会“假装稳定” - Keras 中
monitor='val_loss'是最小化逻辑,monitor='val_accuracy'是最大化逻辑,方向反了就完全失效
patience 值怎么设才不瞎猜?
它不是超参数调优项,而是你对验证信号波动容忍度的底线:
- 小数据集(patience=3 起手,因为验证指标方差大
- 图像分类(ResNet/CNN 类)常用
patience=7~15,因 loss 常有小幅震荡 - NLP 微调(BERT 类)建议
patience=3~5,因预训练权重强,微调易过拟合 - 别按总 epoch 比例设(比如 “20%”),前几轮常是 warmup,真正评估期在后半段
- 如果早停总在第 8 轮触发,但第 12 轮模型更好,说明
patience太小,或验证集太小导致指标不可靠
restore_best_weights=True 为什么不能省?
这是最常被忽略的致命细节:
- 默认情况下,Keras 的
EarlyStopping停止时保存的是**最后一步的权重**,不是历史最优那次 - 最优性能点往往出现在停止前若干 epoch,尤其当验证 loss 曲线呈“U 型”时
- PyTorch 自定义类里也必须显式实现:在
__call__中检测到新低时,用torch.save(model.state_dict(), path)存档 - Hugging Face 的
Trainer对应参数是load_best_model_at_end=True,不是默认开启的 - 忘了这步,等于早停白做——你省了时间,却用了次优模型
验证集划分不靠谱,早停就全废
早停完全依赖验证集质量,但它常被草率处理:
- 验证集必须独立于训练集,且分布要贴近真实测试场景;用随机切分但没打乱顺序,可能引入时间泄漏
- 验证集太小(比如只占 5%)会导致指标抖动剧烈,
patience再大也难稳定判断 - 多任务或长尾分布下,需按标签比例分层抽样,否则
val_loss会被高频类主导,掩盖低频类恶化 - 验证集若混入训练数据(如数据增强未关闭),早停会误判为“还在提升”,实际已过拟合
真正难的不是写个 EarlyStopping 类,而是让验证信号可信——它要求你反复检查数据划分逻辑、指标定义方式、以及每次训练中验证集的实际表现波动范围。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











