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

TensorFlow训练遇图片格式错误,如何无损转换数据集格式?

解决TensorFlow加载图片格式错误的方案

方案一:批量转换图片格式(保留原文件)

直接复制原数据集目录结构,将所有图片转换为TensorFlow兼容的PNG格式,原文件完全保留。使用PIL库实现:

from pathlib import Path
from PIL import Image
import os

# 原数据集路径
original_dir = Path('/content/drive/MyDrive/skin')
# 转换后的新数据集路径
converted_dir = Path('/content/drive/MyDrive/skin_converted')

# 复制目录结构
for class_dir in original_dir.iterdir():
    if class_dir.is_dir():
        new_class_dir = converted_dir / class_dir.name
        os.makedirs(new_class_dir, exist_ok=True)
        
        # 遍历每个图片文件
        for img_path in class_dir.glob('*'):
            try:
                # 打开图片并保存为PNG格式
                with Image.open(img_path) as img:
                    # 处理RGBA转RGB(如果有透明通道)
                    if img.mode == 'RGBA':
                        img = img.convert('RGB')
                    new_img_path = new_class_dir / f'{img_path.stem}.png'
                    img.save(new_img_path, format='PNG')
            except Exception as e:
                print(f"处理图片 {img_path} 出错: {e}")

转换完成后,修改训练代码中的数据集路径为/content/drive/MyDrive/skin_converted即可。

方案二:自定义数据加载管道(无需提前转换)

不修改原数据集,在加载时动态处理图片格式兼容问题,自定义加载函数替代image_dataset_from_directory:

import tensorflow as tf
from pathlib import Path

def load_and_preprocess_image(img_path, label, image_size=(256,256)):
    # 读取原始图片字节
    img_bytes = tf.io.read_file(img_path)
    # 尝试用JPEG解码,失败则用PNG解码(覆盖多数格式问题)
    try:
        img = tf.image.decode_jpeg(img_bytes, channels=3)
    except tf.errors.InvalidArgumentError:
        img = tf.image.decode_png(img_bytes, channels=3)
    # 调整尺寸
    img = tf.image.resize(img, image_size)
    # 适配EfficientNetV2的预处理
    img = tf.keras.applications.efficientnet_v2.preprocess_input(img)
    return img, label

def create_dataset(data_dir, validation_split=0.2, subset='training', seed=123, image_size=(256,256), batch_size=32):
    # 获取类别名称和映射关系
    class_names = sorted([d.name for d in Path(data_dir).iterdir() if d.is_dir()])
    class_to_idx = {name: idx for idx, name in enumerate(class_names)}
    
    # 收集所有图片路径和对应标签
    img_paths = []
    labels = []
    for class_dir in Path(data_dir).iterdir():
        if class_dir.is_dir():
            for img_path in class_dir.glob('*'):
                img_paths.append(str(img_path))
                labels.append(class_to_idx[class_dir.name])
    
    # 划分训练/验证集
    dataset = tf.data.Dataset.from_tensor_slices((img_paths, labels))
    dataset = dataset.shuffle(len(img_paths), seed=seed)
    val_size = int(len(img_paths)*validation_split)
    if subset == 'training':
        dataset = dataset.skip(val_size)
    else:
        dataset = dataset.take(val_size)
    
    # 加载和预处理,启用多线程加速
    dataset = dataset.map(lambda x,y: load_and_preprocess_image(x,y,image_size), num_parallel_calls=tf.data.AUTOTUNE)
    dataset = dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE)
    return dataset, class_names

# 创建训练和验证集
train, class_names = create_dataset('/content/drive/MyDrive/skin', subset='training')
val, _ = create_dataset('/content/drive/MyDrive/skin', subset='validation')

# 后续训练代码保持不变
num_classes = len(class_names)
size = (250, 250)

train = train.map(lambda x, y: (tf.image.resize(x, size), y))
val = val.map(lambda x, y: (tf.image.resize(x, size), y))

base_model = tf.keras.applications.EfficientNetV2L(
    include_top=False,
    weights="imagenet",
    input_shape=(250,250,3),
    classifier_activation="softmax",
    include_preprocessing=True,
)
base_model.trainable = False
inputs = tf.keras.Input(shape=(250, 250, 3))
x = base_model(inputs, training=False)
x = tf.keras.layers.GlobalAveragePooling2D()(x)
x = tf.keras.layers.Dropout(0.2)(x)
outputs = tf.keras.layers.Dense(num_classes)(x)
model = tf.keras.Model(inputs, outputs)
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
epochs=30
history = model.fit(train, epochs=epochs, validation_data=val)

补充说明

  • 方案一适合一次性处理,后续训练直接用转换后的数据集,性能更稳定;
  • 方案二适合不想额外占用存储空间的场景,动态处理图片;
  • 错误本质通常是部分jpg图片编码不符合JFIF标准(比如伪jpg格式),转换或动态解码可解决该问题。

内容的提问来源于stack exchange,提问作者Hussien Adeb Alia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:24:56