运行猫狗分类代码时随机出现PIL.UnidentifiedImageError错误求助
PIL.UnidentifiedImageError 问题分析与解决
问题原因
- 数据集存在损坏/无效图片:部分图片因下载中断、存储故障等导致损坏,或格式异常(如后缀与实际格式不符、文件为空),训练时随机读取到这类图片就会触发错误。
- 数据增强引发的异常:ImageDataGenerator的剪切、缩放等增强操作,可能会让本身有轻微损坏的图片生成无法被PIL识别的临时数据,导致随机报错。
- IO读取异常:训练过程中偶尔出现文件读取不完整的IO错误,使得加载的图片数据无效,PIL无法识别。
解决建议
1. 提前清理无效图片
遍历数据集,用PIL验证图片完整性,删除无法识别的文件:
import os from PIL import Image def clean_invalid_images(folder_path): for root, _, files in os.walk(folder_path): for file in files: file_path = os.path.join(root, file) try: with Image.open(file_path) as img: img.verify() # 验证图片是否完整 except (IOError, SyntaxError, PIL.UnidentifiedImageError): print(f"移除无效图片: {file_path}") os.remove(file_path) # 检查并清理训练、测试集 clean_invalid_images('dog-vs-cat-classification/train/') clean_invalid_images('dog-vs-cat-classification/test/')
2. 使用带错误处理的自定义生成器
自定义Sequence生成器捕获异常,跳过损坏的图片批次,替代原有flow_from_directory生成器:
from tensorflow.keras.utils import Sequence from PIL import UnidentifiedImageError class SafeImageGenerator(Sequence): def __init__(self, base_generator): self.base_generator = base_generator self.base_generator.reset() def __len__(self): return len(self.base_generator) def __getitem__(self, idx): while True: try: return self.base_generator[idx] except UnidentifiedImageError: # 跳过当前损坏批次,重置索引后重新获取 self.base_generator._set_index_array() continue # 包装原有生成器 training_set_safe = SafeImageGenerator(training_set) test_set_safe = SafeImageGenerator(test_set) # 注意:fit_generator已弃用,使用fit()替代 model.fit(training_set_safe, steps_per_epoch=8, epochs=20, validation_data=test_set_safe)
3. 升级Pillow并规范图片加载
- 升级到最新版Pillow,修复旧版本的兼容性问题:
pip install --upgrade pillow
- 测试阶段加载图片时强制转换为RGB格式,避免格式异常:
img = Image.open('dog-vs-cat-classification/test/' + image).convert('RGB')
4. 调整数据增强参数
降低增强操作的幅度,减少极端变换导致的图像损坏:
train_datagen = ImageDataGenerator( rescale=1./255, shear_range=0.1, # 降低剪切幅度 zoom_range=0.1, # 降低缩放幅度 horizontal_flip=True )
内容的提问来源于stack exchange,提问作者keith
相关产品推荐
相关产品推荐

