过拟合是模型在训练集上准确率98%、测试集骤降至70%,本质是死记噪声而丧失泛化能力;需检查数据分布对齐、earlystopping设置、dropout/batchnorm行为及测试集是否污染。

训练集上准确率98%、测试集跌到70%,不是模型“学得不好”,而是它根本没学到泛化规律——大概率是训练集和测试集之间存在隐性分布偏差,或者过拟合已发生但你还没察觉。
训练集和测试集的分布是否真的对齐?
很多开发者把数据按比例随机切分就认为万事大吉,但实际中时间顺序、采集设备、标注习惯等都会造成统计偏移。比如用上午采集的图像训模型,下午光照变化后测试效果断崖下跌;又或者训练集全是正面人脸,测试集突然混入大量侧脸。
- 用
np.mean(X_train, axis=0)和np.mean(X_test, axis=0)分别计算各特征均值,差值 > 0.1 就值得警惕 - 对图像数据,检查训练/测试集的直方图分布(如亮度、对比度)是否重叠;可快速用
cv2.calcHist对比 - 标签分布也要核对:
np.unique(y_train, return_counts=True)vsnp.unique(y_test, return_counts=True),类别频次差异超2倍就可能影响评估
EarlyStopping 是否真的在防过拟合?
EarlyStopping 不是万能开关。如果监控的是 val_loss,但你的任务本质是分类且类别不均衡,val_loss 下降可能掩盖 val_f1_score 持续恶化——模型只是在优化少数类的损失,多数类预测全错。
- 务必确认
monitor参数匹配任务目标:多分类+不平衡 → 改用monitor='val_f1_score'(需自定义指标)或monitor='val_precision' -
patience=5在小数据集上太宽松,1000样本量建议设为patience=2,否则早停形同虚设 -
restore_best_weights=True必须显式开启,否则模型保存的是最后一步权重,未必最优
Dropout 和 L2 正则是否被正确启用?
常见错误是只在模型定义里写了 Dropout 层,却没关掉训练模式——model(x, training=False) 下 Dropout 自动失效,验证/测试时行为和训练时不一致,导致指标失真。
- 调用
model.evaluate()或model.predict()时,TensorFlow 默认training=False,这是对的;但手动写前向传播时必须传training=True(训练)或training=False(推理) - L2 正则要作用在权重上,不是加在 loss 后面:用
kernel_regularizer=tf.keras.regularizers.l2(1e-4)而非loss + 1e-4 * tf.nn.l2_loss(w) - BatchNorm 层在训练/推理时行为不同,若未冻结 BN 统计量(
momentum=0.99是默认值),小 batch 下 BN 估计不准,也会放大测试波动
最容易被忽略的一点:测试集是否被意外“污染”?比如你在做数据增强时,把 ImageDataGenerator 应用到了测试集生成器上,或者标准化参数(mean/std)是用测试集自身算的——这会让测试指标虚高或失真,但真实部署时立刻崩盘。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











