ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

YOLO算法实战:6000张可回收废物图像数据集训练与调参指南

YOLO算法实战:6000张可回收废物图像数据集训练与调参指南 简介面向YOLO系列算法学习与可回收物分类检测场景一套覆盖玻璃瓶、纸瓶、塑料瓶、塑料袋等典型类别的标注数据集可有效解决垃圾分类模型训练数据不足的问题适合目标检测初学者、算法工程师和环保项目开发者用于模型训练、验证与测试。压缩包内共2000个文件以xml标签文件为主整体大小约230MB同时提供yolotxt与vocxml两种标注格式并分目录存放方便按训练需求直接调用。目前已有47人学习下载。数据集已划分好训练集、验证集和测试集兼容yolov5/yolov7/yolov8/yolov9/yolov10/yolo11等主流版本拿到后无需额外整理即可开展训练标注字段如类别索引、归一化中心点和宽高均说明清晰适合用来调试目标检测流程也可作为标签格式转换和迁移学习的练习素材。1. 当YOLO算法遇上可回收废物数据集6000张带标签图像能解决什么做目标检测的工程师应该都遇到过类似的场景项目里缺的不是模型结构而是干净、贴好标签的数据。YOLO算法本身已经成熟到几乎人人能跑但一套针对玻璃瓶、纸瓶、塑料瓶、塑料袋四类可回收废物的标注数据集才是真正决定模型能不能落地的东西。这个zip包里是6000张已经标注好的图像标签格式对齐YOLO的txt规范拿过来就能喂给yolov8训练自己的数据集。对正在做智慧环卫、垃圾分类、工业分拣的朋友来说省掉的是几周标注时间换来的是可以直接调参的起点。新手可以用它跑通整套流程熟手则可以拿它当基准数据去验证YOLO不同版本的效果差异。2. 拆包与数据格式先弄清zip里装了什么再谈训练2.1 解压与目录规划从zip到YOLO标准数据集布局拿到这个zip之后第一步不是急着训练而是把目录结构理顺。常见做法是解压后手动调整成YOLO约定的布局images目录里放原始图像labels目录里放同名txt标签文件。虽然ultralytics的训练脚本支持自定义路径但保持这个约定能少踩很多坑。unzip yolo算法-可回收废物数据集-6000张图像带标签-玻璃瓶纸瓶塑料瓶塑料袋.zip -d waste_dataset cd waste_dataset # 常见解压后可能是散装的先建标准目录 mkdir -p images/train images/val labels/train labels/val解压完务必用ls看一眼实际的文件结构有的压缩包内层还套了一层目录有的则直接把6000张图平铺在同级目录下这两种情况对应的迁移脚本完全不一样。我一般会在解压后先统计图像数量别急着开工。find . -name *.jpg | wc -l find . -name *.txt | wc -l如果输出不是6000对6000先别慌——有的数据集把类别说明和标签说明单独放了文档或者少数图像本身没有目标物体因此没有对应txt文件。只要差异不大比如差几张后续训练时ultralytics会自动跳过没有标签的图像并不会报错。但差太多就该回头检查是否解压不完整。2.2 labels里的玄学YOLO的txt标签格式逐行拆解YOLO系列的标签格式和COCO、VOC完全不同。每个txt文件里每一行代表一个标注框格式固定为class_id x_center y_center width height后四个值全部归一化到0到1之间——是相对于图像宽高的比例不是像素坐标。0 0.453125 0.672656 0.153906 0.205078 1 0.781250 0.344531 0.101562 0.187500 2 0.623047 0.814844 0.089063 0.156250在动手训练之前我建议写一段检查脚本先把标签里是否存在未归一化的像素坐标揪出来。这是个高频翻车点有些标注工具导出的是像素值需要手工除以图像宽高如果忘了这步边界框会飞到图像外面损失函数直接爆掉。# check_labels.py import os label_dir labels/train bad_files [] for f in os.listdir(label_dir): if not f.endswith(.txt): continue with open(os.path.join(label_dir, f)) as fp: for line in fp: parts line.strip().split() if len(parts) ! 5: bad_files.append((f, 字段数不为5)) continue _, cx, cy, w, h parts vals [float(v) for v in (cx, cy, w, h)] if any(v 0 or v 1 for v in vals): bad_files.append((f, 坐标超出0-1范围)) print(f异常文件数: {len(bad_files)}) for item in bad_files[:20]: print(item)这段脚本会打印出所有标签格式异常的文件。字段数不为5说明可能是框的格式混入了别的标注风格比如用了VOC的x1,y1,x2,y2四角坐标坐标超出0-1范围则基本可以断定是没做归一化。无论如何解决思路都一样写一个转换脚本把旧格式统一成YOLO的cx,cy,w,h相对坐标。2.3 类别文件与校验6000张图像里到底有几个类这个数据集按标题描述是四类玻璃瓶、纸瓶、塑料瓶、塑料袋。实际压缩包里大概率会带一个classes.txt或data.yaml记录了类别编号与名称的对应关系。YOLO要求类别编号从0开始连续递增顺序必须和训练脚本里的配置保持一致。如果txt标签里出现了编号5而data.yaml只定义了四个类训练时会直接报索引越界。先确认类别编号范围是一个好习惯awk {print $1} labels/train/*.txt | sort -n | uniq -c这条命令统计训练标签里每一类编号的出现次数。如果输出只有0、1、2、3四行说明没有越界如果出现4或更大的数字说明压缩包里可能有第五类未在标题里体现或者标签导出时类别编号没对齐。这时候需要检查classes.txt里的行顺序手动把多余的类合并或删除。2.4 验证集划分6000张不能全量喂进训练6000张图像对YOLO训练来说不算多工程上更合理的分配是保持原始比例拆成train和val常见做法是8比2即4800张训练、1200张验证。如果zip里已经分好了目录直接用。如果数据是平铺的需要自己做一次分层采样划分确保每一类目标在训练集和验证集中的比例接近。# 按文件名列表做划分避免直接mv打乱数据 python train_test_split.py# train_test_split.py import os, random from shutil import copy2 random.seed(42) image_files [f for f in os.listdir(images) if f.endswith(.jpg)] random.shuffle(image_files) val_ratio 0.2 val_count int(len(image_files) * val_ratio) for idx, fname in enumerate(image_files): sub val if idx val_count else train copy2(fimages/{fname}, fimages/{sub}/{fname}) label fname.replace(.jpg, .txt) if os.path.exists(flabels/{label}): copy2(flabels/{label}, flabels/{sub}/{label})这里用了随机划分对大多数场景够用。但如果你发现某一类比如塑料袋本身样本就很少随机划分可能让验证集里正好缺了这一类导致验证指标失真。稳妥起见按标签中的类别编号做分层采样保证每个类在训练和验证里都有代表。代码不复杂核心思想就是先读标签里每个图像的类别分布再按比例抽样。3. 用YOLOv8跑通可回收废物检测训练命令与关键配置3.1 环境准备与预训练模型下载从ultralytics到yolov8n.pt训练YOLO系列目前最主流的工具是ultralytics框架它把数据增强、损失计算、推理和导出都封装好了。安装只需要一条pip命令pip install ultralytics安装完成后第一次执行训练命令时会自动下载对应的yolo预训练模型下载权重。如果网络环境受限可以先去ultralytics的GitHub Release页面手动下载yolov8n.pt或yolov8s.pt放到工作目录下。yolov8n是nano版本模型文件最小、训练最快适合先跑通流程yolov8s精度更高但显存占用也更大。对于6000张图像的四分类任务我建议直接用yolov8s起步nano虽然在V100上跑得飞快但小目标检测能力的上限摆在那里。3.2 data.yaml的写法路径、类别与yaml格式细节YOLOv8训练时需要一个data.yaml文件描述数据集信息。这个文件写错是最常见的训练失败原因之一。标准写法如下# data.yaml path: /home/user/waste_dataset train: images/train val: images/val names: 0: glass_bottle 1: paper_bottle 2: plastic_bottle 3: plastic_bag注意几个细节。path是数据集的绝对路径train和val是相对path的路径。有些教程里把train写成/home/user/waste_dataset/images/train这种完整路径也可以但前提是和path不冲突。names的编号必须从0开始连续递增顺序要与标签文件里的class_id严格对应——把玻璃瓶和塑料瓶的顺序搞反训练出来的模型不会报错但推理时会指鹿为马。3.3 训练命令与超参数epochs、batch和imgsz怎么设数据准备妥当后训练命令本身并不复杂yolo train datadata.yaml modelyolov8s.pt epochs100 batch16 imgsz640 device0逐参数说明一下。epochs100是训练轮数6000张图像的数据集100轮通常足够收敛如果你的验证集mAP在40轮之后没有明显增长可以提前终止或适当调低学习率。batch16是批大小它受显存限制——单卡12GB跑yolov8s、640分辨率16是安全值如果显存报错降到8甚至4都可以。imgsz640把输入图像缩放到640x640这是YOLOv8的默认输入尺寸。对于可回收废物这种中等大小的物体640足够如果你发现塑料袋这类小目标检测效果差可以试着把imgsz提到960但训练时间会增加一倍以上。训练过程中主要盯两个指标train/box_loss和val/box_loss。box_loss是YOLOv8的边界框回归损失它持续下降说明模型在学习定位垃圾的位置。如果val_loss在下降一段后反弹上扬说明过了拟合点这时候不要急着加数据先把epochs降下来或者开启patience——ultralytics默认会在验证集指标连续多轮不涨时自动提前停止不放心就显式加上patience20。3.4 YOLO损失函数对四类目标的影响从CIoU到DFLYOLOv8的损失函数由三个部分组成边界框回归损失、分类损失和DFLDistribution Focal Loss。边界框回归用的是CIoU变体它比普通IoU多考虑了中心点距离和宽高比DFL则把框的坐标预测建模成概率分布让模型对遮挡和边界模糊的目标更鲁棒。对可回收废物检测来说玻璃瓶和塑料瓶外形相近、颜色可能相似这时分类损失起到主要区分作用而塑料袋因为形状不固定、容易折叠给边界框回归带来的干扰最大能明显感受到box_loss在含有大量塑料袋的批次里波动更剧烈。理解这层关系对后续调参有帮助如果只有塑料袋识别不好调整的是数据增强或损失权重而不是盲目加大imgsz。4. 推理参数的取舍confidence、IoU与NMS的实战选择4.1 confidence阈值玻璃瓶反光导致的误检压不下去怎么办训练好模型后推理阶段最常见的疑问是预测出来一堆框置信度很低该不该信。YOLOv8默认的conf阈值是0.25也就是置信度低于25%的框全部丢弃。对可回收废物场景来说0.25往往偏低——玻璃瓶表面反光、纸瓶上的印刷图案都可能被模型以30%左右的置信度误判成其他类别。我一般会把conf调到0.35到0.5之间具体看你的偏好偏向查全率就用0.3偏向查准率就提到0.5。from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict(test_glass.jpg, conf0.4, iou0.5, saveTrue)iou是NMS非极大值抑制的阈值控制重叠框的合并强度。0.5意味着两个框的IoU超过0.5时保留置信度高的那个。对玻璃瓶和塑料瓶这类外形接近的物体一个瓶子上可能同时出现两个重叠的预测框调低iou到0.4会让输出更干净但代价是漏掉那些确实紧密相邻的瓶罐。如果画面里瓶子排列密集比如一整袋压扁的塑料瓶挤在一起iou反而要适当调高到0.6否则相邻的独立目标会被误合并。4.2 IoU与NMS纸瓶和塑料瓶互相遮挡时的取舍纸瓶和塑料瓶在形状上几乎一样区别主要在材质和表面纹理。当它们堆叠在一起时即便人工标注都会犹豫边界更别说模型。经验是当两类物体Silhouette高度相似、模型输出置信度都在0.5上下波动时提高confidence阈值并不能真正解决问题——提高阈值的后果只是把两个框都丢掉。这时候真正有效的手段是回到训练层面检查labels里这类遮挡样本的标注质量。我见过不少数据集里遮挡严重的瓶子只标了一个框漏了后一个,模型学到的就是一个框代表所有重叠物,推理时NMS会把相邻的预测框抑制掉。另一个实操技巧是调整agnostic_nms参数。YOLOv8的predict方法支持agnostic_nmsTrue表示NMS时不管类别只要框重叠度够高就合并。关闭它默认行为则只在同类之间做抑制。对四个类都是弃用废品的场景建议保持默认的类内NMS因为一个瓶子上同时标了glass和plastic这种情况并不能通过跨类抑制解决反而可能丢掉正确类别的框。4.3 anchor与输入尺寸塑料袋小目标的尺寸适配虽然YOLOv8改成了anchor-free结构但输入分辨率对小型目标的检测依然敏感。6000张数据集里如果塑料袋在画面中占比很小比如远景垃圾桶旁的塑料袋640分辨率下它可能只有20x30像素经过8倍下采样后特征图上的有效信息所剩无几。一个已经被验证有效的做法是把推理分辨率提升到960或1280代价仅仅是推理时间从2ms变成6ms对垃圾分类这种非实时极端场景完全值得。更彻底的办法是训练时直接设置imgsz960让模型从头适应高分辨率输入配合单卡V100大概多花30%的训练时间换来的是小目标AP的明显提升。如果目标场景里塑料袋普遍占比小这个成本必须提前算进去。5. 避坑与排查6000张数据集从zip到模型的血泪经验5.1 坑一zip解压后路径含中文训练直接报错找不到文件现象解压完运行训练命令报FileNotFoundError但路径明明存在。原因这个数据集的zip包标题自带中文解压后的目录名可能也保留了中文。ultralytics底层调用opencv读取图像时对非ASCII路径的兼容性不稳定中文目录名会导致图像加载失败。解决把所有路径改成纯英文。解压时就用-d参数重命名或者在解压后mv成waste_dataset这样的名字。同理data.yaml里的path字段也必须是纯英文路径。5.2 坑二标签格式混用txt文件里混入VOC四角坐标现象训练能正常开始但val/box_loss从一开始就异常高loss曲线完全不平滑。原因数据集标注来源不一有的txt用的是YOLO格式有的是VOC格式x1,y1,x2,y2且没有归一化。YOLO训练期望的是归一化中心坐标如果混入未归一化的四角坐标边界框会拉伸到几千像素外损失函数直接失控。解决先跑第2章里的check_labels.py脚本把异常文件筛出来。然后写个转换函数读取图像的宽高把VOC格式转成YOLO格式覆盖写回txt文件。5.3 坑三塑料袋样本数量太少mAP虚高但实测召回率低现象测试集mAP0.5有0.9以上但现场测试时塑料袋大量漏检。原因四个类别的样本分布严重不平衡比如玻璃瓶占了3500张,塑料袋只有800张。模型在验证集上表现好是因为随机划分正好把塑料袋放进了训练集验证集里这一类的样本少AP计算的不确定性大。解决训练前先看类别分布用awk命令统计每类目标数量。如果哪一类明显偏少先做数据增强旋转、亮度变化、随机裁剪扩到1500张以上。也可以用ultralytics的class_weights参数给少数类更高的损失权重。5.4 坑四zip包伪加密解压时报密码错误但文件能列表现象解压时输入常规密码报错但用unzip -l能列出内部文件清单。原因某些打包工具对zip做了伪加密处理——只是把加密标志位置1实际上并没有用密码保护文件内容。这种包在Windows图形界面下可能正常解压但在Linux的unzip下会要求输入密码。解决不要和加密标志硬刚直接用zipfile库在Python里绕过标志位读取# fix_zip.py import zipfile src waste_dataset.zip dst waste_dataset_fixed.zip with zipfile.ZipFile(src) as zin: with zipfile.ZipFile(dst, w) as zout: for item in zin.infolist(): data zin.read(item.filename) item.flag_bits ~0x1 # 去掉加密标志位 zout.writestr(item, data)这段代码把压缩包内每个文件的加密标志位清除后重新写入新zip。运行后新zip包可以正常无密码解压。注意这只对伪加密有效如果文件真的被AES加密过zin.read()会直接抛异常到时候还是得找到原始密码。5.5 坑五图像尺寸差异过大训练显存溢出现象batch设了16但跑几个step后报CUDA out of memory调成8还是偶尔崩。原因数据集中有的图像是高清长图比如4000x3000虽然ultralytics会做letterbox缩放但显存分配是按批次内最大图算的。偶尔混进一张超高分辨率图峰值显存瞬间拉满。解决训练前统一筛查图像尺寸把异常大的先resize到2560宽之内。常见做法是写个Python脚本用PIL批量处理代价是可接受的信息损失换来的是训练稳定。另一种方式是把batch降到4让每step的显存峰值可控但训练时间会拉长。6. 验证模型效果与进阶路线混淆矩阵、mAP和迁移学习模型训练完成后runs/detect/train目录下会生成confusion_matrix.png和results.png这两张图是判断模型真实水平的切入点。混淆矩阵的横轴是预测类别纵轴是真实类别对角线越亮越好。重点关注非对角线的格子如果玻璃瓶那一行里塑料瓶列特别亮说明模型把玻璃瓶错判成塑料瓶的概率高。在可回收废物场景里这种错判的实际后果比漏检更棘手——瓶子材质不同决定了后端回收工艺不同玻璃混进塑料就是批量事故。mAP指标要分开看mAP0.5反映的是宽松条件下的定位能力mAP0.5:0.95则对框的精确度要求更苛刻。对垃圾分类应用mAP0.5足够日常评估如果计划做精确分拣比如机械臂抓取需要知道瓶子的准确中心点mAP0.5:0.95至少要过0.5否则抓取位置偏差会很明显。进阶方向上迁移学习是收益最高的动作。用coco预训练的权重在6000张废品图上微调是当前最稳妥的路径。如果后续业务扩展到更多类别比如增加易拉罐、纸箱不需要重新标注旧数据只需要在data.yaml的names里追加新类别编号新类别样本量控制在每类500张以上模型就能在已有基础上学会新类。在V100单卡上完成整套数据集训练约需2到4小时这个成本放在项目里完全可控。最后说一个我的习惯每次训练结束把best.pt和last.pt分开存好last.pt阶段性的中间产物best.pt是按验证集指标选出的最优结果。曾经有一次验证集mAP冠军在真实场景里表现平庸回头看恰恰因为验证集划分太随机把简单样本都分进去了。从那以后我在划分数据集时总要检查类别分布。希望这篇笔记能帮你少走这些弯路让这6000张标注图像真正训练出一个能用、敢用的回收物检测模型。本文还有配套的精品资源点击获取
返回列表