加载保存的Keras模型后准确率与训练时不一致如何解决?
这种情况我之前碰过好多次,大概率是几个容易被忽略的细节没做到位,咱们一个个排查:
1. 重点检查模型的运行模式(尤其是带BatchNormalization/Dropout的情况)
如果你的模型里有BatchNormalization或者Dropout这类和运行模式绑定的层,一定要注意:训练时模型处于「训练模式」,而评估/预测时必须切换到「推理模式」。
- 训练完直接评估时,
model.evaluate()会自动切到推理模式,但要是你手动调用过model.train_on_batch或者误设了model.trainable = True,就可能干扰结果; - 加载模型后,务必确保评估时是推理模式:
- 用
model.evaluate()的话,默认是对的,不用额外操作; - 如果是自己用
model.predict()后计算准确率,记得先加一句model.trainable = False,或者直接写model.predict(x, training=False)(TensorFlow 2.x的写法);
- 用
- 另外,保存模型一定要用
model.save(),别只存权重——它会完整保存BatchNormalization层的running_mean和running_var这些关键统计量,要是只存权重再加载,这些统计量会被重置,推理时自然用错数据。
2. 保证数据预处理完全和训练时一致
训练时的准确率是基于你当时的预处理逻辑,加载模型后但凡预处理变了,结果肯定会跑偏:
- 比如训练时你用训练集的均值和标准差做标准化,加载后评估时是不是误用到了整个数据集(含验证/测试集)的均值?
- 检查数据的归一化、缩放、标签编码(比如分类标签的one-hot编码)有没有和训练时完全一样;
- 甚至要确认数据加载的顺序、批量大小(batch size)——BatchNormalization在小批量下的统计量会有差异,虽然这个影响一般没这么大,但也不能完全排除。
3. 用正确的方式保存和加载整个模型
别只存模型权重,一定要用完整保存的方式:
- 训练完保存:
model.save("my_model.h5")或者model.save("my_model")(TensorFlow SavedModel格式); - 加载时直接用:
from tensorflow.keras.models import load_model model = load_model("my_model.h5") - 要是你之前用
model.save_weights()存权重,加载时必须1:1复刻训练时的模型结构(包括每一层的参数、激活函数、正则化等),哪怕结构有一丁点不一样(比如某个层的name没对上,或者BatchNormalization的momentum设置不同),都会导致权重加载错误,进而拉低准确率。
4. 排除随机性干扰(虽然概率较低)
从90%跌到75%大概率不是随机性的锅,但还是可以确认一下:
- 训练和评估时都设置好随机种子,避免偶然差异:
import tensorflow as tf import numpy as np import random tf.random.set_seed(42) np.random.seed(42) random.seed(42) - 确保评估用的是同一批数据,没有随机打乱或者重新划分。
你可以先从第1点和第3点开始排查,这俩是最常见的原因。比如先确认加载模型后是不是在推理模式下评估,再检查模型是不是用完整方式保存加载的。
内容的提问来源于stack exchange,提问作者Abhay Raj Singh
相关产品推荐
相关产品推荐

