You need to enable JavaScript to run this app. 为何仅训练一次的tf.keras模型多次执行predict推理结果不一致
优惠活动
大模型
产品
解决方案
定价
更多

为何仅训练一次的tf.keras模型多次执行predict推理结果不一致

核心问题根源

你观测到的预测值不稳定、准确率每次波动,本质不是模型推理输出发生了变化,而是取真实标签的遍历顺序、和喂给模型做预测的遍历顺序完全错位,导致y_true和y_pred根本没有一一对应。

具体触发逻辑

  1. tf.keras.preprocessing.image_dataset_from_directory 构建数据集时默认开启shuffle=True随机洗牌逻辑,且TensorFlow底层的洗牌操作默认打开reshuffle_each_iteration=True参数——哪怕你传了固定的seed=1337,每一次重新遍历这个数据集(不管是手动取标签、调用model.predict、还是模型内部计算训练指标),都会重新生成一套样本输出顺序,不会沿用上次遍历的排序结果。
    这个设计本来是为了训练时每轮epoch的样本顺序都有差异,提升模型训练效果,但直接把这个数据集拿来做评估就会出问题:固定seed只是决定了第一次洗牌时随机数生成器的初始状态,第一次遍历完成后随机状态会持续推进,后续遍历不会回到初始状态,自然每一次的输出顺序都不一样。
  2. 你在Cell2计算y_true时,是第一次遍历train_ds,此时数据集输出的样本顺序为A;后续两次调用model.predict(train_ds)是第二次、第三次遍历,两次输出的样本顺序分别为B、C,和顺序A完全不重合。
  3. Cell1运行完成后模型的权重是完全固定的,只要输入完全相同的样本,推理输出绝对不会变化。但现在你把顺序A的真实标签,和顺序B、C的预测值放在一起算准确率,相当于标签和预测完全错配,结果自然会每次波动,而且准确率会远低于模型训练时显示的0.9398(你实测的0.593、0.586就是错配后的随机结果,根本不是模型的真实训练准确率)。

修复方法

评估场景下必须使用遍历顺序完全固定的数据集,不能直接复用训练时带每轮洗牌逻辑的train_ds:

  • 构建专门用于评估的数据集,关闭每轮重新洗牌的配置:
eval_ds = train_ds.shuffle(
    buffer_size=1000,
    seed=1337,
    reshuffle_each_iteration=False
)
  • 所有计算真实标签、模型预测的操作都统一使用这个固定顺序的eval_ds:
# 取真实标签
y_true = np.argmax(tf.concat([y for x, y in eval_ds], axis=0), axis=1)
# 第一次预测
y_pred1 = np.argmax(model.predict(eval_ds), axis=1)
# 第二次预测
y_pred2 = np.argmax(model.predict(eval_ds), axis=1)

此时两次model.predict输出的预测数组会完全一致,算出的准确率也不会波动,最终结果会和Cell1训练时显示的准确率基本匹配。

注意事项

  • 训练阶段保留每轮洗牌的逻辑是有必要的,能提升模型泛化效果,不需要修改训练用的train_ds原有配置。
  • 只要保证输入模型的样本顺序、和取真实标签的顺序完全一致,哪怕连续调用十次model.predict,输出的预测结果也不会出现任何变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 06:36:04