ML二分类数据集标签与文件夹不匹配问题求助
我使用Kaggle的表面裂纹检测数据集(包含Positive和Negative两个文件夹),通过以下代码利用ImageDataGenerator划分训练集与验证集,设置class_mode='binary':
data_dir = '/kaggle/input/' my_data_dir = f'{data_dir}/surface-crack-detection/surface-crack-detection/' positive_dir = my_data_dir + 'Positive/' negative_dir = my_data_dir + 'Negative/' # Define image dimensions img_height, img_width = 224, 224 batch_size = 32 # Create ImageDataGenerators without data augmentation datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2) train_generator = datagen.flow_from_directory( my_data_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='binary', subset='training' ) validation_generator = datagen.flow_from_directory( my_data_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='binary', subset='validation' )
但执行以下代码打印验证集文件路径与对应标签时:
for i in range(len(validation_generator)): batch = next(validation_generator) images, labels = batch file_paths = validation_generator.filepaths[i * batch_size:(i + 1) * batch_size] for j in range(len(file_paths)): print(f"File Path: {file_paths[j]}, Label: {labels[j]}")
得到的结果显示Negative文件夹下的图片标签既有1.0又有0.0,不符合预期(Negative文件夹应对应标签0,Positive对应标签1)。请问哪里操作出错了?
核心问题1:生成器默认打乱数据,导致路径与标签错位
flow_from_directory默认参数shuffle=True,生成器会随机打乱验证集数据的顺序。你手动通过i * batch_size计算的文件路径,是按原始未打乱的顺序取的,和next(validation_generator)返回的随机batch的图片、标签完全不对应,自然出现标签匹配错误的情况。
核心问题2:循环方式导致生成器指针不同步
你用for i in range(len(validation_generator))循环,同时多次调用next(validation_generator),会导致生成器的内部指针移动和循环变量i不同步,进一步加剧路径和标签的错位问题。
正确的解决步骤
1. 修改验证集生成器,关闭打乱
在创建validation_generator时添加shuffle=False,保证数据按原始顺序输出,这样文件路径和标签才能一一对应:
validation_generator = datagen.flow_from_directory( my_data_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='binary', subset='validation', shuffle=False # 关键:关闭打乱,保证顺序匹配 )
2. 正确遍历生成器并匹配路径与标签
使用enumerate遍历生成器,利用批次索引计算对应文件路径的范围,同时注意最后一个批次可能小于设定的batch_size:
# 遍历验证集的每个批次 for batch_idx, (images, labels) in enumerate(validation_generator): # 计算当前批次对应的文件路径索引范围 start_idx = batch_idx * batch_size end_idx = start_idx + len(images) # 处理最后一个批次可能不足batch_size的情况 file_paths = validation_generator.filepaths[start_idx:end_idx] # 遍历当前批次的路径与标签 for path, label in zip(file_paths, labels): print(f"File Path: {path}, Label: {label}")
3. 确认文件夹与标签的对应关系
可以先打印class_indices确认标签映射是否符合预期:
print(validation_generator.class_indices)
正常输出应为{'Negative': 0, 'Positive': 1}(按文件夹名称字母排序,Negative在前),如果映射错误,可通过classes参数手动指定标签顺序,但一般默认排序即可满足需求。
内容的提问来源于stack exchange,提问作者Lorentz1234

