PIL.UnidentifiedImageError: 无法识别图像文件 <_io.BytesIO 对象>

7

我正在使用Tensorflow训练我的模型(图像分类)。当我尝试运行以下单元格时,不断遇到错误:

    hist = model.fit(
        train_generator, 
        epochs=100,
        verbose=1,
        steps_per_epoch=steps_per_epoch,
        validation_data=valid_generator,
        validation_steps=val_steps_per_epoch).history

错误为:

Epoch 1/100
27/31 [=========================>....] - ETA: 1s - loss: 0.7309 - acc: 0.6181
---------------------------------------------------------------------------
UnknownError                              Traceback (most recent call last)
<ipython-input-36-b1c104100211> in <module>
      2 val_steps_per_epoch = np.ceil(valid_generator.samples/valid_generator.batch_size)
      3 
----> 4 hist = model.fit(
      5     train_generator,
      6     epochs=100,

/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)
   1098                 _r=1):
   1099               callbacks.on_train_batch_begin(step)
-> 1100               tmp_logs = self.train_function(iterator)
   1101               if data_handler.should_sync:
   1102                 context.async_wait()

/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py in __call__(self, *args, **kwds)
    826     tracing_count = self.experimental_get_tracing_count()
    827     with trace.Trace(self._name) as tm:
--> 828       result = self._call(*args, **kwds)
    829       compiler = "xla" if self._experimental_compile else "nonXla"
    830       new_tracing_count = self.experimental_get_tracing_count()

/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/def_function.py in _call(self, *args, **kwds)
    853       # In this case we have created variables on the first call, so we run the
    854       # defunned version which is guaranteed to never create variables.
--> 855       return self._stateless_fn(*args, **kwds)  # pylint: disable=not-callable
    856     elif self._stateful_fn is not None:
    857       # Release the lock early so that multiple threads can perform the call

/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/function.py in __call__(self, *args, **kwargs)
   2940       (graph_function,
   2941        filtered_flat_args) = self._maybe_define_function(args, kwargs)
-> 2942     return graph_function._call_flat(
   2943         filtered_flat_args, captured_inputs=graph_function.captured_inputs)  # pylint: disable=protected-access
   2944 

/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/function.py in _call_flat(self, args, captured_inputs, cancellation_manager)
   1916         and executing_eagerly):
   1917       # No tape is watching; skip to running the function.
-> 1918       return self._build_call_outputs(self._inference_function.call(
   1919           ctx, args, cancellation_manager=cancellation_manager))
   1920     forward_backward = self._select_forward_and_backward_functions(

/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/function.py in call(self, ctx, args, cancellation_manager)
    553       with _InterpolateFunctionError(self):
    554         if cancellation_manager is None:
--> 555           outputs = execute.execute(
    556               str(self.signature.name),
    557               num_outputs=self._num_outputs,

/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     57   try:
     58     ctx.ensure_initialized()
---> 59     tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
     60                                         inputs, attrs, num_outputs)
     61   except core._NotOkStatusException as e:

UnknownError:  UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7fc88d55c9a0>
Traceback (most recent call last):

  File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/ops/script_ops.py", line 249, in __call__
    ret = func(*args)

  File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/autograph/impl/api.py", line 620, in wrapper
    return func(*args, **kwargs)

  File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/data/ops/dataset_ops.py", line 891, in generator_py_func
    values = next(generator_state.get_iterator(iterator_id))

  File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/data_adapter.py", line 807, in wrapped_generator
    for data in generator_fn():

  File "/opt/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/engine/data_adapter.py", line 933, in generator_fn
    yield x[i]

  File "/opt/anaconda3/lib/python3.8/site-packages/keras_preprocessing/image/iterator.py", line 65, in __getitem__
    return self._get_batches_of_transformed_samples(index_array)

  File "/opt/anaconda3/lib/python3.8/site-packages/keras_preprocessing/image/iterator.py", line 227, in _get_batches_of_transformed_samples
    img = load_img(filepaths[j],

  File "/opt/anaconda3/lib/python3.8/site-packages/keras_preprocessing/image/utils.py", line 114, in load_img
    img = pil_image.open(io.BytesIO(f.read()))

  File "/opt/anaconda3/lib/python3.8/site-packages/PIL/Image.py", line 2943, in open
    raise UnidentifiedImageError(

PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7fc88d55c9a0>


     [[{{node PyFunc}}]]
     [[IteratorGetNext]] [Op:__inference_train_function_24233]

Function call stack:
train_function

我将尝试更改`loss='categorical_crossentropy'`为`loss='binary_crossentropy'`,但问题仍然存在。我希望训练模型,但是Epoch一直卡住。
编辑:
train generator函数及其使用方法如下:
IMAGE_SHAPE = (224, 224)
TRAINING_DATA_DIR = str(data_root)


datagen_kwargs = dict(rescale=1./255, validation_split=.20)
valid_datagen = tf.keras.preprocessing.image.ImageDataGenerator(**datagen_kwargs)
valid_generator = valid_datagen.flow_from_directory(
    TRAINING_DATA_DIR, 
    subset="validation", 
    shuffle=True,
    target_size=IMAGE_SHAPE
)

train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(**datagen_kwargs)
train_generator = train_datagen.flow_from_directory(
    TRAINING_DATA_DIR, 
    subset="training",
    shuffle=True,
    target_size=IMAGE_SHAPE)


for image_batch, label_batch in train_generator:
  break
image_batch.shape, label_batch.shape

输出结果:((32, 224, 224, 3), (32, 2))
print (train_generator.class_indices)

labels = '\n'.join(sorted(train_generator.class_indices.keys()))

with open('labels.txt', 'w') as f:
  f.write(labels)

输出:{'关闭': 0,'打开': 1}


请发布您的 train_generator 函数。 - Lescurel
请确保您文件夹中的所有图像都是真正的图像,且未损坏。 - Lescurel
它们中没有一个是损坏的。实际上,它们大多数都是屏幕截图。它们似乎正常打开。我怎么知道哪一个是损坏的,以便我可以将其删除?@Lescurel - EverydayDeveloper
你可以尝试使用Pillow读取它们所有。 - Lescurel
我该怎么做呢?有很多图片。是否有任何代码可以验证哪个文件导致了问题?我认为它只是表示图像的哈希值 @Lescurel - EverydayDeveloper
让我们在聊天中继续这个讨论 - Lescurel
4个回答

9

其中一个img存在问题,并被@Lescurel指出。要查看该img,您可以运行以下命令:

import PIL
from pathlib import Path
from PIL import UnidentifiedImageError

path = Path("INSERT PATH HERE").rglob("*.jpeg")
for img_p in path:
    try:
        img = PIL.Image.open(img_p)
    except PIL.UnidentifiedImageError:
            print(img_p)

你也可以对png或其他格式的图像进行相同的操作。如果图像存在问题,则运行后立即列出该问题。

2
谢谢,这是一个很好的代码片段,可以在预处理和训练之前识别那些有问题的图像。 - Aman Singh

1
与@EverydayDeveloper类似,但使用glob来保存具有类的所有图像路径。
import PIL
from PIL import UnidentifiedImageError
import glob

imgs_ = glob.glob("/home/ubuntu/imageTrain_dobby/SKJEWELLERY/classification/dataset/jewellery_dataset/train/*/*.jpg")

for img in imgs_:
    try:
        img = PIL.Image.open(img)
    except PIL.UnidentifiedImageError:
        print(img)

1

当我在Mac上访问外部硬盘上的训练数据集时,遇到了同样的问题。flow_from_directory函数返回的文件比我放置在文件夹中的文件还要多。

将整个训练数据集移动到本地驱动器上解决了这个问题。


0

当我试图调用Image.open()时,遇到了相同的错误,但我是在通过多部分请求从Flutter客户端应用程序接收的字节上调用此函数。

问题在于我在客户端没有包含文件名参数:

MultipartFile.fromBytes('image', await image.readAsBytes(),
      filename: image.name)

在添加了filename: image.name之后,Image.open能够识别图片文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接