同一数据兼作验证集与测试集为何性能差异显著?
问题解答
背景回顾
在ResNet迁移模型训练中,将测试集直接作为验证集使用时,第15轮验证指标表现良好:binary accuracy 0.85、f1值0.84、precision 0.84、recall 0.85。但训练完成后,用同一测试集评估得到的混淆矩阵表现极差:
[[223, 277] [233, 267]]
计算得准确率仅为49%,与训练时的验证指标差距巨大。假设代码无错误,这种情况是否正常?
结论
这种情况绝对不正常。当验证集与测试集为同一数据集时,训练阶段的验证指标和后续测试评估结果必须高度一致,如此大的差异必然存在未被察觉的问题。
核心原因分析(即使代码表面无错误,也可能存在这些隐性问题)
- 生成器指针未重置:训练过程中
testGen被每轮验证调用,其内部迭代指针不会自动重置。评估时直接调用model.predict(testGen),会导致预测结果的顺序与testGen.classes的原始顺序不匹配,最终混淆矩阵计算完全错误。 - 模型权重未正确保留:训练完成后如果没有显式保存最终轮次的权重,或者评估时误加载了早期训练阶段的模型权重(比如训练中断后重启加载了旧权重),会导致性能骤降。
- 数据读取顺序错位:
testGen默认shuffle=False,但训练过程中验证阶段的生成器内部状态被多次调用后,可能导致评估时读取的数据顺序与标签顺序不对应。
快速验证方案
- 评估前强制重置生成器,保证数据读取顺序与标签一致:
testGen.reset() prediction = model.predict(testGen, verbose=1) confusion = confusion_matrix(testGen.classes, np.rint(prediction)) - 训练完成后保存模型并重新加载,避免权重丢失或加载错误:
model.save('final_model.h5') from keras.models import load_model model = load_model('final_model.h5', custom_objects={'f1_m':f1_m, 'precision_m':precision_m, 'recall_m':recall_m}) - 随机选取少量样本,手动对比训练时验证阶段的预测结果与评估阶段的预测结果,确认一致性。
内容的提问来源于stack exchange,提问作者Riley K
相关产品推荐
相关产品推荐

