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
相关产品推荐
相关产品推荐

