TensorFlow脚本无法检测图片:目录有图却报错求助
杯子检测脚本报错:指定目录无符合格式图片(实际包含图片)
问题描述
作为TensorFlow新手,我编写了一个杯子检测脚本,执行时提示No images found in directory /Users/myname/Documents/Python/TensorFlow/data/train/cups. Allowed formats: ('.bmp', '.gif', '.jpeg', '.jpg', '.png'),但该目录下确实有图片。脚本代码如下:
import tensorflow as tf # Ordner mit den Bildern definieren becher_images_dir = "/Users/myname/Documents/Python/TensorFlow/data/train/cups" nicht_becher_images_dir = "/Users/myname/Documents/Python/TensorFlow/data/train/not_cups" # Trainingsdaten definieren becher_train_data = tf.keras.preprocessing.image_dataset_from_directory( becher_images_dir, batch_size=32 ) nicht_becher_train_data = tf.keras.preprocessing.image_dataset_from_directory( nicht_becher_images_dir, batch_size=32 ) # Trainingsdaten zusammenfügen train_data = becher_train_data.concatenate(nicht_becher_train_data) # Validierungsdaten definieren validation_split = 0.5 validation_data = train_data.take(validation_split * len(train_data)) # Eingängen definieren x = tf.keras.Input(shape=(224, 224, 3)) # Erstes Konvolutional- und Pooling-Layer conv1 = tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), padding='same')(x) pool1 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=2)(conv1) # Zweites Konvolutional- und Pooling-Layer conv2 = tf.keras.layers.Conv2D(filters=64, kernel_size=(3, 3), padding='same')(pool1) pool2 = tf.keras.layers.MaxPooling2D(pool_size=(2, 2), strides=2)(conv2) # Fully-connected Layer flatten = tf.keras.layers.Flatten()(pool2) dense = tf.keras.layers.Dense(128, activation='relu')(flatten) # Ausgabe output = tf.keras.layers.Dense(1, activation='sigmoid')(dense) # Modell definieren model = tf.keras.Model(inputs=x, outputs=output) # Modell trainieren loss_fn = tf.keras.losses.BinaryCrossentropy() optimizer = tf.keras.optimizers.Adam(learning_rate=0.001) model.compile(loss=loss_fn, optimizer=optimizer, metrics=['accuracy']) model.fit(train_data, validation_data=validation_data, epochs=10) # Modell bewerten model.evaluate(validation_data)
问题原因及解决办法
核心问题:image_dataset_from_directory使用逻辑错误
tf.keras.preprocessing.image_dataset_from_directory的设计逻辑是:传入的目录必须包含子目录,每个子目录对应一个类别,图片放在子目录内。你直接把图片放在了cups目录下,没有子目录,函数会遍历cups下的子目录找图片,自然找不到,因此报错。
解决办法1:调整目录结构(推荐)
- 将
cups目录里的所有图片移动到cups/cup子目录中,同理把not_cups里的图片移动到not_cups/not_cup子目录中。 - 更规范的二分类数据集结构:直接将
cups和not_cups作为train目录的子目录,然后一次性读取train目录,自动识别两个类别,代码更简洁:
# 直接读取train目录,自动识别cups和not_cups两个类别 train_data = tf.keras.preprocessing.image_dataset_from_directory( "/Users/myname/Documents/Python/TensorFlow/data/train", batch_size=32, image_size=(224, 224) # 必须指定,模型输入是224x224,默认256x256会不匹配 ) # 拆分验证集 validation_split = 0.5 val_size = int(len(train_data) * validation_split) validation_data = train_data.take(val_size) train_data = train_data.skip(val_size)
解决办法2:不修改目录,手动加载图片
如果不想调整目录结构,可以用tf.data.Dataset手动遍历图片文件并加载:
def load_class_images(dir_path, label): # 遍历目录下的所有图片文件,按需添加后缀 img_paths = tf.io.gfile.glob(f"{dir_path}/*.jpg") + tf.io.gfile.glob(f"{dir_path}/*.png") dataset = tf.data.Dataset.from_tensor_slices(img_paths) def process_img(path): img = tf.io.read_file(path) img = tf.image.decode_jpeg(img, channels=3) # 若有png可添加decode_png分支 img = tf.image.resize(img, (224, 224)) return img, label return dataset.map(process_img, num_parallel_calls=tf.data.AUTOTUNE) # 加载杯子类(标签1)和非杯子类(标签0) becher_train_data = load_class_images(becher_images_dir, 1) nicht_becher_train_data = load_class_images(nicht_becher_images_dir, 0) # 合并数据集 train_data = becher_train_data.concatenate(nicht_becher_train_data).shuffle(1000)
其他排查方向
- 检查图片后缀:如果图片是大写后缀(比如
.PNG/.JPG),可以在调用image_dataset_from_directory时添加参数:allowed_formats=('bmp', 'gif', 'jpeg', 'jpg', 'png', 'BMP', 'GIF', 'JPEG', 'JPG', 'PNG') - 验证路径正确性:把路径复制到终端,用
ls /Users/myname/Documents/Python/TensorFlow/data/train/cups命令查看是否能列出图片,确认没有拼写错误或隐藏字符 - 检查图片完整性:手动打开几张图片,确认没有损坏无法读取的情况
内容的提问来源于stack exchange,提问作者hallleron
相关产品推荐
相关产品推荐

