训练集得分高、测试集低,主因是数据分布偏移或预处理污染,而非过拟合;需检查train/test数值/图像/标签分布对齐、早停有效性、标准化与独热编码是否用训练集参数、Dropout/BatchNorm推理模式及模型保存完整性。

训练集得分高、测试集很低,大概率不是代码写错了,而是模型根本没学到泛化规律——它在训练集上“背题”,一到新数据就露馅。
检查 train/test 数据分布是否对齐
随机切分不等于分布一致。时间序列、设备采集、标注习惯等都可能造成隐性偏移。
- 数值特征:用
np.mean(X_train, axis=0)和np.mean(X_test, axis=0)对比各列均值,差值 > 0.1 就该警觉 - 图像数据:用
cv2.calcHist比较亮度/对比度直方图重叠度 - 标签分布:运行
np.unique(y_train, return_counts=True)和np.unique(y_test, return_counts=True),若某类别频次相差超 2 倍,说明划分有样本选择偏差
验证 EarlyStopping 是否真起作用
早停不是加了就生效。监控指标错、耐心值设太大、没保存最优权重,都会让早停形同虚设。
- 分类任务 + 类别不平衡时,
val_loss下降 ≠ 模型变好;应改用monitor='val_f1_score'或自定义指标 - 小数据集(如仅 1000 样本)建议
patience=2,patience=5容易错过拐点 -
restore_best_weights=True必须显式开启,否则model.evaluate()评估的是最后一步权重,不是最低验证损失那轮的
确认预处理流程是否污染测试集
测试集标准化参数来自自身、ImageDataGenerator 应用到 test generator、pd.get_dummies 分别调用——这些操作会让测试指标虚高,上线即崩。
立即学习“Python免费学习笔记(深入)”;
- 标准化必须用训练集算出的
mean和std去 transform 测试集,绝不能用测试集自身统计量 - 独热编码必须统一用
OneHotEncoder().fit_transform(X_train)后再.transform(X_test),不能各自pd.get_dummies - 使用
ColumnTransformer+Pipeline可强制封装该逻辑,避免手动出错
排查 Dropout / BatchNorm 在 eval 模式下的行为
TensorFlow/Keras 默认 model.evaluate() 走 training=False,但如果你手动写前向传播,忘了传 training=False,Dropout 就不会关闭,BatchNorm 会用 batch 统计而非 running stats,导致结果不可复现。
- 调用
model(x, training=False)是推理标准写法;训练时才用training=True - L2 正则要加在权重上(如
kernel_regularizer=tf.keras.regularizers.l2(1e-4)),不是在 loss 后硬加tf.nn.l2_loss(w) - 模型保存后加载再
evaluate,务必确认加载的是带完整结构的模型,而不是仅权重文件
最容易被忽略的点是:分布偏移和预处理污染往往同时存在,且它们的表现和过拟合高度相似——你盯着 loss 曲线调正则,其实问题出在数据进来的第一行代码里。


















