You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow Keras训练CNN模型保存加载后评估结果异常问题求助

排查模型保存加载后评估结果异常的建议

这问题我之前帮不少新手排查过,大概率是几个细节没做到位,咱们一步步来捋:

1. 优先检查数据预处理的一致性

这是最常见的原因!加载模型后评估时,测试数据的预处理流程必须和训练时完全一致。比如:

  • 训练时如果对图像做了rescale=1./255归一化,加载模型后评估的测试集是不是也做了同样的处理?
  • 有没有用了不同的均值/标准差做标准化?或者训练时加了数据增强,评估时却忘了关闭增强(比如ImageDataGenerator里的rotation_range、zoom_range这些在评估时应该去掉)?
  • 如果你的模型没有把预处理层嵌入到模型结构里(比如用了独立的预处理代码),加载模型后评估时一定要复用完全相同的预处理逻辑,不能偷懒省略。

2. 确认模型保存与加载的完整性

你用的model.save()确实是保存整个模型,但有几个坑要注意:

  • 如果模型包含自定义层、自定义损失函数或自定义指标,加载时必须通过custom_objects参数指定这些自定义对象。比如:
    modelLoaded = keras.models.load_model('gender_detection.modelTest', custom_objects={'MyCustomLoss': MyCustomLoss})
    
    哪怕你觉得自己没用到自定义组件,也可以检查一下模型结构里有没有这类内容。
  • 手动检查保存的模型文件:打开gender_detection.modelTest文件夹,确认里面存在variables目录(包含权重文件)和saved_model.pb(模型结构文件),如果这些文件缺失或大小异常,说明保存过程出了问题,可能是磁盘空间不足或者权限问题。

3. 对比训练后与加载后的模型权重

直接对比权重是最直观的验证方式:
在保存模型前,打印某一层的权重(比如最后一层的全连接层):

print("训练后模型最后一层权重:", model.layers[-1].get_weights()[0][:5])  # 打印前5个权重值

加载模型后,再打印同一层的权重:

print("加载后模型最后一层权重:", modelLoaded.layers[-1].get_weights()[0][:5])

如果两组权重完全一致,说明保存加载没问题,问题肯定出在数据上;如果不一致,那就是保存或加载过程有错误,比如保存时模型还在训练状态,或者加载时出现了版本兼容问题(比如TensorFlow版本不一致)。

4. 验证测试数据的一致性

有时候两次评估用的测试数据其实不一样:

  • 如果你的test_data是ImageDataGenerator生成的,有没有设置shuffle=False?如果没设置,每次调用evaluate()时生成的测试数据顺序会打乱,虽然理论上准确率不会差这么多,但如果测试集很小,有可能出现极端情况。
  • 可以把测试数据转换成固定的numpy数组,两次评估都用同一组数据:
    # 提取固定的测试数据(假设test_data是批量生成器)
    test_x, test_y = [], []
    for x, y in test_data:
        test_x.append(x)
        test_y.append(y)
    test_x = np.concatenate(test_x)
    test_y = np.concatenate(test_y)
    
    # 第一次评估
    scores = model.evaluate(test_x, test_y, verbose=0)
    # 加载后评估
    scores_loaded = modelLoaded.evaluate(test_x, test_y, verbose=0)
    
    如果这样结果一致,说明是你的测试数据生成器的问题,调整生成器的参数即可。

5. 排查模型模式切换问题

TensorFlow Keras的模型有训练模式(training=True)和评估模式(training=False),有些层(比如Dropout、BatchNormalization)在两种模式下表现不同:

  • 虽然evaluate()方法会自动切换到评估模式,但如果加载模型后你不小心调用了modelLoaded.compile()或者修改了trainable属性,可能会改变模型状态。可以在评估前手动切换:
    modelLoaded.trainable = False
    modelLoaded.compile(...)  # 如果重新编译了,要和原模型用一样的优化器、损失函数
    
    或者直接调用modelLoaded.evaluate()前,先执行modelLoaded.predict()触发模式切换。

如果以上排查都没解决问题,可以把你的模型结构代码、数据预处理代码贴出来,这样能更精准地定位问题。

内容的提问来源于stack exchange,提问作者begginer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 15:44:10