我无法在数据集中找到一些有问题的图像。
我的模型开始训练,但出现以下错误:
tensorflow.python.framework.errors_impl.InvalidArgumentError: Invalid PNG data, size 135347
[[{{node case/cond/cond_jpeg/decode_image/cond_jpeg/cond_png/DecodePng}} = DecodePng[channels=3, dtype=DT_UINT8, _device="/device:CPU:0"](case/cond/cond_jpeg/decode_image/cond_jpeg/cond_png/cond_gif/DecodeGif/Switch:1, ^case/Assert/AssertGuard/Merge)]]
[[node IteratorGetNext (defined at object_detection/model_main.py:105) = IteratorGetNext[output_shapes=[[24], [24,300,300,3], [24,2], [24,3], [24,100], [24,100,4], [24,100,2], [24,100,2], [24,100], [24,100], [24,100], [24]], output_types=[DT_INT32, DT_FLOAT, DT_INT32, DT_INT32, DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_INT32, DT_BOOL, DT_FLOAT, DT_INT32], _device="/job:localhost/replica:0/task:0/device:CPU:0"](IteratorV2)]]
Run Code Online (Sandbox Code Playgroud)
因此,我编写了一个小脚本,在生成 TFRecords 之前运行该脚本以尝试捕获任何有问题的图像。这基本上是教程代码,但批量大小为 1。这是我能想到的尝试捕获错误的最简单方法。
def preprocess_image(image):
image = tf.image.decode_png(image, channels=3)
image = tf.image.resize_images(image, [192, 192])
image /= 255.0 # normalize to [0,1] range
return image
def load_and_preprocess_image(path):
image = tf.read_file(path)
return preprocess_image(image)
mobile_net = tf.keras.applications.MobileNetV2(input_shape=(192, 192, 3), include_top=False)
mobile_net.trainable=False
path_ds = tf.data.Dataset.from_tensor_slices(images)
image_ds = path_ds.map(load_and_preprocess_image, num_parallel_calls=4)
def change_range(image):
return (2*image-1)
keras_ds = image_ds.map(change_range)
keras_ds = keras_ds.batch(1)
for i, batch in tqdm(enumerate(iter(keras_ds))):
try:
feature_map_batch = mobile_net(batch)
except KeyboardInterrupt:
break
except:
print(images[i])
Run Code Online (Sandbox Code Playgroud)
这正式崩溃,但没有正确处理异常。它只是抛出异常并崩溃。所以两个问题:
我已经隔离了一个失败的图像,但是 OpenCV、SciPy、Matplotlib 和 Skimage 都打开了它。例如,我试过这个:
import scipy
images = images[1258:]
print(scipy.misc.imread(images[0]))
import matplotlib.pyplot as plt
print(plt.imread(images[0]))
import cv2
print(cv2.imread(images[0]))
import skimage
print(skimage.io.imread(images[0]))
... try to run inference in Tensorflow
Run Code Online (Sandbox Code Playgroud)
我打印出四个矩阵。我假设这些库都使用 libpng 或类似的东西。
然后图像 1258 使 Tensorflow 崩溃。查看 DecodePng源,看起来它实际上是在崩溃 TF png库。
我意识到我可能可以编写自己的数据加载器,但这似乎是废话。
编辑:
这也可以作为一个片段:
tf.enable_eager_execution()
for i, image in enumerate(images):
try:
with tf.gfile.GFile(image, 'rb') as fid:
image_data = fid.read()
image_tensor = tf.image.decode_png(
image_data,
channels=3,
name=None
)
except:
print("Failed: ", i, image_tensor)
Run Code Online (Sandbox Code Playgroud)
打开一个新的 python 文件。复制下面的代码。指定你的图片所在的目录。并运行代码。Corrupt JPEG data: premature end of data segment您可以在列表中看到消息(如果您有损坏的文件)。
from os import listdir
import cv2
#for filename in listdir('C:/tensorflow/models/research/object_detection/images/train'):
for filename in listdir(yourDirectory):
if filename.endswith(".jpg"):
print(yourDirectory+filename)
#cv2.imread('C:/tensorflow/models/research/object_detection/images/train/'+filename)
cv2.imread(yourDirectory+filename)
Run Code Online (Sandbox Code Playgroud)
对这个问题的一个相当晚且出乎意料的自我回答。
事实证明,问题(很可能)是 RAM 损坏造成的。在 Linux 中发生了一些奇怪的事情(例如文件系统变为只读以及 Firefox 中的随机选项卡崩溃)后,我决定运行 Memtest。我安装了 2x8GB DIMM。事实证明,在 4GB 标记附近(两根内存条上)都有一个坏块,这意味着只有 (a) 当系统负载相当高时和 (b) 如果超过 8GB 利用率左右时,才会弹出错误。我还检查了硬盘是否损坏等问题,但它是一个相当新的 SSD。我之前曾在使用相同系统的 Windows 上进行过非常零星和随机的重启,但我再次认为这只是 Microsoft 强制更新。
所以我把这个贴在这里供后代使用。如果您看到奇怪的事情,例如图像以不可重复的方式损坏,则需要花费几分钟来运行 Memtest 作为健全性检查。严重的错误应该会在 30 秒内弹出,值得运行一整夜(多次)来仔细检查。
上面发布的解决方案仍然有用,我仍然不相信 TF 推出自己的 PNG 加载器,但始终值得检查您的硬件!
| 归档时间: |
|
| 查看次数: |
2115 次 |
| 最近记录: |