简介:这是一份面向精准农业与计算机视觉研究者的YOLOv11应用实践文档,系统讲解多作物叶片分析与病害识别的完整技术链路,适合目标检测初学者以及想要将YOLO落地到农业场景的开发者。文档共26页,单个PDF文件,压缩包大小约1.94MB,支持目录章节跳转与阅读器左侧大纲快速定位,内容排版完整清晰。全文围绕精准农业背景、YOLOv11网络结构与损失函数、多作物叶片数据集构建与预处理、模型训练优化、病害识别实现流程及规模化种植区、温室蔬菜、果园果树等实际落地案例展开,并进一步讨论了数据、模型性能与工程应用中的常见挑战及未来发展方向。目前已有62人学习下载,可作为从理论到实践的入门参考,帮助读者建立一条从数据准备、模型训练到农田部署的完整认知路径。
1. 从“人工翻叶”到一次前向传播:YOLOv11与多作物病害识别的落地逻辑
在一线跑过农业项目的都知道,传统病害识别基本靠农技员下田,一片叶子一片叶子翻,一天看几百株算快的,遇到大面积爆发基本靠猜。这套打法在小农户时代还能撑,放到大规模种植场景就完全跟不上节奏。YOLOv11这类单阶段目标检测算法,把病害识别从“人工巡检”推进到“实时扫描”——模型对图像只做一次前向传播,就能同时输出多个叶片区域的类别和边界框,速度上远非传统滑动窗口方案能比。这份精准农业落地方档从YOLOv11网络结构、多作物叶片数据集构建与预处理,到模型训练、病害识别全流程和实际落地案例都做了展开,本文直接拆出能复现的参数、代码和踩坑记录,给准备上手目标检测做农业项目的读者省点时间。
2. YOLOv11结构拆解:Backbone、Neck、Head与四种损失机制
2.1 骨干网络与颈部:深度可分离卷积 + FPN/PAN的组合为什么更省
YOLOv11的骨干网络沿用轻量化思路,核心是把深度可分离卷积和残差块结合。深度可分离卷积把标准卷积拆成逐通道卷积和逐点卷积两步,参数量和计算量都大幅下降,这对田间部署非常关键——农业场景里很多设备是嵌入式或者低算力边缘盒子,模型太胖根本跑不动。残差块解决的是网络加深后的梯度消失问题,让骨干网络能堆得更深,提取到的叶片纹理、病斑边界这些特征更丰富。
文档给了一段DepthwiseSeparableConv的PyTorch实现:
import torch import torch.nn as nn class DepthwiseSeparableConv(nn.Module): def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1): super(DepthwiseSeparableConv, self).__init__() # 逐通道卷积:每个通道独立做卷积,groups=in_channels 是关键 self.depthwise = nn.Conv2d( in_channels, in_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=in_channels ) # 逐点卷积:1x1卷积做通道混合 self.pointwise = nn.Conv2d(in_channels, out_channels, kernel_size=1) def forward(self, x): x = self.depthwise(x) x = self.pointwise(x) return x逻辑上,depthwise卷积先对每个输入通道独立做空间卷积,只提取单通道内的空间特征;pointwise卷积再用1x1卷积把各通道信息融合起来。参数对比很直观:标准卷积的参数量是in_channels × out_channels × kernel_size × kernel_size,而深度可分离卷积是in_channels × kernel_size × kernel_size + in_channels × out_channels,通道数越大省得越多。实际用的时候,groups=in_channels这个参数容易被漏掉,漏了就不是深度可分离卷积,而是普通卷积,参数量直接打回原形。
颈部网络这块,YOLOv11采用的是FPN与PAN结合的结构。FPN负责把深层语义特征和浅层空间特征融合,解决多尺度检测问题——小麦叶片上的条锈病斑可能只有几十个像素,而整片叶子的枯死区域可能占据图像三分之一,这两个尺度如果只靠最后一层特征图,小目标基本就丢了。PAN则是在FPN自顶向下的路径之外,再加一条自底向上的路径,让浅层位置信息也能传到深层,两者配合下来,不同尺寸的检测头各司其职。实际调参时,颈部层的特征融合维度一般不用动,除非你换了自己的骨干网络,那时候才需要检查FPN的通道数是否匹配。
2.2 损失函数与初始化:CIoU、二元交叉熵和预训练权重的配合
损失函数决定了模型“往哪个方向学”。YOLOv11的损失由三部分组成:边界框损失、置信度损失和类别损失。
边界框损失用的是CIoU,它在IoU的基础上多考虑了中心点距离和宽高比。单纯用IoU,当预测框和真实框完全不重叠时梯度为0,模型不会更新;CIoU加了中心点距离惩罚项,即使两个框没有交集,梯度仍然存在,训练早期不会卡死。文档里的CIoU实现要点如下:
import torch def ciou_loss(pred_boxes, target_boxes): # 计算交集面积 x1 = torch.max(pred_boxes[:, 0], target_boxes[:, 0]) y1 = torch.max(pred_boxes[:, 1], target_boxes[:, 1]) x2 = torch.min(pred_boxes[:, 2], target_boxes[:, 2]) y2 = torch.min(pred_boxes[:, 3], target_boxes[:, 3]) intersection = torch.clamp(x2 - x1, min=0) * torch.clamp(y2 - y1, min=0) pred_area = (pred_boxes[:, 2] - pred_boxes[:, 0]) * (pred_boxes[:, 3] - pred_boxes[:, 1]) target_area = (target_boxes[:, 2] - target_boxes[:, 0]) * (target_boxes[:, 3] - target_boxes[:, 1]) union = pred_area + target_area - intersection iou = intersection / union # 最小外接矩形与中心点距离 c_x1 = torch.min(pred_boxes[:, 0], target_boxes[:, 0]) c_y1 = torch.min(pred_boxes[:, 1], target_boxes[:, 1]) c_x2 = torch.max(pred_boxes[:, 2], target_boxes[:, 2]) c_y2 = torch.max(pred_boxes[:, 3], target_boxes[:, 3]) c2 = (c_x2 - c_x1) ** 2 + (c_y2 - c_y1) ** 2 center_pred = torch.stack( ((pred_boxes[:, 0] + pred_boxes[:, 2]) / 2, (pred_boxes[:, 1] + pred_boxes[:, 3]) / 2), dim=1 ) center_target = torch.stack( ((target_boxes[:, 0] + target_boxes[:, 2]) / 2, (target_boxes[:, 1] + target_boxes[:, 3]) / 2), dim=1 ) d2 = torch.sum((center_pred - center_target) ** 2, dim=1) # 宽高比惩罚项 v = (4 / (torch.pi ** 2)) * torch.pow( torch.atan((target_boxes[:, 2] - target_boxes[:, 0]) / (target_boxes[:, 3] - target_boxes[:, 1])) - torch.atan((pred_boxes[:, 2] - pred_boxes[:, 0]) / (pred_boxes[:, 3] - pred_boxes[:, 1])), 2 ) alpha = v / (1 - iou + v) ciou = iou - (d2 / c2 + alpha * v) return (1 - ciou).mean()几个容易出错的地方:计算交集面积前要做torch.clamp,否则预测框在图像外面时会出现负数坐标,导致交集面积变成负值;宽高比的torch.atan在宽高为0时会返回0而不是nan,所以标注框坐标里宽度或高度为0的异常框不会直接导致crash,但会污染梯度,建议在数据加载阶段就把这类标注过滤掉。
置信度损失和类别损失都采用二元交叉熵。目标检测天然存在正负样本极度不平衡的问题——一张大田照片里,叶片病害区域可能只有几十个框,但背景像素点有几十万个。BCE对每个位置独立计算损失,配合YOLOv11中的正负样本分配策略,模型能优先学习那些真正包含目标的区域,而不是被背景带偏。
最后说初始化。文档里专门提到训练前用预训练模型做初始化,这是农业目标检测项目里性价比最高的一步。预训练权重在大规模通用数据集上学到的是通用视觉特征,比如边缘、纹理、颜色渐变,这些特征在叶片图像上同样适用。直接从头训一个YOLOv11,收敛速度慢不说,数据量不够时还容易过拟合。实际项目里,我一般会下载官方预训练权重,然后在自己的叶片数据集上微调,训练轮数可以从100轮直接砍到30轮左右。
3. 多作物叶片数据集:从实拍采集、标注到清洗增强的完整链路
3.1 数据来源与多样性设计:作物、病害、生长阶段的三维覆盖
数据集决定模型性能的上限,这句话在农业场景里尤其真实。YOLOv11的骨干网络再能提特征,如果训练数据里只有单一光照、单一品种、单一病害类型的样本,模型一到真实田间就露馅。构建数据集时,需要考虑三个维度的覆盖:作物种类、病害类型、生长阶段。
作物种类方面,小麦、水稻、玉米、番茄、葡萄这些主栽作物的叶片形态差异极大。小麦叶片窄长且平行叶脉明显,番茄叶片是复叶结构,葡萄叶片掌状深裂,模型需要把这些底层形态差异学到,才能在推理时准确判断“这片叶子属于哪类作物、有没有病”。病害类型上,真菌病害多表现为霉斑或粉状物,细菌病害更常见水渍状斑点,病毒病害往往伴随花叶或黄化,不同类型在颜色和纹理上的特征完全不同。生长阶段也很关键,幼苗期的叶片颜色偏浅、叶面积小,成熟期的叶片可能已经有自然老化斑点,这些都会干扰模型判断,如果数据里只有某一生长阶段的样本,模型在其他阶段的表现会大打折扣。
| 数据来源 | 优点 | 注意点 |
|---|---|---|
| 田间实拍 | 最贴近实际工况,背景真实 | 光照、角度、距离需要控制 |
| 农业科研机构 | 标注专业,病害类型全 | 获取周期长,需要合作对接 |
| 公开数据集(PlantVillage等) | 即拿即用,类别丰富 | 背景单一,泛化性差,需补充实拍数据 |
我个人的习惯是公开数据集打底,实拍数据做增量。公开数据集提供的干净背景、标准化光照样本可以帮助模型快速收敛,实拍数据则用来提升模型在真实田间的鲁棒性。两者比例建议在1:1到1:2之间,全用公开数据训出来的模型,拿到大田里通常会有明显的掉点。
3.2 标注规范与质量控制:从标注原则到处理细节
标注工具首推LabelImg,Python环境直接pip install labelimg就能启动。RectLabel是macOS平台的替代品,操作逻辑类似。选工具不是重点,标注规范才是决定数据集质量的核心。
病害识别场景里,标注有几个具体原则。第一,边界框尽量紧贴病害区域,宁可稍微往里收一点,也不要框到太多健康组织,否则模型学到的是“健康叶片+病斑”的混合特征,定位精度上不去。第二,不规则形状的病斑用最小外接矩形,不要试图用旋转框,YOLO系列的输出是水平矩形框,旋转框标注反而增加复杂度。第三,一片叶子上同时有真菌病斑和细菌病斑时,必须分开标注成两个框、两个类别,合并标注会让模型无法区分不同病害的边界。
质量控制方面,双人标注是最有效的方案。两个人各自独立标同一批图,对比结果,对不一致的框逐一定夺。抽样检查的节奏一般是每标注完200张抽10张复检,发现问题及时纠正。还有一个容易被忽视的点:标注人员对病害的认知水平直接影响标注质量,项目启动前要把不同病害的视觉特征做成图例手册,新人上手前先过一遍,否则“看起来都差不多”的病害类别会越标越乱。
3.3 图像清洗与增强:模糊检测、去重与数据划分
收上来的原始图像不是都能直接进训练集。田间拍摄经常有抖动模糊、重复连拍、镜头脏污这类问题,需要先做一轮清洗。
模糊检测用拉普拉斯方差就行,文档里的实现很简洁:
import cv2 def is_blurry(image, threshold=100): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Laplacian 算子做二阶导,方差越小说明图像越“平”,即越模糊 fm = cv2.Laplacian(gray, cv2.CV_64F).var() return fm < thresholdthreshold=100是个经验值,实际使用时可以抽十几张人工确认为“模糊”和“清晰”的图,计算它们的拉普拉斯方差,取一个分界值。室内标准光照下阈值可以放到150,田间强光照下正常清晰图像的方差会偏低,需要适当下调。
去重方面可以用感知哈希算法,原理是把图像缩小到固定尺寸、转灰度、计算哈希指纹,两张图像哈希值差异小于阈值就认为是重复图。这个步骤在无人机航拍场景里非常重要——无人机在同一区域连续拍摄几十张,大量重叠图像如果不处理,会让模型在某个特定角度上严重过拟合。
清洗完之后做增强。几何变换里的随机旋转(-30°到30°)、水平翻转、缩放都是基础操作,注意旋转后空出的区域要填充像素值,用固定灰度填充即可,不要用黑色,黑色边缘会让模型学到不存在的边界特征。颜色变换里亮度因子在0.5到1.5之间随机调整,可以模拟早晨逆光和正午强光两种极端天气。噪声添加一般是高斯噪声,均值0、标准差10左右,模拟手机摄像头在弱光环境下的成像噪声。
最后是数据划分:训练集占70%到80%,验证集和测试集各占10%到15%。划分时必须保持各类别的样本比例和原始数据集一致,不能简单随机切分。比如番茄早疫病样本只有200张,如果随机划分时全部进了训练集,测试集里这个类别就等于没有,验证结果就失真了。用train_test_split加stratify=y_labels参数可以避免这个问题。
4. YOLOv11训练与优化:环境配置、参数调节与常见问题排查
4.1 环境搭建与配置文件解读:从YAML入手了解入口
硬件方面,文档给的最低门槛是NVIDIA GeForce RTX 3060及以上,显存至少8GB,内存16GB起步。1280分辨率下训练,建议直接上24GB显存的显卡,不然batch size会被压得很小,训练稳定性和速度都受影响。CPU选择多核高频型号,数据预处理和图像解码阶段CPU依然是瓶颈。
软件环境核心是PyTorch的安装,CUDA版本要对齐。文档里的安装命令是基于CUDA 11.3的:
pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113拿不到新版CUDA匹配版本时,先去PyTorch官网查一下自己显卡驱动对应的CUDA版本,再选对应的安装命令,不要盲目装最新版。
配置文件这块,文档给出了一个简化版YAML:
model: backbone: 'efficientnet_b0' # 骨干网络选择 neck: 'PANet' # 颈部网络选择 head: 'YOLOHead' # 检测头选择 train: batch_size: 16 # 批量大小 epochs: 100 # 训练轮数 learning_rate: 0.001 # 学习率 optimizer: 'Adam' # 优化器 data: train_path: 'data/train.txt' # 训练数据路径 val_path: 'data/val.txt' # 验证数据路径 num_classes: 10 # 类别数量这个文件看起来简单,但对整个训练流程起到决定性作用。batch_size决定了每一步更新时看到的样本数量;learning_rate是模型参数更新的步长,调大调小都有坑;num_classes必须和标注文件里的类别数完全一致,多一个少一个都会在数据加载时报错。
4.2 超参数调整策略:学习率、批量大小和动态调度
训练参数里最玄学的就是学习率。学习率过大会导致损失不收敛甚至爆炸,过小则训练速度极慢。数据量不大时,从0.001起步是比较稳妥的选择。批量大小方面,如果显存足够,尽量用16或32,更大的batch size让梯度估计更平稳,但也意味着每个epoch迭代次数变少,需要相应增加训练轮数。
学习率衰减是个必须做的操作。前几轮模型参数离最优解远,需要大步长快速接近;后期接近最优解后继续用大步长容易来回震荡,需要调小步长精细调整。常见的做法是StepLR:
import torch.optim as optim from torch.optim.lr_scheduler import StepLR optimizer = optim.Adam(model.parameters(), lr=0.001) # 每10个epoch学习率乘0.1 scheduler = StepLR(optimizer, step_size=10, gamma=0.1) for epoch in range(100): train_one_epoch() scheduler.step()step_size和gamma这两个参数需要配合训练轮数来定。100个epoch的训练,10步一衰减、衰减系数0.1,意味着到30轮时学习率只有初始值的千分之一,后70轮基本都在微调。如果数据集比较小,可以把step_size调大到15或20,避免学习率降太快导致后期几乎不更新。训练中要盯着loss曲线,如果loss在某个epoch后不再下降,说明学习率已经太小,这时候可以提前结束训练,不用傻等100轮跑完。
4.3 训练中的五个常见发现场:现象、原因与恢复方案
第一个坑是显存溢出(OOM)。现象是训练刚开始就报CUDA out of memory,程序直接退出。原因是batch_size太大或者输入分辨率设置过高。解决方法是先减batch_size,从16降到8或4,如果还溢出就把输入分辨率从640降到512。注意用Ultralytics框架时,训练配置里的imgsz参数默认是640,改成1280做高精度训练时,显存占用会翻好几倍,需要同步调低batch size。
第二个坑是loss直接变NaN。现象是前几个epoch训练正常,某个epoch结束后loss打印显示nan。原因通常是学习率过高导致梯度爆炸,或者标注数据里有异常的边界框坐标。解决方法是先把学习率降到原来的十分之一看看是否恢复,如果恢复就说明是学习率问题。如果降完学习率还是nan,用脚本检查标注文件里有没有宽度或高度为0的框,有没有坐标超出图像边界的框,这类脏数据会让损失函数计算出无效值。
第三个坑是验证集mAP忽高忽低。现象是每个epoch结束后的mAP波动很大,没有稳定的上升趋势。原因是验证集的样本量太少,或者各类别样本比例失衡。解决方法是检查验证集是否每个类别都至少分布了20张以上的样本,如果某个类别只有3到5张,它的AP波动就会拖累整体mAP。必要的时候从训练集匀一部分样本到验证集,重新划分后再次训练,大概率能缓解。
第四个坑是小目标漏检,特别是叶片上早期的病斑。现象是模型能检到大面积枯死区域,但直径只有几十个像素的初期病斑完全没反应。原因是输入分辨率不够,小目标在640分辨率下可能只占几个像素,特征提取时直接被下采样丢掉了。解决方法有两个:一是把输入分辨率提到1280,这个方案最直接但显存压力大;二是针对性做数据增强,比如随机裁剪放大叶片局部区域,让模型在训练时多看到“小目标长什么样”。
第五个坑是训练loss下降但验证loss升高。现象是训练集loss一路走低,但验证集loss在某个epoch后反弹。原因是典型的过拟合,模型把训练集里的背景噪声和标注错误也背下来了。解决方法是加正则化,常用的有weight decay,把优化器里weight_decay=0.0005加上;或者用早停,验证集mAP连续5个epoch不提升就停止训练,保留最佳权重。做过农业项目的应该都有体会,病害数据集的采集成本高、样本量很难做到海量,过拟合是大概率事件,早停机制一定要加上。
5. 病害识别落地:从图像采集、特征提取到预警报告的完整流程
5.1 图像采集设备与预处理:田间作业的关键点
采集设备的选择取决于作业场景,不是越贵越好。手持式采集用普通智能手机就行,现在的手机摄像头在光线充足时能拍出足够清晰的叶片特写,关键是要保持稳定,避免运动模糊。大面积巡检用无人机挂载多光谱相机效率更高,但要注意飞行高度和速度的配合,飞太快叶片纹理细节会丢失。温室大棚里可以布固定摄像头,定点定时自动采集,配合环境传感器数据做综合分析。
采集注意事项有几个经验性的点。时间段上,晴天上午9点到11点之间是最佳拍摄窗口,此时太阳高度角合适,光照充足且均匀,叶片表面没有明显反光。阴天全天都可以拍摄,但色温偏冷,需要后期做白平衡校正。避免在大风天气拍摄,叶片晃动会导致动态模糊,看似拍清楚了,实际边缘都是虚的。拍摄角度方面,尽量让镜头平面和叶片表面平行,极端倾斜角度下叶片形态失真,模型很难正确识别。
预处理步骤对应训练时的图像处理逻辑,推理阶段也要保持一致性。具体来说,输入图像先缩放到模型要求的尺寸,一般是640x640或1280x1280;然后做归一化,把像素值从0到255映射到0到1区间;最后是通道顺序,OpenCV读入的是BGR,必须转成RGB再送进模型,否则颜色特征全部错乱,病害识别基本是瞎猜。
5.2 特征提取与检测定位:手工特征与深度特征的抉择
在深度学习普及之前,叶片病害识别主要靠手工特征。颜色直方图描述叶片和病斑的颜色分布,纹理特征用灰度共生矩阵或局部二值模式,形状特征描述病斑的几何形态。这些方法的优点是计算量小,缺点是对光照变化极其敏感,同一片叶子在不同光线下提取出的特征差异可能比不同病害的差异还大,泛化能力很有限。
YOLOv11的特征提取是完全自动的。骨干网络逐层学习从边缘、纹理到语义的特征表示,浅层特征倾向于响应颜色和纹理变化,深层特征更关注病斑的整体形态和位置关系。检测头在多个尺度的特征图上同时做预测,每个位置预测多个锚框,输出边界框坐标、置信度和类别概率。
推理阶段直接用训练好的权重做前向传播。以Ultralytics框架为例:
from ultralytics import YOLO # 加载训练好的模型权重,换成你自己的 best.pt model = YOLO('runs/train/exp/weights/best.pt') # 对一张田间拍摄的叶片图像做预测 results = model.predict('field_leaf.jpg', imgsz=640, conf=0.25) for r in results: boxes = r.boxes.xyxy.cpu().numpy() # 边界框坐标 classes = r.boxes.cls.cpu().numpy() # 类别ID confs = r.boxes.conf.cpu().numpy() # 置信度conf=0.25是置信度阈值,低于这个值的检测结果会被过滤掉。实际使用要根据场景调整:如果是做早期预警,希望尽量少漏检,阈值可以降到0.15;如果是做最终防治决策,误报会带来不必要的喷药成本,阈值可以提高到0.4甚至更高。这个参数不用在训练阶段改,推理时动态调节就行,对模型权重没有影响。
5.3 结果可视化与报告生成:把检测转成动作
检测结果本身只是一堆坐标和类别ID,对农户没有意义,必须转成能指导农事操作的信息。可视化方面,最简单的做法是按病害类别给边界框着色,比如真菌病害用红色框,细菌病害用蓝色框,病毒病害用黄色框,并在框顶标注类别名称和置信度。这些标注后的图像可以直接反馈给农户做人工复核。
更进一步,可以把检测结果聚合成分区域报表。统计每个检测框的坐标,按农田地块划分区域,计算每个区域内的病害框数量、各类别占比、平均置信度,生成表格输出。这样农户看到的不再是“第247张图上有3个框”,而是“东北地块番茄早疫病检出率15%,建议3天内完成针对性喷雾”。效果评估时重点关注两个指标:查准率,即检测出的病害框中确实有病的比例,衡量的是误报成本;查全率,即所有真实病害中有多少被检出来了,衡量的是漏报带来的风险。这两个指标在编制报告时必须同时列出来,只报mAP对田间决策没有直接参考价值。
6. 三个落地场景与模型验证技巧
6.1 小麦、温室蔬菜和果园部署的三个不同姿势
小麦大规模种植区的思路是“无人机巡检+区域预警”。无人机按设定航线自动采集图像,模型实时推理,检测结果按地块聚合告警。这里要注意航拍图像分辨率和大田尺度之间的匹配,一张航拍图可能覆盖十几种植行,检测框的坐标需要做地理投影,才能准确定位到病发区域。
温室蔬菜场景更强调“早期发现”。温室环境相对可控,光照变化幅度小,可以布置定点摄像头每隔一小时自动采集图像。由于温室作物种植密度高,叶片相互遮挡严重,推理时的置信度阈值要适当调低,优先保证不漏检。检测到初期病斑后,与温室的温湿度传感器数据联动,判断是否存在快速扩散风险,再决定是否进行干预。
果园场景的难点在光照和背景复杂度上。果树叶片表面有蜡质层,晴天拍摄时强反光严重;果园地面有杂草、落果、枝干倒影,背景噪声比小麦田大得多。果园应用建议使用手持设备,拍摄时主动寻找顺光角度,避免直射反光区域。模型的训练数据里要专门加入不同光照条件下的果园实拍图,否则在复杂背景中漏检率会明显上升。
6.2 验证模型的进阶方法:从mAP到外场测试
训练结束后的验证分两层。第一层是标准化的mAP评估,在测试集上计算各类别的平均精度,这一步能客观反映模型在“干净数据”上的表现。第二层是外场测试,把训练和测试时完全没见过的、新拍摄的田间照片直接送进模型,观察检测效果。两层验证缺口比较大的时候,说明模型过拟合了训练数据分布,需要回头补充训练数据的多样性。
我自己的习惯是,新模型拿到后先做一轮带标注的外场测试,统计每个类别的查准率和查全率。同一组照片分别在不同时段(清晨、正午、傍晚)拍摄,模拟农户实际使用时的光照条件。然后刻意加入一批背景复杂的照片,比如杂草丛生的田边、有昆虫爬过的叶片、沾了水珠的叶子,检验模型在恶劣输入下的稳定性。质检模型在mxnet的合成数据上mAP很漂亮,拿到真实果园里就漏检,原因就在于没有做这层外场测试。
从那以后我每次训完农业检测模型,都会强制走一遍“测试集mAP → 外场带标注实测 → 不同光照复测”这个流程,哪怕时间紧张也不跳过。模型跑100轮很快,但在错误场景下部署带来的返工成本更高。希望这篇拆解能帮你在做YOLOv11多作物叶片病害识别时少走几步弯路,祝落地顺利。
本文还有配套的精品资源,点击获取