资讯动态

多版本YOLO农作物病虫害检测数据集构建与训练验证实战

发布时间:2026/10/19 10:58:20 来源:尧图企业网站定制
1. 项目背景与整体思路拆解1.1 项目起点为什么盯上农作物病虫害检测做农作物病虫害检测这件事最初其实源于一个很实际的农业需求。某位做农业植保的朋友找到我说他们那边大棚蔬菜和果园的巡检基本靠人工老师傅一天最多看几十亩地眼神稍微累一点就会漏掉早期病斑。他们想让我帮忙验证一下用目标检测模型能不能快速圈出叶片上的病斑和虫害区域至少先把“有没有病”“大概在哪个位置”这个问题解决掉。听完我就知道这事儿的核心根本不是花哨的算法而是数据能不能撑起来以及模型能不能在真实田间条件下跑稳。所以我当时的定位非常清晰不搞多复杂的网络结构就是用目标检测里的主流YOLO系列把数据、训练、验证这套流程完整跑通给后续落地打底。为什么选择YOLO系列而不是其他检测框架一个原因是社区生态太成熟了从数据标注到训练脚本再到部署导出整条链路都有现成轮子另一个原因是YOLO系列在速度和精度之间平衡得很好农田场景下往往需要边缘盒子或者嵌入式设备实时推理不能像服务器端两阶段检测器那样追求极致精度却拖垮帧率。而且YOLO版本迭代很快把v5、v8、v9放在一起对比可以直观看到不同代际在同一个数据集上的表现差异。1.2 核心需求拆解数据、模型、验证三块缺一不可把标题拆开看“数据集分享”和“多版本YOLO模型训练验证”其实是两个关联但独立的任务。数据集部分要解决的是数量够不够、标注准不准、场景多样性强不强。模型训练验证部分要解决的是不同版本YOLO在这个数据集上的精度、召回、推理速度到底差多少以及实际田间环境下谁更靠谱。我给自己定了三个阶段性目标整理出一份结构清晰、类别均衡的病虫害检测数据集用至少三个版本的YOLO完成训练记录完整实验参数用一套统一的评估指标对比模型挑出最适合落地的那一版。说句实在话很多人一上来就直接去GitHub找现成模型套数据训练跑完发现mAP挺高拿到现场就翻车。问题恰恰出在“数据集”和“真实场景”的断层上。所以我从一开始就坚持两个原则第一数据必须尽量贴近真实田间拍摄条件不要全是高清、正中、背景干净的摆拍图第二验证集里要故意放进去一些光照变化、叶片重叠、远距离小目标的难例这样模型好不好一眼就能看出来。2. 数据集构建与预处理方案2.1 数据来源与筛选策略这次整理的数据集主要以公开渠道可获取的农作物病虫害图像为基础覆盖了水稻、小麦、玉米和柑橘四类作物共整理出有效图像约12000张。图像来源有几个渠道一部分来自大学实验室公开的植物病害图像库一部分来自农业技术平台发布的田间巡视图还有一部分是自己用手机在大棚和果园里实拍的补充样本。实拍样本量虽然不大但价值很高因为手机拍摄的角度、光照、虚化程度跟实验室标准化拍摄差异很大能让模型对真实场景更鲁棒。筛选阶段我把明显有问题的图像直接剔掉了。什么叫明显有问题比如分辨率和尺寸严重过小、图像重复、标签与图像内容明显不符、病斑区域被过度遮挡之类的。另外我还做了个去重操作用感知哈希把近乎相同的图像挑出来只保留一张。这一步很多人会忽略但重复图像一旦进了训练集会让模型对某些特定背景过拟合测试分数虚高现场实测却露馅。筛选完后的类别分布是动态调整过的。最初各类别数量差别很大比如稻瘟病图像特别多而柑橘溃疡病图像偏少。在训练之前我对数量偏少的类别做了针对性补充采集并用后续的增强策略硬拉了回来。最终九类目标的分布大致控制在每类1200到1500张之间整体相对均衡。2.2 标注规范与细节处理标注环节直接决定模型上限这一步偷懒后面全白干。我用的标注工具是常见的labelImg类图形界面工具输出YOLO格式的txt文件。标注规范上我给自己定了几条硬性规则病斑边界框必须紧贴病斑边缘不要刻意扩大框住整个叶片一张叶片上如果有多处独立病斑分别标注为多个目标被严重遮挡且无法判断类型的病斑直接忽略不硬标边界框面积小于整图面积0.5%的微小目标训练初期先不纳入后面专门做难例挖掘。这里重点说一下边界框的判定。很多人标注更愿意框大一点觉得“反正是目标检测框差不多就行”其实这是个坑。框大了之后模型学到的位置信息就是模糊的尤其是对贴在一起的多个病斑大框会把相邻背景全包进去导致类别区分困难。我后期是回到原图上对比着标注确保框的边沿尽量压着病斑变色区域的边界。标注完成后我做了两轮检查。第一轮由另外的人随机抽检10%的数据标注不一致的地方统一讨论后修正第二轮我看着类别分布把那些容易混淆的比如稻瘟病和稻胡麻叶枯病单独抽出来逐张核验。整个过程很费时间但数据质量是数据集最核心的竞争力这笔时间花得值。2.3 数据增强策略与数据集划分数据增强我选择了比较克制但贴近实际场景的组合。随机水平翻转、随机缩放、亮度对比度调节这三项是必开的。病害图像在田间的核心变量是光照强度和拍摄角度所以亮度扰动范围我调到了正负25%色相扰动给了正负5度。没有用太激进的随机裁剪因为病虫害目标相对集中过度裁剪反而会把病斑截成碎片让模型学出错误特征。增强后的等效训练样本量大约是原始数据的3倍但有一个细节必须提醒增强操作应该在训练过程中在线完成而不是预先离线生成大批量文件。离线增强会大幅度增加磁盘占用而且容易在数据打乱时造成同源样本“串通”影响验证集评估的真实性。我用的方案是在训练配置里直接挂载在线增强参数每个epoch看到的图像都不完全一样训练更充分。数据集划分上我按8:1:1切分训练集、验证集和测试集。但这里有个关键操作划分前先按图像来源的拍摄时段和地块分组同一个时间批次的图像尽量放进同一个子集不做随机散切。这样做是为了避免相似背景的重复图像同时出现在训练集和测试集里导致指标虚高。测试集最终单独锁起来训练过程中只看验证集指标测试集只在全部模型跑完后统一评估一次。3. 多版本YOLO模型训练实战3.1 训练环境与通用配置说明训练机器用的是单张消费级显卡显存24GB放在个人工作站上跑的。这类规模的数据集加YOLO系模型单卡完全够用没必要为了写论文去堆多卡。操作系统是Ubuntu深度学习框架按各模型官方要求装了对应版本。这里要特别提醒一句YOLOv5和YOLOv8、YOLOv9对PyTorch版本的要求并不完全一致尤其是低版本v5对算子支持比较保守高版本依赖新的CUDA算子。我直接用虚拟环境各自建了一个独立环境省的互相污染。通用训练参数我做了统一约定方便公平对比输入分辨率640x640训练轮数120轮Batch size32显存不够就调小梯度累计优化器SGD初始学习率0.01余弦退火损失函数各模型自带默认配置未做修改数据加载器线程数8有一点必须说清楚Batch size只要不是极端小对最终精度影响没那么玄学。真正影响公平性的是输入分辨率、训练轮数、优化器策略这几个大项。我把这些大项都锁定了才能让版本差异真正体现在模型结构上。3.2 YOLOv5的训练流程与参数细节YOLOv5虽然已经不算新但它胜在工程化做得好、部署生态稳所以我把它作为基准版本。训练前需要准备数据配置文件内容大致是类别列表和训练验证集的路径。给个精简示例# crop_disease.yaml train: ./datasets/crop_disease/images/train val: ./datasets/crop_disease/images/val test: ./datasets/crop_disease/images/test nc: 9 names: [ rice_blast, rice_brown_spot, wheat_rust, wheat_fusarium_head_blight, corn_leaf_blight, corn_southern_rust, citrus_canker, citrus_greening, citrus_anthracnose ]训练命令就是官方标准方式python train.py \ --data crop_disease.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 32 \ --epochs 120 \ --device 0 \ --workers 8 \ --project runs/train_v5s这里我想展开讲讲训练过程中观察到的现象。v5s在前期loss下降很快基本到第20轮的时候验证集mAP0.5已经到0.7以上。但是到了第60轮之后loss曲线出现了小幅震荡这是数据中相似背景样本较多导致的正常现象并不一定是过拟合。我观察它的验证集指标在80轮后基本平缓所以后续几个版本统一都用120轮既保证充分收敛又不至于让v5s因为训练过长反而起波动。3.3 YOLOv8与YOLOv9的训练差异记录YOLOv8的训练流程相比v5更简单命令行入口统一了。默认的优化器策略已经改成了AdamW偏多我为了对比公平还是手动切回了SGD。在训练过程中v8n作为轻量版收敛得很快显存占用非常友好batch 32跑起来毫无压力。v8s稍重一些但显存占用也就多了1GB出头。实际感受下来v8n的训练过程稳定性不如v8s在60轮左右验证集mAP略有平台期但v8s连续稳步上升到了最后一轮。YOLOv9的训练用起来稍微别扭一点主要在于它的模型重参数化和辅助分支设计日志输出里会多几个loss项光看loss曲线无法直接判断收敛状态。我个人的经验是遇到这种多分支结构别盯着总loss看重点看验证集的mAP曲线那个反而更直接。v9t在显存占用上介于n和s之间训练速度比v8s快大概15%但精度上跟v8s互有胜负。多版本训练的价值就在这里你以为新版一定全面碾压旧版但实际数据会告诉你不是这么回事。v9t在部分小目标类别上确实更强但在光照极端的样本上反而误检更多。模型不是越新越好是要看任务属性的。4. 模型评估与实测验证结果4.1 评估指标与多版本对比评估指标我选了三项最核心的mAP0.5、mAP0.5:0.95、以及在测试集上的单张平均推理耗时。mAP0.5是目标检测常用的宽松指标主要看能不能框出目标mAP0.5:0.95更严格对框的定位精度要求高能体现模型在边界框质量上的差异。推理耗时是在同一张显卡上、相同batch输入条件下测的。各版本在固定测试集上的结果如下模型版本参数量输入尺寸mAP0.5mAP0.5:0.95单张推理耗时(ms)权重体积YOLOv5s7.2M6400.9120.6878.114.1MBYOLOv8n3.2M6400.9180.7035.95.9MBYOLOv8s11.2M6400.9340.7359.322.5MBYOLOv9t4.8M6400.9210.7127.610.8MB从这个表能读出几个信息YOLOv8n能用不到一半的参数量追平v5s的精度说明结构确实改进了但真要追求最高精度还是得靠v8s这种正常规模模型。v9t处在两者之间算是个不错的折中。不过表格只反映统计结果实际场景里的表现还要看图。4.2 典型场景验证光照变化与小目标检测我在测试集里特意挑了三张典型图像做人工核验分别是背光环境下柑橘叶片上的溃疡病斑、低分辨率手机拍摄的水稻叶片、杂草背景中特别小的玉米锈病孢子堆。背光那张图v5s把叶片阴影区域误检成了病斑v8n和v9t也各有一次误检只有v8s和v9t中的一次正确框出了全部六个病斑且没有多余框。低分辨率水稻图上v5s漏检了一个位于叶缘的病斑其余三版都检出来了。而玉米锈病孢子堆这种特别小的目标v5s基本只能检出50%左右v8s明显好一些检出七成左右。这说明越是小目标越依赖感受野和特征提取能力的升级旧版本在结构上的短板是实打实的。综合这些实测我最终倾向把YOLOv8s作为推荐方案。精度最高、误检最少代价是推理速度慢一些但对农业巡检的实时性要求来说单张9毫秒在边缘设备上也就二三十帧的水平完全够用。v8n适合部署在算力很弱的单片机上精度损失可以接受。4.3 错误分析哪类目标最容易翻车评估模型不能只看总指标还必须拆类别看。我把v8s的逐类AP统计拉了一下发现稻胡麻叶枯病的AP只有0.85比平均水平低一截而稻瘟病达到0.95。原因不复杂稻胡麻叶枯病和稻瘟病在颜色、纹理上很接近而且病斑尺寸偏小、形态多变连人眼判读都很容易搞混。这属于典型的数据瓶颈问题不是单纯换模型就能解决的。针对这个问题我做了两个方向的调整一是把这两类的训练图像按更多样化的角度重新筛查剔除特征不明确的模糊样本二是尝试用了简单的自动难例挖掘把验证集里预测置信度低但确实是真值的图挑出来补充进训练集重复训练一轮。调整后稻胡麻叶枯病的AP提升到了0.88左右增幅有限但方向是对的。想继续提高就得从数据源头上想办法比如引入多光谱图像辅助判别那是另一个课题了。5. 常见问题与排查技巧实录5.1 损失值不下降或者训练震荡遇到loss不下降先别怪模型按下面的顺序排查。第一看学习率SGD配0.01时如果数据量小或者Batch size偏小很容易震荡这时候可以把学习率降到0.005或0.002重试。第二看数据标注有没有问题某一类目标框尺寸分布极端比如全是超大框或全是极小框会让回归分支不知所措。第三看归一化方式YOLO格式的标注坐标必须归一化到0-1区间如果谁手工改数据时写成了像素坐标训练一开始loss就会非常离谱。我自己训练过程中遇到过一次奇怪现象前20轮loss正常下降到第30轮突然跳高然后又慢慢降回来。排查后发现是某个批次里混入了半小时前刚新增的标注图像而且这批图像的标注风格跟旧数据不一致。所以说标注中途最好不要边标注边训练要么等全部标注完再开始要么把新增数据单独作为增量集处理不要直接混进随机批次。5.2 验证集mAP很高但现场实测很差这个问题实在太典型了。模型在测试集上mAP能到0.9以上拿手机去大棚里一拍就拉胯检测框乱跳置信度飘忽。核心原因是训练数据与实测场景的域差异。大棚里是逆光加遮阳网纹理叶子背面反光这些特征在公开数据集里几乎没有。如果注定要在某个特定环境部署最好的办法是实地采集几百张那个环境的图像做轻量微调。另外一个容易被忽略的问题是输入图像尺寸和比例。手机上拍的照片大多是3:4或16:9模型输入是640x640方形。YOLO内部会自动做等比例缩放加灰边填充如果部署代码里没有正确处理缩放和填充方式边界框映射就会出问题。很多现场翻车案例并不是模型不行是预处理代码有问题。5.3 环境依赖与版本兼容性坑训练YOLOv5、v8、v9的过程中环境是最大的隐形杀手。v8和v9相对友好v5遇到过算子在较新PyTorch版本下执行出错的情况。我的建议是直接按官方requirements约定版本装不追新。如果显卡驱动只支持到某个CUDA版本那就用对应的PyTorch轮子文件安装别图省事先装最新版后面对不上再返工特别痛苦。还有一个老生常谈但值得再说一遍的点数据集路径不要用中文名不要放在带有空格的目录下模型权重文件名不要带特殊字符。这种问题遇到时完全没有报错提示就是读不到数据查起来极其烧时间。我因为路径里多了一个空格卡了整整一个晚上才找到原因。注意训练前先跑一个极小的批次比如10张图、2轮epoch做连通性测试。能跑通再上全量数据否则调试一次成本极高。5.4 数据集分享的格式与说明文档建议既然标题里敢写“数据集分享”那数据集发布时的格式规范一定要做好。图像和标注文件的组织方式我建议直接设计成YOLO训练可用的目录结构让拿到数据的人解压之后就能训练不需要另写转换脚本。目录结构大概这样crop_disease/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── crop_disease.yaml ├── README.md └── class_names.txt同时附一个README把每类目标的定义、拍摄环境、标注规范、划分逻辑以及已知局限写清楚。很多分享者的README写得非常简陋别人拿了数据根本不知道里面的坑在哪里。比如哪两类容易混淆、哪些图像有遮挡、采集设备差异有多大这些信息对二次使用和模型调优比图像本身还重要。为了方便大家直接看效果我还在README里放了一张每个类别的样例网格图一行一类每类放八九张代表图像。这样做的好处是别人一眼就能看出类别间差异减少后续标注和使用上的认知误差。6. 实操心得与后续扩展建议训练整套流程走完最大的收获不是某一个模型的指标而是建立了一套相对可靠的数据到验证的闭环。以后再接到类似的检测需求比如农田害虫检测、作物病害分级我只需要换数据集和类别配置剩下的流程完全复用评估套路也现成。这就是工程化积累的价值。如果后续想继续深挖有几个方向我觉得很有价值。一是把检测和图像分类结合检测框定位后再用一个轻量的分类网络判断病害严重程度等级从“有没有病”升级到“病多重”。二是引入多尺度训练在输入尺寸上做随机调整比如640/672/704随机切换这个方法在同类任务里被反复验证能提升小目标精度。三是数据层面收集一些带复杂背景的难例比如虫子趴在泥土上、病斑被露水反光干扰这些才是真正拉开模型差距的样本。最后说一个我在评估时的小技巧不要只保留最后的权重文件每个epoch结束后的权重最好都留几份尤其是验证集mAP峰值对应的那一个epoch。YOLO类的训练往往在最后阶段会出现验证集指标轻微下降的情况用峰值权重做测试往往能再白捡零点几个点的mAP。我自己最终确定的模型就是用倒数第二次epoch的权重而不是最后一轮的。这个细节听着小实际测试下来收益是实打实的。数据、模型、验证这三块都扎扎实实地做好农作物病虫害检测的落地就没有想象中那么玄乎。希望这份资料和实践记录能帮到正在做相似事情的人少走几步弯路。

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

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

免费获取报价 →
↑