ARTICLE DETAIL

资讯详情

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

田间杂草检测数据集构建与YOLO模型训练全流程实战

田间杂草检测数据集构建与YOLO模型训练全流程实战 简介面向YOLOv5/v6/v7/v8模型训练任务的农作物杂草数据集专门服务于需要训练玉米与杂草检测模型的开发者和农业智能化研究人员。包内含2000个文件由500张jpg原图及对应的500个xml、500个txt、500个json标注文件组成分别兼容VOC、YOLO、COCO主流标注格式可免去格式转换直接用于不同版本YOLO的模型训练与效果验证压缩包整体约774MB。所有图像均对玉米作物与杂草进行了精细的边界标注类别区分明确有助于模型稳定学习两类目标的视觉特征同时丰富的格式也方便在多个框架间进行对比实验与算法迁移。目前已有1836人学习下载适合具备基础目标检测知识、希望获取高质量农业场景数据集开展课题研究或工程落地的读者。 先申明一下上一篇写《基于YOLO的农作物杂草检测实践》时好几个人后台私信问数据集能不能共享。我手里这套数据是去年在黑龙江和山东两个玉米主产区采集的前后忙了两个月整理完正好适配YOLOv5/v6/v7/v8四个版本。这篇就把数据集的构建思路、标注规范、格式适配和训练踩坑一次性讲透需要的可以直接抄作业。1. 数据集构建的底层逻辑与场景价值1.1 为什么杂草检测非要用专用数据集很多人上来就打算用COCO或者VOC这种通用数据集跑迁移学习我劝你趁早打消这个念头。通用数据集里的杂草类别极其稀少即使有也多是园艺场景的单株杂草和田间自然环境下杂草丛生、叶片重叠、光照不均的真实状态差着十万八千里。目标检测模型有个残酷的规律训练集和部署场景的分布差异直接决定模型落地效果的上限。你拿通用数据集训出来的权重去做田间除草机器人的视觉识别晴天强光下能掉到40%以下的mAP这不算夸张我自己实测过。所以做农业项目自建一套贴近真实作业环境的数据集是绕不开的坎。我说的高质量指的是满足三个条件一是图像分辨率不低于1280x720能看清杂草的纹理特征二是标注框贴合目标边缘IoU控制在0.85以上三是样本覆盖了不同生长周期、不同光照条件、不同土壤背景。这三条缺一条训练出来的模型就会有明显短板。1.2 杂草检测的典型应用场景拆解这套数据集主要服务于三类落地场景每类场景对数据的要求其实不太一样。第一类是精准喷雾设备就是那种悬挂在拖拉机后方的智能喷杆。它需要模型在行进过程中实时识别喷杆下方的杂草然后控制对应喷嘴开关。这类场景要求检测速度快单帧推理时间控制在30毫秒以内并且对小草出苗后10天以内的敏感度要高因为这时候是除草的最佳窗口期。第二类是田间机器人也就是在地里跑的那种轮式或履带式除草平台。这类设备通常配备多路摄像头需要模型有较强的泛化能力因为机器人在田垄间移动时视野会不断变化杂草的尺度也从几厘米到几十厘米不等。我在采集数据时特意拍了不同距离的样本就是这个原因。第三类是无人机巡田主要用于大面积草害分布测绘。无人机高度一般在10到30米图像是俯视视角杂草在画面里占比小属于典型的小目标检测问题。这时候数据集中就需要包含高空视角的样本否则模型在无人机画面上会大量漏检。我建这套数据集的初衷就是让一个数据集能同时兼顾这三种场景的基础需求而不仅仅是为某一台设备定制的数据原料。2. 数据采集与标注的核心细节2.1 田间采集的设备选型与拍摄技巧先说说采集设备。我用的主力机型是大疆精灵4 RTK搭配的是自带的2000万像素云台相机。RTK版比普通版贵不少但好处是每张照片自带经纬度和高度信息方便后续做数据地理标记如果要做处方图这些信息可以直接用。手机作为补充设备也很重要。我在地里忙不过来的时候会掏出iPhone 12 Pro Max拍一些近景样本用来补充杂草的细节纹理。手机拍摄时需要注意一个容易忽略的点手机相机的默认白平衡会过度优化绿色导致杂草叶片的颜色偏鲜艳和无人机拍出来的色调有差异。解决办法是拍摄时锁定白平衡或者后期统一做色彩校正。拍摄技巧上有四个关键参数值得记一下拍摄角度无人机镜头垂直向下90度手机保持与地面成45度到60度夹角同时兼顾了俯视和侧视视角拍摄高度无人机固定10米高度手机距目标0.3到1.5米时间段上午9点到11点、下午2点到4点这个时段阳光不是直射阴影干扰小存储格式全部保存为JPEG质量系数90以上尽量不拍RAW格式否则后期处理工作量会大不少2.2 标注工具的选型和标注规范标注工具我用过LabelImg、Labelme和Roboflow最终推荐LabelImg。原因很简单它原生支持YOLO格式的txt标注文件导出省掉了格式转换这一层而且安装是pip install labelimg一键完成不像Labelme还得自己写脚本转格式。但有一个现实问题要注意LabelImg在老版本上是Python 2的现在新版本基于PyQt5跑在Python 3上操作界面有点老派习惯就好。另外它不支持多类别自动补全标注时需要手动输入类别名我在标注2000张图后手都快抽筋了所以建议把常用类别名称复制到剪贴板标注时候直接CtrlV粘贴。标注规范方面我踩过一些坑整理成几条原则只标注草高超过地面3厘米的杂草低于这个高度的芽苗在图像上只有几个像素标注了反而干扰训练杂草叶片相互遮挡严重时只标注可见部分的边缘不要凭经验脑补被遮挡的部分边界模糊的目标比如叶片颜色和土壤颜色接近的宁可标大一圈也不要标小一圈框大一点模型学到的特征是完整的单张图里的杂草数量超过20株时分成两次标注先标大目标再标小目标避免标注遗漏2.3 类别体系设计的经验数据集包含7类常见杂草马唐、狗尾草、反枝苋、藜灰菜、苘麻、苍耳、稗草。这里有个比较关键的思路——类别名的设计要贴近农业习惯不要用拉丁学名。我第一版标注时用了拉丁学名结果下地和农户沟通时大家都不知道我在说啥后来全部改成通用中文名沟通效率一下就上来了。还有一个容易犯的错误是类别粒度划分不当。比如藜和灰菜其实是同一种植物在不同地区的叫法我一开始标成两类导致两类样本的特征几乎一样训练时模型经常混淆。后来合并成一类mAP直接涨了3个点。合并形态相似的物种是提升模型性能最短平快的方法。3. YOLOv5/v6/v7/v8格式适配全流程3.1 数据集目录结构与配置文件的统一制作这四代YOLO虽然结构不同但训练数据格式是同源的都遵循同一个规范一张图像对应一个同名txt文件txt里每行是class x_center y_center width height坐标值全部归一化到0到1之间。目录结构统一做成这样dataset/ ├── images/ │ ├── train/ # 840张 │ ├── val/ # 180张 │ └── test/ # 80张 └── labels/ ├── train/ # 840个txt ├── val/ # 180个txt └── test/ # 80个txt制作data.yaml时四代版本有一个小差异要留意YOLOv5和v6需要指定路径v7和v8用的是相对路径或者基于当前运行目录的路径。我建议直接用绝对路径写死在yaml文件里虽然不够优雅但能避免路径解析问题一旦出现File not found错误排查起来很浪费时间。path: /home/user/yolo_weed_dataset train: images/train val: images/val test: images/test nc: 7 names: [马唐, 狗尾草, 反枝苋, 藜, 苘麻, 苍耳, 稗草]3.2 从采集图像到YOLO标签的批量转换脚本如果你用的是LabelImg导出的VOC格式XML文件需要批量转换成YOLO格式。我用Python写了一个通用脚本核心逻辑就是解析XML里的bounding box坐标然后除以图像宽高做归一化import os import xml.etree.ElementTree as ET def convert_annotation(xml_path, txt_path, class_names): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): cls_name obj.find(name).text if cls_name not in class_names: continue cls_id class_names.index(cls_name) box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) x_center (x1 x2) / 2 / img_w y_center (y1 y2) / 2 / img_h width (x2 - x1) / img_w height (y2 - y1) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) with open(txt_path, w) as f: f.write(\n.join(lines)) class_names [马唐, 狗尾草, 反枝苋, 藜, 苘麻, 苍耳, 稗草] xml_dir path/to/xml txt_dir path/to/labels os.makedirs(txt_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if not xml_file.endswith(.xml): continue basename os.path.splitext(xml_file)[0] convert_annotation( os.path.join(xml_dir, xml_file), os.path.join(txt_dir, basename .txt), class_names ) print(转换完成)这个脚本在XML文件零报错的情况下能跑通但实际使用时我遇到过几个问题一是有些图像在标注后被重新裁剪过宽高和XML里记录的不一致了导致坐标错位。二是XML里有空的目标框比如某个bounding box的xmin等于xmax这种直接跳过就行。三是某些对象类别名和预设不一致脚本里要做容错处理否则会在index查找时报错中断。我还建议转换完成后做一次可视化校验用OpenCV把标注框画在图像上人工抽检20到30张看有没有框线错位的情况。这一步看似多余实际上能省掉训练完后才发现数据集错误的大坑。3.3 四个版本训练命令的差异与统一验证先给一组我实测过的各版本最简启动命令# YOLOv5 python train.py --data weed.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 # YOLOv6 python train.py --data weed.yaml --weights yolov6s.pt --img 640 --batch 16 --epochs 100 # YOLOv7 python train.py --data weed.yaml --weights yolov7.pt --img 640 --batch 16 --epochs 100 # YOLOv8 yolo detect train dataweed.yaml modelyolov8s.pt imgsz640 batch16 epochs100表面上看命令差不多实际有个细节很多人不注意YOLOv5和v7的默认anchors是从COCO数据集聚类出来的跟杂草这种小目标为主的数据集分布差异很大。建议在训练前关闭自动锚框或者让模型重新聚类具体是在yaml配置里设置anchors为空列表模型会自动通过k-means重新计算。YOLOv8的anchor-free设计在这点上省心不少默认配置就能直接跑。batch size的设置也要结合显存来。我在一块RTX 309024G显存上batch调到16比较稳如果强行调到32训练速度反而因为显存溢出时的换页操作慢下来。显存8G的用户建议batch设4到8之间优先保证训练的稳定性。4. 训练过程中的参数调优与关键决策4.1 预训练权重的选择策略四代YOLO都提供了不同大小的预训练权重从n/s/m/l/x往上体积和精度递增。我的建议是在杂草数据集这种中小规模样本1100张上选择s或m版本就够了不用上l或x。原理很简单迁移学习的本质是让模型在大数据集上学到底层特征边缘、纹理、形状然后在小数据集上微调高层语义。底座越大的模型参数量越多微调时越容易在小数据集上过拟合。我实测过yolov5s和yolov5l在同样100个epoch下mAP50差距不到1%但推理速度差了近一倍。所以除非你的部署设备根本不在乎速度否则s版本是性价比之王。如果你用的是YOLOv8官方推荐的预训练权重路径是Ultralytics在GitHub上发布的release下载时要留意版本号2.x和8.x权重的数据集格式在某些细节上有差异虽然官方做了兼容但最好保持一致省心。4.2 训练轮数与早停策略的实测经验我的数据集中1100张图分成840训练、180验证、80测试。在这个规模下最佳训练轮数大概在100到150之间。我试过几个轮数配置结果如下训练轮数mAP50mAP50-95备注5072.4%45.1%明显欠拟合10084.2%56.8%较优继续训练收益减小15085.1%57.6%基本持平20084.8%57.3%轻微过拟合从我自己的实验结果看100到120轮是比较合理的区间。如果资源紧张为了赶进度只跑50轮模型会明显欠拟合不建议这么做。YOLOv5和v8都支持早停也就是Early Stopping可以设置patience参数比如连续20个epoch验证集没有提升就提前终止。我实测下来这个机制在小数据集上偶尔会误判验证集mAP在前80轮波动很大第81轮才稳定上升结果被早停机制在第65轮就腰斩了。稳妥的做法是把patience设大一点YOLOv5设成100YOLOv8直接用默认的就可以。4.3 数据增强策略与过拟合的对抗1100张图不算多不加增强很容易过拟合。我在配置里开了以下几种增强实测效果都挺明显Mosaic增强把4张图拼成一张变相扩大batch内的目标多样性也能让小目标被更多尺度看到HSV扰动色相、饱和度、明度各随机变化模拟不同天气和光照随机翻转但要注意只能水平翻转垂直翻转会让杂草变成倒立的违和状态模型学的特征就不对了随机仿射变换包括旋转、缩放和平移不过增强不要开过头。我试过把旋转角度设成45度结果模型对正常的直立杂草反而不太敏感了。比较稳妥的旋转范围是正负15度这个区间能模拟田间无人机轻微倾斜的状态但又不至于破坏杂草的形态先验。5. 常见训练问题与排查实录5.1 标注内容错位与标签文件丢失问题训练过程中如果突然报错提示某个标签文件不存在或者某个txt文件是空的通常有两个原因一是原始标注时就有漏标的目标二是在数据集划分时某个图像文件复制到了train目录但对应的txt标签文件没有同步复制过去。排查方法是写一个小脚本遍历images目录里的所有jpg文件检查同名txt是否存在于labels目录find dataset/images/train -name *.jpg | while read img; do labeldataset/labels/train/$(basename ${img%.jpg}).txt if [ ! -f $label ]; then echo 缺失标签: $img fi done缺失的标签我遇到过三次原因分别是手工整理时误删除、Windows和Linux之间文件名大小写不一致、以及网盘同步时漏掉部分小文件。所以每次切换环境后我都习惯先跑一遍这个脚本再开始训练。5.2 验证集mAP很高但实际使用时效果差的真相这是最让人头疼的情况训练时看到验证集mAP50到85%以上高高兴兴把权重部署到实地设备上结果在田间一测识别率惨不忍睹。复盘后我发现核心原因是数据集划分时没有按地块划分。我的图像里有黑龙江和山东两个来源每个来源的土壤颜色、光照条件、杂草群落都不同。如果训练集中两个地块的样本都有验证集也恰好两个地块的都有模型其实是背题背出来的高分——它对具体的地块特征过拟合了。解决方案是按地块划分让训练集只包含黑龙江的样本验证集和测试集只包含山东的样本这样验证分数反映的是模型的泛化能力而不是记忆能力。修改划分后mAP50虽然掉到了76%左右但实际田间表现却涨了不少这个分数才是真实的。5.3 显存溢出与训练崩溃的应急处理训练时显存溢出是家常便饭尤其是batch size没根据显卡结构调整的情况。报错信息通常是CUDA out of memory这时候不用慌按优先级依次做三件事把batch size减半比如从16降到8把图像分辨率从640降到512代价是mAP可能会掉1到2个点尝试开启混合精度训练AMPYOLOv5默认就是开启的v6需要显式设置另外有一个容易被忽视的坑训练过程中如果显示器还接着其他程序比如浏览器开了很多标签页显存会被占掉一部分。这时候即使batch设置的合理也可能OOM报错。建议训练期间关掉不必要的图形程序给模型腾出显存。5.4 检测框重叠与误检的后处理优化训练结束后推理时经常会遇到同一个目标被多个检测框重复框住或者背景区域被误判为杂草的情况。前者是NMS阈值设置不合适后者是置信度阈值太低。我在实际部署中会把置信度阈值从默认的0.25提到0.45左右NMS的IoU阈值保持0.5不变。这样误检率能下降一半以上虽然会有少量真目标漏掉但对于除草设备来说漏掉一株杂草的代价远小于把作物当杂草除掉。还有一个高阶技巧值得一试就是针对杂草目标普遍较小的问题在推理阶段做TTA测试时增强YOLOv5里直接加--augment参数即可推理速度慢一点但小目标召回率能涨5个点左右。如果部署设备性能允许这个参数值得开。6. 后续扩展与迁移实战建议这套数据集目前是7个类别后面如果要做其他作物或者更多草种的检测不需要重新采集。我打算做扩展的时候验证了一个可行思路以现有数据作为基础用半自动标注的方式去辅助标注新数据。具体操作是先用现有模型对新采集的图像做预测得到一个初版标注框然后导入LabelImg做人工修正。这种human-in-the-loop的方式能把标注效率提升至少3倍而且新数据会不断扩充训练集形成一个良性循环。实测下来从1100张扩展到2200张后整体的mAP50又涨了3个点。部署层面如果要把训练好的模型导出成ONNX或者OpenVINO格式YOLOv5和v8的官方仓库都提供了导出脚本v5是export.pyv8直接在CLI里yolo export模型就能搞定。导出时需要注意Opset版本的兼容性我之前导出成ONNX后导入OpenVINO时因为opset版本过高直接报错后来锁定到opset 12才顺利转换。这篇从数据采集到训练部署的全流程就梳理到这。我做的数据集目前放在GitHub仓库里需要的可以评论区留言看到会发链接。如果你在复现过程中遇到什么奇怪的问题也欢迎回来交流田间数据这种东西多数坑都是踩过才记得住的。本文还有配套的精品资源点击获取
返回列表