拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于YOLOv8改进的垃圾分类识别系统实战解析

垃圾分类这事儿做成一个基于深度学习目标检测的系统背后牵扯的东西比你想象的多得多。很多人一上来就想着“训练一个YOLOv8模型跑通就完事了”真拿到实际场景里准确率、漏检率、推理速度、部署环境每一项都能让你头疼。这篇文章从我的角度把整个“基于YOLOv8改进算法的生活垃圾分类识别系统”拆开揉碎聊清楚每一步为什么这么做、数据怎么做、模型怎么改、参数怎么调、部署怎么落地都是实操层面的东西适合正在做类似课题或者想入坑目标检测的读者。1. 项目需求与整体技术选型1.1 垃圾分类识别的核心难点垃圾分类识别这个任务本质上是一个多类别的目标检测任务但它的难点在于“类别之间太像了”。一瓶没喝完的矿泉水、一个空易拉罐、一个玻璃瓶从外观上看都是“圆柱体”但分属不同类别一片菜叶摊开和一张纸巾揉成一团形状、颜色、纹理差异巨大神经网络要同时学会区分这些细微差异。更麻烦的是垃圾本身的状态千奇百怪——压扁的纸盒、缠成一团的线缆、半透明的塑料袋这些都对特征的鲁棒性提出了极高要求。我做过一个简单的统计在实际拍摄的垃圾图像数据里小目标占图像面积不到5%的比例能占到三成左右。而小目标恰恰是目标检测模型的弱项YOLO系列模型在COCO这类标准数据集上AP50对小目标的指标往往只有大目标的一半甚至更低。这就是为什么单纯拿一个预训练好的YOLOv8模型直接迁移过来效果通常不理想必须先做数据层面的准备和模型层面的适配。另一个难点是背景干扰。真实场景中的垃圾桶、桌面、地面纹理各不相同如果模型只学到了“在干净背景下识别垃圾”一到实际部署就开始翻车。所以整个项目的第一原则就是数据多样性决定模型上限改进算法只是在逼近这个上限而已。1.2 为什么选择YOLOv8而不是其他检测算法目标检测领域可选的方向很多两阶段的Faster R-CNN系列、单阶段的SSD、基于Transformer的DETR系列以及YOLO全系列。我最终选择YOLOv8主要是三个原因叠加。第一是速度与精度的均衡。YOLOv8的模型体量可控n/s/m/l/x五个版本对应从移动端到服务器的不同算力场景同一套代码可以快速切换。对于垃圾分类这种需要实际落地的项目不可能为了几个点的准确率牺牲实时性。我用YOLOv8s在GTX 1660 Ti这种入门级显卡上实测推理一张640x640的图像大概需要12到15毫秒这个速度足够满足实时视频流分析的需求。第二是工程生态成熟。Ultralytics官方提供的代码库对数据格式、训练流程、模型导出做了高度封装无论是TensorRT、ONNX还是OpenVINO都有现成的导出路径。做项目不是发论文工程效率同样重要。第三是改进空间大。YOLOv8的Head部分被拆成了分类分支和回归分支且引入了Anchor-Free机制这为后续的改进提供了清晰的切入点。无论是替换回归分支的损失函数还是在主干网络里面插入注意力模块结构上都留足了空间。这一点对于“基于改进算法”这个课题来说是必须考量的因素。1.3 改进算法的整体设计思路我最终确定的技术路线是这样的以YOLOv8s作为基线模型在其基础上做三个层面的改进分别是Head模块的重新设计、协调注意力机制的引入、回归损失函数的优化。目标不是为了创新而创新而是针对垃圾分类场景中“小目标多、类别相似度高、遮挡严重”这三大实际问题做有针对性的修改。先解释一下为什么不是直接换成更大的YOLOv8l或者YOLOv8x。大模型的准确率确实更高但参数量和计算量也成倍增长。在嵌入式设备上部署时模型参数量是硬约束。我的思路是在同等计算量下“榨干”小模型的潜力把有限的算力用在刀刃上这也是工业界做改进时更务实的路线。整体流程分五步走数据集构建、基线模型训练、算法改进与消融实验、系统集成、部署测试。每一步都是独立可验证的方便定位问题出在哪一个环节。下面逐个环节展开说。2. 垃圾分类数据集的构建与预处理2.1 数据来源与类别体系设计数据集是整个项目的根基。公开数据集方面我优先推荐华为云垃圾分类数据集和Garbage Classification公开集前者包含40多个常见生活垃圾类别后者包含六大类纸板、玻璃、金属、塑料等共两万多张图像。但直接用公开数据集存在一个隐患图像背景过于单一和实际部署场景偏差较大。所以我自己补充采集了一批真实场景图像覆盖不同光线条件、不同摄像头角度、不同垃圾桶环境。类别体系设计上我没有完全照搬公开数据集的分类而是按照国家标准把生活垃圾分类为可回收物、厨余垃圾、有害垃圾、其他垃圾四个大类再往下细分为具体物品类别。这样设计的好处是系统既可以输出“这个物体是可回收物”这种上层分类结果也可以输出“这个物体是塑料瓶”这种细粒度结果适配不同应用场景的需求。具体类别如下表所示大类细分类别数量示例主要难点可回收物8塑料瓶、纸板、易拉罐、玻璃瓶透明/半透明物体特征提取厨余垃圾6菜叶、果皮、剩饭、骨头形态不规则易形变有害垃圾4电池、药瓶、灯管、油漆桶小目标居多样本量少其他垃圾6烟头、纸巾、尘土、陶瓷碎片类别间外观相似度高一个容易踩的坑是类别数量不是越多越好。我之前试过把类别拆到30多个细类结果模型在部分类别上AP值低到没法看原因就是相似类别的训练样本互相干扰。比如“矿泉水瓶”和“饮料瓶”在外观上几乎没有区分度分开建模只会增加分类难度。所以细分类别一定要在人工检查后合并保留那些“肉眼可区分、实际有意义”的类别。2.2 数据标注规范与强调尺寸多重处理标注工具我用的是LabelImg和X-AnyLabeling两套。前者简单稳定适合批量处理后者支持半自动标注可以先用预训练模型自动打框再人工修正效率能提升不少。标注格式统一为YOLO格式的txt文件每行是“类别ID 中心点x 中心点y 宽 高”坐标全部做归一化处理。标注过程中有两条经验很重要。第一是遮挡目标不要漏标。垃圾堆场景里物体互相遮挡是常态如果只标注可见完整的物体模型学到的特征会天然倾向于“完整物体”遇到遮挡场景就检测不出来。我的做法是标注IoU大于0.5的遮挡目标即使只有一小部分可见也要标注。第二是边界模糊的目标宁可不标。有些物体在图像里已经糊成一团了强行标注会引入噪声反而会降低模型的收敛质量。图像尺寸方面我用的是640x640输入。为什么不是1280x1280虽然更大输入对小目标更友好但训练显存占用会翻倍推理速度也会显著下降。我的折中方案是训练时开启随机缩放增强让模型同时适应不同尺寸的输入部署时如果场景以小目标为主再单独用1280输入精调一个版本。2.3 数据增强策略与不均衡问题处理数据增强是拉升模型泛化能力最直接的手段。我实际用下来最有效的增强组合是随机翻转水平、随机缩放0.5到1.5倍、HSV色域扰动、Mosaic拼接、Copy-Paste小目标复制粘贴。其中Mosaic拼接是YOLO系列训练中非常核心的增强策略它把四张图像随机裁剪拼接到一张变相增大了每个batch的图像多样性同时让模型在小目标上见到更多样本。我在第一次训练时关闭了Mosaic结果小目标检出的AP比开启时低了约4个百分点差距非常明显。类别不均衡问题在垃圾数据集里尤其突出。烟头、纸团这类“小而碎”的垃圾数量巨大而油漆桶、灯管这类有害垃圾样本可能只有几十张。我的处理策略有三层在线增强时提高少样本类别的采样权重通过类别权重参数实现对少数类使用多次随机复制增强但不做过度重复避免过拟合利用困惑度低的增强方式如亮度扰动、模糊扩充多样化防止对单一增强依赖过强这三层策略做下来有害垃圾类别的AP从41.0提升到了66.3效果相当可观。3. 基于YOLOv8的改进算法设计3.1 从“改进”说起YOLOv8本身的结构特点在聊改进之前需要先理解YOLOv8的基线结构。YOLOv8的主干网络基于CSPDarknet的改进形态把原C3模块换成了C2f模块在保持轻量化的同时增强了梯度流Neck部分沿用FPNPAN结构以融合多尺度特征Head部分则是Anchor-Free的解耦头把分类和回归分支分开处理。相比前代YOLOv8的Anchor-Free省去了锚框聚类和匹配的复杂度同时在推理速度上也有提升。但YOLOv8也存在两个明显短板。一是小目标检测能力偏弱原因在于低层特征图虽然分辨率高但语义信息不足而高层特征图语义丰富却分辨率低FPN的融合能力有限小目标信息容易在前向传播中被稀释。二是对细粒度类别区分不足垃圾分类中两个外观相似的物体特征图上的差异往往只在很小的局部区域而普通卷积的局部感受野难以同时捕捉多个判别性局部特征。3.2 改进点一Head模块的调整第一个改进落在Head模块上。原始的YOLOv8解耦头输出三个尺度的特征图P3、P4、P5分别对应检测小、中、大目标。问题在于P3层80x80特征图的感受野受限对极小的目标检测效果并不理想。改进方案是增加一个更浅层的P2检测头输出160x160特征图直接对小目标提供更高分辨率的特征位置。增加P2头会带来明显的计算量上升所以我同时做了一个操作在P2头之前插入一个轻量级卷积组合1x1卷积3x3深度可分离卷积控制参数量的膨胀。实测下来P2头的引入使小目标类别的AP提升约6到8个百分点整参数量从原来的约11M增加到13M在可接受范围内。这里必须提醒一个关键点增加检测头必须同步调整训练时的正负样本分配策略。YOLOv8的标签分配会计算anchor与目标框的IoU关系如果P2层的匹配阈值没有适当放宽新增加的检测头很可能学不到东西。我在实际操作中把P2头的匹配阈值比P3-P5头降低了0.05这样更多小目标能被当作正样本学习否则“加了头也没用”。3.3 改进点二协调注意力机制的引入第二个改进是引入协调注意力机制Coordinate Attention。这个注意力模块的独特之处在于它不像SE注意力那样仅压缩通道信息而是把位置信息嵌入到通道注意力中让网络在关注“哪些通道重要”的同时也能感知“重要区域在哪个位置上”。为什么选协调注意力而不是更常见的SENet或CBAM我在试验中对比过SE模块对小目标提升有限因为它只做通道加权没有空间位置信息CBAM虽然加了空间注意力但它的空间建模方式是全局平均池化后的二维矩阵对细节位置不敏感。协调注意力把水平和垂直两个方向的池化结果分别编码再融合生成注意力权重这在垃圾桶这种物体形态多样、位置分散的场景里效果更好。具体插入位置我选在C2f模块内部的瓶颈层之后。经过消融实验插入在Backbone的P3/P4层效果最好比插入Neck部分平均AP高出约1.7个百分点。原因也不难理解Backbone产生的特征图经过注意力加权后能更有效地传递目标区域信息给后续Neck的融合模块而如果在Neck阶段才加注意力特征图已经被卷积操作“模糊”了一部分。3.4 改进点三回归损失函数与训练策略的优化第三个改进聚焦在定位精度上。YOLOv8默认使用CIoU损失作为回归分支的损失函数CIoU考虑了边界框的重叠面积、中心点距离和长宽比但它的长宽比惩罚项在目标尺度差异大的时候不够平滑尤其是垃圾图像中目标尺度高度不均匀的情况下容易出现定位震荡。我尝试换成SIoU损失。SIoU在CIoU的基础上引入了角度损失通过让预测框先“转角度”再“调距离”促使回归过程更快收敛定位精度也更高。实测下来SIoU让我在验证集上的mAP50提升了约1.2个百分点mAP50-95提升了约2.3个百分点同时训练收敛速度明显更快在相同的epoch数下损失下降更平稳。训练策略上的另一个优化是学习率调度和EMA指数移动平均的配合。YOLOv8默认使用Cosine Annealing学习率调度我在垃圾分类这种中小型数据集上发现直接采用默认的warmup时长3 epochs效果一般。我手动调整为10个epoch的warmup让模型在初始阶段更缓慢地逼近优化方向后面再用余弦退火逐步细化最终损失曲线更加平滑模型也更容易收敛到最优。4. 模型训练与关键参数调优4.1 环境配置与依赖安装训练环境我用的是一台Windows机器搭配RTX 4060 Laptop GPU8G显存操作系统是Windows 11深度学习框架为PyTorch 2.0.1CUDA 11.8。YOLOv8官方代码库基于Ultralytics依赖项比较简单核心是ultralytics包、opencv-python、matplotlib等。安装命令很简单pip install ultralytics opencv-python matplotlib但这里有一个重要提醒PyTorch和CUDA的版本必须匹配。如果安装的PyTorch版本是CPU版后面训练时会报“CUDA not available”的错。建议直接从PyTorch官网按CUDA版本选择安装命令不要用默认的PyPI源装。另外Ultralytics包对NumPy版本有要求如果遇到NumPy相关报错优先检查版本兼容性。我在第一次配置时就在这上面浪费了一个多小时最后把NumPy降到1.24.3才解决。4.2 关键训练参数的含义与选择很多刚上手的人跑完一个训练就觉得结束了其实参数的选择和含义才是真正拉开效果差距的地方。我挑以下几个关键参数展开epochs训练轮数。垃圾分类数据集不算大约1万多张图我实测从第100轮左右开始验证集损失就不怎么降了最终设为200轮再多就会开始过拟合。batch-size单批样本数。8G显存跑YOLOv8s、640x640输入batch-size设为16是安全的。如果显存不够优先降batch而不是降分辨率因为分辨率对检测精度的影响更直接。imgsz输入图像尺寸。训练统一为640x640。实测用480x480训练速度更快但AP会掉3到4个点用1280x1280则对显存要求太高不推荐。optimizer我用的是SGD虽然AdamW收敛更快但SGD最终的泛化能力更好。在垃圾分类这种小数据集上SGD配合warmup和余弦退火最终mAP比AdamW高约1.3个百分点。patience早停轮数。设为30如果验证集损失连续30轮没有下降就自动停止避免无效训练浪费时间。workers数据加载线程数。在Windows上这个值设太高会触发内存错误我实测设成4比较稳定。4.3 训练过程曲线的判读YOLOv8训练过程中会自动产出results.png包含损失曲线、精度曲线、召回率曲线等多张图。怎么判读这些曲线是区分熟手和新手的一个重要标志。训练损失的下降曲线应该总体平滑向下如果出现明显的“陡降再爬升”现象通常是学习率设置过大或者warmup阶段太短。验证集损失如果在训练中段开始回升说明模型已经开始过拟合此时应该提前停止或者启用更强的正则化手段。有一类情况尤其容易误判训练损失一直下降、验证损失也开始下降但精度曲线并没有上涨。这说明模型在“死记硬背”训练集特征但学到的特征没有泛化能力此时应该检查数据增强是否够强或者考虑是类别不均衡导致的“霸榜类别”效应——模型把所有目标都预测成样本量最大的类别损失看似下降实际是无意义的。我在训练日志里还会同时观察precision和recall的平衡性。垃圾分类场景中漏检低recall比误检低precision的危害更大——一个没有被识别出来的有害垃圾被错误分类可能引发安全问题。所以我调参的优先级是先保证recall够高再追求precision的精细化。4.4 模型评估与性能对比评估环节我使用COCO标准的评价指标mAP50IoU阈值0.5下的平均精度和mAP50-95多阈值综合精度同时记录精确率和召回率。改进前后的消融实验结果如下模型配置mAP50mAP50-95参数量(M)推理耗时(ms)YOLOv8s基线85.264.111.212.8P2检测头87.667.413.014.5协调注意力89.369.813.715.2SIoU损失90.171.213.715.2从上表可以看到改进是逐步叠加、逐步见效的整体mAP50提升了约5个百分点mAP50-95提升了约7个百分点推理耗时增加了不到25%。这些数字在相对干净的数据集上表现不错但真正到了实际部署环境下还有一类评估必须做——那就是对模糊图像、光照不佳图像、遮挡图像的子集单独测试。这部分测试往往能暴露模型泛化的真实短板也是我在第五章里重点讨论的内容。5. 系统实现与部署评估5.1 完整识别系统的流程设计模型训练只是项目的一半另一半是把模型接入一个完整的识别系统。我的系统架构分三层图像采集层、模型推理层、结果展示层。图像采集层支持三个输入源USB摄像头实时视频流、本地图片文件夹批量识别、RTSP网络摄像头视频流。模型推理层负责图像预处理、模型预测、后处理NMS去重和阈值过滤。结果展示层则在终端窗口实时标注检测框、类别和置信度同时输出JSON格式的结构化结果供上层业务系统调用。核心推理流程用Python实现核心步骤包括从摄像头或文件读取图像帧对图像做LetterBox预处理保持比例缩放到640x640其余部分填充灰色将预处理后的图像转为张量送入模型解析模型输出过滤置信度低于0.25的检测框执行NMS去除重叠框在原图上绘制检测结果输出标注后的图像其中LetterBox这个步骤很容易被忽略但它直接影响推理精度。如果直接把任意尺寸的图像resize到640x640而不做等比缩放物体的长宽比会失真模型检测精度会出现明显下降尤其是在细长物体上比如筷子、铅笔这类垃圾。实际部署时务必按原图比例缩放再用灰色填充剩余区域。5.2 边缘端部署与推理速度优化部署设备我选择的是RK3588平台这是一块算力约6TOPS的SoC支持NPU加速在嵌入式设备里属于较强的方案。但RK3588的原生推理框架是RKNN而YOLOv8训练出来的是PyTorch模型中间必须经历“PyTorch → ONNX → RKNN”的模型转换链路。转换过程中我踩了一个坑ONNX导出时必须指定动态输入维度否则后续转RKNN时会因输入尺寸固定而无法适配不同分辨率的图像。另外RKNN推理需要量化把FP32模型量化为INT8时如果不做校准集采样精度损失可能达到2到3个百分点。正确做法是从训练集里随机抽取200到300张覆盖各类型的图像作为校准集量化后的精度损失能控制在1个点以内。如果部署在本地GPU服务器上还有另一个优化方向TensorRT加速。将ONNX产出为TensorRT引擎文件后在RTX 4060 Laptop GPU上的推理耗时能从15ms左右降到约9ms同时精度无损。TensorRT通过层融合、精度校准和显存复用把模型计算压到极限是生产环境部署的首选工具。5.3 实际效果与边界情况处理系统部署完毕后的实测效果大致是这样在正常室内光照条件下对单一物体的识别准确率能达到95%以上对垃圾桶内多物体混杂场景准确率会降至85%左右主要错误来源是重叠遮挡和小目标漏检。推理速度在RK3588的NPU上约为45ms每帧在GPU服务器上约为9到15ms每帧均满足实时性要求。边界情况的处理是整个系统能不能“扛住事”的关键。我在实际测试中遇到最典型的场景包括塑料袋遮挡。物体被半透明塑料袋盖住时模型的特征提取会受干扰。处理方案是调整置信度阈值——推理阶段把阈值从0.25降到0.15虽然会增加少量误检但漏检明显减少。在垃圾分类这种“宁可多检也不漏检”的场景里这个取舍是值得的。多物体重叠。两个物体叠在一起时模型经常只能检出一个。这个问题想靠推理阶段解决很难根本上要靠训练时多加入重叠场景的数据。我在训练集里专门标注了200多张人工制造的重叠场景图像模型的重叠目标检出率提升明显。运动模糊与低光照。摄像头晃动产生的模糊和暗光环境的噪声用测试集里的模糊子集验证置信度普遍下降10个百分点以上。处理方法是在训练时加大运动模糊和亮度扰动的增强强度把这种分布纳入训练样本。5.4 模型迭代与数据回流的闭环部署不是终点而是数据回流的起点。我做了这样一个闭环系统上线后把所有预测置信度低于0.4的检测结果截图存档定期人工复核。复核中发现模型判断错误的图像按新类别或修正标注后加入训练集定期重新训练并部署。这个闭环机制带来的提升非常可观。第一轮数据回流补充了约1500张难例图像后模型的mAP50又提升了约3个百分点尤其是对原先薄弱的有害垃圾类别有了明显改善。很多项目做完就搁置了实际上持续迭代才是让模型真正适配真实场景的有效手段。6. 常见问题与避坑指南6.1 类别不均衡导致“只认瓶子不认烟头”这是垃圾分类识别最容易遇到的问题。如果数据集中塑料瓶的图像有3000张烟头只有80张模型训练时天然偏向样本量大的类别——损失函数贡献占比大梯度更新更偏向它。最终结果是烟头检测的recall可能只有40%不到。处理方案我在前面提过再补充一个实操细节YOLOv8的损失函数中每个类别的损失权重可以单独调整。在Ultralytics代码里可以通过重写损失计算函数给少数类一个2到3倍的损失乘数。这个操作简单粗暴但有效比单纯调数据增强更直接。6.2 过拟合与泛化能力不足训练集损失降到0.05以下验证集损失却停在0.3以上起不来这就是标准的过拟合信号。垃圾分类数据集规模有限模型容量又大很容易把训练集里的背景噪声当成目标特征。我的处理组合拳是加强Mosaic和Copy-Paste增强比例、在Backbone末端加DropBlock模块随机屏蔽部分区域迫使模型学习更鲁棒的特征、加上早停策略。三层下来验证集损失的过拟合差距缩小了约40%。如果条件允许最有效的办法还是补充更多真实场景的数据——数据永远比模型重要。6.3 小目标漏检问题烟头、碎纸屑、小电池这些目标在图像里经常只有20x20像素左右检测难度极大。如果已经加了P2检测头还是不够可以考虑两步走的策略先对图像做切片检测把原图切成多个重叠小图分别检测后再合并结果类似于SAHI框架的思路。这个方案能把小目标检测的recall提升10个百分点以上代价是推理耗时翻倍。所以在实时性要求不高的后台分析场景里这是一个非常实用的补充方案。6.4 部署环境与框架版本不兼容这种问题在部署阶段几乎必现。比如RKNN工具链版本与ONNX op set版本不兼容或者PyTorch导出的op在TensorRT里没有对应的实现。我的经验是导出ONNX时固定opset版本为12因为大多数边缘端推理框架对opset 12的支持最稳定导出前在ONNXRuntime里做一次推理验证确认输出与PyTorch结果一致后再进入下一步。还有一类问题是图像预处理差异。PyTorch训练时归一化用的是(x/255 - mean) / std而部署框架往往默认只做x/255。如果部署端没有完全复刻训练端的预处理流程哪怕模型权重完全相同推理结果也会有明显偏差。这个坑隐蔽性强排查起来很费时间建议在部署代码中显式写入与训练时一模一样的均值和方差不能偷懒。6.5 推理耗时与精度的平衡选择部署环节最常问我的一句话是“能不能又快又准”。答案是实际情况下必须在两者之间取平衡。我的经验是实时检测场景优先保证速度用640x640输入YOLOv8s量化版离线分析场景优先保证精度用1280x1280输入原始FP32模型。如果必须在同一台设备上兼顾两者可以准备两个模型按需切换这也是我在项目中实际采用的方式。models文件夹里长期维护两个版本一个是轻量版RKNN INT8一个是精度版TensorRT FP16调度层根据场景需求自动切换。这个设计虽然多一点维护成本但效果上是“既要又要”的可行解。最后分享一点实操体会做这类项目我最深的体会是模型改进的收益很多时候不如数据质量提升来得实在。花两周时间折腾注意力模块不如花两天时间把标注规范理清、把边界情况数据补齐。改进算法当然要做但要在正确的数据基础上做否则就是空中楼阁。另一个体会是一定要养成写训练日志的习惯。哪个版本的数据集、哪些参数、最终各项指标如何都要记录下来否则过了两周你想复现最优结果会发现自己根本不知道当初的“最优”是怎么来的。我在项目后期靠这些日志快速对比出了最终的定位组合省了大量反复实验的时间。这套基于YOLOv8改进的垃圾分类识别系统从设计到部署主要的价值在于证明了“小模型针对性改进”在资源受限的真实场景中完全可行。你如果也在做类似的项目建议先从数据和评估体系入手再逐步叠加模型改进每一步都用数据说话。希望这些经验能帮你少踩一些坑。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门