You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keras的image_dataset_from_directory中忽略损坏图片而不删除

加载图片时忽略损坏文件的解决方案

使用Keras的image_dataset_from_directory时,确实没有直接参数跳过损坏图片,但可以通过两种方式实现保留文件、加载时过滤的需求:

方法1:预筛选有效图片后构建数据集

先遍历目录检查所有图片的有效性,收集有效路径后再创建数据集,避免加载时触发异常:

步骤1:编写图片有效性检查函数

import os
from PIL import Image

def is_image_valid(file_path):
    try:
        with Image.open(file_path) as img:
            img.verify()  # 验证图片结构完整性
            img.load()  # 额外检查像素数据,避免头文件正常但内容损坏的情况
        return True
    except (IOError, SyntaxError, ValueError):
        return False

步骤2:收集有效图片路径与标签

data_dir = "你的图片根目录路径"
class_names = sorted([d for d in os.listdir(data_dir) if os.path.isdir(os.path.join(data_dir, d))])
class_indices = {name: idx for idx, name in enumerate(class_names)}

valid_paths = []
valid_labels = []

for cls_name in class_names:
    cls_dir = os.path.join(data_dir, cls_name)
    for img_file in os.listdir(cls_dir):
        img_path = os.path.join(cls_dir, img_file)
        if is_image_valid(img_path):
            valid_paths.append(img_path)
            valid_labels.append(class_indices[cls_name])

步骤3:构建并预处理数据集

import tensorflow as tf
from tensorflow.keras.layers import Rescaling

def load_image(path, label, img_size=(256, 256)):
    img = tf.io.read_file(path)
    img = tf.image.decode_image(img, channels=3, expand_animations=False)  # 忽略动图
    img = tf.image.resize(img, img_size)
    return img, label

# 创建数据集
dataset = tf.data.Dataset.from_tensor_slices((valid_paths, valid_labels))
dataset = dataset.map(load_image, num_parallel_calls=tf.data.AUTOTUNE)

# 常规数据集操作:打乱、分批、预取
dataset = dataset.shuffle(1000).batch(32).prefetch(tf.data.AUTOTUNE)

# 添加归一化层(可选)
normalizer = Rescaling(1./255)
dataset = dataset.map(lambda x, y: (normalizer(x), y))

方法2:基于image_dataset_from_directory过滤无效样本

如果已经依赖image_dataset_from_directory的默认配置(如自动划分验证集、类名自动识别等),可以利用return_file_paths参数获取文件路径,再过滤损坏样本:

import tensorflow as tf

data_dir = "你的图片根目录路径"
img_size = (256, 256)
batch_size = 32

# 获取包含文件路径的原始数据集(先不分批)
raw_dataset = tf.keras.utils.image_dataset_from_directory(
    data_dir,
    image_size=img_size,
    batch_size=None,
    return_file_paths=True  # 返回 (图片, 标签, 文件路径) 元组
)

# 定义过滤函数:检查图片是否可正常解码
def filter_corrupted(image, label, file_path):
    try:
        # 重新解码验证图片有效性
        img_bytes = tf.io.read_file(file_path)
        tf.image.decode_image(img_bytes, channels=3, expand_animations=False)
        return tf.constant(True)
    except tf.errors.InvalidArgumentError:
        return tf.constant(False)

# 过滤无效样本,并移除路径信息
filtered_dataset = raw_dataset.filter(filter_corrupted)
filtered_dataset = filtered_dataset.map(lambda img, label, path: (img, label))

# 分批与预取
filtered_dataset = filtered_dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE)

注意事项

  • 方法1适合数据集规模较小的场景,提前过滤能减少后续加载的异常风险;
  • 方法2更适配image_dataset_from_directory的原生配置,但需要注意先设置batch_size=None,过滤后再分批;
  • 图片有效性检查可以结合PIL和TensorFlow的解码逻辑,确保覆盖更多损坏场景(如文件头正常但数据损坏的图片)。

内容的提问来源于stack exchange,提问作者Tuan Do

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:11:01