基于YOLOv8改进算法的垃圾分类检测系统实战:从数据集制作到边缘部署

发布时间:2026/10/1 13:32:50
基于YOLOv8改进算法的垃圾分类检测系统实战:从数据集制作到边缘部署 1. 从一张随手拍的照片说起垃圾分类识别到底难在哪我住的小区去年换了四分类智能回收箱刚开始那两周志愿者阿姨站在箱子旁边挨个指导。有意思的是真正让居民犯难的并不是“知不知道要分类”而是“手里这个东西到底算哪一类”。一杯没喝完的珍珠奶茶杯盖是可回收、杯身是其他垃圾、里面的珍珠是厨余吸管又是其他垃圾。你让一个赶着上班的人站在箱子前面拆解三分钟他下次大概率还是随手一扔。这就是垃圾分类识别系统真正要解决的问题把“人判断”变成“机器判断”。而机器判断这件事落到技术实现上本质上是一个目标检测任务——不是简单判断整张图属于哪个类别而是要在图像里框出每一个垃圾对象再给出它的类别标签。为什么必须用目标检测而不是普通图像分类因为真实场景里一张照片往往包含多个物体比如桌面上同时有香蕉皮、塑料瓶和废纸团分类模型只能给整张图一个标签而检测模型能告诉你“左上角那个是厨余右下角那个是可回收”。这套系统适合谁来参考如果你是计算机相关专业的学生正在找毕业设计或课程设计题目这套“YOLOv8改进算法生活垃圾图像识别”的组合非常典型既有成熟基线可以跑通又有足够的改进空间可以写出工作量。如果你是刚入门深度学习的开发者想找一个能覆盖“数据集制作—模型训练—改进创新—部署落地”全流程的实战项目垃圾分类检测也是一个门槛适中、效果直观的方向。哪怕你只是想搞清楚YOLOv8到底怎么训练自己的数据集这套流程同样适用。我前后在这个方向上折腾了大概四个月从最开始拿官方权重直接推理到后来自己标注数据集、改网络结构、调参调到凌晨中间踩的坑足够写一本小册子。下面我把整套东西拆开讲包括为什么这么设计、每一步怎么做、参数怎么算、遇到问题怎么排查。你照着走大概率能少走很多弯路。2. 整体方案设计与技术选型思路2.1 为什么是YOLOv8而不是Faster R-CNN或SSD目标检测算法大致分两派两阶段检测器以Faster R-CNN为代表和单阶段检测器以YOLO系列、SSD为代表。两阶段的做法是先由区域建议网络生成一堆候选框再对每个候选框做分类和回归精度通常更高但速度慢。单阶段则是直接在特征图上预测框和类别速度快适合实时场景。垃圾分类识别系统的典型落地形态是什么是回收箱上的摄像头、是手机App拍照识别、是小区门口的边缘计算盒子。这些场景对推理速度有硬要求——用户拍完照等三秒才出结果体验就崩了。YOLOv8在单阶段检测器里属于比较新的版本它相比YOLOv5的主要变化包括C2f模块替换C3模块更丰富的梯度流、解耦头结构分类和回归分支分开、Anchor-Free检测头不再依赖预设锚框、Task-Aligned Assigner正负样本匹配策略。这些改动让它在同等参数量下精度更高在小目标上表现也更稳。我实测过一组对比同一份生活垃圾数据集YOLOv5s的mAP0.5大概在0.82左右YOLOv8s能到0.86上下推理速度在GTX 1660 Ti上都在30 FPS以上。对于垃圾分类这种类别间差异明显、但类内形态多样的任务YOLOv8的Anchor-Free设计反而更省心——你不用再去聚类计算适合自己数据集的锚框尺寸了。2.2 数据集从哪来公开数据集与自建数据集的取舍这是很多人卡住的第一步。垃圾分类公开数据集有几个来源比如TrashNet主要是单物体分类不是检测标注、TACOTrash Annotations in Context有检测标注但类别体系偏细、以及一些国内竞赛数据集。我的建议是公开数据集打底自建数据集补场景。原因很直接。公开数据集里的图片往往是实验室环境、背景干净、光照均匀而真实场景是逆光、遮挡、堆叠、模糊。你如果只用公开数据集训练模型在测试集上mAP很漂亮一到实际场景就拉胯。我的做法是从公开数据集里挑出可用的检测标注数据再自己用手机在小区回收站、厨房、办公室拍了大约2000张真实场景图用LabelImg和Roboflow做标注和增强。类别体系我最终定为四类对应主流四分类可回收物recyclable、厨余垃圾kitchen、有害垃圾hazardous、其他垃圾other。这里有个经验不要一上来就分几十个细类。比如“可回收物”下面再分塑料瓶、纸箱、易拉罐标注成本翻倍而且模型容易在相似材质间混淆。先做粗分类跑通闭环再考虑细分类扩展。2.3 改进点怎么选别为了改而改“基于YOLOv8改进算法”这个说法很宽泛改进方向可以有很多换主干网络、加注意力机制、改损失函数、改特征融合结构、引入Transformer模块等等。但我要泼一盆冷水改进不是越多越好也不是越新越好。我见过不少项目堆了三四个模块结果mAP反而降了因为模块之间互相打架或者参数量暴涨导致小数据集过拟合。我的改进思路遵循一个原则针对垃圾分类任务的真实痛点选模块。垃圾分类检测的痛点是什么第一小目标多——烟头、瓶盖、电池这些物体在图像里占比很小第二遮挡和堆叠严重——垃圾桶里东西是叠在一起的第三类间相似——不同颜色的塑料袋可能分属不同类别但外观接近。针对小目标和遮挡我最终选了三个改进点在Neck部分引入协调注意力机制Coordinate Attention让网络更好地捕捉位置信息把部分C2f模块替换为可变形卷积DCNv3提升对不规则形状物体的建模能力在损失函数上用WIoU替换CIoU改善遮挡情况下的框回归质量。这三个改动我都单独做过消融实验确认每个都有正向收益才保留。消融实验的数据后面会详细给。3. 核心细节解析与实操要点3.1 数据集制作标注质量决定上限先说一个残酷的事实模型效果的上限由数据决定不是你改网络改出来的。我见过太多人花两周改结构mAP涨了0.5个点但回头把标注错误清理一遍mAP直接涨3个点。标注工具我用的是LabelImg本地标注适合小批量和Roboflow在线标注增强格式转换适合团队协作。标注格式选YOLO格式每张图对应一个txt文件每行是类别id 中心x 中心y 宽 高坐标都归一化到0到1之间。这里有个细节归一化坐标保留6位小数太少会损失精度太多没必要。标注时我总结了几个要点。第一框要贴紧物体边缘不要留太多背景但也不要把物体截断。第二遮挡物体要标可见部分如果遮挡超过70%就考虑丢弃这张图因为标注歧义太大。第三同类物体堆叠时逐个标注不要用一个框圈一堆。第四边界情况要统一标准比如“沾了油的纸盒”算可回收还是其他垃圾这个规则要在标注前定好所有标注人员统一执行否则模型会学到矛盾的标签。数据增强我用的是Albumentations库配置了随机翻转、随机旋转±15度、亮度对比度调整、HSV色域扰动、随机裁剪、Mosaic增强。Mosaic是YOLO系列的经典增强把四张图拼成一张能显著提升小目标检测效果。但要注意Mosaic增强在训练后期要关闭YOLOv8默认是最后10个epoch关闭这个设置是合理的因为拼接图会让物体尺度失真后期关闭能让模型适应真实分布。3.2 YOLOv8环境配置版本兼容是最大的坑环境配置这块我踩的坑比训练本身还多。核心问题是PyTorch版本、CUDA版本、ultralytics库版本三者必须匹配。我的配置是Ubuntu 20.04、CUDA 11.8、cuDNN 8.6、PyTorch 2.0.1、ultralytics 8.0.x。如果你用Windows建议直接用Anaconda建虚拟环境避免污染系统Python。安装命令大致是这样conda create -n yolov8 python3.9 conda activate yolov8 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics8.0.196这里有个关键点不要直接pip install ultralytics不指定版本。ultralytics更新很频繁不同版本之间API有变化比如8.0早期版本和8.1之后版本在训练参数命名上就有差异。你如果照着旧教程操作很可能报参数不存在的错。我建议锁定一个稳定版本把版本号写进requirements.txt。验证环境是否装好跑这几行import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果cuda.is_available()返回False别急着往下走先把驱动和CUDA版本对齐。GTX 1660 Ti这张卡我用了很久6GB显存跑YOLOv8s、batch size设16、imgsz设640是够的但如果你要跑YOLOv8m或更大显存会吃紧得降batch size或者用梯度累积。3.3 训练参数含义每个数字背后都有逻辑YOLOv8训练时那一堆参数很多人是抄别人的配置但不知道为什么要这么设。我挑几个最关键的讲。imgsz输入图像尺寸默认640。这个值直接影响显存占用和推理速度。640是精度和速度的平衡点如果你检测的目标特别小可以提到1280但显存翻倍、速度减半。垃圾分类场景里瓶盖、电池这类小目标我试过896mAP涨了约1.2个点但FPS从35降到22最后权衡还是用640。batch批大小。显存够就设大一点梯度更稳。但要注意batch和learning rate是联动的。经验公式是lr 0.01 * batch / 64YOLOv8默认batch16、lr0.01如果你把batch改成32lr可以适当提到0.02。不过YOLOv8用了余弦退火调度初始lr的影响没那么敏感。epochs训练轮数。小数据集几千张一般100到300轮就收敛了。我设的是200轮配合早停patience50实际大概在160轮左右验证集指标不再提升就停了。optimizer优化器默认SGD也可以选AdamW。SGD收敛慢但泛化好AdamW收敛快但容易过拟合。小数据集我建议SGD配合momentum0.937、weight_decay0.0005。lr0和lrf初始学习率和最终学习率因子。lr00.01lrf0.01意思是学习率从0.01余弦退火到0.0001。warmup_epochs预热轮数默认3。前3轮学习率从很小线性升到lr0避免一开始梯度爆炸。close_mosaic最后多少轮关闭Mosaic增强默认10。这些参数在train函数里传进去就行from ultralytics import YOLO model YOLO(yolov8s.yaml) model.train( datatrash.yaml, epochs200, imgsz640, batch16, optimizerSGD, lr00.01, lrf0.01, warmup_epochs3, close_mosaic10, patience50, device0, workers8, projectruns/trash, namebaseline )3.4 网络结构改进注意力机制怎么加才有效协调注意力Coordinate AttentionCA的核心思想是把通道注意力分解成两个一维特征编码分别沿水平和垂直方向聚合信息。相比SE注意力只做全局池化CA保留了位置信息这对检测任务很重要——因为检测需要知道物体在哪。在YOLOv8里加CA位置一般选在Neck的C2f模块之后。具体做法是写一个CA模块类然后在ultralytics/nn/modules/block.py里注册再在解析配置时把对应层的C2f替换成C2f_CA。这里要注意不是加得越多越好。我一开始在Backbone和Neck里加了6个CA结果参数量涨了15%mAP只涨了0.3。后来精简到只在Neck的P3和P4层加参数量涨5%mAP涨1.1。原因是浅层特征图分辨率高加注意力计算开销大但收益小深层特征语义强加注意力性价比更高。可变形卷积DCNv3的引入要更谨慎。DCNv3能自适应调整采样位置对不规则形状物体友好但它的实现依赖特定算子在部分环境里编译会出问题。我建议先用官方提供的DCNv3实现确认能跑通再集成。集成位置我选在Backbone最后两个stage替换普通卷积。损失函数换成WIoU这个改动最简单只需要在ultralytics/utils/loss.py里把BboxLoss的iou计算替换掉。WIoU的核心是给不同质量的锚框动态分配梯度增益让模型更关注中等质量的框避免被低质量样本带偏。4. 完整实操流程与关键环节实现4.1 数据集组织与配置文件编写数据集目录结构要规范YOLOv8要求这样组织datasets/trash/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/划分比例我用的是训练集:验证集:测试集 7:2:1。如果数据量少可以8:1:1但验证集不能少于总数据的10%否则指标波动大。划分时要保证类别分布均衡不能某个类别全在训练集里。我写了个脚本统计每个类别的实例数按比例分层抽样。配置文件trash.yaml长这样path: /home/user/datasets/trash train: images/train val: images/val test: images/test nc: 4 names: 0: recyclable 1: kitchen 2: hazardous 3: othernc是类别数names是类别名。这里有个容易犯的错names的索引必须和标注文件里的类别id对应。我见过有人标注时用1到4配置里写0到3结果训练时类别全错位mAP惨不忍睹。4.2 基线模型训练与指标解读先跑基线不加任何改进目的是建立一个参照系。训练命令就是上面那段把model换成yolov8s.pt用预训练权重或yolov8s.yaml从零训练。强烈建议用预训练权重收敛快、效果好尤其小数据集。训练过程中看几个关键指标。box_loss和cls_loss是训练损失正常应该持续下降如果震荡剧烈说明lr太大或batch太小。mAP0.5是IoU阈值为0.5时的平均精度mAP0.5:0.95是IoU从0.5到0.95每隔0.05取一次的平均后者更严格。垃圾分类任务里mAP0.5能到0.85以上算不错mAP0.5:0.95能到0.6以上算良好。我基线跑下来200轮训练最终验证集mAP0.5是0.862mAP0.5:0.95是0.613。各类别里可回收物和厨余垃圾的AP最高都在0.9以上有害垃圾最低只有0.78因为样本最少且形态差异大电池、灯管、药品混在一起。4.3 改进模型训练与消融实验改进模型训练流程和基线一样只是模型配置文件换成改过的yaml。关键是消融实验每次只加一个改进看单独收益再组合看叠加效果。我的消融实验结果大致如下模型配置mAP0.5mAP0.5:0.95参数量(M)FPSYOLOv8s基线0.8620.61311.235CA(Neck P3/P4)0.8730.62811.833DCNv3(Backbone)0.8690.62212.130WIoU0.8660.61911.235CADCNv3WIoU0.8910.64712.728可以看到三个改进叠加后mAP0.5涨了2.9个点mAP0.5:0.95涨了3.4个点代价是FPS从35降到28参数量涨了1.5M。这个trade-off我认为是值得的因为28 FPS仍然满足实时要求一般25 FPS以上人眼就感觉流畅了。消融实验有个细节每次实验要固定随机种子否则结果波动可能比改进收益还大。YOLOv8里设seed42并且用相同的训练轮数和早停策略。4.4 训练可视化损失曲线和热力图怎么看YOLOv8训练完会在runs/trash/下生成结果包括results.csv、confusion_matrix.png、PR_curve.png等。损失曲线我习惯用pandas读csv再matplotlib画这样能自定义样式import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/trash/baseline/results.csv) df.columns df.columns.str.strip() plt.figure(figsize(10, 5)) plt.plot(df[epoch], df[train/box_loss], labeltrain box loss) plt.plot(df[epoch], df[val/box_loss], labelval box loss) plt.xlabel(Epoch) plt.ylabel(Loss) plt.legend() plt.savefig(loss_curve.png, dpi300)热力图Grad-CAM能直观看到模型关注哪里。如果模型总是关注背景而不是物体本身说明数据有问题或者模型没学好。我一般用pytorch-grad-cam库对改进前后的模型各生成一批热力图对比改进后的模型在遮挡物体上的关注区域明显更集中。4.5 模型导出与边缘部署初探训练完的.pt权重可以导出成ONNX、TensorRT等格式方便部署。导出命令model YOLO(runs/trash/improved/weights/best.pt) model.export(formatonnx, imgsz640, simplifyTrue)导出ONNX后可以用onnxruntime推理也可以用TensorRT进一步加速。如果要在RK3588这类边缘设备上部署需要转成RKNN格式流程是ONNX转RKNN再用RKNN Toolkit推理。这个过程坑很多主要是算子支持和量化精度问题。我的建议是先在PC上把精度调好再考虑部署不要一边调模型一边调部署问题会互相干扰。5. 常见问题与排查技巧实录5.1 训练不收敛或mAP异常低这是最常见的问题。排查顺序我总结成一张表现象可能原因排查方法解决loss不下降lr太小或太大看loss曲线前10轮调lr0试0.001和0.01loss震荡batch太小看batch设置增大batch或梯度累积mAP始终0.1左右标注格式错可视化标注框检查坐标是否归一化某类别AP为0该类样本太少统计类别分布补充样本或过采样验证集好测试集差过拟合对比train/val loss加正则、减参、增数据我遇到过一次mAP死活上不去最后发现是标注文件里坐标没归一化写的是像素值。YOLOv8不会报错但学出来全是乱的。可视化标注框是排查这类问题的第一手段用cv2.rectangle把标注画到图上一眼就能看出对不对。5.2 显存不足CUDA out of memoryGTX 1660 Ti只有6GB显存跑YOLOv8s时如果imgsz设1280、batch设16必爆。解决办法按优先级降batch16→8→4、降imgsz1280→896→640、用梯度累积模拟大batch、换更小的模型YOLOv8n。梯度累积的写法是设batch4, accumulate4等效batch16但显存占用按4算。还有个隐藏的显存杀手workers设太大。DataLoader的worker进程也会占显存一般设4到8就够设16反而可能爆。5.3 小目标检测效果差垃圾分类里小目标确实难。除了前面说的提高imgsz、加注意力还有几个技巧。第一在数据增强里加小目标复制粘贴把一些小物体随机贴到其他图上增加小目标样本。第二调整Anchor-Free的回归范围YOLOv8默认的reg_max16可以适当调大。第三用SAHI切片推理把大图切成小图分别检测再合并对小目标提升明显但速度会慢。5.4 模型在真实场景泛化差这是最让人头疼的。训练集mAP 0.9实际拍照识别一塌糊涂。原因通常是域偏移训练数据分布和真实场景不一致。解决办法持续收集真实场景数据迭代训练。我后来做了个简单机制把识别错误的图片自动保存下来每周人工标注一批加进训练集迭代三轮后真实场景准确率从60%提到85%。另外测试时增强TTA也能提升泛化推理时对图片做翻转、缩放多次预测再融合mAP能涨1到2个点代价是推理时间翻倍。5.5 类别不平衡怎么处理有害垃圾样本少模型容易偏向多数类。我用了三个手段组合过采样把有害垃圾图片复制多份、类别权重在损失里给少数类更高权重、数据增强倾斜对少数类做更强的增强。YOLOv8本身没有直接的类别权重参数需要改损失函数或者用copy_paste增强。实测下来过采样增强倾斜最简单有效有害垃圾AP从0.78提到0.84。6. 一些掏心窝子的实操心得先说数据集。我最大的教训是标注一致性比标注数量重要。早期我找了两个同学帮忙标注结果一个人把“沾油纸盒”标成厨余另一个标成可回收模型学得一脸懵。后来我写了一份标注规范文档每个类别给10个正例和5个反例标注前统一培训标注后抽查10%一致性才上来。这件事花了两天但省下了后面两周的调参时间。再说改进。不要迷信最新论文的模块。我试过把某个顶会的最新注意力机制搬过来结果在小数据集上过拟合严重mAP反降。后来我明白一个道理小数据集上简单有效的模块比复杂新颖的模块更靠谱。CA、DCNv3、WIoU这三个都是经过大量实践验证的稳定、易集成、收益明确。训练策略上预训练权重小学习率微调是王道。我试过从零训练200轮才勉强追上预训练50轮的效果。如果你数据量少于5000张务必用预训练权重并且冻结Backbone前几轮再解冻能有效防止过拟合。最后说部署。不要等到模型完美了才考虑部署。我早期一直纠结mAP差0.5个点迟迟不部署结果部署时发现ONNX导出有算子不支持又回头改结构浪费很多时间。正确做法是基线模型跑通后先走一遍导出和推理流程确认链路通畅再回头优化精度。这样你心里有底知道改进后的模型能不能落地。还有个小技巧用TensorBoard或WandB记录实验。我一开始用Excel记后来实验多了根本管不过来。WandB能自动记录超参、指标、曲线还能对比不同run强烈推荐。YOLOv8训练时加project和name参数配合WandB集成实验管理会清爽很多。这套系统我从零到能跑通真实场景前后大概四个月其中两个月在数据上一个月在调参和改结构一个月在部署和迭代。如果你时间紧建议把重心放在数据和基线调优上改进模块选一两个稳定的就行。毕竟一个能用的系统比一个论文漂亮但跑不起来的系统有价值得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询