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

使用Keras ImageDataGenerator处理预拆分CNN数据集是否正确?是否存在数据泄漏?

问题描述

我手上的数据集已预先拆分为训练集、验证集和测试集,文件夹结构如下:

  • Test目录:包含Class1和Class0子目录
  • Val目录:包含Class1和Class0子目录
  • Train目录:包含Class1和Class0子目录

我用以下代码定义路径:

# Define paths
train_dir = os.path.join(PATH, 'train')
val_dir = os.path.join(PATH, 'val')
test_dir = os.path.join(PATH, 'test')

# Specify them by class
train_safe_dir = os.path.join(train_dir, 'class1')  
train_malicious_dir = os.path.join(train_dir, 'class0')  
val_safe_dir = os.path.join(val_dir, 'class1')  
val_malicious_dir = os.path.join(val_dir, 'class0')
test_safe_dir = os.path.join(test_dir, 'class1')  
test_malicious_dir = os.path.join(test_dir, 'class0')

接着用ImageDataGenerator生成数据生成器:

train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(batch_size=batch_size,
                                                directory=train_dir,
                                                shuffle=False,
                                                target_size=(IMG_H, IMG_W),
                                                class_mode='binary')
val_generator = val_datagen.flow_from_directory(batch_size=batch_size,
                                            directory=val_dir,
                                            target_size=(IMG_H, IMG_W),
                                            class_mode='binary')
test_generator = test_datagen.flow_from_directory(batch_size=batch_size,
                                                directory=test_dir,
                                                shuffle=False,
                                                target_size=(IMG_H, IMG_W),
                                                class_mode='binary')

我有以下疑问:

  1. 用results = CNN.evaluate(test_generator, batch_size=64)这种方式评估测试集是否正确?
  2. 这样的处理是否存在数据泄漏?
  3. 如果不正确,处理测试集的正确方法是什么?
  4. 我曾尝试把测试集不按类别划分(所有测试图片放在同一个目录下),但得到的准确率极低且不合理,求相关建议。

解答

1. 当前测试集评估方式是否正确?

是正确的。你用flow_from_directory加载测试集,仅做了rescale=1./255的归一化处理,和训练/验证集的预处理逻辑完全一致,再调用model.evaluate评估的流程符合标准规范。测试集设置shuffle=False不影响评估结果,因为evaluate只计算整体指标,和样本顺序无关。

2. 是否存在数据泄漏?

从你给出的代码来看,不存在数据泄漏。原因如下:

  • 训练、验证、测试集是完全独立的文件夹,无数据交叉
  • 测试集的ImageDataGenerator仅做归一化,没有使用任何训练集的统计信息(比如均值、方差),且训练集也未应用数据增强,不存在增强逻辑泄漏的问题
  • 整个训练过程未用到测试集的任何数据或指标

3. 处理测试集的正确方法

你当前的方法就是标准的正确流程,核心要点总结:

  • 测试集必须和训练/验证集保持一致的预处理逻辑(这里统一除以255归一化,完全符合要求)
  • 测试集绝对不能参与模型训练、调参的任何环节(包括不能用测试集选模型、调学习率等)
  • 加载测试集时,要确保类别映射和训练集一致(flow_from_directory会自动按文件夹名生成类别映射,只要测试集的Class0/Class1和训练集对应,就不会有问题)

4. 测试集不按类别划分准确率极低的原因及建议

当你把所有测试图片放在同一个目录下时,flow_from_directory无法自动识别类别标签,如果直接错误加载,模型拿到的标签是混乱的,准确率自然会低到离谱。

建议方案:

  • 若必须使用无类别划分的测试集,需提前准备好每个测试样本的标签(比如一个CSV文件,包含filename和label两列),然后用flow_from_dataframe加载:
    import pandas as pd
    test_df = pd.read_csv('test_labels.csv')
    test_generator = test_datagen.flow_from_dataframe(
        dataframe=test_df,
        directory=test_dir,
        x_col='filename',
        y_col='label',
        target_size=(IMG_H, IMG_W),
        batch_size=batch_size,
        class_mode='binary',
        shuffle=False
    )
    
  • 同时要检查标签数值的一致性:比如训练集里Class0对应0、Class1对应1,测试集的标签也要保持同样的映射,否则模型预测结果会和真实标签不匹配,导致准确率异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:17:15