ARTICLE DETAIL

资讯详情

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

基于YOLO的番茄叶片病害目标检测:数据集转换与训练全流程

基于YOLO的番茄叶片病害目标检测:数据集转换与训练全流程 简介这份资源面向具备一定Python与PyTorch基础、希望上手番茄叶片病害目标检测的开发者与学习者提供从数据处理到可视化识别的完整工程。包内共1470个文件以730张jpg图像、358个xml标注、363个txt标签为主另含3个py脚本、3个pt权重、3个yaml配置及训练日志、预测结果图等压缩包约40.55MB。已有109人学习下载。资源覆盖数据集划分、模型训练与PyQt界面推理全流程运行01脚本可将原始数据转为YOLO格式并生成train.txt、val.txt与data.yaml02脚本用于训练模型03pyqt.py则提供可视化界面点击加载图片再点检测即可完成识别适合直接调用已训练权重做推理也可重新训练以适配自有数据。目录中保留的results.csv、验证批次预测图与标签图便于复盘训练过程与评估检测效果对课程设计、毕业项目或病害识别入门实践均有参考价值。1. 番茄叶片病害目标检测从一张病叶照片到可复现的检测流水线大棚里番茄叶片刚出现水渍状暗斑时人眼往往要凑近反复确认等整株萎蔫再打药已经晚了。基于 Python 深度学习对番茄叶片病害做目标检测要解决的就是这件事让模型在一张叶片图像上直接框出病斑位置并给出类别而不是只告诉你「这片叶子有病」。它和图像分类最大的区别在于分类输出一个标签目标检测输出若干带坐标的框和置信度能定位到具体病斑区域方便后续统计面积、判断扩散方向。这套方案适合三类人想入门深度学习目标检测的学生、需要给农业场景做原型验证的工程师、手里有病害图像想跑通全流程的从业者。标题里带的数据集和代码本质是把「数据准备—标注格式转换—模型训练—推理验证」这条链路打包好让你不用从零攒数据就能跑起来。下面按我实际落地的顺序拆开讲重点放在能抄作业的步骤和参数上。2. 番茄叶片病害数据集从原始图像到 YOLO 可训练格式2.1 先搞清楚数据集里到底有什么拿到一个目标检测数据集压缩包别急着解压就训练。我一般先做三件事看目录结构、统计图像数量、抽样看标注质量。番茄叶片病害常见类别包括早疫病、晚疫病、叶霉病、健康叶片等不同数据集类别命名不统一有的用中文文件夹名有的用英文缩写。先确认类别数和每类样本量类别极度不均衡会直接导致模型偏向多数类。# 查看数据集目录结构先摸清组织方式 find tomato_dataset -maxdepth 2 -type d # 统计图像数量确认规模 find tomato_dataset -name *.jpg -o -name *.png | wc -l # 查看标注文件格式常见有 xml(voc)、txt(yolo)、json(coco) find tomato_dataset -name *.xml | head -3 find tomato_dataset -name *.txt | head -3上面三条命令分别解决「结构是什么」「有多少张」「标注什么格式」。如果输出的是 xml说明是 VOC 格式需要转成 YOLO 的 txt如果直接是 txt 且每行是类别 x_center y_center w h那已经是 YOLO 格式可以跳过转换。注意坐标是归一化到 0-1 的不是像素值这是新手最容易看错的地方。2.2 VOC 转 YOLO转换脚本和四个边界坑大部分公开番茄病害数据集是 VOC 格式转 YOLO 是绕不开的一步。核心逻辑是读 xml 里的bndbox把绝对坐标转成归一化的中心点加宽高。import os import xml.etree.ElementTree as ET # 类别映射必须和后续 data.yaml 里的 names 顺序完全一致 classes [early_blight, late_blight, leaf_mold, healthy] def convert(size, box): dw, dh 1.0 / size[0], 1.0 / size[1] x (box[0] box[1]) / 2.0 y (box[2] box[3]) / 2.0 w box[1] - box[0] h box[3] - box[2] return x * dw, y * dh, w * dw, h * dh def convert_annotation(xml_path, out_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w, h int(size.find(width).text), int(size.find(height).text) with open(out_path, w) as f: for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) bndbox obj.find(bndbox) box (float(bndbox.find(xmin).text), float(bndbox.find(xmax).text), float(bndbox.find(ymin).text), float(bndbox.find(ymax).text)) bb convert((w, h), box) f.write(f{cls_id} .join([f{v:.6f} for v in bb]) \n)classes列表的顺序决定了标签编号一旦训练中途改动之前训的权重全废。convert里先算中心点再归一化顺序不能反。四个边界坑一是坐标越界xmin 小于 0 或 xmax 大于图像宽度转换后会出现负数或大于 1 的值训练时报错二是空标注文件有些图像没有目标转换后是空 txtYOLO 会当成负样本要确认这是否符合预期三是类别名大小写不一致Early_blight和early_blight会被当成两类四是图像和标注文件名必须一一对应差一个后缀就找不到标签。2.3 划分训练集验证集和 data.yaml 配置转换完别把所有数据丢进训练。按 8:2 或 7:3 划分验证集用来观察是否过拟合。目录结构建议images/train、images/val、labels/train、labels/val分开。import os, random, shutil random.seed(42) # 固定随机种子保证每次划分一致方便复现 imgs [f for f in os.listdir(images_all) if f.endswith(.jpg)] random.shuffle(imgs) split int(len(imgs) * 0.8) for i, img in enumerate(imgs): phase train if i split else val shutil.copy(fimages_all/{img}, fimages/{phase}/{img}) label img.replace(.jpg, .txt) shutil.copy(flabels_all/{label}, flabels/{phase}/{label})random.seed(42)这行别省否则每次划分不同实验没法对比。划分后写data.yamlpath: ./tomato_dataset train: images/train val: images/val nc: 4 names: [early_blight, late_blight, leaf_mold, healthy]nc是类别数必须和 names 长度一致写错会直接报维度不匹配。path用相对路径时训练命令要在对应目录下执行否则找不到数据。3. 用 YOLO 系列模型训练番茄病害检测器3.1 模型选型为什么优先选 YOLO 而不是两阶段检测器目标检测主流分两派两阶段如 Faster R-CNN先出候选框再分类精度高但慢单阶段如 YOLO 系列一次前向就出框和类别速度快、部署友好。番茄叶片病害检测通常在田间或边缘设备上跑实时性要求高YOLO 更合适。YOLOv8 是当前工程落地比较稳的版本API 统一训练和推理都封装好了新手不用自己写数据加载器。选它不是因为最新而是因为文档全、社区问题多、踩坑容易搜到答案。如果你追求更轻量可以选 n 或 s 版本如果精度优先且显存够选 m 或 l。3.2 训练命令和必调参数环境装好后训练就一条命令的事但参数决定成败。# 安装依赖ultralytics 封装了训练推理全流程 pip install ultralytics # 开始训练 yolo detect train \ data./tomato_dataset/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/tomato \ nameexp1modelyolov8s.pt是预训练权重用 COCO 上训过的参数初始化小数据集上收敛快很多别从零训。epochs100是上限配合patience20验证指标 20 轮不提升就早停省时间。imgsz640是输入分辨率病斑小的话可以提到 800 或 1024但显存占用翻倍。batch16看显存调爆显存就减到 8 或 4。lr00.01是初始学习率太大震荡太小收敛慢0.01 是常用起点。project和name决定结果保存路径方便多组实验对比。3.3 训练过程看什么指标训练日志里重点看三个box_loss定位损失、cls_loss分类损失、mAP50和mAP50-95。box_loss 和 cls_loss 持续下降是正常如果震荡不降多半是学习率太大或标注有问题。mAP50 是 IoU 阈值 0.5 时的平均精度mAP50-95 更严格。番茄病斑边界模糊mAP50 能到 0.7 以上就算可用别盲目追求 0.9那往往是过拟合或数据泄漏。验证集指标远低于训练集说明过拟合加数据增强或减模型复杂度。from ultralytics import YOLO # 加载训练好的权重做推理 model YOLO(runs/tomato/exp1/weights/best.pt) results model.predict(sourcetest_leaf.jpg, conf0.25, iou0.45, saveTrue) # 打印每个检测框的类别和置信度 for r in results: for box in r.boxes: cls model.names[int(box.cls)] conf float(box.conf) xyxy box.xyxy.tolist()[0] print(f{cls} {conf:.2f} {xyxy})conf0.25是置信度阈值低于它的框不输出调高减少误检调低减少漏检。iou0.45是 NMS 的 IoU 阈值重叠框超过这个值会被合并病斑密集时适当调高避免漏掉相邻病斑。saveTrue会把画框结果存下来方便肉眼核对。4. 番茄病斑检测的避坑与排查清单4.1 训练 loss 不降反升现象前几轮 loss 正常下降突然飙升或变成 nan。原因通常是学习率过大或数据里有脏标注比如坐标越界、宽高为负。解决先把lr0降到 0.001 试再写脚本扫一遍所有 label 文件检查是否有值不在 0-1 之间或宽高为 0 的行把异常样本剔除或修正。4.2 验证集 mAP 很高但实际推理一塌糊涂现象训练日志里 mAP50 到 0.9拿新照片一测全是误检。原因多半是数据泄漏训练集和验证集里有同一张图的不同副本或者验证集图像和训练集高度相似。解决划分前对图像做去重用感知哈希或简单 md5 比对确保验证集是模型没见过的场景。另外检查推理时的预处理是否和训练一致比如归一化方式、通道顺序。4.3 小病斑检测不到现象大块病斑能框出来早期小斑点全漏。原因是下采样后小目标特征丢失。解决提高输入分辨率到 1024或在模型里加 P2 小目标检测层。数据层面对含小病斑的图做 mosaic 增强时注意别把病斑裁掉。推理时把conf降到 0.1 看是否召回如果召回但误检多说明模型对小目标判别力不足需要补小目标样本。4.4 类别混淆严重现象早疫病和晚疫病互相认错。原因这两类病斑在早期视觉特征确实接近标注时人也会犹豫。解决先核对标注一致性同一张图不同人标可能标成不同类。然后考虑合并易混类别或引入更细的特征比如病斑边缘颜色、是否有同心轮纹。数据量不足时类别合并比硬分更实际。4.5 显存爆了训练中断现象跑几轮后 CUDA out of memory。原因是 batch 太大或 imgsz 太高。解决先把 batch 减半还不行就降 imgsz。也可以用梯度累积模拟大 batch但 YOLO 封装里要手动改配置。另外训练前关掉其他占显存的进程用nvidia-smi确认没有残留。5. 把检测器推到可用验证方法与调优技巧训练完不是终点得验证它到底能不能用。我一般做三层验证第一层在留出的验证集上跑看 mAP 和混淆矩阵第二层找几张训练分布外的真实照片比如不同光照、不同角度、不同品种的番茄叶看泛化第三层如果要做面积统计把检测框面积累加和人工标注的面积做相关性对比相关系数低于 0.8 说明框不准得回头调。调优上有个实用技巧冻结 backbone 微调。番茄病害数据集通常不大从头训容易过拟合。先把 backbone 冻结只训检测头 20 轮再解冻全部微调 50 轮往往比直接训 100 轮效果好。# 第一阶段冻结 backbone只训检测头 yolo detect train data./tomato_dataset/data.yaml modelyolov8s.pt \ epochs20 freeze10 lr00.01 namestage1 # 第二阶段解冻全部小学习率微调 yolo detect train data./tomato_dataset/data.yaml \ modelruns/tomato/stage1/weights/best.pt \ epochs50 lr00.001 namestage2freeze10表示冻结前 10 层具体层数看模型结构YOLOv8s 的 backbone 大概在前 10 层。第二阶段学习率降到 0.001避免破坏已学好的特征。这个两段式训练我在多个小数据集上试过mAP 通常能比直接训高 3 到 5 个点。另一个技巧是测试时增强TTA推理时对图像做翻转、缩放多尺度预测再融合能提升 1 到 2 个点代价是速度慢几倍适合离线分析不适合实时。results model.predict(sourcetest_leaf.jpg, augmentTrue, conf0.25)augmentTrue开启 TTA。注意它只在推理时生效训练时的增强是另一套配置。最后说个血泪经验别在标注质量差的数据上死磕模型。我见过太多人模型换了一茬又一茬mAP 上不去回头一看标注框歪的、漏标的、类别标错的占了三成。花两天重新过一遍标注比调两周参有用得多。数据集和代码只是起点真正决定效果的是你对数据的理解和清洗。希望帮到你。本文还有配套的精品资源点击获取
返回列表