垃圾分类这事,说起来不算新话题,但真正把它做成一套能落地、能实时跑起来的系统,难度比我预想的大不少。去年我参与了一个模拟项目,目标很直接:用摄像头识别生活场景里的常见垃圾,按可回收、有害、厨余和其他四类自动分拣提示,同时把检测结果上传到后台做数据统计。最初我们考虑过传统图像分类方案,但在真实场景里效果实在不稳定,后来把技术栈切换成YOLO系列,才慢慢把项目推到了可演示、可交付的状态。
这篇文章就围绕这套“基于YOLO系列的生活垃圾智能检测与分类系统”展开,把我们从数据集准备、模型训练、性能优化到边缘设备部署的完整过程做个梳理。里面没有太多理论空谈,更多是实际踩坑后的总结,包括哪些参数值得调、哪些地方容易翻车、怎么在低算力设备上保住检测速度。如果你正准备做类似的目标检测项目,或者想把一个CV模型从训练环境搬到现实设备上,这篇文章应该能给你一些参考。当然,每个人手里的硬件、数据和业务场景都不一样,我的方案不是标准答案,只是把一条已经走通的路讲清楚,剩下还得靠你自己在实际项目中再打磨。
1. 项目整体设计与方案选型
1.1 为什么最终选了YOLO系列
团队里最开始有人提过用Faster R-CNN,理由是精度高。但我们在真实场景里做了一次模拟推演就放弃了:Faster R-CNN在CPU上的推理延迟高得离谱,一张1280分辨率的画面跑一次要接近两秒,放在部署机上根本没法用。后来又看了SSD和EfficientDet,速度尚可,但在小目标、遮挡物体上的表现比较一般。YOLO系列这时候优势就很明显了,它将目标检测任务重构为单个回归问题,用锚框加分类头一次完成所有预测,在速度和精度之间取得了更容易接受的平衡。特别是YOLOv8之后,算法里加入了anchor-free检测头、C2f模块等设计,对我们的垃圾识别场景来说已经足够友好,不需要再额外上太复杂的技巧。
选YOLO还有一个比较现实的原因:社区生态完善,网络上有大量预训练权重和案例,遇到问题很容易找到类似场景的解决方法。我们项目里用了YOLOv5、YOLOv8和YOLOv10做了横向对比,发现每个版本的侧重点不太一样。v5胜在稳定、资料多,很多老牌部署方案都基于它;v8的接口更现代,训练和导出流程清爽,官方对自定义数据集支持得很好;v10在实时性上有额外优化,但对部分硬件加速库的支持还不够完全。最终正式版本用了YOLOv8n作为基础模型,因为它在模型体积、推理速度和检测精度之间最适合我们手里的边缘设备。
1.2 系统需要解决的核心问题
过去我做过一些通用目标检测,比如行人、车辆、安全帽这些,垃圾检测看着简单,实际难在类别内部差异太大。同一个“可回收物”类别里,有矿泉水瓶、纸箱、易拉罐,外形上几乎没有任何共同特征。而“厨余垃圾”里果皮、剩菜、茶叶渣的颜色和形状千奇百怪。如果一开始就按照四分类去训一个模型,很容易出现类别内特征过于分散的问题,模型不知道怎么把“瓶子”和“罐子”统一映射到同一个“可回收物”语义空间里。
所以项目在需求拆解阶段就把“先细分类、后粗分类”的思路确定了下来:第一层先识别具体物体,比如矿泉水瓶、玻璃瓶、报纸、塑料袋、电池、香蕉皮;第二层再由程序映射到投放类别。这样模型任务更聚焦,训练难度降低,后续类别调整也不需要重新训练整个模型,只要修改映射规则就行。系统最终要解决的是三个问题:看见垃圾、认准垃圾、告诉用户怎么扔。其中“认准”是最核心的环节,YOLO模型承担了这部分最难的工作。
1.3 应用场景与部署边界
我们调研了几类典型场景,包括校园垃圾分类投放点、社区垃圾房、小型环保宣传站。这些场景有一个共同点:摄像头安装位置相对固定,光照变化集中在白天和夜晚两个状态,拍摄角度一般朝下或略带俯视。这意味着我们可以用固定机位的数据来提高模型稳定性,而不需要像自动驾驶那样应对各种极端视角。
部署边界同样需要提前划清楚。模型训练可以用大算力服务器,但实际推理要在边缘设备上完成,否则每个点位拉一台GPU服务器太不现实。我们对比过几种方案,包括树莓派、Jetson系列和小型工业电脑,最终选了Jetson系列设备作为主要推理平台,算力适中、生态成熟、可以跑TensorRT加速。当然,在真正部署前,还要经过一系列量化、剪枝和导出操作,这些后面单独展开讲。
2. 数据集构建与标注实践
2.1 数据来源与类别体系设计
垃圾检测没有现成的完美数据集,公开数据集中图片背景、拍摄角度、物体种类和我们需求匹配度有限。我们采用了“公开数据集筛选 + 自行拍摄 + 网络来源补充”的三合一策略。公开部分主要选用常见的垃圾图片集,筛选标准是单类别图片数量足够、背景干扰可控;自行拍摄部分覆盖了项目实际场景中的垃圾袋、垃圾桶、地面散落物等姿态;网络来源部分用来补充一些罕见物品,比如温度计、药品、过期化妆品等有害垃圾。
类别体系我们参考了地方垃圾分类指导目录,但做了一层更细致的拆分。模型训练阶段定义了13个子类:塑料瓶、玻璃瓶、易拉罐、纸箱、报纸书本、塑料袋、一次性餐具、果皮、剩饭剩菜、茶渣、电池、药品、其他。其中“其他”是一个兜底类别,收集的是上述类别都不包含的常见杂物。这里特别提醒一句:兜底类别的图片一定要足够多,否则模型会把所有不认识的东西都硬塞进某个已知类别,产生大量误检。
2.2 标注工具与标注重难点
工具方面我们试过LabelImg和X-AnyLabeling,最后团队大部分标注工作都在X-AnyLabeling上完成。原因很简单:它支持自动化辅助标注,可以用一个初始训练好的模型先跑一遍,生成伪标签,人工只需要修正边界框和漏检目标。在已经有一定基础模型的条件下,标注效率能提高一倍多。LabelImg虽然轻量、稳定,但全手工画框在几百张图片时还好,上千张就明显吃力。
标注过程中有四个容易踩的坑。第一,小目标千万不要漏标。很多生活垃圾相对画面尺寸很小,标注员注意力稍不集中就漏掉,模型学不到小目标特征,推理时就容易漏检。第二,边界框要贴合物体轮廓,宁缺毋滥。太松的框会把背景特征包进去,太紧的框又截断物体主体,都会干扰特征提取。第三,遮挡物体要单独标注并在训练时做遮挡增强。两个垃圾叠在一起时,模型要有能力识别出露在外面的部分。第四,类别不平衡要在标注阶段就控制。比如果皮图片数量如果远多于电池,模型会偏向预测厨余类,后面加再多的loss权重也不如数据层面来得直接。
2.3 数据增强策略与训练集划分
生活垃圾图像的特性决定了数据增强策略不能照搬通用目标检测方案。常见的水平翻转、随机裁剪、色彩扰动、仿射变换都可以用,但要注意垃圾的颜色在某些类别里是重要特征。比如果皮的新鲜程度影响颜色深浅,但如果增强时把色彩饱和度和色调扰动幅度调得过大,模型可能会把可回收物和厨余类混淆。我们最终把色调扰动控制在正负10度以内,饱和度扰动控制在正负25%以内。
此外还加入了Mosaic增强和Copy-Paste增强。Mosaic把四张图拼接成一张,可以丰富单张图片中的目标数量,提升模型对小目标的感知能力。Copy-Paste则从一张图里抠出目标物体粘贴到另一张背景图上,对增加“垃圾放在垃圾房地面、草地”等真实场景很有帮助。训练集、验证集、测试集按7:2:1划分,划分时按图片维度随机切分,而不是按视频帧或同一场景整批切分,这是为了保证验证集分布独立。数据总量最后定格在1.2万张左右,标注框4.8万个,单类别平均约3700个框,算是一个勉强够用的规模。
3. 模型训练实验与调优记录
3.1 YOLOv8n的训练配置与参数选择
训练用了YOLOv8n作为基线,输入分辨率设为640x640,预训练权重使用COCO上的通用权重。Batch size受限于显卡显存,设置了16,初始学习率0.01,使用SGD优化器加余弦退火调度。训练轮数设定为200轮,前3轮用warmup让学习率从0缓慢上升到初始值,避免模型前馈阶段梯度剧烈震荡。这里有个细节,YOLO框架默认的weight decay是0.0005,适合通用目标检测,但在垃圾场景中我们发现稍微增大到0.001有助于抑制过拟合,因为数据规模不大,正则化作用更明显。
训练过程里,我做了三个对照组来验证关键因素:一组只用了基础数据增强,一组加入了Mosaic和Copy-Paste,一组在第二组基础上额外调节了损失权重。结果显示数据增强的贡献最大,把验证集mAP从0.71提升到了0.78;而调损失权重只带来约0.02的提升。说明在垃圾检测这类视觉特征差异大的任务里,数据质量的影响通常会大于复杂的损失函数设计。训练过程中保存最佳模型以验证集mAP为标准,最终best.pt在验证集上的mAP50是0.842,mAP50-95是0.612。
3.2 不同YOLO版本的横向对比
为了给部署方案更多选择,同时测试了YOLOv5s、YOLOv8n、YOLOv8s和YOLOv10n。配置基本一致,统一用640输入,300轮早期实验后根据表现提前停止。以下是验证集上的对比结果:
| 模型 | 参数量 | 模型体积 | mAP50 | mAP50-95 | 推理耗时(GPU) |
|---|---|---|---|---|---|
| YOLOv5s | 7.2M | 约14MB | 0.811 | 0.573 | 约5.2ms |
| YOLOv8n | 3.2M | 约6MB | 0.842 | 0.612 | 约4.1ms |
| YOLOv8s | 11.2M | 约22MB | 0.856 | 0.631 | 约5.8ms |
| YOLOv10n | 2.3M | 约4.7MB | 0.823 | 0.586 | 约3.7ms |
推理耗时在GPU上差距不大,但模型体积差异对边缘部署影响明显。YOLOv8n只有6MB左右,相比YOLOv8s少了近16MB,在存储较小的设备上更友好。YOLOv10n速度最快,体积最小,但mAP略低于v8n,而且后续转成TensorRT时我们发现部分算子兼容性处理起来比较麻烦,需要手动替换几个自定义模块。综合稳定性和精度考虑,正式系统选了YOLOv8n。
3.3 训练曲线分析与关键调参策略
训练中最重要的观察指标是验证集上的mAP曲线和损失曲线,而不是只看训练精度。训练精度很高、验证精度低,基本可以确定过拟合;二者同步上升则说明模型还在正常学习。我们第一版跑了100轮就手动停了,原因是验证损失在第80轮左右就开始缓慢上升,而训练损失还在下降,明显过拟合。随后采取的调整是增加数据增强强度、把dropout加进检测头、weight decay调高到0.001。
另一个容易忽视的参数是类别损失权重。四分类垃圾检测中“有害垃圾”出现频率最低,模型天然缺少它的样本,如果不调整,测试时经常把电池识别成其他类。我单独给有害类的分类损失加了1.5倍权重,同时把该类图片通过复制粘贴增强扩充到与其他类接近的数量,效果比单独调权重更好。最终调参之后的结论是:先保数据均衡,再调损失权重,损失权重只在数据无法扩充时起作用。
4. 模型优化与边缘端部署
4.1 剪枝与量化流程
模型训练完并不能直接拿去部署,6MB的浮点模型直接跑在边缘设备的推理框架里,速度只有个位数帧率,完全达不到实时要求。我们首先做了通道剪枝。YOLOv8n结构相对紧凑,大幅度全局剪枝容易导致精度骤降,所以使用基于BN层缩放因子的稀疏训练,先训练50轮让部分通道的缩放因子逼近0,再剪掉这些低贡献通道。剪枝比例控制在25%,验证集mAP只损失了0.9%,但模型体积减少了约22%。
接着做INT8量化。使用TensorRT的PTQ方式,拿500张有代表性的真实场景图做校准集,计算每层激活值的分布并映射到INT8表示。校准集的选择很关键,如果只用验证集里的干净图片,量化后模型对弱光、模糊场景的精度下降会很明显。我从不同时间段、不同天气条件的实测视频里截帧,构成500张校准集,使量化后的模型在夜间图片上的mAP下降控制在2%以内。最终导出的INT8引擎体积只有2.8MB,在目标边缘设备上的推理耗时约24ms,稳定跑在30FPS以上。
4.2 部署架构与推理流程
系统部署采用边缘计算加轻量后端的结构。摄像头通过RTSP协议推流到Jetson设备,Jetson运行TensorRT引擎,以多线程方式从缓冲区拉取视频帧,执行检测推理,输出检测框、类别、置信度,再绘制结果写入显示缓冲区。同时通过MQTT协议把结构化检测结果上报到中心服务器,服务器负责数据持久化和Web展示。这样的好处是检测不依赖外网,断网时本地系统还能继续工作。
摄像头采集帧率设定为25FPS,但推理线程设定了独立的帧间隔控制。如果每帧都推理,设备温度容易过高,实测长时间运行后会掉帧。我在推理循环里增加了一个简单的控制逻辑:距离上一帧检测超过100ms且当前帧为关键帧时,立即执行推理;否则跳过该帧,直接复用上一帧的检测结果进行绘制。这种方式保持了实时感,又降低了算力压力,设备连续运行两天没有出现卡顿或过热降频。
推理时对YOLO输出的后处理也做了一点自定义。原始输出经过阈值过滤和NMS后,部分重合框会残留。我根据垃圾场景特点,把NMS的IoU阈值设为0.45,同时限制每个类别最多输出20个目标,防止画面中出现高密度垃圾堆时输出框过多。置信度阈值设在0.35,既能过滤大部分误检,又不会放过真实目标,这个值是通过在验证集上做阈值扫描得到的。
4.3 摄像头与成像条件适配
我们一开始吃了不少亏,因为用了普通USB摄像头,画质差、动态范围窄,逆光场景下垃圾区域一片黑。后来换成了带宽动态功能的工业摄像头,成像质量明显改善,弱光环境下的检测精度也随之提升。镜头焦距、安装高度、拍摄角度这三个参数都要在部署时调试。大多数垃圾投放点的摄像头建议离地1.8到2.2米,俯角30到45度。这样既能覆盖投放口及周边地面,又不至于因为俯角太大导致目标严重变形。
如果条件允许,建议在识别区域补一盏补光灯。垃圾房的灯光往往偏暗,尤其在傍晚和夜间,对检测效果影响很大。我们测试过在摄像头旁边加装LED补光灯后,夜间帧的平均置信度从0.42提升到0.61,漏检率显著下降。这个提升有时候比调整模型参数更明显,所以部署现场的光照问题一定不能忽略。
5. 系统功能与完整应用闭环
5.1 检测分类与提示模块
系统最核心的功能是检测并提示用户正确投放。当摄像头识别到有人接近投放点并出现垃圾时,系统在屏幕上实时画出检测框,标注物体名称和所属分类。如果用户准备投放的可回收物被正确识别,屏幕显示绿色提示;如果出现有害垃圾,则用橙色高亮并伴有语音提醒。语音播报模块通过边缘设备的音频输出接口驱动,内置了三段提示语,根据分类结果自动切换。
对于“怎么扔”这个环节,我们还接了一个知识库。用户可以在交互屏上点击检测结果中的类别,查看对应的详细投放说明,比如“电池属于有害垃圾,应投放至红色有害垃圾桶”。这个功能看似简单,但对终端用户友好度提升很大,尤其对老年人群体很有帮助。后端的分类映射表是独立配置的,运营人员不需要懂模型,就可以通过后台维护投放指引。
5.2 数据统计与告警机制
所有检测记录上传到服务器后,按时间、地点、垃圾类别三个维度进行聚合。后台可以查看每日投放量趋势、各类垃圾占比、误检率变化等指标。我们通过告警规则来及时发现模型退化:如果某一类别的平均置信度连续三天下降超过10%,系统自动生成告警,通知管理员检查设备或准备更新训练数据。这个机制在一次真实场景中帮了大忙,摄像头被树叶遮挡了三分之一,检测率明显下降,置信度异常告警迅速暴露了问题。
告警机制还包括“危险垃圾滞留”场景。如果系统在同一个画面中检测到有害垃圾并持续超过60秒无人处理,会向管理员发送消息提醒。这种功能对社区垃圾房的日常管理有实际价值,因为有些居民可能把电池、药品混投后离开,管理员无法实时盯守,自动告警能帮助及时发现和处理。
5.3 客户端界面与交互设计
客户端采用Web技术实现,部署在本地服务器上。界面分成实时监控、分类统计、投放指引、设备管理四个页签。实时监控页融合了视频流、检测结果列表、最近30分钟分类比例图。为了方便管理多个投放点,地图视图中每个点位用一个圆点标识,颜色对应设备健康状态,点进去就能看到实时画面和检测数据。
交互上注意两点:一是检测结果的展示要附带置信度提示,避免用户在目标识别模糊时误以为系统出错;二是界面操作路径要短,管理员最常用的“查看异常告警”按钮放在首页顶部。项目开发中也做了移动端适配,让运维人员能在手机上接收告警消息、预览设备状态。整体界面用简洁的浅色主题,强调信息可读性,没有为了视觉效果牺牲使用效率。
6. 常见问题与排错实录
6.1 过拟合与类别混淆的排查思路
训练过程中遇到最典型的问题是:验证集mAP50在0.75附近停滞,训练集loss依旧下降,且大量混淆集中在“塑料瓶”和“玻璃瓶”之间。这个现象的原因很直观,两种类别都是透明的瓶状物体,视觉特征高度重合。单纯的模型改进很难解决,我们的办法是回到数据层面,单独收集一批强调瓶身质感、瓶颈形状、标签差异的样本,并增加瓶内有无液体的状态变化,确保模型学到区分特征。同时给训练集加入裁剪不完整瓶子的负样本,让模型明白“只看局部不能确定类别”时,倾向于输出低置信度而不是硬猜。
如果模型出现整体偏向某类别的倾向,比如把很多检测目标都预测为“其他”,建议先从数据比例找原因,再看置信度阈值。我之前试过把置信度阈值调高来减少误检,结果反而让低置信度的真实目标漏掉。最佳做法是统计各类别在验证集上的置信度分布,用每个类别独立的阈值替代全局阈值,这个技巧在垃圾检测中特别有效。
6.2 边缘设备上的性能瓶颈定位
部署后在Jetson上遇到过一个非常奇怪的现象:单跑推理程序帧率正常,但接入摄像头视频流后帧率骤降一半。排查发现是图像采集线程和推理线程共用同一个锁,导致采集端在等待推理完成时阻塞了摄像头取流。解决办法是把采集和解码放到独立线程,并通过环形队列在采集与推理之间解耦,推理线程只从队列取最新帧,不再阻塞采集。代码改动量不大,但性能恢复接近理论值。调试这类问题,建议先用性能分析工具看线程等待时间,而不是盲目升级硬件。
另一个常见瓶颈是日志写入。每次检测都输出全量JSON日志到磁盘,长时间运行后磁盘I/O占用飙升,间接拖慢推理线程。我们的优化策略是本地只记录关键事件,正常的检测流直接通过MQTT上报,不再落盘。同时采用定时批量写日志的方式减少刷盘频率。部署类项目很容易忽略这类“跟模型没关系”的性能问题,但实际它们往往才是影响体验的关键。
6.3 长尾类别数据扩充的实用方法
有害垃圾、药品、温度计这些类别在自然场景中太少见,样本数量很难扩充。我试过从网上找图,质量参差不齐,很多图片背景复杂而且目标极小,标注成本高。后来换了一种思路:自建简易合成场景。找一张中性桌面或地面背景,把真实收集的电池、药盒、过期化妆品放在上面,用手机在不同光照和角度下拍摄,低成本得到大量相对标准的数据。这些数据虽然背景单一,但作为补充样本能显著提高模型的鲁棒性。
6.4 常见问题速查参考
| 症状 | 可能原因 | 处理建议 |
|---|---|---|
| 验证集mAP高但实测漏检 | 训练数据与现场背景差异大 | 增加现场真实场景数据并做背景融合增强 |
| 夜间小目标丢失 | 光照不足、红外模式成像差 | 加装补光灯,调整ISP参数 |
| 类别输出跳动明显 | 相邻帧置信度波动大 | 增加检测帧间隔,并结合时序平滑处理 |
| 部署后模型体积超预期 | 未做INT8量化 | 使用TensorRT PTQ量化并校准 |
| 某类长期预测错误 | 数据不均衡或特征重叠 | 扩充样本并适当调整类别损失权重 |
| 设备运行温度过高 | 推理负载过大 | 降低处理帧率,增加散热措施 |
7. 项目复盘与实际体会
这个项目做下来,我最深的体会是:垃圾分类识别本身不算一个高不可攀的技术难题,但真正把它做成可交付的系统,难点在于工程细节的串联。从数据集构建、模型选型,到部署环境的每一件琐事,任何一个环节断裂都会导致整体体验崩塌。模型精度再高,现场光照不行、摄像头清晰度不够、数据上报延迟、告警误报频繁,用户照样不会买账。
如果后续继续迭代,我建议从两个方向入手:一是持续积累真实场景数据,尤其是长尾类别,定期增量训练模型;二是把“只看图片”升级为“结合上下文”,比如融合投放行为时序、垃圾桶满溢状态等多模态信息,进一步提高智能管理水平。对正在做类似项目的人,我的建议是先把现场跑通,再回头优化模型指标。很多时候一个补光灯带来的收益,比折腾几天网络结构还大。真实项目不是刷榜单,稳定、可用、可维护才是第一优先级。