使用tf.keras加载图像数据集时提示‘找到0个文件0个类别’的解决方法
解决TensorFlow
image_dataset_from_directory 提示“Found 0 files belonging to 0 classes”的问题 问题背景
你的数据集结构如下:
DATASET/ ejercicio1/ train/ frames/ ejercicio1_train_0001.jpg ejercicio1_train_0002.jpg ... test/ frames/ ejercicio1_test_0001.jpg ejercicio1_test_0002.jpg ... val/ frames/ ejercicio1_val_0001.jpg ejercicio1_val_0002.jpg ... ejercicio2/ ...(结构同ejercicio1)
执行代码时路径已被正确识别,但TensorFlow返回提示:Found 0 files belonging to 0 classes。
核心原因
tf.keras.utils.image_dataset_from_directory的默认逻辑要求:传入的目标目录下,必须直接包含以类别命名的子文件夹,每个子文件夹内放置对应类别的图片。而你的代码传入的是.../frames目录,该目录下直接存放图片文件,没有类别子文件夹,导致函数无法识别类别,因此返回0类0文件。
解决方案
方案一:调整数据集结构(推荐)
根据你的分类任务目标,选择对应的结构调整方式:
情况1:以ejercicio作为分类类别
如果你的任务是区分ejercicio1、ejercicio2等类别,重新组织数据集为TensorFlow标准格式:
DATASET/ train/ ejercicio1/ ejercicio1_train_0001.jpg ejercicio1_train_0002.jpg ... ejercicio2/ ejercicio2_train_0001.jpg ... test/ ejercicio1/ ejercicio1_test_0001.jpg ... ejercicio2/ ... val/ ejercicio1/ ... ejercicio2/ ...
修改代码中目录指向,将train_dir改为os.path.join(DATASET_DIR, TRAIN_DIR_NAME),直接传入包含类别子文件夹的目录即可。
情况2:每个ejercicio是独立分类任务
如果每个ejercicio内部包含多个分类类别,需要在frames目录下为每个类别创建子文件夹:
DATASET/ ejercicio1/ train/ frames/ clase1/ ejercicio1_train_0001.jpg ... clase2/ ejercicio1_train_xxx.jpg ... test/ frames/ clase1/ ... clase2/ ... val/ frames/ clase1/ ... clase2/ ... ejercicio2/ ...(同理)
此时原代码的目录路径无需修改,函数会自动识别frames下的子文件夹为类别。
方案二:手动加载图片(不修改数据集结构)
如果无法调整数据集结构,可手动遍历图片文件并分配标签,替代image_dataset_from_directory:
def create_custom_dataset(directory, img_size, batch_size, class_label): # 筛选目录下的图片文件 image_extensions = ('.jpg', '.jpeg', '.png', '.bmp') image_paths = [ os.path.join(directory, f) for f in os.listdir(directory) if f.lower().endswith(image_extensions) and os.path.isfile(os.path.join(directory, f)) ] if not image_paths: print(f"No se encontraron imágenes en: {directory}") return None # 定义图片加载与预处理逻辑 def load_and_preprocess(path): img = tf.io.read_file(path) img = tf.image.decode_jpeg(img, channels=3) img = tf.image.resize(img, img_size) # 根据你的模型调整预处理方式,这里以MobileNetV2为例 img = tf.keras.applications.mobilenet_v2.preprocess_input(img) return img, class_label # 构建数据集 dataset = tf.data.Dataset.from_tensor_slices(image_paths) dataset = dataset.map(load_and_preprocess, num_parallel_calls=tf.data.AUTOTUNE) dataset = dataset.shuffle(buffer_size=len(image_paths)).batch(batch_size).prefetch(tf.data.AUTOTUNE) return dataset # 修改主逻辑部分 train_datasets = [] test_datasets = [] val_datasets = [] exercise_names = [d for d in os.listdir(DATASET_DIR) if os.path.isdir(os.path.join(DATASET_DIR, d))] # 为每个ejercicio分配独热编码标签(对应原代码的categorical模式) class_count = len(exercise_names) class_label_map = {name: tf.one_hot(idx, depth=class_count) for idx, name in enumerate(exercise_names)} for exercise in exercise_names: class_label = class_label_map[exercise] train_dir = os.path.join(DATASET_DIR, exercise, TRAIN_DIR_NAME, FRAME_DIR_NAME) test_dir = os.path.join(DATASET_DIR, exercise, TEST_DIR_NAME, FRAME_DIR_NAME) val_dir = os.path.join(DATASET_DIR, exercise, VAL_DIR_NAME, FRAME_DIR_NAME) print(f"Ruta de entrenamiento: {train_dir}") print(f"Ruta de prueba: {test_dir}") print(f"Ruta de validación: {val_dir}") if os.path.exists(train_dir): train_dataset = create_custom_dataset(train_dir, IMG_SIZE, BATCH_SIZE, class_label) if train_dataset: train_datasets.append(train_dataset) if os.path.exists(test_dir): test_dataset = create_custom_dataset(test_dir, IMG_SIZE, BATCH_SIZE, class_label) if test_dataset: test_datasets.append(test_dataset) if os.path.exists(val_dir): val_dataset = create_custom_dataset(val_dir, IMG_SIZE, BATCH_SIZE, class_label) if val_dataset: val_datasets.append(val_dataset)
原代码问题总结
原代码传入image_dataset_from_directory的目录是.../frames,该目录下直接存放图片,没有按类别划分的子文件夹,不符合函数的预期输入结构,因此无法识别类别和图片。
内容的提问来源于stack exchange,提问作者Adri
相关产品推荐
相关产品推荐

