ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YOLOv8改进算法的生活垃圾图像识别实战:从数据到RK3588部署

基于YOLOv8改进算法的生活垃圾图像识别实战:从数据到RK3588部署 1. 从一堆垃圾照片说起这个项目到底在做什么先聊点实在的。我手头攒了大概一万两千张生活垃圾的照片是过去半年从几个小区投放点、学校食堂后厨、写字楼茶水间一点一点拍回来的。塑料瓶、外卖盒、废纸板、果皮、碎玻璃、旧电池、用过的纸巾、沾油的塑料袋什么都有。最开始我想得很简单拿个现成的开源模型跑一遍不就行了结果实测下来通用检测模型在垃圾这个场景里表现相当拉胯——它能把塑料瓶认成“水瓶”但分不清“可回收”和“其他垃圾”遇到被压扁的纸杯、撕碎的包装袋、堆叠的快递盒框都画不准更别提分类了。这就是我做基于YOLOv8改进算法的生活垃圾图像识别这个项目的直接原因。目标很明确输入一张垃圾照片模型输出每个垃圾实例的位置框和类别标签类别按四分类走——可回收物、厨余垃圾、有害垃圾、其他垃圾。整套系统最终要能跑在边缘设备上比如RK3588这类板子配合摄像头做实时识别给投放点做辅助提示。适合谁看这篇内容如果你正在做深度学习相关的课程设计、毕业设计或者想拿目标检测练手但不知道选什么题目再或者你已经跑通了YOLOv8官方demo但不知道怎么改成自己的数据集、怎么调参、怎么改进网络结构那这篇东西应该能帮你省不少时间。我会把数据准备、模型选型、改进思路、训练调参、部署落地这几个环节里我踩过的坑和验证过的做法都摊开讲。不搞虚的直接上干货。需要提前说明的是下面涉及的具体参数和网络改动都是基于我自己的数据集和硬件条件调出来的你拿去用的时候一定要结合自己的实际情况做调整别照搬。深度学习这行没有一套参数能打遍天下。2. 整体方案设计与技术选型思路2.1 为什么是YOLOv8而不是Faster R-CNN或者YOLOv5选检测框架这件事我前后折腾了差不多两周。最开始用的是Faster R-CNN两阶段检测器精度确实稳但推理速度实在受不了。我拿GTX 1660 Ti跑一张640×640的图要将近200毫秒这还没算后处理。垃圾识别这个场景如果是投放点实时提示至少得做到15帧以上才有实用价值两阶段方案直接pass。然后试了YOLOv5速度上来了但有几个问题让我最终转向YOLOv8。第一YOLOv5的anchor机制在小目标密集场景下调起来很烦垃圾堆里那些碎纸片、瓶盖、烟头尺寸变化太大anchor尺寸不好覆盖。YOLOv8换成了anchor-free的解耦头省掉了这块调参的麻烦。第二YOLOv8的C2f模块比YOLOv5的C3模块在梯度流动上更顺我实测在同等参数量下mAP能高1.5到2个点。第三Ultralytics这套框架的工程化做得确实好从训练到导出ONNX再到部署链路很顺省了很多自己写脚本的时间。至于YOLOv3、YOLOv5这些老版本不是不能用但如果你是新开项目没必要从老版本起步。YOLOv8的社区活跃度、文档完整度、预训练权重质量都明显更好。我见过有人拿YOLOv3做垃圾分类调了半天最后mAP卡在0.6上不去换成YOLOv8之后同样的数据直接到0.72这不是模型本身差多少而是训练策略和损失函数设计上的代差。2.2 四分类还是细分类类别体系怎么定垃圾分类的类别体系不同城市标准不一样。上海是干垃圾、湿垃圾、可回收物、有害垃圾北京是厨余垃圾、可回收物、有害垃圾、其他垃圾。我做的是通用四分类但实际落地时你得根据目标场景调整。这里有个坑要提醒别一上来就做细分类。我最初想直接分到“塑料瓶”“易拉罐”“纸箱”“果皮”这种细粒度结果发现两个问题。一是标注成本爆炸一万张图标了快三周还没标完二是类间差异太小比如“塑料瓶”和“塑料杯”在图像上几乎一样模型学起来很吃力最后细分类的mAP反而比四分类低了将近10个点。我的建议是先做四分类把检测框和粗分类做稳再考虑在可回收物下面做二级分类。二级分类可以单独训一个分类网络把检测框裁出来的图送进去这样两个任务解耦调起来灵活得多。2.3 改进方向的选择注意力机制还是结构重参数化YOLOv8本身已经很强了但在垃圾场景下有几个明显短板。一是遮挡严重垃圾经常堆在一起互相遮挡二是小目标多碎纸、瓶盖、烟头这些占比很大三是背景杂乱投放点的背景有墙面、地面、垃圾桶本体干扰很多。针对这些问题我试了几个改进方向。协调注意力机制Coordinate Attention是我最终保留的它把位置信息嵌入到通道注意力里对遮挡场景下的目标定位帮助很明显。具体做法是在Backbone的C2f模块后面插入CA模块让网络在提取特征时同时关注通道维度和空间位置。实测mAP提升了大概2.3个点推理速度只掉了不到5%。另一个试过但没保留的是Transformer检测头。理论上Transformer对全局建模更强但我的数据集规模不够大训练时过拟合很严重验证集loss震荡得厉害。如果你有十万级以上的标注数据可以试试小数据集上还是CNN更稳。结构重参数化RepVGG那套我也试了训练时多分支、推理时合并成单路理论上能提升精度不掉速度。但在YOLOv8上改起来比较麻烦而且提升幅度只有0.8个点左右性价比不高最后放弃了。3. 数据集构建与预处理实操3.1 数据采集别只从网上爬网上开源垃圾数据集不少比如TrashNet、TACO这些。但直接拿来用有个大问题域不匹配。TrashNet的图大多是白底、单物体、摆拍跟你实际场景里垃圾堆在桶里的样子差太远了。我试过拿TrashNet训的模型直接跑实拍图mAP直接掉到0.4以下。我的做法是网上数据集只用来做预训练或者补充长尾类别主力数据必须自己拍。拍摄时注意几个点。光照要覆盖白天、傍晚、室内灯光、阴天这几种典型条件别全是大晴天拍的。角度要多样俯拍、平拍、斜45度都要有。背景要包含实际投放点的墙面、地面、桶内壁。垃圾状态要真实别摆得太整齐该揉团的揉团该堆叠的堆叠。我前后拍了大概一万两千张筛选之后保留了九千多张有效图。筛选标准很简单模糊的删、重复的删、标注歧义太大的删。最后按8:1:1划分训练集、验证集、测试集。3.2 标注LabelImg还是CVAT标注工具我用过三个LabelImg、Labelme、CVAT。LabelImg最轻量但只支持矩形框而且多人协作很麻烦。Labelme支持多边形但垃圾检测用矩形框就够了多边形反而增加标注负担。CVAT是网页版的支持多人协作、任务分配、审核流程适合团队作业。如果你是一个人做LabelImg够用了。如果是团队强烈建议上CVAT不然版本管理和标注一致性会让你崩溃。我吃过这个亏三个人标同一批图一个人把“沾油纸盒”标成可回收另一个人标成其他垃圾最后训练出来的模型在这类样本上完全混乱。标注规范要提前定死。我定的规则是可回收物包括干净的塑料瓶、易拉罐、纸箱、玻璃瓶、金属制品厨余垃圾包括果皮、菜叶、剩饭、茶叶渣有害垃圾包括电池、灯管、药品、油漆桶其他垃圾包括纸巾、烟头、陶瓷碎片、沾污塑料。边界模糊的样本比如沾了油的纸盒统一归到其他垃圾宁可保守也不要模棱两可。3.3 数据增强Mosaic之外还要加什么YOLOv8默认开了Mosaic增强把四张图拼成一张对小目标检测帮助很大。但垃圾场景下光靠Mosaic不够。我额外加了这几项随机遮挡模拟垃圾互相遮挡的情况随机在图上画几个灰色矩形面积占比5%到20%。这个增强让模型在遮挡场景下的召回率提升了差不多4个点。色彩抖动调整亮度、对比度、饱和度、色调模拟不同光照条件。注意幅度别太大否则颜色特征会失真比如把蓝色塑料瓶调成绿色模型会学乱。随机旋转和缩放垃圾的姿态是不固定的旋转增强很有必要。但旋转角度别超过30度否则框的标注会变得很奇怪。混合增强把两张图按一定比例混合模拟垃圾堆叠的半透明效果。这个要慎用比例控制不好会引入噪声。这里有个细节Mosaic增强在训练最后10个epoch要关掉让模型在真实分布上做微调。我试过全程开Mosaic最后mAP比关掉的情况低了1.2个点。4. YOLOv8改进细节与训练调参4.1 网络结构改动CA注意力插入位置的选择协调注意力模块的插入位置我试了三种方案。方案一是在Backbone每个C2f后面都插参数量增加太多推理速度掉了15%。方案二是只在SPPF后面插一个提升有限只有0.7个点。方案三是在Backbone的P3、P4、P5三个输出层前各插一个这是最终采用的方案。具体来说P3层负责小目标检测插入CA后对小目标的定位精度提升明显P4层负责中目标提升中等P5层负责大目标提升最小。三个位置加起来mAP提升了2.3个点推理速度只掉了4.8%这个 trade-off 是可以接受的。代码层面的改动不复杂在ultralytics的nn/modules里加一个CA类然后在Backbone的forward里对应位置调用就行。注意CA模块的通道数要和输入特征图对齐不然会报维度错误。4.2 损失函数调整CIoU换成WIoUYOLOv8默认用CIoU作为边界框回归损失。CIoU考虑了重叠面积、中心点距离和长宽比但在垃圾场景下有个问题低质量样本比如标注框画得不太准的会产生较大的梯度干扰模型收敛。我换成了WIoUWise-IoU它根据锚框的质量动态调整梯度权重对低质量样本的惩罚更温和。实测下来训练稳定性明显提升验证集loss震荡幅度减小了大概30%最终mAP提升了1.1个点。WIoU的实现也不难在loss.py里把CIoU的计算替换掉就行。注意WIoU有几个超参数比如单调聚焦系数我用的默认值你可以根据自己数据集的情况微调。4.3 训练参数学习率、批次大小、epoch怎么定训练参数这块我前后跑了十几组实验最后定下来的配置是这样的参数取值说明初始学习率0.01用余弦退火调度最低降到0.0001批次大小16GTX 1660 Ti 6GB显存再大就OOM了训练轮数300前200轮正常训练后100轮关Mosaic微调优化器SGD动量0.937权重衰减0.0005预热轮数3前3轮学习率从0.0001线性升到0.01输入尺寸640×640再大显存不够再小小目标看不清学习率这块有个经验如果你用预训练权重初始学习率可以设小一点0.001到0.005就行如果从头训0.01起步比较合适。我试过0.02训练前期loss直接炸了调回来才稳住。批次大小受显存限制这个没办法。如果你有更大的显存比如RTX 3090的24GB批次可以开到64训练速度会快很多而且BN层的统计更准。小批次训练时BN层的running mean和variance估计会有偏差这是没办法的事只能靠多训几轮来弥补。4.4 训练过程监控损失曲线怎么看YOLOv8训练时会输出几个损失box_loss、cls_loss、dfl_loss。box_loss是边界框回归损失cls_loss是分类损失dfl_loss是分布焦点损失。正常情况下的曲线应该是这样的训练初期三个loss都快速下降大概50轮之后下降变缓200轮之后基本平稳。如果box_loss震荡厉害可能是学习率太大或者标注框质量太差。如果cls_loss下降很慢可能是类别不平衡需要调整类别权重或者补充少数类样本。我遇到过cls_loss卡在0.8下不去的情况排查后发现是“有害垃圾”这个类别样本太少只占总数的3%左右。后来补了大概500张有害垃圾的图cls_loss才降到0.4以下。验证集的mAP曲线也要盯着。正常情况下mAP0.5应该稳步上升如果出现明显下降大概率是过拟合了需要加正则化或者早停。我设的早停patience是50轮也就是验证集mAP连续50轮不提升就停。5. 模型部署与边缘端落地5.1 导出ONNX还是TensorRT训练完之后模型要部署到边缘设备上。YOLOv8支持导出多种格式我试了ONNX和TensorRT两种。ONNX的好处是通用性强RK3588、Jetson、x86服务器都能跑但推理速度一般。TensorRT在NVIDIA设备上速度最快但只支持NVIDIA的GPU。我的目标设备是RK3588所以最终走的是ONNX路线然后用RKNN-Toolkit2转成RKNN格式。导出ONNX时注意几个点。opset版本选11或者12太高了RKNN可能不支持。输入尺寸要固定别用动态shape边缘设备上动态shape会拖慢推理。导出后先用onnxruntime跑一遍确认输出和PyTorch一致再做后续转换。5.2 RK3588部署实操RK3588的NPU算力是6TOPS跑YOLOv8s在640×640输入下实测能到25帧左右基本满足实时需求。部署流程大概是这样的第一步用RKNN-Toolkit2把ONNX转成RKNN。转换时要指定量化方式我用的int8量化精度掉了大概1.5个点但速度提升了将近一倍。如果精度要求高可以用fp16速度会慢一些。第二步在板子上装RKNN的运行时库写推理脚本。输入图像要先做letterbox缩放到640×640归一化到0到1然后送进NPU。输出是三个尺度的特征图需要做后处理解码成框和类别。第三步后处理用C写Python太慢了。解码包括sigmoid激活、阈值过滤、NMS。NMS的IoU阈值我设的0.45再高会漏检再低会误检。这里有个坑RK3588的NPU对某些算子支持不好比如CA模块里的某些操作转换时可能会报错。解决办法是把CA模块换成NPU友好的实现或者把CA模块放到CPU上跑。我最后是把CA模块简化了一下用1×1卷积加sigmoid替代精度掉了0.3个点但转换顺利通过了。5.3 实际场景下的性能表现在投放点实测了两周白天光照好的情况下识别准确率能到85%以上。傍晚和夜间灯光昏暗时掉到70%左右。遮挡严重的情况下比如垃圾堆得很满召回率会明显下降。有个有意思的发现模型对“可回收物”的识别最准因为塑料瓶、易拉罐这些形状规整、颜色鲜明。对“厨余垃圾”的识别最差因为果皮、菜叶这些形状不规则而且经常和纸巾、塑料袋混在一起。后续优化方向我打算补一批夜间和遮挡场景的数据再试试用开放词汇目标检测的思路让模型能识别训练集里没见过的垃圾类别。不过那是另一个项目的事了。6. 常见问题与排查技巧实录6.1 训练不收敛怎么办这是最常见的问题。我遇到过几次排查思路是这样的先看数据。标注框有没有越界类别标签有没有写错图像路径有没有问题我遇到过标注文件里类别索引从1开始而不是从0开始的情况模型训练时直接报错。再看学习率。学习率太大loss会震荡甚至发散太小loss下降极慢。可以先用小学习率跑几十轮看看趋势再逐步调大。然后看批次大小。批次太小BN层统计不准loss会抖。如果显存不够可以用梯度累积模拟大批次。最后看预训练权重。如果用了不匹配的预训练权重比如拿COCO的80类权重训4类垃圾分类头需要重新初始化不然会干扰。6.2 mAP上不去怎么调mAP卡在某个值上不去通常有几个原因。一是数据量不够特别是少数类样本太少。解决办法是补充数据或者用重采样。二是模型容量不够可以换更大的模型比如从YOLOv8n换到YOLOv8s或m。三是增强不够可以加更多样的增强策略。四是超参数没调好可以试试网格搜索或者贝叶斯优化。我自己的经验是数据质量比数据量更重要。同样是一万张图标注精准的比标注粗糙的mAP能高5个点以上。所以别急着堆数据先把标注质量抓上去。6.3 部署时推理速度慢怎么优化推理速度慢先从输入尺寸下手。640×640降到416×416速度能提升差不多一倍但小目标检测会受影响。如果场景里小目标不多降尺寸是最直接的优化。然后看量化。int8量化比fp16快将近一倍但精度会掉。如果精度要求不高int8是首选。再看后处理。NMS是CPU上跑的如果框很多NMS会成为瓶颈。可以试试用GPU版的NMS或者减少候选框数量。最后看硬件。RK3588的NPU算力有限如果模型太大可以考虑剪枝或者用更小的模型。YOLOv8n比YOLOv8s快很多精度只差两三个点看你怎么取舍。6.4 常见问题速查表问题现象可能原因排查方法解决方案训练loss不下降学习率太小、数据有问题检查标注、调大学习率重新标注、调整学习率验证集mAP震荡批次太小、学习率太大看loss曲线增大批次、降低学习率过拟合严重数据太少、模型太大对比训练和验证loss加数据、加正则化、换小模型推理速度慢输入尺寸大、未量化测各环节耗时降尺寸、int8量化、剪枝小目标漏检多输入尺寸小、P3层特征弱看小目标召回率增大输入、加强P3层类别混淆严重类间差异小、样本不平衡看混淆矩阵补充数据、调整类别权重7. 一些个人体会和后续扩展思路这个项目从立项到跑通前后花了差不多四个月。最大的感受是深度学习项目里数据工程占的时间远超模型调参。我大概有六成时间花在采集、清洗、标注、增强上真正调模型的时间不到两成。很多人一上来就想着改网络结构、换损失函数但如果你数据没做好再花哨的改进也白搭。另一个体会是别迷信SOTA。YOLOv8已经是很成熟的框架了官方默认配置在大多数场景下都能跑出不错的结果。改进要有的放矢先分析你的场景有什么特殊问题再针对性地改。我见过有人为了改而改加了一堆模块最后mAP没提升多少推理速度掉了一半得不偿失。后续扩展的话有几个方向可以考虑。一是做多模态结合重量传感器或者红外传感器提高分类准确率。二是做增量学习让模型能持续学习新出现的垃圾类别。三是做端云协同边缘设备做粗筛云端做精细分类。这些方向都挺有意思但每个都需要不少投入得看实际需求来定。最后分享一个小技巧训练时把验证集的图定期保存预测结果肉眼看看哪些图预测错了。这比看mAP数字直观得多能帮你快速定位问题。我就是在看预测图的时候发现模型把“蓝色塑料袋”和“蓝色塑料瓶”搞混了后来补了这类样本才解决。
返回列表