垃圾目标检测数据集实战:YOLOv8训练、避坑与ONNX部署全流程 简介这是一份面向计算机视觉开发者、环保科技团队及高校师生的垃圾目标检测数据集聚焦单类别Trash识别可服务于智能垃圾分类、清洁机器人视觉、违规倾倒监测及目标检测教学等场景。资源包共492个文件以245张jpg真实场景图片与245个同名txt标注文件为主另含1个yaml数据配置和1份docx说明文档压缩包约33.05MB训练集231张、验证集14张均采用标准化YOLO边界框格式可直接接入YOLO系列、Faster R-CNN等主流框架。图片采集自实际环境覆盖多样光照、角度与背景标注经过校验有助于提升模型泛化能力。目前已有198人学习下载适合需要快速验证算法或搭建环保识别原型的读者参考使用。1. 垃圾目标检测数据集从“能跑”到“能落地”的第一道坎如果你做过环卫巡检机器人、智能垃圾分类箱或者城市固废监管平台大概率会遇到同一个尴尬模型在 COCO 上 mAP 挺好看一换到真实垃圾场景就崩。原因不复杂——通用数据集里“垃圾”这个类别的样本又少又杂塑料袋、纸盒、饮料瓶、烟头、建筑渣土混在一起类间差异大、类内差异更大而且遮挡、堆叠、光照变化几乎是常态。这份垃圾目标检测数据集就是冲着这个缺口来的它把生活垃圾、可回收物、有害垃圾等常见目标做了标注格式对齐 YOLO 训练习惯能直接喂给 YOLOv5/v8 这类框架。适合谁做环保类视觉项目的算法工程师、带学生做课设的高校老师以及想拿行业数据集练手目标检测的入门者。它解决的不是“有没有数据”而是“数据能不能直接用、标注能不能信、类别能不能对上你的业务”。2. 数据集结构与 YOLO 格式对齐先看清标签再谈训练2.1 目录组织与标注格式拿到一个目标检测数据集我第一件事不是写训练脚本而是把目录结构和标签文件翻一遍。行业数据集最常见的坑就是“图片和标签对不上号”训练时 loss 不降排查半天发现是文件名后缀不一致。这份数据集按 YOLO 惯例组织典型结构如下dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamlYOLO 格式的标签是每张图对应一个.txt每行一个目标格式为class_id x_center y_center width height坐标全部归一化到 0~1。这里有个容易被忽略的点归一化用的是图片原始宽高不是网络输入尺寸。如果你在预处理阶段先 resize 再算坐标标签就全错了。常见做法是保持原图不动让 YOLO 的 dataloader 自己处理 letterbox 缩放。data.yaml是训练入口内容大致长这样path: ./dataset train: images/train val: images/val nc: 6 names: [plastic, paper, glass, metal, organic, hazardous]nc是类别数names的顺序必须和标签里的class_id严格对应。我见过有人改了names顺序却没改标签结果模型把塑料瓶识别成有害垃圾这种错误在验证集上表现为“类别混淆严重但 mAP 还行”特别隐蔽。2.2 类别分布与长尾问题行业数据集绕不开长尾分布。垃圾场景里塑料瓶、纸盒这类样本多有害垃圾电池、灯管样本少直接训练会导致模型对少数类几乎不响应。先统计一下每类实例数import os from collections import Counter label_dir dataset/labels/train counter Counter() for f in os.listdir(label_dir): if f.endswith(.txt): with open(os.path.join(label_dir, f)) as fp: for line in fp: cls int(line.split()[0]) counter[cls] 1 for cls_id, cnt in sorted(counter.items()): print(fclass {cls_id}: {cnt} instances)跑完你会看到类似class 0: 3200、class 5: 180的分布。差距超过 10 倍就要考虑处理策略过采样少数类、在 loss 里加类别权重或者用 copy-paste 增强合成少数类样本。我一般先用cls_pw参数给 YOLOv8 加类别权重改动最小效果也够用。提示统计实例数时注意区分“图片数”和“实例数”一张图可能有多个目标按图片数统计会低估长尾程度。2.3 标签可视化验证训练前必须做一次可视化抽检确认标注框位置正确、类别无误。用 OpenCV 画框最直接import cv2 import os img_path dataset/images/train/0001.jpg label_path dataset/labels/train/0001.txt img cv2.imread(img_path) h, w img.shape[:2] with open(label_path) as f: for line in f: cls, xc, yc, bw, bh map(float, line.split()) x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, str(int(cls)), (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.imwrite(check.jpg, img)这段代码把归一化坐标还原成像素坐标再画框。重点看三件事框是否贴合目标、类别 ID 是否和data.yaml对得上、有没有漏标的目标。漏标比错标更麻烦因为模型会把漏标区域当背景学导致召回率上不去。抽检比例建议不低于 5%如果发现系统性偏移比如框整体偏左上大概率是标注工具导出时坐标系搞反了。3. 用 YOLOv8 跑通训练参数怎么设、日志怎么看3.1 环境准备与数据配置YOLOv8 通过 ultralytics 包安装一条命令搞定pip install ultralytics训练前把data.yaml里的路径改成绝对路径或相对于训练脚本的路径避免“找不到图片”的报错。我习惯在项目根目录建一个configs/放 yaml训练脚本里用--data configs/garbage.yaml指定。如果你的数据集类别名和业务系统不一致改names就行但记住标签里的class_id是数字改名字不影响训练只影响推理时的输出标签。3.2 训练命令与关键参数一条典型的训练命令yolo detect train \ dataconfigs/garbage.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/garbage \ nameexp1逐个说参数modelyolov8n.pt是 nano 版预训练权重垃圾检测这种类别不多、场景相对固定的任务n 或 s 版通常够用上大模型容易过拟合。imgsz640是输入分辨率如果你的图片里小目标多比如烟头、瓶盖可以提到 960但显存占用会翻倍。lr00.01是初始学习率YOLOv8 默认用 SGD 时这个值比较稳用 AdamW 的话降到 0.001。patience20是早停耐心值验证集 mAP 连续 20 轮不涨就停省时间。注意batch要根据显存调8G 显存跑 640 分辨率n 版模型 batch16 基本是上限报 OOM 就往下调别硬撑。3.3 训练日志解读与中断恢复训练开始后终端会打印每轮的 box_loss、cls_loss、mAP50、mAP50-95。重点盯两个信号cls_loss 不降说明类别学习有问题可能是标签类别错乱或长尾太严重mAP50 涨到某个值后震荡不升说明模型容量或数据量到瓶颈了。如果训练中途断了用resume接着跑yolo detect train resume modelruns/garbage/exp1/weights/last.ptlast.pt是最后一轮权重best.pt是验证集最优权重。推理和部署用best.pt继续训练用last.pt。我踩过的坑是拿best.pt去 resume结果优化器状态对不上loss 直接起飞。记住这个区别能省你半天排查时间。3.4 验证集评估与混淆矩阵训练完跑一次验证yolo detect val modelruns/garbage/exp1/weights/best.pt dataconfigs/garbage.yaml输出里除了 mAP还会生成混淆矩阵图。垃圾检测最容易出的问题是“可回收物”和“其他垃圾”互相混淆因为塑料袋、纸巾这类目标在不同标注标准下归类不一致。如果混淆矩阵显示某两类互相误判严重先回去查标注规范别急着调模型。数据问题模型救不了这是血泪经验。4. 避坑与排查标注、路径、显存的三类翻车现场4.1 图片与标签文件名不匹配现象训练启动后报No labels found或 loss 恒为 0。原因图片是.jpg标签是.JPG.txt或者图片名带空格、中文标签名做了清洗。解决写个脚本统一文件名图片和标签只保留主名一致扩展名各自保留。批量重命名用 Python 的os.rename最稳别手动改。4.2 类别 ID 从 1 开始导致越界现象训练报IndexError: index out of range或类别全错。原因有些标注工具默认类别从 1 开始编号而 YOLO 要求从 0 开始。解决全局扫描标签文件把class_id减 1同时确认data.yaml的names列表长度等于最大 ID 加 1。这个坑在跨工具导出的数据集里特别常见。4.3 显存溢出与 batch 设置现象训练几轮后突然 OOM或者一开始就报 CUDA out of memory。原因图片分辨率不一致dataloader 按最大尺寸分配显存或者batch设太大。解决先把imgsz固定训练前用脚本统计图片尺寸分布把超大的图筛出来单独处理batch从 8 开始试稳了再往上加。别迷信“batch 越大越好”小数据集小 batch 反而泛化更好。4.4 验证集 mAP 虚高现象验证集 mAP 0.9一上真实场景就废。原因训练集和验证集来自同一段视频的相邻帧几乎一模一样等于变相泄漏。解决按视频或采集批次划分 train/val别随机按帧分。如果数据集已经分好了检查一下 val 里的图片是不是在 train 里出现过相似帧。这个坑最隐蔽也最致命。4.5 标签坐标超出 0~1 范围现象训练不报错但框位置诡异或者某些目标永远学不会。原因标注时框拖到了图片边界外归一化后坐标小于 0 或大于 1。解决训练前跑一遍校验脚本把越界坐标裁剪到 [0,1]同时记录哪些文件被修正过回头检查标注质量。5. 从训练到部署ONNX 导出与推理加速的实操细节5.1 导出 ONNX 并验证一致性训练完的.pt权重适合研究和验证真正部署到边缘设备或服务端通常要转 ONNX。导出命令yolo export modelruns/garbage/exp1/weights/best.pt formatonnx imgsz640 opset12opset12兼容性最好别盲目追新版本。导出后必须做一致性验证用同一张图分别跑 PyTorch 和 ONNX比较输出框的坐标和置信度。差异超过 1e-3 就要查常见原因是预处理letterbox 的 padding 值没对齐。我一般写个脚本把两边结果画在同一张图上肉眼比对最直观。5.2 推理脚本与后处理参数ONNX 推理的核心是预处理和后处理要对齐训练配置。预处理做 letterbox 缩放后处理做 NMS。关键参数是conf_thres和iou_thres垃圾检测场景下目标密集堆叠时iou_thres设 0.5 容易把相邻目标合并可以降到 0.4conf_thres从 0.25 起步漏检多就降到 0.15误检多就提到 0.4。这两个值没有万能解拿验证集跑一轮 PR 曲线按业务对漏检和误检的容忍度选。5.3 边缘设备部署的量化取舍如果部署到 Jetson 或瑞芯微这类边缘设备ONNX 还可以进一步转 TensorRT 或 RKNN做 FP16 甚至 INT8 量化。量化能提速 2~3 倍但小目标召回率通常会掉几个点。我的习惯是先跑 FP16看精度损失是否可接受如果必须上 INT8一定用真实场景的校准集别拿训练集凑合。校准集分布不对量化后的模型在特定光照下会集体失效这种问题在实验室里根本复现不出来。5.4 一个验证部署效果的小技巧部署上线前我会做一件事把验证集里模型表现最差的 20 张图挑出来单独跑一遍部署管线和 PyTorch 结果逐张对比。这 20 张图往往包含遮挡、逆光、密集堆叠等边界情况能提前暴露 80% 的部署问题。从那以后我每次导出模型都强制走一遍这个“最差样本回归”比看整体 mAP 有用得多。希望这套流程能帮你在垃圾检测项目上少走几个弯路。本文还有配套的精品资源点击获取