使用Keras ImageDataGenerator划分Flickr8k数据集遇0类问题求助
解决Flickr8k图像字幕任务中ImageDataGenerator的"Found 0 images belonging to 0 classes"报错
错误原因
flow_from_directory的设计逻辑是读取目标目录下的子文件夹作为类别,每个子文件夹内的图片对应一个类别。但Flickr8k的图片都直接存放在同一个目录下,没有子类文件夹,因此该函数无法识别任何类别和图片,触发报错。
解决方案
针对Flickr8k的数据集结构,推荐两种可行方案:
方案一:使用flow_from_dataframe(更适配图像字幕任务)
Flickr8k自带标注文件(如captions.txt),用flow_from_dataframe可以直接关联图片与字幕,同时完成数据划分和增强:
import pandas as pd from tensorflow.keras.preprocessing.image import ImageDataGenerator # 读取字幕标注文件 df = pd.read_csv("path/to/flickr8k/captions.txt") # 按8:2比例划分训练/验证集 train_df = df.sample(frac=0.8, random_state=42) val_df = df.drop(train_df.index) # 初始化带数据增强的生成器(训练集用) train_datagen = ImageDataGenerator( rescale=1/255, rotation_range=20, # 随机旋转±20度 width_shift_range=0.2, # 随机水平平移20% height_shift_range=0.2, # 随机垂直平移20% horizontal_flip=True # 随机水平翻转 ) # 生成训练数据集 train_generator = train_datagen.flow_from_dataframe( dataframe=train_df, directory="path/to/flickr8k/images", # 图片存储目录 x_col="image", # DataFrame中存储图片文件名的列名 y_col="caption", # 存储对应字幕的列名 target_size=(280, 280), batch_size=32, class_mode=None, # 非分类任务,无需类别标签 shuffle=True ) # 初始化仅做归一化的生成器(验证集禁用增强) val_datagen = ImageDataGenerator(rescale=1/255) val_generator = val_datagen.flow_from_dataframe( dataframe=val_df, directory="path/to/flickr8k/images", x_col="image", y_col="caption", target_size=(280, 280), batch_size=32, class_mode=None, shuffle=False )
方案二:手动创建训练/验证子文件夹
如果不想处理DataFrame,可以手动划分图片到不同子文件夹,满足flow_from_directory的目录要求:
from tensorflow.keras.preprocessing.image import ImageDataGenerator import os import shutil import random # 原始图片目录 image_dir = "path/to/flickr8k/images" # 新建训练、验证目录 train_dir = "./train_images" val_dir = "./val_images" os.makedirs(train_dir, exist_ok=True) os.makedirs(val_dir, exist_ok=True) # 获取所有图片文件 all_imgs = [f for f in os.listdir(image_dir) if f.lower().endswith((".jpg", ".jpeg", ".png"))] # 划分训练/验证集 train_size = int(len(all_imgs) * 0.8) train_imgs = random.sample(all_imgs, train_size) val_imgs = [f for f in all_imgs if f not in train_imgs] # 复制图片到对应目录 for img in train_imgs: shutil.copy(os.path.join(image_dir, img), os.path.join(train_dir, img)) for img in val_imgs: shutil.copy(os.path.join(image_dir, img), os.path.join(val_dir, img)) # 生成训练数据(带增强) train_datagen = ImageDataGenerator( rescale=1/255, rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, horizontal_flip=True ) train_generator = train_datagen.flow_from_directory( directory="./", # 父目录,包含train_images子文件夹 target_size=(280, 280), batch_size=32, class_mode=None, shuffle=True ) # 生成验证数据(仅归一化) val_datagen = ImageDataGenerator(rescale=1/255) val_generator = val_datagen.flow_from_directory( directory="./", target_size=(280, 280), batch_size=32, class_mode=None, shuffle=False )
关键注意事项
- 验证集不要使用数据增强,避免引入额外噪声,保证评估结果准确。
- 数据增强的参数(如旋转角度、平移范围)可根据任务需求调整,进一步缓解过拟合。
- 图像字幕任务需保证图片与字幕一一对应,
flow_from_dataframe是更高效的选择。
内容的提问来源于stack exchange,提问作者KIMIA Ghassemzadeh
相关产品推荐
相关产品推荐

