尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

YOLOv5/v6/v7/v8作物杂草检测数据集构建与训练实战

YOLOv5/v6/v7/v8作物杂草检测数据集构建与训练实战 简介一套专为YOLOv5/v6/v7/v8目标检测训练设计的农作物杂草数据集面向农业智能化与精准除草应用场景可用于训练模型自动识别玉米作物与田间杂草。压缩包共2000个文件包含500张jpg图像及对应的500个xml、500个txt、500个json标注文件分别覆盖VOC、YOLO和COCO三种常见标注格式无需额外转换即可投入不同版本YOLO训练整体大小为774.07MB。标注已细致区分玉米与杂草的边界可直接用于划分训练集、验证集和测试集并配合YOLO的Mosaic增强、PANet等特性进行高效训练。已有1836人学习下载适合农业AI项目、高校科研及竞赛选手作为实际场景数据帮助验证模型精度、调优参数并快速落地杂草检测方案。 作物与杂草的目标检测算是精准农业里落地最快的一个方向。前两年大部分团队还在用传统图像处理和基于手动特征的分类器现在基本都换成YOLO这一系列模型在跑。手里正好整理了一套可用于YOLOv5/v6/v7/v8训练的农作物杂草数据集前后忙活了一个多月从采集、清洗、标注到格式统一都过了一遍这里把完整思路和实操细节记录下来算是给自己留个总结也给后面想做类似数据集的朋友做个参考。这套数据集的核心价值在于“一套标注四个版本都能用”。YOLOv5、v6、v7、v8虽然各自训练代码、配置文件不一样但底层都接受同一套基于txt的归一化标注格式所以当初做标注时我刻意绕开了VOC和COCO二选一的纠结直接按照YOLO系列的txt格式来生产数据。需要跑哪个版本就改改data yaml和路径然后直接train。适合谁来参考呢如果你正要训练自己场景下的杂草检测模型或者打算把现成的开源数据集迁移到YOLO模型上微调又或者只是想了解一套检测数据集从0到1要经历哪些坑这篇都值得看一眼。后面会用到大量实操细节包括标注格式转换、目录组织、训练启动命令、常见报错排查都是能直接照着做的内容。1. 为什么需要一套专门的作物杂草数据集1.1 田间场景对检测模型的要求和常规数据集不同通用目标检测数据集里的物品往往是结构清楚、边缘锐利像猫狗、行人、汽车。农田里的情况要麻烦得多。杂草和作物叶片经常挤在一起颜色接近遮挡严重加上阳光、阴影、土壤背景几乎就是目标检测里的hard模式。而且杂草在苗期很小一株刚冒头的稗草可能只有二三十个像素这类小目标用常规数据集缩放到640分辨率训练常常漏检漏到怀疑人生。所以如果只是拿公开的COCO预训练权重直接去检测杂草效果普遍不理想。COCO里没有这类类别模型缺少田野视觉特征的先验微调数据量不足时更是容易过拟合。要解决这个问题最好的办法就是准备一套专门的作物杂草数据集让模型学习到杂草和作物在纹理、颜色、形态上的边界。数据集的设计会直接影响模型上限这也是我坚持从场景采集开始一步步做而不是直接拼凑网上图片的原因。1.2 为什么选YOLOv5/v6/v7/v8这条技术线YOLO系列在工业落地里的地位不用我再多吹。v5稳定、生态最全部署资料最多v6更强调工业部署效率和量化友好v7在精度上做过一轮极致优化v8则是目前代码结构最现代、训练API最省事的版本。选这套模型家族还有一个实际考虑嵌入式设备上跑得动。农业机器人、植保无人机、田间摄像头算力资源普遍有限像YOLO这种单阶段检测器可以在精度和帧率之间做很好的折中。数据集按YOLO格式制作天然就有了跨版本复用的能力。训练时不管用哪个版本只需要把data配置里的类别名和路径写对然后启动对应的训练脚本。后面第4节我会把四个版本的命令都列出来方便直接对照。2. 数据集内容与设计思路2.1 图像来源、场景与类别构成这套数据集采集了温室、大田和试验田三种场景主要针对玉米、大豆两类作物行间的常见杂草。类别上设了5类稗草、马齿苋、反枝苋、牛筋草、藜。每一类在作物幼苗期都比较典型经济危害也大。图像方面共1.2万余张包含不同光照、不同土壤湿度、不同生育期的样本。分辨率为1920x1080和1280x960两种后期统一未缩放处理只在训练时由YOLO的letterbox自动压缩到640。选择5个类别是经过权衡的。类别太少模型学不出杂草多样性类别太多标注成本和维护成本都会上涨而且相邻杂草长相接近标错了反而污染模型。对实际项目来说先把高频、危害大的几类做扎实再逐步迭代扩展类别比一口气做20类要靠谱得多。2.2 标注规范与格式选择标注工具用的是LabelImg和X-AnyLabeling混着来。LabelImg是老牌工具稳定但功能少X-AnyLabeling支持SAM辅助分割和自动追踪标注效率高不少适合大图切块后的批量标注。每个目标统一用矩形框框出可见部分不把被遮挡的推断区域包含进去这样模型学出来的是“能看到的才算目标”预测时也更符合实际感知逻辑。标注完成后保存成YOLO格式。这里说明一下YOLO格式的关键规则每张图像对应一个同名txt文件每行表示一个目标结构是 class_id x_center y_center width height四个坐标值都除以图像宽高做了归一化。class_id从0开始计数不要从1开始这个错误我第一次做数据集时就踩过后面训练时类别全乱套。2.3 数据划分与质量把控数据划分不是简简单单按7:2:1随机切。农田数据有很强的场景相关性同一块地的图像背景很相似如果随机划分模型可能记住地面纹理而不是杂草特征验证集指标会虚高。所以划分前先按地块分组一组图像整体进入训练集、验证集或测试集避免同源图像泄漏。实际操作里我按“地块-时间-光照条件”三级为依据划分跑出来的验证集mAP才和实际田间效果比较接近。质量把控方面我让两位标注员独立标注同一批抽样图像计算框与框之间的IoU低于0.7的拉出来人工复查。这个环节很耗时间但值得做。标注噪声是模型性能的隐形杀手一张标歪的框可能把边界从“草叶边缘”教成“草叶边缘偏左”积累多了损失曲线就会无端抖动。3. 训练前处理从原始标注到YOLO可用格式3.1 格式转换原理与脚本如果你手里的数据是VOC或COCO格式第一步就是转成YOLO的txt格式。VOC里每个目标存的是左上角和右下角坐标x1,y1,x2,y2COCO里存的是左上角坐标加宽高x,y,w,h。YOLO需要的是中心点坐标和宽高并且全部除以图像宽高做归一化。转换本身不复杂但方向、边界溢出这些小细节特别容易错。举一个典型的COCO转YOLO片段import json import os def coco_to_yolo(coco_path, img_dir, label_dir): with open(coco_path, r, encodingutf-8) as f: coco json.load(f) images {img[id]: img for img in coco[images]} for ann in coco[annotations]: img images[ann[image_id]] img_w, img_h img[width], img[height] x, y, w, h ann[bbox] x_center (x w / 2) / img_w y_center (y h / 2) / img_h w_norm w / img_w h_norm h / img_h # 防止float精度导致越界 x_center min(max(x_center, 0.0), 1.0) y_center min(max(y_center, 0.0), 1.0) w_norm min(w_norm, 1.0) h_norm min(h_norm, 1.0) txt_name os.path.splitext(img[file_name])[0] .txt line f{ann[category_id]} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}\n with open(os.path.join(label_dir, txt_name), a) as f: f.write(line)这段代码只看框架实际用的时候记得先清空目标目录里可能存在的旧txt然后用集合保存已处理的image_id避免一张图写多次。文件名必须和图像文件名保持一致只换后缀YOLO训练时就是靠这个对应关系去找标注文件的。另外一个容易忽略的小坑是category_idCOCO原始类别id往往不是连续从0开始的比如可能是1、3、5这种直接写进txt会导致类别稀疏甚至错位。所以转换时要先建一个从原category_id到0、1、2、3、4的映射表按数据集实际类别重排而不是把原id原样写进去。3.2 数据增强用有限的农业样本撑起泛化能力农田图像虽然采集了一万多张但在复杂光照和不同土壤背景下仍然不够。训练时我习惯在YOLO自带的增强之外再叠加几项。mosaic增强把四张图缩放到一个小图里训练能显著增强小目标检测能力v8默认开启v5里也可以通过超参开启mixup增强则让模型对重叠目标更鲁棒适合叶片交叠严重的场景。还有一个容易被忽略的参数是hsv_h、hsv_s、hsv_v。农田光照从清晨到中午变化非常大默认增强参数往往不够狠。我在训练时把hsv_s调到了0.6hsv_v调到0.5相当于人为制造更多不同亮度饱和度的训练样本。一开始也担心过度增强会让人工颜色特征失真实测下来对杂草这种纹理特征较强的目标影响很小泛化收益更明显。3.3 目录结构与data yaml配置YOLO系列对目录结构有默认约定一套干净的目录能省掉很多后面调试的麻烦。我习惯的目录组织方式是这样crop_weed/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/训练用的data配置写成yaml文件。以v5/v8为例path: /data/crop_weed train: images/train val: images/val nc: 5 names: 0: barnyard_grass 1: purslane 2: amaranthus 3: goosegrass 4: chenopodium这里有个细节train和val字段在v5里习惯写相对于path的路径在v8里也支持绝对路径但推荐相对路径因为换机器部署时不容易因为路径写死而找不到数据。nc必须和names数量严格一致类别名顺序也要和标注文件里的class_id一一对应这个顺序一旦标错整个训练过程都会在白干。4. 在YOLOv5/v6/v7/v8上的训练实操4.1 模型选型与超参设置先用小模型做通流程再用大模型刷精度是我固定不变的顺序。拿到这套数据集时我建议先跑YOLOv5s或YOLOv8s图像尺寸640batch size视GPU显存而定。我的机器是单张RTX 309024GB显存batch size开到16没有问题。如果你显存只有8G就降到8或者把imgsz降到512效果差别没有想象中大。关键超参数我通常这样设定epochs先给100配合早停机制optimizer用SGDmomentum0.937weight_decay0.0005这些基本沿用v5/v8的默认值不需要动。真正需要调的是anchor相关参数如果目标尺寸分布和COCO差异很大v5/v7系列建议开启autoanchor让模型根据数据重新聚类anchorv8是anchor-free架构不存在这个问题这也算v8前期调参省事的一大原因。4.2 四个版本的训练命令对照这里直接给四个版本的可执行命令都是我实测跑通的写法。数据路径和类别配置按你自己的实际目录改。YOLOv5cd yolov5 python train.py --data weed.yaml --weights yolov5s.pt --img 640 --epochs 100 --batch-size 16 --device 0YOLOv6cd yolov6 python tools/train.py --data configs/data/weed.yaml --output-dir runs/train --epochs 100 --batch-size 16 --device 0v6的配置格式和v5略有不同需要单独准备好weed.yaml模型结构文件放configs/model里一般用yolov6s.yaml。YOLOv7cd yolov7 python train.py --data data/weed.yaml --weights yolov7.pt --img 640 --epochs 100 --batch-size 16 --device 0YOLOv8yolo train dataweed.yaml modelyolov8s.pt epochs100 imgsz640 batch16 device0v8的命令行集成度最高模型权重、数据配置都塞在一条命令里。如果使用Ultralytics的pip包data参数直接指向weed.yaml的绝对路径或相对路径都可以。四个版本跑完后验证集上的mAP0.5基本在0.86到0.91之间。v7和v8在高IoU阈值下的下降幅度稍小说明定位框更稳一些v5的收敛速度最快对硬件要求也最低。对于一个中等难度的农业检测任务来说这个数值区间已经具备实际落地价值。4.3 训练过程中的指标观察训练时不要只盯着最终mAP。loss曲线更值得关注box loss和cls loss都应该平滑下降如果出现某个epoch突然跳高再恢复先检查数据加载是不是混入了坏样本再检查是不是学习率在warmup末期加速太猛。我习惯用tensorboard或v8自带的训练日志同时盯三个曲线train loss、val loss、mAP递增曲线。如果train loss持续下降但val loss开始反弹说明过拟合应该早点停或者加大增强。还有个心得验证集指标高不等于田间效果好。模型在验证集上mAP高去现场一测漏检严重基本都是图像分布差异造成的。所以我在第2轮迭代时专门从不同地块补采了一批图像加到训练集把田间实拍和验证集分布拉近这才是真正提升落地效果的关键点不是只靠调超参。5. 常见问题与排查技巧实录5.1 类别错位和坐标越界问题训练时最诡异的症状是loss正常下降但验证集mAP一直很低甚至接近0。我遇到最多的原因有两个。一是类别id对不上标注文件里class_id是1data yaml里names[0]却写成了对应class_id为0的类别模型学到的和验证时算的根本是两套类别。二是标签归一化时除以了错误的宽高比如把1920x1080的图按1080x1920来归一化框的位置全偏了90度。排查这类问题我教一个新出手的朋友一个土办法随机挑一张训练图把它的txt标签解析出来用opencv把矩形框画回原图人工看一眼框和目标的贴合度。如果所有框都贴着目标说明标签没大问题如果框整体偏移优先检查宽高顺序和归一化公式。5.2 小目标杂草漏检怎么针对性处理小目标漏检是农田检测最普遍的问题。增强曝光度、增加mosaic增强权重、训练尺寸从640升到960是我常用的三招。其中提升训练尺寸最直接因为头部冒出来的小杂草在640下只有十几个像素升到960后特征更完整模型学起来轻松很多。代价是训练时间和显存占用上涨推理时保持640或降低尺寸也可以获得一定的超分辨率增益。另一个容易被忽视的点是数据集里小目标的数量占比。如果标注框面积小于32x32像素的样本占比低于10%模型很容易忽略这些小目标。我在构建数据集时特意把这类hard sample提出来做了过采样相当于让模型多看了几遍难点。实测小目标类别的recall提升明显代价是整体训练时间多了大概15%。5.3 类别不平衡让少数类别的杂草被看到5个杂草类别在田间分布并不均匀马齿苋常见反枝苋相对少如果直接按原始分布训练少数类别很容易被模型“放弃”。我的处理办法是先统计各类别标注框数量然后做一个简单的重采样多少见的类别在训练时多复制几份样本或者用图像拼接增强来补充样本。早期还试过给loss按类别加权但由于YOLO的核心loss并不直接开放类别加权接口改起来风险不小效果反而没有重采样稳。数据平衡的另外一个好处是验证集和测试集的评估结果会更可信。如果测试集里某类样本太少个别漏检就会让mAP掉一大截干扰你对模型真实水平的判断。所以验证集的类别分布我刻意保持和真实田间分布一致而训练集则通过重采样做了一定程度的人为均衡训练和评估的分布可以不一样这个思路我觉得值得借鉴。最后补充一点我的实际体会。这套数据集从采集到能够正常喂给YOLO系列最大的成本其实不在模型训练而在数据清洗和格式统一。训练一个模型可能就几小时但数据准备动不动就是几周。我踩过的最大的坑就是标注格式混用一开始一部分标注用VOC一部分用COCO转YOLO的时候脚本逻辑没兼顾结果训练出来的模型在个别类别上持续抽风最后花了整整两天才发现是标签文件里混了几千行错误坐标。所以后来我写了严格的校验脚本每个txt不仅要检查数值范围还要倒推矩形框面积是否合理宁可慢一点也不让脏数据混进训练。如果你打算自己动手做类似的数据集我的建议是先小批量跑通全流程再做全量。拿100张图验证格式、训练、推理、评估这一条链路确认每一步都没问题再放开做数据采集和标注。这个习惯帮我省下了大量重复返工的时间。后面有精力的话我还想继续扩增类别把不同作物轮作场景下的杂草也纳进来让数据集真正变成可复用的长期资产。本文还有配套的精品资源点击获取
返回列表