1. 这个警告到底在说什么?别慌,先看懂它
如果你在用YOLOv5训练自己的模型,跑着跑着突然在终端里看到一串黄色的 WARNING: Ignoring corrupted image and/or label,心里肯定“咯噔”一下。我刚开始玩目标检测那会儿,看到这个警告也是一头雾水,尤其是发现数据集里几千张图片莫名其妙“消失”了,训练样本直接少了一截,模型效果肯定受影响。
简单来说,这个警告是YOLOv5在数据加载阶段,给你当了一回“质检员”。它在读取你准备好的图片和对应的标签文件时,发现有些“货”不合格——要么是图片文件本身损坏了,要么是标签文件的格式有问题。为了保证训练过程稳定,YOLOv5的默认策略是:静默忽略这些坏数据,只加载那些检查通过的。所以你的2万张数据集,可能最后只有1万9千张真正进入了训练循环,那丢失的1千张就被这个警告默默过滤掉了。
你可能会问:“我的图片明明能打开啊,怎么看都是好的,怎么就损坏了?” 这里有个常见的误解。我们人类用眼睛看图,用的是图片查看器、Photoshop这些软件,它们容错性很强,即使文件有点小毛病,也能渲染出大致正常的图像。但YOLOv5在训练时,是用代码以二进制流的方式严格读取文件数据的,它对文件完整性的要求近乎“洁癖”。特别是对于JPG/JPEG这种常见的压缩格式,它有一个非常严格的校验:文件必须以特定的二进制标记 \xff\xd9 结尾。这个标记就像文章结尾的句号,告诉程序“数据到此为止,是完整的”。如果你的JPG文件因为各种原因(比如下载中断、存储介质错误、编辑软件保存有瑕疵)丢失或损坏了这个“句号”,哪怕图片内容99%是好的,在YOLOv5眼里,它也是一张“损坏的图片”。
标签文件的问题则更多样。可能是你标注时,边界框的坐标值超出了0-1的归一化范围(比如出现了1.2或者-0.1);也可能是标签文件里出现了重复的行;或者更直接的,图片对应的.txt标签文件根本不存在(nm, missing label)或者里面是空的(ne, empty label)。这些都会被归入“corrupted”的范畴。
所以,看到这个警告别急着烦躁,它其实是帮你发现数据集底层问题的“警报器”。我们的目标不是简单地屏蔽警告(虽然有时为了快速验证可以临时这么做),而是从根本上修复这些有问题的数据,确保每一份标注好的样本都能物尽其用,让模型学到更多。接下来,我们就一步步来当这个“数据医生”。
2. 深入代码:警告是从哪里冒出来的?
要解决问题,先得找到病根。这个警告信息来源于YOLOv5源码中的 utils/datasets.py 文件,具体是在 verify_image_label 这个函数里。这个函数是数据加载流水线的“质检关卡”,每一对(图片,标签)都要经过它的火眼金睛。
我们来拆解一下这个函数的关键部分,理解它到底在检查什么。当你看到下面这段代码时,就找到了核心:
def verify_image_label(args):
# Verify one image-label pair
im_file, lb_file, prefix = args
nm, nf, ne, nc = 0, 0, 0, 0 # number missing, found, empty, corrupt
try:
# verify images
im = Image.open(im_file)
im.verify() # PIL verify
shape = exif_size(im) # image size
assert (shape[0] > 9) & (shape[1] > 9), f'image size {shape} <10 pixels'
assert im.format.lower() in IMG_FORMATS, f'invalid image format {im.format}'
if im.format.lower() in ('jpg', 'jpeg'):
with open(im_file, 'rb') as f:
f.seek(-2, 2)
assert f.read() == b'\xff\xd9', 'corrupted JPEG'
首先,它用PIL库的 Image.open 打开图片,并立刻调用 im.verify()。这是PIL库自带的初步完整性检查。接着,它检查图片的宽和高是否都大于10像素,排除那些尺寸过小、几乎没有信息的图片。然后,检查图片格式是否在允许的列表(如.jpg, .png, .bmp等)内。
重点来了:对于 jpg 或 jpeg 格式的图片,它执行了一个额外的、严格的二进制校验。with open(im_file, 'rb') as

4187

被折叠的 条评论
为什么被折叠?



