使用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')
我有以下疑问:
- 用
results = CNN.evaluate(test_generator, batch_size=64)这种方式评估测试集是否正确? - 这样的处理是否存在数据泄漏?
- 如果不正确,处理测试集的正确方法是什么?
- 我曾尝试把测试集不按类别划分(所有测试图片放在同一个目录下),但得到的准确率极低且不合理,求相关建议。
解答
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
相关产品推荐
相关产品推荐

