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

fit_generator与predict_generator验证结果存在差异的问题求助

解决fit_generator验证F1正常但predict_generator预测F1偏低的问题

这种情况我碰到过好几次,核心问题基本都出在数据处理的一致性或者标签匹配上,下面是几个最可能的原因和对应的解决办法:

1. 训练/验证与测试数据的预处理不一致

你用了val_datagen和test_datagen两个生成器,如果它们的预处理配置不一样(比如一个做了归一化,另一个没做;或者一个加了训练时才用的数据增强,另一个参数不同),模型看到的输入分布就会有差异,自然预测结果不准。

比如如果你的val_datagen是这样的:

val_datagen = ImageDataGenerator(rescale=1./255)

那test_datagen必须完全一致,不能漏掉rescale参数,也不能额外加rotation_range这类只适合训练的数据增强操作。

解决办法:直接复用同一个数据生成器配置给测试集,比如:

# 统一预处理配置
common_datagen = ImageDataGenerator(rescale=1./255)

# 验证生成器
validation_generator = common_datagen.flow_from_directory(
    directory=val_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    shuffle=True,
    classes=["0", "1"],
    class_mode="categorical"
)

# 测试生成器
test_generator = common_datagen.flow_from_directory(
    directory=test_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    shuffle=False,
    classes=None,
    class_mode=None
)

2. 真实标签与预测结果的对应关系错误

你把验证集的两个子文件夹合并成了单个测试文件夹,这意味着你需要手动生成真实标签,但很容易出现标签顺序和预测结果顺序不匹配的问题:

  • validation_generator会自动给0文件夹的样本打标签[1,0],1文件夹的样本打[0,1];
  • 而test_generator的shuffle=False,样本顺序是按文件夹内的文件排序,但合并后无法直接从生成器获取标签,手动生成时如果顺序错了,计算F1肯定会偏差。

解决办法:通过test_generator.filenames获取样本文件名,然后根据文件名反向映射到原来的类别:

# 假设原来的验证集里,文件名包含类别信息,或者你有原路径映射
true_labels = []
for filename in test_generator.filenames:
    # 根据实际情况判断,比如原路径是val_data_dir/0/xxx.jpg,现在filename是xxx.jpg
    # 这里需要你根据自己的文件命名规则调整
    if "class0" in filename:  # 示例条件,替换成你的判断逻辑
        true_labels.append(0)
    else:
        true_labels.append(1)

# 把预测结果转成类别
predictions_classes = np.argmax(predictions, axis=1)

# 计算F1
from sklearn.metrics import f1_score
print(f1_score(true_labels, predictions_classes))

3. 类别映射顺序不匹配

在validation_generator里你指定了classes=["0", "1"],这意味着模型输出的第一个维度对应类别0,第二个对应类别1;但test_generator里classes=None,虽然是单个文件夹,但模型的输出顺序还是和训练时一致的。如果你计算F1时把预测的argmax结果对应错了类别(比如把0当成1,1当成0),分数会骤降。

解决办法:明确类别映射关系,比如:

# 训练时的类别顺序是["0", "1"],所以argmax=0对应类别0,argmax=1对应类别1
predictions_classes = np.argmax(predictions, axis=1)
# 确保true_labels里的0和1和这个顺序完全对应

4. 预测的样本数量计算错误

你手动计算steps的方式可能有误差,比如nbr_test_samples和test_generator.samples的实际数量不一致,导致预测时只处理了部分样本,或者重复处理,结果不完整。

解决办法:直接用生成器的samples属性计算,或者让Keras自动处理:

# 方式1:用math.ceil计算准确的steps
import math
steps = math.ceil(test_generator.samples / batch_size)
predictions = myModel.predict_generator(test_generator, steps=steps, verbose=1)

# 方式2:Keras 2.2及以上版本可以省略steps,自动计算
predictions = myModel.predict_generator(test_generator, verbose=1)

5. 模型状态异常

确认在调用predict_generator之前,模型没有被重新编译、加载其他权重或者修改过结构。比如如果训练完后你不小心执行了myModel.compile(...),模型的权重会被重置,预测结果自然不对。

解决办法:训练完成后直接调用predict_generator,不要对模型做任何额外修改;如果需要保存模型,训练后用myModel.save()保存,预测时再加载。


内容的提问来源于stack exchange,提问作者Quang Hieu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:51:35