ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

yolov5垃圾分类识别实战:从数据准备到树莓派部署全攻略

2026/9/9 23:25:23 拓冰建站 浏览量
yolov5垃圾分类识别实战:从数据准备到树莓派部署全攻略 简介基于yolov5的垃圾分类识别项目面向具备一定Python与深度学习基础的学习者解决四类生活垃圾可回收、有害、厨余、其他的模型训练与图像识别问题。项目内置模型权重与推理脚本下载后使用PyCharm打开将测试图片放入data/images运行dect.py即可获得识别结果输出保存在runs/dect-exp目录中。考虑到训练时间有限当前模型采用小规模数据集训练重点覆盖瓶子、报纸、电池、剩饭、碎瓷片等典型物品适合入门目标检测与迁移学习实践。资源压缩包共1001个文件约72MB以txt标注文件、jpg/jpeg图像、yaml配置文件、Python脚本及pt模型权重为主同时包含Dockerfile、依赖清单等环境辅助文件便于复现与二次开发。目前已有5558人学习下载适合课程设计、毕业设计或垃圾分类AI demo快速搭建。通过本项目可掌握YOLOv5数据组织、训练配置、推理调用与结果解析的完整流程也可基于现有代码替换数据集进行扩展训练。 垃圾分类识别最近来找我咨询的人特别多很多是准备做毕业设计或者参赛。大家上来就问yolov5能不能直接拿官方权重识别垃圾我每次都要泼一盆冷水官方预训练权重是在COCO上训的能识别person、car、dog但认不出“厨余垃圾”和“可回收垃圾”你必须自己准备数据、自己训练、自己调优最后还要考虑跑在什么硬件上。这篇文章我把整个yolov5垃圾分类识别项目从零到部署的经验完整拆解一遍重点讲清楚数据、训练、部署和排错这四个环节里那些文档里不会告诉你的细节适合正在做毕设、接外包或者想入门目标检测的开发者。1. 垃圾分类识别的真实难点为什么不能直接拿公开模型用1.1 先把任务定义清楚分类、检测还是实例分割很多人把“垃圾分类识别”理解成一个纯图像分类问题输入一张裁剪好的垃圾图输出“可回收/厨余/有害/其他”。但真实场景里摄像头看到的是一整块区域可能同时存在易拉罐、快递纸箱、塑料袋你需要先把每个垃圾在哪里找出来再判断类别这正是目标检测的任务。所以用yolov5做检测定位比单纯分类更贴近实际。也有人在接到项目后直接拿yolov5官方权重测试看到它能框出“bottle”就以为成功了但官方模型只识别COCO的80类其中的bottle、cup、bowl等只能覆盖很小一部分垃圾类别而且没有垃圾袋、电池、剩菜这种常用类别。正确的做法是把任务定义成“目标检测分类”用yolov5训练自己的类别集合。如果你只是对已经裁剪好的单张垃圾图做分类那用ResNet、MobileNet这类图像分类网络就够了完全没必要上检测模型。我见过好几个方案卡在“分类还是检测”的定位上导致后面整个流程都在绕远路。1.2 数据集质量决定模型上限垃圾分类公开数据集有不少华为垃圾分类数据集、TrashNet等TrashNet只有几千张图且多数是白底单物体照搬到真实场景效果很差。单纯依赖公开数据集会踩两个坑一是类别分布严重不平衡玻璃、纸类多有害垃圾少二是背景过于干净模型会学习“背景特征”而不是“垃圾特征”。我在项目中采用“公开数据自采数据”结合自采部分不少于总量的30%专门拍摄复杂背景、遮挡、凌乱堆叠的垃圾照片。清洗数据比采集数据更麻烦。标注完要用脚本检查每张图的标注框是否越界、宽高是否为0、类别id是否越界。一个常见问题标注时从1开始计数但YOLO格式要求从0开始如果类别编号错位模型训练时不会报错但预测结果全是错类。我写了一个几十行的检查脚本逐个txt读取遇到越界或空文件就打印出来这步能省后面大量排查时间。1.3 易混淆类别26类还是6大类垃圾类别标得越细消费者越满意但模型越容易翻车。我做第一版项目时按“塑料瓶、玻璃瓶、易拉罐、纸盒、报纸、果皮、电池……”分了26类训练完后验证集mAP有0.82实际一测玻璃瓶被频繁误检成塑料瓶因为透明瓶身和塑料瓶在视觉上太接近。后来我把类别调整成二级体系粗分为可回收、厨余、有害、其他4大类大树下再分小类模型先出大类用户再确认小类。对于实际落地我个人建议宁可做宏观4类也不要硬啃26类。四个类别的类间差异明显模型更容易收敛对光线、角度变化的鲁棒性也更好。等4类跑稳定了再逐步细分每细分一次都要重新采集对应类别的新样本否则mAP虚高但实际不可用。这条“先粗后细”的思路同样适用于工业瑕疵分类、农产品分级等项目。我有学员一上来就按生活垃圾管理条例的几十个细类做结果训练了两周识别一塌糊涂后来砍到4大类两天就达到了交付标准。2. yolov5网络结构选型从n到x我为什么推荐yolov5s2.1 结构拆解Backbone、Neck、Headyolov5由三部分组成Backbone用CSPDarknet提取特征Neck用PANet做多尺度融合Head输出分类和回归结果。对垃圾分类项目来说最需要理解的是Neck的多尺度融合。为什么垃圾目标尺度跨度大。烟头、纽扣电池是几十像素的小目标快递纸箱则可能占画面一半。小目标要靠浅层特征里的纹理信息大目标要靠深层特征里的语义信息。yolov5的PANet把不同层的特征反复融合让网络同时“看”到小目标和大目标这是它能做垃圾检测的原因之一。如果你用的是纯分类网络比如ResNetFC小目标很容易被池化层丢掉所以在定位场景下yolov5是更稳妥的起点。2.2 n/s/m/l/x实测对比不要被mAP带偏我用同一个垃圾分类数据集约1.2万张、6大类分别训练了yolov5n、yolov5s、yolov5m测试环境是桌面GPU和树莓派5结果很有参考价值模型参数量mAP0.5桌面GPU推理耗时(ms)树莓派5 CPU推理耗时(ms)yolov5n1.9M0.76665yolov5s7.2M0.8210110yolov5m21.2M0.8415210所以我的结论是如果做毕设或者快速上线选yolov5s精度和速度都不差如果显存很紧张且对精度要求不高yolov5n也能跑但小目标漏检明显yolov5m在GPU上优势不大在树莓派上基本不能用。网络并非越深越好对垃圾这种背景复杂但类别镜框不算极小的任务yolov5s是性价比甜点。这段实测数据还说明了另一件事别看n和s的mAP只差0.06但n的框经常“忽大忽小”尤其在预测多个堆叠垃圾时s的回归框更稳定。如果你的项目要展示给老师或者客户看这个稳定性比那0.06的mAP更直观。2.3 和v6/v8的对比成熟生态比新版本更省心经常被问现在都有v8了还用yolov5吗我理解这种心态但从项目落地角度说yolov5的教程、预训练权重、边缘端部署案例onnx、tflite、ncnn都是最多的遇到问题一搜就有答案。v6/v8在COCO上的指标确实好一点但换到垃圾数据集上优势不会自动保留还得重新调超参数。网上流传的“yolov5和v8推理速度对比”多数是在同一张GPU卡上跑官方模型硬件不同结果完全不同。我在树莓派和ARM开发板上测过yolov5s的onnx模型兼容性明显更好量化工具链更成熟。做项目不是发论文稳定性才是第一位。所以这个项目我坚持用yolov5s不追新。3. 训练自己的垃圾分类数据集从标注到超参数调整的完整链路3.1 数据采集与标注最枯燥却又最影响结果的环节如果只做演示采集每个类别200张就够但如果要上线或者应付导师的随机测试建议每类至少500张以上并且覆盖以下变化不同角度俯拍、侧拍、不同光线室内灯光、室外自然光、不同背景桌面、地面、垃圾袋内、不同完整度压扁的易拉罐、撕开的纸箱。没有这些变化模型一部署就“见光死”。标注工具我用了labelImg也可以用labelme导出为PascalVOC格式后再统一转成YOLO的txt格式。转换脚本的逻辑很简单读取xml里的xmin、ymin、xmax、ymax换算成归一化的中心坐标和宽高写入txt。需要注意坐标可能越界比如标注框超出图片边界需要clip到0~1之间。划分数据集时用脚本按8:1:1随机划分避免把所有同类图片放进同一个文件夹导致某个类别在验证集缺失。我第一次训练时就是忘了打乱导致验证集里根本没有“有害垃圾”mAP看着很高实际完全没法用。这里还建议大家顺手统计一下每个类别的样本数量。如果发现自己采集的纸箱图有500张但电池只有30张那就要在训练前先做数据扩充而不是等训练完了再补救。数据分布表可以用一个简单的Python脚本来输出到CSV方便后续复盘。3.2 训练配置和超参数改这些就够了yolov5训练前要准备一个data.yaml内容大概是path: /data/trash train: images/train val: images/val nc: 6 names: [cardboard, glass, metal, paper, plastic, trash_bag]训练命令python train.py \ --data trash.yaml \ --weights yolov5s.pt \ --img 640 \ --batch-size 16 \ --epochs 100 \ --device 0这里最常用的调节项是img和batch-size。img 640代表把输入图像缩放/填充到640x640垃圾目标通常不大一开始不建议降到320否则小目标信息丢失。显存不够时优先减少batch-size而不是降img。预训练权重必须选和你的任务接近的yolov5s.pt是在COCO上预训练的里面学到的基础特征可以直接迁移到垃圾识别比从零训练收敛快得多。超参数我基本只动三个地方学习率lr0从默认0.01改成0.005小数据集上下更平稳mosaic增强概率酌情降低如果数据集不到2万张mosaic太激进会引入大量拼贴噪声hsv增强里的饱和度偏移可以加大一点垃圾颜色是强特征绿色玻璃、黄色纸箱适度破坏颜色能提升鲁棒性但不能调过头否则颜色本身成为不可靠特征。yolov5的超参数文件是data/hyps/hyp.scratch.yaml直接改就好不用从头写。3.3 类别不平衡小样本类别这样救有害垃圾电池、过期药物样本往往只有其他类别的十分之一。单独靠过采样会让网络反复看同一批图很快过拟合。更有效的做法是给样本少的类别“造数据”用Copy-Paste增强把电池、药片的分割区域贴到干净背景上并随机旋转缩放用MixUp增强把难样本和常见样本混合训练调整loss权重在train.py的ClassLoss里给稀有类别提高权重或者用autoBalance参数自动加权。这些方法不能全上否则训练时间翻倍。我实际组合是“过采样轻微Copy-Paste”把稀有类样本扩充到3倍左右同时把总epochs降一点防止过拟合。最终验证集上稀有类mAP从0.41涨到0.68效果显著。特别提醒一下Copy-Paste的素材要裁剪干净不要把背景残渣一起贴进去否则模型可能学到素材边缘的伪影。我自己写了一个半自动脚本用labelme的polygon输出做切割能省不少力气。如果没有精力做这么细那就退而求其次把稀有类图片整体多复制几份放到训练集里同时把它放入更多的mosaic组合中也能有一定提升。4. 边缘端部署实战树莓派5上跑yolov5的优化与取舍4.1 部署硬件怎么选别在STM32上死磕yolov5很多同学一听到边缘端立刻想到STM32但STM32属于MCU主频低、内存小跑yolov5即便是n版本也达不到实时除非做剪枝INT4量化极低分辨率工程难度极高。我看到的毕设选题里“基于STM32的边缘端yolov5车辆检测与车位管理”这种题目落地时其实更依赖摄像头和上位机MCU只做控制识别是在树莓派或者手机端完成的。做项目前先把“算力边界”想清楚能少走很多弯路。如果需要一个硬件模块直接运行yolov5做垃圾分类树莓派5是性价比不错的选择。它用的arm64架构可以跑onnxruntime也可以跑TensorFlow Lite功耗不高社区资料多。相比之下Jetson Nano算力更强但价格高、缺货严重如果只是垃圾桶识别场景树莓派5足够。4.2 导出ONNX并在树莓派5上运行用yolov5自带的export.py导出ONNXpython export.py --weights best.pt --include onnx --opset 11然后在树莓派5上安装onnxruntimepip install onnxruntime推理代码不要照搬detect.py因为detect.py默认处理整个目录、打印日志、画图保存全是性能杀手。我精简后的推理流程是读取图片 - 缩放到640x640保持比例用灰色填充 - 转RGB - 转CHW并归一化 - onnxruntime session跑一次 - 拿到输出张量 - 解码框和类别 - NMS过滤。解码时需要注意yolov5的onnx输出形状是(1, 25200, 85)以6类计算其中25200640/8、16、32三个尺度的anchor总数855类别数。当你改了类别数最后一维会变容易踩坑。4.3 实测帧率和优化清单我在树莓派5上实测yolov5s转onnx后纯Python推理单张约110ms大概9FPS做三个优化后提升到65ms左右约15FPS固定输入尺寸不做动态letterbox减少每帧重复计算的缩放比例解码和NMS用cv2.dnn.NMSBoxes代替自己写的循环线程池并发处理摄像头采集和模型推理把I/O时间藏起来。如果还想更快可以量化到FP16或者INT8但INT8在树莓派CPU上支持不完整容易掉精度折中方案是导出FP16 ONNX配合onnxruntime的CPU执行精度损失小速度提升10%左右。要我说垃圾分类场景15FPS够用了毕竟垃圾桶里的东西不会跑实时性的压力远小于车载项目。如果你是做实时车辆检测同样的优化思路可以继续压缩输入尺寸到416帧率能再上一个台阶但小目标会损失严重。5. 踩坑实录与排查链路Loss不降、误检、训练崩掉怎么办5.1 训练时Loss变成nan或直接发散我遇到过最典型的“训练崩掉”是loss变成nan训练完了一套权重完全不能用。排查顺序是先看是不是学习率太大把lr0从0.01降到0.001再试检查是否用了half精度--half显存不够的人爱开但小数据集上容易梯度爆炸检查数据集里有没有空标签文件或全0的框yolov5不报错但会污染loss如果用了自定义anchor检查anchor尺寸是否离目标真实尺寸太远极端情况下也会导致loss发散。其中空标签文件最隐蔽labelImg在保存时偶尔会漏写类别生成一个空文件训练时该样本不贡献loss表面上没事但验证时会影响判断。我用脚本把小于等于0行内容的txt全部找出来删掉后问题立刻消失。5.2 Loss一直降但mAP上不去这种情况多半是过拟合或者验证集分布和训练集不一致。垃圾数据里很常见训练集大多是室内干净背景验证集里有室外垃圾桶照片模型自然翻车。我的排查路线是先看训练集loss和验证集loss的差距如果训练loss很低但val loss居高不下就是过拟合此时优先降低epochs、加大dropout或者减少模型复杂度。如果两边loss都不低那就是数据问题——补拍对应场景而不是继续调参。另外检查一下验证集是否包含了所有类别用脚本统计val目录下的类别数量缺类会导致mAP虚高或计算报错。5.3 部署后误检严重负样本和阈值调整模型在自己的测试视频里很准一装到实际场景就到处乱框多出来的“手”“人影”“地面纹理”全被识别成垃圾。这个问题的根源是训练集缺少负样本。解决方法是在训练数据里加入一大批不包含任何垃圾的图片可以是桌面、地面、草地、堆杂物角落并给每张图生成内容为空的标注txt。yolov5从yolov5-5.0版本开始把空标签样本计入训练loss的“background”项能有效抑制误检。我的经验是负样本占正样本的10%~20%误检率能下降一半以上。另一个直接手段是把推理参数里的conf_thres从默认0.25提高到0.35iou_thres从0.45调到0.5宁可漏检也不要乱检。垃圾分类是服务型场景频繁误报比漏报更影响体验。最后分享一个贯穿整个项目的经验垃圾分类识别能不能落地瓶颈不在模型结构而在数据是否贴近真实场景、部署硬件是否匹配、验收标准是否清晰。我一开始沉迷调网络、涨mAP后来到了树莓派上才发现一个稳定的yolov5s加一套干净的训练数据远比一个浮夸的高精度大模型好用。如果你也在做类似项目建议一开始就固定“部署硬件-目标帧率-类别粒度”这三个约束再倒推数据采集和模型选型。这个思路在车辆检测、缺陷识别这些边缘端项目上都通用可以少走很多弯路。本文还有配套的精品资源点击获取