尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

650张行李箱缺陷检测数据集:YOLOv8训练、格式转换与调优实战

发布时间:2026/9/23 17:08:21

资讯中心
01
ARTICLE

650张行李箱缺陷检测数据集:YOLOv8训练、格式转换与调优实战

650张行李箱缺陷检测数据集:YOLOv8训练、格式转换与调优实战
简介面向行李箱外观质检与目标检测算法入门者这份数据集提供650张清晰行李箱图片并同时给出VOC与YOLO两种标注格式覆盖正常状态与损伤两类目标。标签名称分别为damaged、good_condition矩形框总数达936个其中损伤样本框199个、完好样本框737个可直接用于训练YOLO系列、SSD或Faster R-CNN等目标检测模型。压缩包共包含1952个文件主要分为JPEGImages图像、Annotations的XML标注、labels的TXT标注三类每一类均对应650个文件目录结构简洁便于按批次划分训练集与验证集。图片未做增强处理保持原始清晰度适合自行尝试数据扩充或迁移学习。资源大小约25.11MB目前已有126人学习下载。对刚接触缺陷检测或需要一份小型实操数据的开发者来说这是一套便于上手、标注规范的训练资源。1. 650张2类的行李箱缺陷检测数据集为什么先复现比先收集更重要做行李箱表面质检的人大概率遇到过这种窘境客户说“你先拿几百张图试试”结果翻遍全网找不到一个能把划痕、凹痕、脏污明确标成矩形框的数据集。别说650张有的项目连50张带标注的都凑不齐。标题里这个行李箱缺陷检测数据集卡在刚好能启动一个POC的量级上——650张、2类、同时给YOLO和VOC两种格式。这个规模放在深度学习里不算大但它恰好覆盖了“验证算法路线、跑通训练流程、给客户出演示结果”所需的全部素材。数据集下载到手之后真正的坑往往不在模型而在格式。YOLO格式的txt和VOC格式的xml坐标语义完全不同180度反转的也有。这篇文章会按我处理这类数据集的实际顺序展开先核验目录、再做格式转换、然后跑一次yolov8训练自己的数据集的完整流程最后讲清楚五个高频踩坑点和验收部署时的置信度调优。适合手里有一个具体检测任务、正在找数据练手或准备上生产线POC的工程师。2. 打开压缩包先看格式VOC与YOLO的目录骨架和坐标语义2.1 拿到压缩包先核对什么两张“文件清单”多数双格式数据集的压缩包解压后是两套独立目录。VOC那套沿用了PASCAL VOC的经典骨架YOLO那套则是images和labels成对出现。我拿到手的第一件事不是看图片而是用find命令把整个目录结构拍一遍确认没有缺文件。$ unzip dataset-luggage-defect-650-2cls.zip -d ./luggage_defect $ cd ./luggage_defect $ find . -maxdepth 2 -type d | sort ./yolo_format ./yolo_format/images ./yolo_format/labels ./voc_format ./voc_format/Annotations ./voc_format/JPEGImages ./voc_format/ImageSets/MainVOC格式下JPEGImages放原始图像Annotations放同名xml标注ImageSets/Main里通常是train.txt、val.txt这类划分文件。YOLO格式下images和labels目录里的文件按同名前缀一一对应labels下的txt文件每行是一条目标记录。这个骨架本身不复杂但它是后续一切操作的根基——目录对不上训练时第一个报错就是“assertion failed: image not found”到时候再回头补文件就很被动了。2.2 VOC和YOLO的坐标语义为什么程序员反而容易搞混VOC的xml里坐标是像素绝对值xmin、ymin、xmax、ymax代表矩形框左上角和右下角在原图中的位置。YOLO格式则完全不同txt里每行五个数class_id、x_center、y_center、width、height前四个都是相对图片宽高的归一化比例取值在0到1之间。格式存储位置每行内容坐标基准VOCxml文件xmin, ymin, xmax, ymax像素坐标绝对值YOLOtxt文件class_id, cx, cy, w, h归一化坐标相对图片宽高类别索引由标签名映射而来从0开始计数class_id0代表第一个类别搞混的典型场景是一个人手工打开一个txt看到“0 0.5 0.3 0.1 0.2”以为后面四个数是随意的小数就把标签记成五个数——其实是把归一化坐标当成了原始像素值。另一个人从xml里读到xmin521直接写进yolo训练结果模型把整张图当成目标框。这两种错误在650张这种小数据集上会立刻暴露因为训练出来的模型不是不收敛而是收敛到一个完全错误的位置分布上。2.3 数据集下载后先跑的三行核验代码不管数据是下载的还是同事交接的我都会先跑一遍一致性检查。检查三件事图片和标注文件是否同名一一对应、标签类别集合是否只有两类、有没有哪些标注框越界。import os from collections import Counter # 图片目录和txt标注目录 img_dir yolo_format/images label_dir yolo_format/labels img_names {os.path.splitext(f)[0] for f in os.listdir(img_dir)} label_names {os.path.splitext(f)[0] for f in os.listdir(label_dir)} print(图片数:, len(img_names), 标注数:, len(label_names)) print(无标注的图片:, len(img_names - label_names)) print(无图片的标注:, len(label_names - img_names)) # 统计两个类的样本数量 class_counter Counter() for f in os.listdir(label_dir): with open(os.path.join(label_dir, f)) as fp: for line in fp: class_counter[int(line.split()[0])] 1 print(类别分布:, dict(class_counter))这段代码输出三个关键信息图片和标注是否一一对应、两个类的目标框总数、以及类别索引是否只有0和1。650张数据里如果出现十几张无标注图片通常不是bug而是拍摄时恰好拍了没有缺陷的行李箱壳体这类图属于难负样本我一般会单独放到一个目录留作验证。类别分布如果出现极端不均衡比如一个类占了90%训练时必须考虑采样策略后面第5章会专门说。3. VOC转YOLO的转换脚本与四个边界坑3.1 反向脚本从VOC到YOLO的最小实现有些项目里团队习惯用labelimg打标导出默认就是VOC格式的xml而yolov8训练又只要YOLO格式的txt。这个数据集同时给了两份省了我自己转格式的时间但更常见的生产场景是只有VOC所以转换脚本我一定要自己会写。下面的脚本可以直接跑通常见VOC目录import xml.etree.ElementTree as ET import os # class_names顺序和训练yaml里的names保持一致 class_names [scratch, dent] def voc_to_yolo(xml_file, out_dir): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) labels [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: continue cls_id class_names.index(name) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) cx (xmin xmax) / 2 / img_w cy (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h labels.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) txt_name os.path.splitext(os.path.basename(xml_file))[0] .txt with open(os.path.join(out_dir, txt_name), w) as fp: fp.write(\n.join(labels)) xml_dir voc_format/Annotations out_dir yolo_format/labels os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): voc_to_yolo(os.path.join(xml_dir, xml_file), out_dir)逻辑很简单解析xml拿到图片宽高和每个目标的像素框换算成归一化的中心点坐标和宽高六位小数写出。两个参数需要你按实际数据改class_names的顺序决定了类别索引这个顺序在训练时和val推理时必须全局一致另一点是如果xml里存在dimensions标签但缺size那说明数据源不是标准labelimg得手动补宽高。3.2 四个边界坑第一是坐标越界。标注人员手抖画框时稍微拖出去一点xmax就可能等于img_w2归一化后超过1。训练前最好做一次钳制cx和w如果超过1直接裁剪到[0, 1]区间如果是负数多半是坐标解析顺序搞错了。不处理的话yolo训练时计算IoU容易出现令人费解的mAP波动。第二是类别索引错位。常见场景是原始xml里只有一个类“scratch”有人图省事把class_names写成[“scratch”, “dent”]最后发现所有标注都被推进了索引0第二个类永远没数据。正确做法是打印一遍所有xml里出现的name集合严格按名称排序或按自定义优先级映射不猜。第三是空标注问题。有些xml里只有object标签没有bndbox或者object被标注人员删了一半。转换后txt文件为空这本来没问题但650张里有大量空标注会导致训练时背景样本过强。我的原则是空txt保留但单独挑出来做验证集背景难例不混进训练集。第四是文件名大小写。VOC里叫IMG_001.JPG标注叫img_001.xmlLinux下直接就检索不到对应关系。转换脚本里统一做一次lower()比后面排查半天路径问题省事得多。3.3 标注工具与版本管理团队协作里的两个习惯现在标注这块最常见的工作流还是labelimg开voc模式拉框存成xml再批量转yolo格式训练。这个流程本身不复杂但团队协作有两个容易被忽略的细节。一个是对接外部标注团队时提前约定好类别中英文名、命名规范和xml里哪些标签必须保留比如defect_type、light_condition这种业务字段否则回传的数据根本没法直接用。另一个是标注文件的版本管理我习惯把xml或txt连同对应的图片一起放进git每次修订标注记录一次commit这样模型指标突然变化时还能回头查是哪一次标注改动引入的。4. 用YOLOv8训练自己的数据集目录、参数与损失曲线判读4.1 目录编排与data.yaml配置yolov8训练自己的数据集目录安排比想象中严格。虽然ultralytics框架接收的是图片路径但如果你从别的项目直接拷贝数据集结构经常会在验证时报“dataset not found”。一个稳妥的结构是这样$ mkdir -p luggage_yolo/train/images luggage_yolo/train/labels $ mkdir -p luggage_yolo/val/images luggage_yolo/val/labels # 用软链接组织数据不要复制省一半磁盘空间 $ ln -s /path/to/yolo_format/images/*.jpg luggage_yolo/train/images/ $ ln -s /path/to/yolo_format/labels/*.txt luggage_yolo/train/labels/650张的规模train和val划分我一般按8:2来切随机切分就好。但有个前提如果同一只行李箱拍了不同角度的多张图要保证同一只箱子只出现在train或val里避免验证集“泄题”。这点在工件级检测里很关键跨视角相似度会导致mAP虚高显得模型很能打一上现场就现原形。yaml文件这样写# luggage.yaml path: ./luggage_yolo train: train/images val: val/images nc: 2 names: 0: scratch 1: dent这里的names顺序必须和训练txt里的class_id一致不能改了标签名忘了改txt文件。我自己就吃过这个亏把第0类和第1类调换顺序没重新生成txt训练日志里loss很正常但预测出来的类别标签全反了。4.2 第一次训练用的保守参数650张数据量不大第一次训练我建议用保守一点的参数先跑通再调优。$ yolo detect train \ dataluggage.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ patience50 \ lr00.001 \ augmentTrue \ project./runs \ nameluggage_first这里用yolov8n而不是s或m是因为650张样本量撑不起大模型用n能明显减少过拟合风险。epochs150是给足收敛空间patience50表示验证集指标连续50个epoch没提升就自动早停这比死等150个epoch更省时间。lr00.001是相对保守的初始学习率如果你习惯用0.01配yolov8n在少样本场景下大概率遇到loss翻车。参数我常用的值什么时候改modelyolov8n.pt数据超过2000张且有明显小目标时考虑yolov8simgsz640行李箱表面缺陷普遍较小时可以上960但训练时间增加两倍batch16显存不够降到8数据集极小时降到4epochs150残余loss仍在下降就加到300patience50训练时间紧张就降到30接受略差一点的模型lr00.001小数据集不要直接上0.01这句话我每次都会跟新同事说超参数不是玄学但也别追求一次调对。小数据集上先固定lr0、epochs、patience三个参数跑通再去动imgsz和模型尺寸不然出了问题时变量太多排查起来很痛苦。4.3 训练中怎么读yolo损失函数和mAP曲线训练时终端打印的是box_loss、cls_loss、dfl_loss和各类mAP指标。第一次跑的人往往只盯着mAP50看到0.35就觉得模型不行。其实在小数据集上前30个epoch的mAP波动非常正常重点看三条loss曲线的整体趋势。box_loss反映的是框回归的误差如果它在前30个epoch稳定下降说明模型学到了位置信息cls_loss是分类误差如果下降缓慢多半是类间特征太接近——比如划痕和轻微压痕在视觉上本身就不容易区分dfl_loss是分布焦点损失它控制边界框的精细程度在行李箱边缘反光多的图片上dfl_loss到后期仍然震荡是正常现象。我判断的标准很简单三个loss分别下降且后期在某个区间震荡就是健康训练如果val的mAP平了但loss还在掉说明过拟合开始了早停机制应该触发不触发就手动停止。用yolo predict立刻跑几张验证图看看框的位置比看一堆曲线更直观。5. 行李箱缺陷检测踩坑记录五个最常见的问题与排查顺序5.1 loss发散或不下降先看学习率再看数据现象训练刚开始的几十个batchbox_loss跳到几十甚至出现nan训练直接废掉。原因八成是学习率太高yolov8n配合lr00.01在少样本场景下非常容易发散。剩下两成是数据本身的问题图片损坏、标注框全为0、或者某张图的分辨率异常导致预处理阶段除零。解决先把lr0降到0.001重新跑一版多数情况立即恢复正常。如果还是nan用一个小脚本逐张检查图片是否能被cv2.imread成功解码、标注坐标是否都在[0,1]区间内把坏文件挑出来宁可删掉也不要保留。这个顺序不要反过来——先检查数据再调超参能省出至少半天浪费的算力。5.2 mAP成绩好看真机却漏检严重现象验证集mAP50到0.85一接到现场拍的行李箱照片就漏检尤其是深色箱体上的划痕。原因这是典型的验证集分布和实际场景不一致。验证集里大多是标注团队挑的“清晰缺陷”亮度均匀、缺陷明显现场是产线侧光、反光、运动模糊叠加特征分布完全变了。650张数据本身不足以覆盖这种域偏移。解决从训练集里抽20张最“难”的图单独做盲测包括仰拍、暗光、反光的箱子。如果mAP跌了20个点以上说明泛化能力不够。这时不要急着堆数据先做两步把训练集按rayleigh分布重新采样保证深色箱体和浅色箱体的比例平衡再收集现场实在跑不动的照片人肉标上框哪怕只有50张混合进训练集重训一版效果通常立竿见影。5.3 过拟合的判据不是“epoch太多”现象训练loss已经很低但验证集mAP连续40个epoch不动甚至往下走用模型跑训练集某些图时检测框比验证集的准得多。原因数据量只有650张模型容量相对过剩开始“背”训练集里箱子纹理的细节而不是学缺陷本身。解决这不是单纯减少epoch的事。我一般按这个顺序试a) 把model从yolov8n换成yolov8n但加大增强——打开hsv_h、hsv_s和fliplr让模型见到更多颜色和翻转变化b) 如果增强没救回来减少一半可训练参数比如换用更小的输入分辨率imgsz480c) 最后才是提前终止。记住在小数据集上增强永远比调网络结构重要。5.4 两类缺陷样本比例悬殊怎么办现象650张里凹痕只有120张划痕占530张。训练出来的模型对凹痕召回率只有40%但划痕召回率有90%。原因类别不均衡导致模型在训练时把权重倾斜到多数类。yolo默认的cls_loss是按样本数累计的少数类的梯度贡献被淹没。解决我最简单的方法不是改损失函数——yolo支持class_weight参数但650张不至于用那么重的手段。先把少数类做复制粘贴增强对120张凹痕图做轻度旋转、缩放、平移生成300张增强样本参与训练。代价是这些增强样本之间高度相似所以我会限制增强幅度只做±10度旋转和±5%缩放。如果复制增强还不行再看是否需要调整loss权重。5.5 部署时误检一堆置信度阈值该谁说了算现象模型部署到测试机上箱体上明明没有缺陷输出一堆框或者简单划痕检测出来了但凹痕漏掉了。原因训练时用的置信度阈值和部署推理时完全不同。yolo训练时通常把conf默认设成0.25但现场光线复杂、角度多模型给出的置信度整体偏低。你把阈值调到0.5漏检率上升降到0.1误检率爆炸。这个阈值本质上不是算法问题是业务口径问题。解决我处理这类检测任务的惯例是先在一个固定的“困难样本集”上扫一遍conf从0.05到0.7、步长0.05的PR曲线找到precision和recall的交叉点附近作为初始阈值。这个值大概率不在0.5附近更可能在0.2到0.4之间。然后再根据实际需求调客户更在意漏检缺陷流出就压低阈值更在意误检停机复查成本就抬高阈值。这个决策要留在部署阶段做而不是训练阶段。6. 验收与部署用业务口径调置信度而不是用算法默认值6.1 验收指标看混淆矩阵不只看mAP训练完拿到的results.png里有混淆矩阵比mAP数值更值得看。mAP是一个压缩后的单点指标它掩盖了每个类别的真实行为混淆矩阵能直接告诉你凹痕被分到了划痕、还是被当成了背景。650张数据的模型因为样本量不大混淆矩阵往往能暴露某个类的confusion集中在哪个方向。我验收时固定看两行凹痕class_id1的True Positive数量和False Negative数量以及背景行的False Positive数量。前者决定漏检率后者决定误检率这两个数才真正决定这个模型能不能给客户演示。6.2 导出ONNX与现场联调的三个动作模型验收通过后导出成ONNX已经是个标准动作$ yolo export modelruns/luggage_first/weights/best.pt formatonnx imgsz640导出后我一般做三个动作一是启动一个ONNX Runtime推理脚本确认导出后的模型和pytorch版本预测结果一致允许个位数像素的误差二是把conf阈值参数暴露给现场配置而不是写死在推理代码里三是用一段现场拍摄的行李箱视频跑一遍在线流式检测观察有没有单帧跳变——目标在连续帧中断断续续出现通常是NMS的iou阈值设置过紧或者输入帧率丢帧导致跟踪不稳定。现场联调还有一个小细节确保推理输入的图像尺寸固定为imgsz640不要直接拿相机分辨率往里塞。尺寸不一致预处理会自动resize但标注框坐标没跟着换算画到原图上全偏。这个问题我遇到过两次每次都浪费半天。6.3 我保留到现在的两个习惯第一个习惯是每个训练项目我都会保留一份“验证集盲测样本”至少30张这些图只用来做最终验收绝不参与训练。模型再怎么调哪怕效果不好至少能保证评估口径一直没变。第二个习惯是每次跑完训练第一时间把best.pt和训练yaml复制到一个固定目录以日期命名归档。三天后回来想复现当时的指标结果忘了当时用了什么参数这种翻车我经历过不止一次。650张的行李箱缺陷检测模型说不上复杂但它能帮你把yolo训练的整个闭环走通——收集数据、标注规范、格式转换、训练调参、部署验收。这些能力比模型本身值钱。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。