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

tf.keras Functional模型相同数据下predict/evaluate结果不一致是什么原因

问题背景

你定义的Functional模型代码如下:

base_model = VGG16(include_top=False, input_shape=(224,224,3), pooling='avg')
inputs = tf.keras.Input(shape=(224,224,3))
x = preprocess_input(inputs)
x = base_model(x, training=False)
x = tf.keras.layers.Dropout(0.2)(x, training=True)
outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs)

遇到的问题:在数据集shuffle=False、所有随机种子均已初始化的前提下,使用完全相同的batch调用.evaluate()或.predict()时,每次得到的结果都有微小差异。
最初排查时曾判定x=preprocess_input(inputs)语句构造的两层是引入随机性的原因,preprocess_input是tf.keras.applications.vgg16下的VGG16预处理函数。

对比验证

重写为Sequential形式的模型代码如下:

new_model = tf.keras.Sequential()
new_model.add(model.layers[0]) #input layer
new_model.add(tf.keras.layers.Lambda(preprocess_input))
new_model.add(model.layers[3]) #vgg16
new_model.add(model.layers[4]) #dropout
new_model.add(model.layers[5]) #dense

重写后问题消失,调用.evaluate()或.predict()可以得到一致的结果。

根因说明

该异常行为和preprocess_input无关,核心原因是Dropout层的调用参数设置差异:

  • 定义Functional模型时,Dropout层的调用手动传入了training=True参数,该参数会强制Dropout层在所有阶段都执行随机失活逻辑,包括评估、预测阶段,因此每次运行都会随机屏蔽部分神经元输出,导致结果存在波动。
  • 改写为Sequential模型时,只是复用了原模型的Dropout层实例,没有额外传入training=True的调用参数,此时Keras会遵循默认逻辑:训练阶段开启Dropout,.evaluate()/.predict()阶段自动关闭Dropout,不再执行随机失活,因此每次运行结果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:18:05