ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

流水线皮带异物检测:110张VOC+YOLO数据集训练YOLOv8实战

流水线皮带异物检测:110张VOC+YOLO数据集训练YOLOv8实战 简介本资源为流水线皮带传送带异物检测数据集面向从事工业视觉检测、智能制造与深度学习目标检测的开发者及学生可用于训练和验证传送带异常识别模型。数据集采用Pascal VOC与YOLO双格式标注包含110张jpg图片及一一对应的110个xml文件和110个txt文件标注类别为anomaly共191个矩形框使用labelImg完成标注标注准确合理。压缩包共332个文件以txt标注、xml标注和jpg图像为主整体约17.76MB目录结构清晰便于直接接入YOLO或VOC训练流程。目前已有391人学习下载适合作为工业异常检测赛题或课程实验的入门数据帮助读者快速搭建训练与验证环境理解标注格式转换与数据组织方式。1. 流水线皮带异物检测110 张 VOCYOLO 数据集到底能不能训出能用的模型流水线皮带传送带上的异物检测是工业视觉里最容易被低估的场景之一。锚杆、铁片、大块矸石、塑料桶碎片混在煤流或矿石里一旦卡进滚筒或撕裂皮带停机损失按小时算。很多团队第一反应是「先搞个数据集跑个 YOLO 看看」于是找到了这个 110 张、1 类别、同时提供 VOC 和 YOLO 两种标注格式的压缩包。问题来了110 张图连 YOLOv8 默认的 8 张 batch 都凑不出几个完整 epoch这东西到底能不能用我的结论是——能但前提是你把它当「冷启动种子集」而不是「训练全集」并且必须配合强增强、预训练权重和一套针对工业场景的采集补数流程。这篇笔记就按这个思路把 VOCYOLO 双格式的转换、YOLOv8 训练参数、小样本翻车点和现场补数方法讲透适合产线算法工程师、工控视觉开发者以及手里只有少量标注图、想先跑通闭环再谈落地的团队。2. VOC 与 YOLO 双格式拆解110 张图里到底装了什么2.1 VOC 的 XML 结构和 YOLO 的 txt 差在哪VOC 格式每张图对应一个 XML核心字段是folder、filename、sizewidth/height/depth、object下的name、pose、truncated、difficult和bndboxxmin/ymin/xmax/ymax。YOLO 格式则是每张图一个同名 txt每行class_id cx cy w h全部归一化到 0~1。这个数据集只有 1 个类别所以 class_id 恒为 0省掉了类别映射表的麻烦但也意味着你没法靠类别名反推异物类型——如果现场要区分「铁器」和「非铁」这个数据集本身给不了得自己扩类。VOC 的坐标是绝对像素值左上角为原点YOLO 是归一化中心点坐标。转换时最容易翻车的是size字段和实际图片尺寸不一致或者 XML 里depth写成 1 而图片是三通道。我一般会先写个校验脚本把每张图的 PIL 尺寸和 XML 里的 width/height 对一遍不一致的直接剔掉别让脏数据进训练集。2.2 用 Python 把 VOC 转成 YOLO 的最小脚本虽然压缩包里两种格式都有但实际用的时候经常遇到「YOLO 的 txt 缺了几张」或者「想统一重划 train/val」的情况所以转换脚本还是得备一个。下面这段是我常用的版本带尺寸校验和越界裁剪import os import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(xml_dir, img_dir, out_dir, class_map): os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(xml_dir, xml_file)) root tree.getroot() img_name root.find(filename).text img_path os.path.join(img_dir, img_name) # 尺寸校验XML 声明尺寸必须和真实图片一致 with Image.open(img_path) as im: iw, ih im.size size root.find(size) if int(size.find(width).text) ! iw or int(size.find(height).text) ! ih: print(f尺寸不一致跳过: {img_name}) continue lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_map: continue bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 越界裁剪防止归一化后出现负数或大于1 xmin, xmax max(0, xmin), min(iw, xmax) ymin, ymax max(0, ymin), min(ih, ymax) cx (xmin xmax) / 2.0 / iw cy (ymin ymax) / 2.0 / ih w (xmax - xmin) / iw h (ymax - ymin) / ih lines.append(f{class_map[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) out_txt os.path.join(out_dir, os.path.splitext(img_name)[0] .txt) with open(out_txt, w) as f: f.write(\n.join(lines)) voc_to_yolo(Annotations, JPEGImages, labels, {foreign: 0})逻辑说明先解析 XML 拿到绝对坐标再用真实图片尺寸做归一化而不是用 XML 里的 size这样即使 XML 写错也能兜住。参数上class_map把类别名映射到 0单类别场景直接写死。越界裁剪那两行是血泪经验——工业图里经常有标注框贴着边缘甚至超出 1 像素不裁的话 YOLO 训练时会出现 w 或 h 为负loss 直接 NaN。2.3 110 张图的划分策略别用 8:1:1110 张图按 8:1:1 分验证集只有 11 张mAP 波动能到 0.2 以上根本没法判断模型好坏。我的做法是如果只是验证流程跑通用 5 折交叉验证每折 88 训 22 验最后看 5 折平均 mAP如果是要交付一个初版模型留出 20 张作为固定测试集剩下 90 张里再切 10 张做验证训练集 80 张。80 张图配合 mosaic、mixup、随机旋转一个 epoch 也就 10 个 iteration跑 300 epoch 在单卡 V100 上不到 20 分钟完全耗得起。提示划分时按「拍摄时段」或「皮带位置」分层别随机打散。同一段皮带的连续帧如果同时进训练和验证验证指标会虚高现场一上就露馅。3. 用 YOLOv8 在 110 张图上跑通训练参数、增强与预训练权重3.1 环境配置和数据集 yaml 怎么写环境用 conda 建一个干净环境ultralytics 装最新稳定版即可别去追 main 分支。CUDA 版本和显卡驱动对齐V100 用 CUDA 11.8 或 12.1 都行。数据集目录按 YOLO 标准结构放dataset/ images/ train/ # 80 张 val/ # 10 张 test/ # 20 张 labels/ train/ val/ test/yaml 文件里path写绝对路径train、val、test写相对路径names用字典{0: foreign}。这里有个小坑如果 yaml 里nc和names长度不一致ultralytics 会直接报错退出不会静默容忍。3.2 关键训练参数小样本下哪些必须改直接上命令这是我在 110 张图上跑通的配置yolo detect train \ datadataset.yaml \ modelyolov8s.pt \ epochs300 \ imgsz640 \ batch8 \ lr00.001 \ lrf0.01 \ warmup_epochs5 \ mosaic1.0 \ mixup0.15 \ degrees15 \ translate0.1 \ scale0.5 \ fliplr0.5 \ flipud0.0 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ patience50 \ workers4 \ device0参数说明modelyolov8s.pt而不是 n 或 m是因为 110 张图用 n 容易欠拟合m 参数量太大容易过拟合s 是平衡点。lr00.001比默认的 0.01 小一个量级小样本下大学习率会让 loss 震荡。mosaic1.0保持默认这是小样本最有效的增强四图拼接相当于把 80 张扩成 320 张的视觉多样性。mixup0.15别开太高工业异物和背景对比度强mixup 过头会让异物边缘糊掉。flipud0.0是因为皮带图有明确的重力方向上下翻转不符合物理。patience50配合 300 epoch早停留足空间。3.3 训练过程看什么loss 曲线和混淆矩阵的读法跑起来之后重点盯三个东西。第一是train/box_loss和val/box_loss的分离程度如果 val loss 在 50 epoch 后开始抬头说明过拟合要么加增强要么减 epoch。第二是混淆矩阵单类别场景下矩阵是 2x2看背景被误判成异物的比例——工业场景里背景误报比漏报更烦人因为会触发无谓停机。第三是metrics/mAP50-95110 张图能到 0.6 以上就算这个数据集榨干了别指望 0.9。注意YOLOv8 的混淆矩阵在单类别时经常出现「总和不为 1」的情况因为背景类不计入归一化。别慌看绝对数值就行。4. 小样本异物检测的避坑清单从 BN 崩溃到验证集虚高4.1 现象训练几个 epoch 后 loss 变 NaNBN 层报错原因batch8 时如果某张图里没有标注框纯背景图YOLOv8 会把它当负样本但 BN 层在极小 batch 下方差估计不稳连续几个 batch 全背景就会崩。解决训练前扫一遍 labels把空 txt 的图挑出来要么补标要么移出训练集或者把 batch 提到 16但 110 张图 batch16 一个 epoch 只有 5 个 iteration梯度更新太少不推荐。4.2 现象验证集 mAP 0.85现场测试漏检一半原因验证集和训练集来自同一段视频的相邻帧背景几乎一样模型记住了背景而不是异物。解决按时间或位置分层划分验证集必须包含训练集没见过的皮带段、光照条件。如果数据量实在不够至少做一次「留一拍摄时段」的交叉验证。4.3 现象模型把皮带接头、托辊当成异物原因VOC 标注时只标了「异物」没标「负样本」模型没见过皮带正常结构的长什么样。解决从现场视频里截 200 张纯背景图含接头、托辊、煤流正常状态作为负样本加入训练集labels 留空。这一步能把误报率降一个数量级。4.4 现象推理时小目标异物全漏原因110 张图里异物尺寸普遍偏大模型没学过小目标。解决训练时imgsz640已经够用但要在数据增强里加scale0.5让目标缩小同时推理时用imgsz1280做测试时增强TTA小目标召回能提 10~15 个百分点。4.5 现象换一条皮带产线模型直接失效原因过拟合到特定皮带的颜色、纹理、光照。解决训练时加hsv_h0.015, hsv_s0.7, hsv_v0.4做颜色抖动再加随机灰度化hsv_s0的概率设 0.1强迫模型学形状而不是颜色。但根本解法还是补新产线的数据110 张图跨产线迁移能保住 50% 性能就算不错。5. 从 110 张到可交付补数策略与推理端的一个实用技巧110 张图训出来的模型直接上产线是不负责任的但作为「冷启动种子」它有一个高价值用法半自动标注。具体做法是用训好的模型对现场连续视频做推理置信度阈值设 0.25把检出的框存成 YOLO txt然后人工只做「删错框、补漏框」标注效率能从纯手工的 1 张/分钟提到 5~8 张/分钟。我一般会按这个节奏补数第一轮补 300 张重训第二轮补到 800 张再重训到 1500 张左右模型基本能稳定在 mAP50 0.85 以上这时候才谈部署。推理端有个技巧值得单独说工业相机帧率高但异物是稀疏事件没必要每帧都跑 YOLO。用背景差分或简单的帧间差分做前置触发只有画面变化超过阈值时才调 YOLOGPU 占用能降 80%。触发阈值我一般设像素变化率 3%~5%太低会被光照波动误触发太高会漏掉慢速移动的小异物。这个组合在 V100 上单卡能扛 8 路 1080p 流延迟控制在 80ms 以内。最后说个我自己的习惯每次拿到这种「小样本双格式」的数据集先花 10 分钟写个统计脚本把每张图的标注框数量、宽高分布、面积占比打出来。110 张图里如果框数分布是长尾的——比如 80% 的图只有 1 个框——那训练时就要调box损失权重或者用 focal loss 变体。这个动作比盲目调 epoch 有用得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表