1. 项目概述:当YOLOv5遇上垃圾分类
去年夏天,我在小区垃圾站目睹了一场"厨余垃圾该扔哪个桶"的争论后,萌生了用AI解决垃圾分类问题的想法。经过三个月的迭代,这套基于YOLOv5的垃圾识别系统在测试集上达到了94.3%的mAP,部署在树莓派上也能保持15FPS的实时检测速度。不同于常见的演示项目,这个系统特别针对中国垃圾分类标准进行了优化,处理了光照变化、遮挡等现实场景中的棘手问题。
整套方案包含三个核心模块:① 自建的3.2万张标注数据集(覆盖46类常见生活垃圾)② 经过通道剪枝的轻量化YOLOv5s模型 ③ 带分类结果语音提示的交互界面。最让我自豪的是,通过改进的K-means++锚框聚类方法,模型对小目标垃圾(如电池、药片)的识别率提升了27%。
2. 核心方案设计
2.1 数据集构建的魔鬼细节
市面公开的垃圾分类数据集往往存在两个问题:类别体系不符合国内标准(比如将"塑料袋"简单归为"塑料"),以及缺乏真实场景的复杂背景。为此我采用了"三步采集法":
-
基础数据收集:
- 使用爬虫抓取主流电商平台的商品图片(确保包装完整性)
- 在20个小区垃圾站定点拍摄不同时段、天气条件下的场景
- 通过数据增强生成遮挡、旋转等挑战性样本
-
标注规范制定:
python复制# 标注示例(YOLO格式)
class_id x_center y_center width height
3 0.452 0.671 0.12 0.08 # 3对应"易拉罐"
特别设计了"复合标签"机制,比如"奶茶杯"需要同时标注材质(塑料/纸)和残留物状态(空/半满)
- 数据清洗策略:
- 用CLIP模型过滤标注错误的样本
- 对长尾类别(如有害垃圾)进行定向过采样
- 保留5%的"困难样本"用于后期模型调优
2.2 模型选型的权衡之道
对比试验了四种架构后,最终选择YOLOv5s作为基础模型,主要基于三点考量:
-
速度-精度平衡:
模型 mAP@0.5 参数量(M) 推理速度(ms) Faster RCNN 89.2 136 120 SSD300 85.7 26.3 45 YOLOv5s 91.4 7.2 22 YOLOv5m 93.1 21.2 48 -
改进方案:
- 锚框优化:用遗传算法重新聚类出更适合垃圾形状的9组锚框
- 注意力增强:在Backbone末端添加SE模块,提升对小目标的敏感度
- 分类头改进:将原生的单标签分类改为多标签输出(材质+垃圾类型)
-
轻量化处理:
bash复制
python prune.py --weights yolov5s.pt --percent 0.3 --cfg models/yolov5s.yaml通过通道剪枝减少30%计算量,精度仅下降1.2个百分点
3. 关键实现步骤
3.1 环境配置避坑指南
推荐使用conda创建隔离环境,特别注意这两点:
-
PyTorch版本选择:
- CUDA 11.3 + PyTorch 1.10组合在RTX 30系显卡上表现最稳定
- 树莓派部署需编译带OpenMP支持的PyTorch 1.8
-
依赖项冲突解决:
python复制# 特殊处理opencv-python与headless版本冲突 pip uninstall opencv-python-headless -y pip install opencv-python==4.5.5.64
3.2 训练技巧实录
-
超参数调优:
yaml复制# data/hyps/hyp.scratch-low.yaml lr0: 0.0032 # 初始学习率 lrf: 0.12 # 最终学习率衰减系数 momentum: 0.843 weight_decay: 0.00036 warmup_epochs: 2.5发现余弦退火(Cosine)比阶梯式(Step)学习率调度更适合长周期训练
-
增强策略组合:
- Mosaic增强概率设为0.7(过高会导致小目标失真)
- 添加随机灰度化(概率0.1)模拟监控摄像头场景
- 采用Albumentations进行非刚性形变增强
-
早停策略改进:
python复制# 在utils/callbacks.py中修改 patience = 15 # 原值为30 min_delta = 0.002 # 增加判断灵敏度
3.3 部署优化实战
-
TensorRT加速技巧:
python复制# export.py关键参数 parser.add_argument('--engine', action='store_true', help='TensorRT engine export') parser.add_argument('--dynamic', action='store_true', help='Dynamic batch size')实测在Jetson Nano上可使推理速度从45ms提升到18ms
-
边缘设备优化:
- 使用ONNX Runtime替代PyTorch原生推理
- 将分类结果缓存为本地SQLite数据库,减少重复计算
- 采用多线程处理:1个线程负责图像采集,1个线程处理检测,1个线程管理UI更新
4. 典型问题解决方案
4.1 误检漏检分析
案例1:透明塑料袋识别率低
- 原因:缺乏纹理特征,容易与背景混淆
- 解决:在数据集中添加不同折叠状态的塑料袋样本,并在HSV色彩空间加强饱和度增强
案例2:堆叠物品分割错误
- 方案:添加分割分支,先用Mask R-CNN提取物体轮廓,再送入YOLO分类
4.2 模型量化陷阱
当尝试将FP32模型转为INT8时,发现有害垃圾类别的识别率骤降23%。通过分析发现:
- 该类别的特征分布范围较广(如温度计、电池等尺寸差异大)
- 解决方案:
python复制# 在calibrator.py中修改 calibrator = EntropyCalibrator2( num_bins=2048, # 默认是256 truncation=0.9999 # 保留长尾分布 )
4.3 现实场景挑战
光照变化应对:
- 在推理前添加自动白平衡(AWB)预处理
- 训练时采用RandomGamma增强(gamma_range=[0.5, 1.5])
遮挡处理:
- 添加CutOut数据增强(最大遮挡比例30%)
- 在NMS阶段调高IoU阈值到0.6
5. 效果验证与改进方向
测试集上的混淆矩阵显示,最容易混淆的是"纸巾"和"湿巾"(相似度达38%)。通过添加表面纹理分析分支,将区分度提升到72%。
未来可尝试:
- 引入多模态数据(如近红外图像判断材质)
- 开发增量学习方案应对新垃圾类别
- 结合重量传感器数据提升分类准确率
关键经验:垃圾识别项目的成败60%取决于数据集质量。建议在数据收集阶段就邀请环卫工人参与样本标注,他们的实操经验能发现许多工程师想不到的边界情况。