资讯动态

YOLOv5 4.0垃圾分拣全流程实战:环境配置、数据集制作与模型训练

发布时间:2026/10/19 17:33:26 来源:尧图企业网站定制
做垃圾分拣这个项目的时候我用YOLOv5 4.0版本从环境配置、数据集制作到模型训练完整走了一遍把整条业务流里的实操细节和踩过的坑都梳理出来。这套流程不光是跑通了一个Demo而是真正在分拣产线上跑过、经过业务验证的适用于任何固定场景的工业目标检测项目。如果你正准备用YOLOv5做物料分拣、缺陷检测这类任务这篇文章应该能帮你省下至少两周的摸索时间。1. 项目整体设计与算法选型思路1.1 垃圾分拣业务流到底要解决什么做这个项目之前我先在合作方的分拣中心产线旁蹲了一段时间。传送带上过来的物料大致是这几类塑料饮料瓶、易拉罐、纸箱碎片、玻璃瓶还有其他零散杂物。工人在传送带两侧肉眼识别、手动挑拣一天八小时下来漏拣率高、劳动强度大而且人员流动频繁培训成本也不低。业务方给的指标很直接识别准确率不低于92%误检率控制在5%以内单次推理耗时不超过50毫秒要能跟上产线1.5米/秒的传送速度另外设备要能7乘24小时连续跑。这些指标单独看都不算苛刻但凑到一起就有点麻烦。我一开始试过两阶段检测方案准确率确实能到95%以上但推理速度掉到每秒只有几帧根本跟不上传送带。后来也试过用分类网络先切割再判断的路子逻辑复杂不说对遮挡和小目标处理不理想。折腾了几轮之后我把方案收敛到了YOLOv5 4.0这是我在精度、速度和工程复杂度之间反复权衡后的选择。这里多说一句做工业项目跟做竞赛不一样竞赛刷一个点可能就够了但产线项目要考虑的是算法能不能长时间稳定跑、出问题好不好排查、换数据好不好迁移。这也是我把版本锁定在4.0而不是追新版本的原因——4.0的生态资料成熟社区讨论多出了任何报错基本都能搜到这对我这种要快速交付的项目来说价值很大。1.2 YOLOv5 4.0的核心特性与选型依据YOLOv5 4.0是单阶段目标检测框架核心思路是把目标检测当成回归问题直接做输入一张图经过骨干网络提取特征再通过检测头输出目标的类别概率和边界框坐标。跟两阶段方案最大的区别是少了一个候选区域提取环节所以速度快。4.0版本在结构上有几个特点值得说Focus模块对输入图像做切片操作把空间信息重排到通道维度上在早期就完成下采样比传统的卷积分支更省计算。实测在同样输入尺寸下Focus层能让前向速度提升约10%。CSPNet骨干网络把底层的梯度流劈成两条路径再合并减少重复梯度计算这也是模型能保持轻量的主要原因。PANet特征金字塔从顶层到底层多路径融合特征对小目标的召回有明显帮助。垃圾分拣场景里纸箱碎片、瓶盖这些东西尺寸都不大这个设计很关键。自适应锚框计算训练时会根据你的数据集自动重新计算锚框尺寸不用手工调。在模型规模的选型上我最终选了yolov5s作为主力模型。对比过m和l版本m的mAP确实比s高一个多点但推理时间也上去了在低算力工控机上跑不稳定。s版本在保证92%以上准确率的前提下单帧推理在GTX 1660上能跑到20毫秒以内余量很充足。2. 环境配置从显卡驱动到跑通Demo2.1 硬件环境与CUDA版本配对先说硬件。训练环境我用的是一台双路工作站配一张RTX 3060显卡12GB显存。这个配置在当下算是比较入门的深度学习设备了跑yolov5s用batch-size 16完全没问题。推理环境是产线上的工控机用的GTX 16606GB显存跑s模型也够。很多人问要不要上更好的卡我的看法是起步阶段没必要。YOLOv5s的显存占用不高6GB以上就能正常训练12GB就挺宽裕。真正吃显存的是你设置的batch-size和输入分辨率这两个参数可以根据卡的情况动态调整。与其纠结买什么卡不如把数据集做好这个对最终效果的贡献比显卡大得多。版本匹配这块是新手最容易翻车的地方。我踩过一次坑装好了CUDA 11.8结果PyTorch装成了CPU版本训练时GPU利用率始终是0%。后来学乖了先查PyTorch官方对CUDA版本的支持表再反推显卡驱动版本。推荐的版本组合是这样一套组件推荐版本说明显卡驱动510.x及以上向下兼容CUDA11.3与PyTorch 1.10.1对应cuDNN8.2配合CUDA 11.3Python3.8兼容性最稳PyTorch1.10.1对应build版本支持CUDA 11.3这套组合是我实测过的最稳配置。如果你用的PyTorch是更新的版本就去官网找对应的CUDA版本遵循PyTorch决定CUDACUDA决定驱动这个顺序就不会错。2.2 创建虚拟环境与安装依赖环境我建议用conda来管理。深度学习的依赖关系很乱特别是装过其他项目的话不同版本互相污染是常有的事。用虚拟环境隔离是必须的。具体步骤创建Python 3.8环境conda create -n yolov5 python3.8激活环境conda activate yolov5安装PyTorch这里要注意用官方源给出的CUDA版本对应的命令比如CUDA 11.3对应的是pip install torch1.10.1cu113 torchvision0.11.2cu113拉取代码git clone -b v4.0 https://github.com/ultralytics/yolov5.git注意加-b v4.0参数默认分支现在是更新版本跟4.0的代码结构有差异进入目录后安装依赖pip install -r requirements.txtrequirements.txt里大部分是常用库有可能会跟系统里已有的版本冲突。我遇到比较多的是opencv-python和numpy的版本问题如果安装时报错可以先单独升级这两个库再继续。装完之后别急着跑训练先用自带的推理脚本验证一下环境是通的。找一张测试图片执行python detect.py --source data/images/如果能在输出目录里看到画了框的结果图说明前向推理的链路是通的。这一步能过滤掉绝大多数环境配置问题后面训练报错排查起来范围会小很多。2.3 训练数据目录结构与自检顺便把训练数据的目录结构也讲一下因为后面所有操作都依赖这个结构。YOLOv5约定的是images和labels两棵目录树dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/每张jpg图片对应一个同名的txt文件放在labels目录下。txt里每行表示一个目标格式是class_id x_center y_center width height注意这里x_center、y_center、width、height都是相对图片宽高的归一化坐标范围0到1。比如一张640x640的图某个目标中心在(160, 320)宽100高200对应的一行就是0 0.25 0.5 0.15625 0.3125。不少新手在这里犯迷糊用绝对像素值写进去训练的时候loss直接崩掉。我的习惯是先用脚本批量检查一遍txt文件里的坐标是否都在0到1之间再开始训练。3. 数据集制作质量比数量更重要3.1 图像采集的现场要点数据集是这整个项目里投入时间最多的环节也是决定模型上限的环节。算法圈子里有句话叫垃圾进垃圾出用在垃圾分拣项目上特别贴切。采集图像的时候我总结了几个关键点第一尽量贴近真实部署场景。因为最终要部署到传送带上所以采集的时候就要在传送带旁边架摄像头按实际的角度、高度、光线条件来拍。我们在现场用跟部署同型号的工业相机以45度俯视角拍摄帧率15fps连续录了几小时再抽帧得到原始图像。这样得到的训练数据跟推理时的分布基本一致模型泛化问题会少很多。第二要覆盖环境变化。产线白天和晚上的灯光不一样晴天和阴天的自然光也不一样甚至传送带新旧程度都会影响反射。所以我分三个时间段去采上午、下午、晚上每个时间段各采一批保证数据里有足够的光线多样性。第三类别数目要均衡。我们定义了四个主要类别plastic_bottle、aluminum_can、cardboard、glass_bottle。每个类别采集了大约600张有效图像。如果某个类别数量特别少模型就会偏向于不预测这个类别这在分拣业务里是致命的因为漏拣意味着物料进错通道。每类600张够不够我的经验是对于固定场景、类别外观变化不大的任务每类300到500张是底线600张以上效果会比较稳定。如果外观变化大的比如纸箱有各种颜色和折痕建议每类至少800到1000张。也不用过度追求数量关键在多样性和标注质量。3.2 标注流程与格式规范标注工具我用的是labelImg轻量、跨平台、直接支持YOLO格式导出。标注的时候要注意几个细节边界框要紧贴目标不要留太多背景。尤其是玻璃瓶这种透明物体边界模糊标注标准要统一。我们定了一条规则以瓶身主体为准不包含瓶口螺纹部分。遮挡目标的处理。传送带上的物料经常互相叠压我的原则是遮挡超过50%的目标不标注遮挡小于50%的尽量框全。这个规则要保证所有标注员执行一致不然标注一致性差了模型学出来的框会很乱。类别标签拼写要统一。我们吃过亏有人标成plastic_botle有人标成plastic_bottle多了一个字母训练时被当成两个类。建议在标注前把类名模板固定好复制粘贴填。标注完之后用脚本把labelImg生成的XML或TXT文件做一次全量检查。重点检查有没有空文件漏标了、类别ID有没有超出范围、坐标值是否都在0到1之间、有没有重复标注的同一目标。这一步检查在批量操作里可以避免很多后续问题。3.3 数据增强策略与数据集划分YOLOv5 4.0在训练时默认开启了Mosaic数据增强把四张训练图片随机拼接成一张。这个增强策略对提升小目标检测能力非常有效因为拼接之后的图里目标尺寸相对变小了等于变相增加了小目标样本。对垃圾分拣场景瓶盖、易拉罐拉环这些小目标Mosaic的贡献很明显。除此之外我还开了随机水平翻转、HSV色彩抖动饱和度、亮度、色调各微调。这里要注意垃圾分类场景里有些类别对颜色敏感比如区分新的铝罐和旧的铝罐所以色彩抖动我调得比较保守hsv_h0.015、hsv_s0.5、hsv_v0.4没有用默认的激进值。数据划分我用的是9:1即90%训练、10%验证。因为总数不算特别大验证集太小的话评估结果波动会很大。划分的时候用随机种子固定保证每次实验的可复现性。4. 模型训练配置、命令与参数调优4.1 自定义数据集配置文件的修改YOLOv5训练前要准备一个数据集yaml文件告诉程序去哪儿找数据、分几个类。在data目录下新建一个custom.yaml内容模板是这样# 自定义数据集配置 train: /path/to/dataset/images/train val: /path/to/dataset/images/val # 类别数量与名称 nc: 4 names: [plastic_bottle, aluminum_can, cardboard, glass_bottle]train和val路径建议写绝对路径避免相对路径引发的各种奇奇怪怪的问题。写相对路径的时候程序的工作目录必须是项目根目录才行一旦你从别的目录执行命令就会找不到数据。这个yaml文件里最容易出错的地方是nc和names长度不一致。如果nc写了4names里只有3个训练时大概率会报IndexError或者训练出来的模型类别错乱。检查方法很简单写完之后用一个小脚本读一下yaml确认nc等于len(names)。4.2 训练命令与关键超参数准备工作做完训练命令长这样python train.py \ --data data/custom.yaml \ --cfg models/yolov5s.yaml \ --weights weights/yolov5s.pt \ --batch-size 16 \ --epochs 150 \ --img 640 \ --name garbage_sorting_exp1参数逐个解释--cfg指定网络结构定义文件。yolov5s.yaml对应的是s模型的结构如果想要m或l版本改这里就行。--weights预训练权重。强烈建议用官方提供的yolov5s.pt做迁移学习初始化而不是从零训练。预训练模型在COCO上学习过的通用特征迁移到我们的小数据集上收敛速度能快好几倍最终精度也更高。第一次用需要先下载几十MB的权重文件。--batch-size受显卡显存限制。RTX 3060跑16没问题如果显存不够报CUDA out of memory就降到8。batch太小训练不稳定但不是越大越好16到32是比较常用的区间。--epochs150轮。我试过100轮和200轮150轮左右就能稳定收敛到后面loss曲线基本是平的了。如果验证集mAP已经连续20轮不再提升可以提前停。--img训练输入分辨率。640是YOLOv5的标准分辨率速度和精度平衡最好。试过960的小目标精度确实有提升但推理时间几乎翻倍产线实时性受影响最终定在640。训练过程中每轮结束后会在runs/train/garbage_sorting_exp1目录下生成当轮的权重文件。注意看控制台输出的指标val Objectness、val Classification、mAP0.5这几个值。我重点关注mAP0.5垃圾分拣业务对定位精度要求不算极端框稍微偏一点不影响分拣所以mAP0.5达标就行。4.3 Loss曲线与评估指标解读训练结束后到runs/train/garbage_sorting_exp1目录下看一眼results.png里面有训练全程的loss曲线和指标曲线。这里分享几个我总结的读图经验训练loss和验证loss都在下降且差距不大说明模型在正常学习没有过拟合。如果训练loss还在降、验证loss开始反弹那就是过拟合了可以降低epochs、增大数据增强强度或者加dropout。mAP0.5曲线训练到后期应该会趋于平缓。如果曲线一直上下震荡波动超过五个点先检查验证集是不是太小或者某些类别的样本数太少。我们遇到过一次这种情况排查发现验证集里glass_bottle只有三四十张去掉几张难的样本评估结果就剧烈波动后来把验证集扩充到每类至少80张曲线才稳定下来。验证阶段还可以用python val.py --data data/custom.yaml --weights runs/train/garbage_sorting_exp1/weights/best.pt来看详细评估。val.py会生成混淆矩阵和PR曲线混淆矩阵能直观看到哪些类别互相搞混。我们第一版模型里玻璃瓶和塑料瓶的混淆比较严重后来分析是标注时透明瓶身边界不统一导致的重新规范标注之后混淆明显降低。这个过程我建议不要省它告诉你的不是模型好不好而是数据哪里有问题。5. 常见问题与排查技巧实录5.1 训练阶段高频报错与解决这一节是我踩坑最多的地方整理成一个速查表遇到问题直接对着查就行。问题现象可能原因解决办法CUDA out of memorybatch-size过大或显卡显存不足调小batch-size或降低img尺寸到416做试探AssertionError: labels require 5 columns标注txt格式错误检查txt是不是每行5个值类ID是否为整数IndexError: index 5 is out of boundsnc与实际类别数不对应核实yaml里的nc和names长度NaN loss学习率过高、数据里有损坏图片降低初始学习率用脚本清理损坏图像Training loss正常但mAP为0验证集路径写错生成的是空数据集检查yaml中val路径是否存在且非空GPU显存占用0%PyTorch装了CPU版本重装对应CUDA的GPU版PyTorchKeyError: val训练中断后恢复断点时找不到验证集确认yaml中val字段存在模型输出框偏移严重标注坐标用了绝对像素值确认txt中坐标为归一化的0到1浮点数除了查表这里分享一个通用的排查思路先把问题缩小到数据、配置、环境三个类别之一。怎么缩小用最小复现法——把训练命令减到最简单张图片、batch-size 1、epochs 1。如果这样还报错说明是配置或数据问题如果跑通了再逐步加参数就能定位是哪个环节触发的。5.2 数据集相关的典型问题数据集方面我遇到的最诡异的一个问题训练到中途报错说某个图片解码失败。排查发现那张图是从视频抽帧存下来的文件扩展名是jpg实际内容却是其他格式编码。YOLOv5的加载器按扩展名解码遇到这种伪造扩展名的图就会异常。解决方法是写个脚本把所有训练图片重新解码再编码一次统一转成标准jpg。还有一个典型问题标注文件与图片文件不完全同名。比如图片叫image_001.jpg标注文件叫image_001.txt没问题。但如果有一张图没有对应标注文件或者标注文件是多余的训练时有的报错有的直接跳过行为不一致。我建议训练前跑一个校验脚本比对两边文件集的差异并输出清单。5.3 推理阶段的问题排查训练好了不等于部署就顺利。我遇到过最多的问题是模型推理正常但检测框置信度整体偏低比如都是0.3到0.5的区间。排查下来发现两个原因一是训练时的输入分辨率和部署推理时的输入分辨率不一致YOLOv5对分辨率的敏感度比想象中高二是图像预处理方式不同训练时做了色彩增强推理时的原图直接输入反而让模型不适应。解决方法在推理脚本里保持跟训练一致的前处理流程尤其是归一化和resize的方式。YOLOv5官方detect.py里的预处理已经处理好了如果你是自己写的推理逻辑一定要对照源码保持一致。6. 模型导出与垃圾分拣业务流集成6.1 模型导出从PyTorch到生产格式训练完成后需要把PyTorch格式的权重导出为部署格式。垃圾分拣产线上用的是工控机加普通USB工业相机没有专用的AI加速卡所以我优先选择ONNX格式再用ONNX Runtime进行推理。导出命令很简单python export.py --weights runs/train/garbage_sorting_exp1/weights/best.pt --include onnx --img 640导出后可以用python detect.py --weights best.onnx --source data/images/test.jpg验证ONNX模型推理结果跟PyTorch模型的输出做对比。我测过ONNX的推理结果和PyTorch模型基本一致mAP差距在0.3个点以内在可接受范围。如果产线上有TensorRT环境可以进一步导出engine格式。TensorRT能利用GPU的深度优化推理速度比ONNX Runtime快30%到50%。我们最终在工控机上实测TensorRT模式下单帧推理时间稳定在12毫秒左右完全满足50毫秒以内的要求。6.2 业务流串联相机、检测、分拣控制部署的逻辑不复杂但注意点不少。整个业务流是一条单行道工业相机以固定帧率采集传送带画面将当前帧送入检测模型模型输出检测框和类别ID程序根据类别ID和检测框位置判断目标对应哪个分拣通道将分拣指令通过串口发送给PLC或者分拣机构记录检测日志和统计数据这里要特别注意一个时序问题从图像采集到分拣机构动作之间传送带会把目标往前带一段距离所以程序里必须做检测位置加传送带速度的补偿计算。我们用的公式很简单补偿距离 传送带线速度 ×检测耗时 控制耗时。如果不做这个补偿分拣机构永远打在目标的前方或后方。这个坑我们在现场调试时专门踩过一开始以为检测延迟可以忽略结果发现1.5米/秒的速度下100毫秒的延迟就会导致15厘米的偏差框都打在瓶子左边机构完全抓不到。后来在程序里加了延迟补偿常量现场调了几组数值才定位准确。置信度阈值也要单独调。训练阶段用的confidence是0.25这是官方默认适合展示效果。业务部署时我们调到了0.55效果立刻干净很多。理由很简单分拣业务的误检代价比漏检大因为误检会把正确物料拨错通道造成二次污染所以宁可漏检一些低置信度的目标也不要误检。这个权衡思路分享给大家不同业务的阈值调优方向是不一样的。7. 写在最后的一些体会项目收尾之后回头看这套垃圾分拣检测流程能跑通最核心的不是某一个模型有多强而是把数据集、模型、部署三个环节的细节都抠到位了。尤其是数据集环节我花的时间比模型训练多一倍但回报也是最大的。训练跑了十几个实验版本最终效果排第一的版本用的反而是采集质量最高、标注最规范的那套数据。还有一点想提醒后来者YOLOv5的版本迭代很快网上搜到的教程经常混着不同版本的代码逻辑很多命令在4.0上管用在新版本上就变了。如果你决定用4.0就认准4.0的官方仓库和文档不要混用。下载代码时注意加-b v4.0参数这个细节能帮你避开很多莫名其妙的兼容问题。最后产线项目永远是先跑通再优化。不要一上来就追求最佳准确率先用小数据集、小模型把整条业务链路打通再逐步增加数据量、调整参数。链路通了后面每一步优化都是可预期、可控的。这套流程不局限于垃圾分拣任何用YOLOv5做工业检测的固定场景项目都可以按这个思路来推进。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑