同一数据生成器下model.fit与model.evaluate精度值为何不同?
问题原因与解决方案
核心原因
ImageDataGenerator.flow_from_directory默认开启shuffle=True,且生成器是有状态迭代器:在model.fit完成后,生成器的迭代指针停留在数据集末尾,model.evaluate会从该位置开始循环遍历数据,导致评估用的数据顺序、批次划分和训练最后一轮完全不同,计算出的loss和精度自然存在差异。- 训练过程中显示的metrics是每批次结果的移动平均值,而
model.evaluate是对整个数据集的精确计算,这也会带来微小误差,但你遇到的大幅差异主要由生成器状态问题导致。
解决方法
方法1:重置生成器状态
在调用model.evaluate前,手动重置生成器的迭代指针,让它回到数据集开头:
datagen = ImageDataGenerator(rescale=1.) data = datagen.flow_from_directory("database_prova") model_1.fit(data, epochs = 5) print("This is the evaluation step") data.reset() # 重置生成器指针 model_1.evaluate(data)
方法2:创建独立的训练/评估生成器
为训练和评估分别创建独立的生成器实例,避免状态干扰:
# 训练生成器 train_datagen = ImageDataGenerator(rescale=1.) train_data = train_datagen.flow_from_directory("database_prova") model_1.fit(train_data, epochs = 5) # 评估生成器 eval_datagen = ImageDataGenerator(rescale=1.) eval_data = eval_datagen.flow_from_directory("database_prova", shuffle=False) # 评估时关闭shuffle,结果更稳定 print("This is the evaluation step") model_1.evaluate(eval_data)
方法3:关闭生成器的shuffle(不推荐训练时使用)
如果不需要打乱数据,可在flow_from_directory中设置shuffle=False,此时生成器每次迭代顺序一致,fit最后一轮和evaluate的结果会更接近:
datagen = ImageDataGenerator(rescale=1.) data = datagen.flow_from_directory("database_prova", shuffle=False) model_1.fit(data, epochs = 5) print("This is the evaluation step") model_1.evaluate(data)
注意:训练时关闭shuffle可能导致模型过拟合,仅建议在评估阶段关闭。
内容的提问来源于stack exchange,提问作者Jonny_92
相关产品推荐
相关产品推荐

