简介:本资源面向具备一定Python与深度学习基础、希望上手番茄叶片病害目标检测的开发者与学习者,提供一套可直接运行的YOLO实战方案。压缩包共1470个文件,约40.55MB,其中730张jpg为图像样本,358个xml与363个txt分别对应标注与YOLO格式标签,另有3个py脚本、3个pt权重、3个yaml配置及png、csv等训练日志与可视化结果,覆盖数据、训练与推理全流程。已有109人学习下载。资源包含数据集与完整代码,运行01脚本可将数据转为YOLO格式并生成train.txt、val.txt与data.yaml,02脚本用于模型训练,03脚本提供PyQt可视化界面,点击加载图片与检测按钮即可完成识别,也可直接调用已训练权重快速验证。借助现成权重、训练曲线与验证批次预测图,读者能省去数据整理与调参成本,快速复现并理解目标检测在农业病害场景中的落地方式。
1. 番茄叶片病害目标检测:从一份 .zip 到能跑通的检测器
拿到「基于python深度学习对番茄叶片病害目标检测-含数据集和代码.zip」这类资源,多数人的第一反应是解压、找train.py、直接python train.py,然后被路径报错、类别不匹配、显存溢出轮番教育。番茄叶片病害检测属于典型的细粒度农业视觉任务:早疫病、晚疫病、叶霉病、斑枯病这些类别在叶片上的病斑形态高度相似,颜色、纹理、边界差异都很微妙,背景还夹杂土壤、茎秆、水滴和光照变化。它要解决的不是「有没有病」,而是「是哪一种病、病斑在哪、占多大面积」,所以目标检测比单纯图像分类更贴合实际需求。这套方案适合三类人:想用真实农业数据集跑通 YOLO 全流程的深度学习入门者、需要给温室或田间巡检做病害定位原型的工程师、以及手里有类似 .zip 资源但一直没跑通的从业者。下面按「数据长什么样 → 怎么转格式 → 怎么训 → 坑在哪 → 怎么验证」的顺序拆开讲。
2. 番茄叶片病害数据集:先看清标注格式再动手
2.1 农业病害数据集的三种常见组织方式
这类 .zip 里的数据集,落地时最常见的是三种结构。第一种是分类式目录,train/早疫病/xxx.jpg、train/晚疫病/xxx.jpg,只有图像级标签,没有边界框,这种只能做分类,做检测得自己补标注。第二种是 VOC 式,每张图配一个同名.xml,里面bndbox记录xmin/ymin/xmax/ymax,类别写在name里。第三种是 YOLO 式,每张图配一个.txt,每行class_id cx cy w h,坐标全部归一化到 0~1。判断方法很简单,解压后先看有没有Annotations和JPEGImages两个目录,有就是 VOC;看到labels目录加一堆.txt就是 YOLO。我一般会先跑一遍统计,确认类别分布和框的数量,因为农业数据集经常出现某类只有几十张、某类上千张的极端不平衡。
import os, glob from collections import Counter # 统计 VOC 标注里的类别分布,先摸清数据底细 xml_dir = "data/Annotations" counter = Counter() for xml_path in glob.glob(os.path.join(xml_dir, "*.xml")): with open(xml_path, "r", encoding="utf-8") as f: content = f.read() # 简易提取 <name> 标签,正式场景建议用 xml.etree import re for name in re.findall(r"<name>(.*?)</name>", content): counter[name.strip()] += 1 for cls, num in counter.most_common(): print(f"{cls}: {num}")这段代码的作用是先做数据体检。xml_dir指向标注目录,Counter累计每个类别出现的次数,re.findall只是快速预览,正式处理建议换成xml.etree.ElementTree避免漏标签。跑完你会看到类似「早疫病 820、晚疫病 640、健康 300」的分布。如果某一类低于 200 个框,训练时就要考虑过采样或强增强,否则模型会偏向多数类。这一步不做,后面 mAP 虚高你还以为是模型强。
2.2 把 VOC 转成 YOLO 格式:转换脚本与四个边界坑
YOLO 训练只认归一化 txt,所以 VOC 转 YOLO 是绕不开的一步。转换的核心是把xmin/ymin/xmax/ymax转成中心点加宽高,再除以图像宽高。坑集中在四点:图像尺寸要从对应 jpg 读,不能写死;类别名到 id 的映射必须固定且全数据集一致;坐标要裁剪到 [0,1],标注越界会直接让训练 loss 变 NaN;空标注图要么删要么留空 txt,不能生成全零行。
import os, glob import xml.etree.ElementTree as ET from PIL import Image classes = ["早疫病", "晚疫病", "叶霉病", "斑枯病", "健康"] # 顺序固定,训练和推理必须一致 cls2id = {c: i for i, c in enumerate(classes)} def voc_to_yolo(xml_path, img_dir, out_dir): tree = ET.parse(xml_path) root = tree.getroot() img_name = root.find("filename").text img_path = os.path.join(img_dir, img_name) w, h = Image.open(img_path).size # 真实尺寸,别写死 640 lines = [] for obj in root.findall("object"): name = obj.find("name").text.strip() if name not in cls2id: continue # 未登记类别直接跳过,避免 id 错位 bbox = obj.find("bndbox") xmin = float(bbox.find("xmin").text) ymin = float(bbox.find("ymin").text) xmax = float(bbox.find("xmax").text) ymax = float(bbox.find("ymax").text) # 裁剪越界坐标,防止归一化后超出 [0,1] xmin, xmax = max(0, xmin), min(w, xmax) ymin, ymax = max(0, ymin), min(h, ymax) if xmax <= xmin or ymax <= ymin: continue # 无效框丢弃 cx = (xmin + xmax) / 2 / w cy = (ymin + ymax) / 2 / h bw = (xmax - xmin) / w bh = (ymax - ymin) / h lines.append(f"{cls2id[name]} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}") out_path = os.path.join(out_dir, os.path.splitext(img_name)[0] + ".txt") with open(out_path, "w") as f: f.write("\n".join(lines)) for xml in glob.glob("data/Annotations/*.xml"): voc_to_yolo(xml, "data/JPEGImages", "data/labels")classes列表的顺序就是最终模型输出的类别顺序,一旦训练完再改,权重全部作废。Image.open读真实宽高是关键,很多翻车案例是标注工具按 640 导出、原图却是 1920,直接除错。坐标裁剪那两行是后悔药,农业数据集手工标注经常有框超出边界。转换完建议抽查 5 张,用可视化脚本把框画回图上,确认没偏移再进训练。
3. 用 YOLOv8 跑通训练:配置文件、参数与显存控制
3.1 数据集 yaml 怎么写才不出错
YOLO 系列训练入口是一个 yaml 描述文件,里面写清训练、验证、测试三个路径和类别名。路径建议用绝对路径,相对路径在不同工作目录下会翻车。nc是类别数,必须和names长度一致,多一个少一个都会在加载时直接报错。
# tomato.yaml path: /home/user/tomato_detection # 数据集根目录 train: images/train # 训练图目录 val: images/val test: images/test nc: 5 # 类别数,必须等于 names 长度 names: 0: 早疫病 1: 晚疫病 2: 叶霉病 3: 斑枯病 4: 健康path加train拼出完整路径,所以images/train下放 jpg,labels/train下放同名 txt,YOLO 会自动按文件名找标签。常见错误是图片和标签目录层级不对应,比如图片在images/train而标签在labels,训练时找不到标签会静默跳过,最后 mAP 为 0 你还找不到原因。划分比例我一般按 7:2:1,农业数据量小的时候可以 8:1:1,但验证集至少留 100 张以上才有统计意义。
3.2 训练命令与关键参数怎么调
环境上,pip install ultralytics就能拿到 YOLOv8 的训练接口,GPU 建议 8G 显存起步。番茄叶片病害这种细粒度任务,我一般从yolov8s或yolov8m起步,n 太小欠拟合,l 以上小数据集容易过拟合。
# 单卡训练,imgsz 640,batch 按显存调 yolo detect train \ data=tomato.yaml \ model=yolov8s.pt \ epochs=150 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=30 \ project=runs/tomato \ name=exp1epochs=150配合patience=30是早停,30 轮验证指标不升就停,省时间也防过拟合。imgsz=640是精度和速度的平衡点,病斑特别小可以上 1024,但显存翻倍。batch=16在 8G 显存上跑 yolov8s 基本安全,报 OOM 就降到 8 或 4。lr0=0.01是初始学习率,小数据集可以降到 0.005 更稳。训练日志里重点看box_loss和mAP50,前者不降说明标注有问题,后者震荡说明学习率偏大或数据太杂。
3.3 数据增强:农业场景该开哪些、该关哪些
YOLO 默认开启 mosaic、HSV 抖动、随机翻转。番茄叶片场景里,HSV 抖动对光照变化有帮助,mosaic 能提升小目标召回,但mixup和copy_paste在病斑任务上要谨慎,病斑被过度混合后语义会乱。我一般保留默认增强,额外加一点旋转,因为田间拍摄角度多变。
from ultralytics import YOLO model = YOLO("yolov8s.pt") model.train( data="tomato.yaml", epochs=150, imgsz=640, batch=16, degrees=15.0, # 随机旋转 ±15 度,模拟拍摄角度 hsv_h=0.015, # 色调抖动,应对光照差异 hsv_s=0.7, hsv_v=0.4, mosaic=1.0, # 保留 mosaic 提升小病斑召回 mixup=0.0, # 病斑语义敏感,关掉 mixup fliplr=0.5, )degrees=15别开太大,叶片旋转超过 30 度病斑形态会失真。mixup=0.0是我的血泪经验,开了之后模型会把两类病斑叠在一起学,验证集上类别混淆严重。mosaic=1.0保留,因为病斑在整张图里占比小,mosaic 拼图能增加小目标样本。增强参数没有万能值,建议先跑 20 轮看验证曲线,再决定加不加。
4. 训练不收敛、mAP 上不去:排查清单
4.1 现象:loss 一直是 nan 或突然爆掉
原因通常是标注坐标越界或宽高为负,归一化后出现非法值。解决方法是回到转换脚本,加坐标裁剪和无效框过滤,转换后跑一遍校验,确认所有 txt 每行都是 5 个字段、后四个在 [0,1] 内。另一个可能是学习率太大,lr0从 0.01 降到 0.001 再试。
4.2 现象:mAP50 卡在 0.3 上不去
先看类别分布,如果某类样本极少,模型基本学不会。解决是对少数类过采样,或在 yaml 里给类别加权。其次检查标注质量,农业数据集常见框只框了病斑一部分,模型学到的是残缺特征。我一般会抽 20 张验证集预测图,人工看框得准不准,比盯数字有用。
4.3 现象:训练集指标高、验证集崩
典型过拟合。番茄叶片数据集通常几千张,yolov8m 以上很容易过拟合。解决是换小模型、加增强、加 dropout,或者冻结 backbone 前几层先训 head。patience设小一点,早停能救回不少时间。
4.4 现象:推理时类别全错或框乱飞
八成是类别顺序不一致。训练时names的顺序和推理时你解析结果的顺序必须完全一样。另一个原因是推理输入尺寸和训练不一致,训练 640 推理 1280 会导致框偏移。统一用训练时的imgsz。
4.5 现象:显存溢出 OOM
batch太大或imgsz太高。先降 batch 到 8,再不行降 imgsz 到 512。也可以用amp=True混合精度,显存能省三成左右,精度损失很小。多卡场景注意device参数别写错。
5. 验证与部署:从 mAP 到能用的检测器
训练完不能只看 mAP,得落到具体验证和导出。验证命令一行就够:
yolo detect val model=runs/tomato/exp1/weights/best.pt data=tomato.yaml imgsz=640重点看三个指标:mAP50反映整体检测能力,mAP50-95反映框的精准度,precision/recall看漏检和误检的平衡。番茄病害场景里 recall 比 precision 更重要,漏检一个病斑比多框一个健康区域代价大。如果 recall 偏低,降低置信度阈值到 0.25 再验证。
导出部署格式时,农业巡检常在边缘设备跑,ONNX 是通用选择:
from ultralytics import YOLO model = YOLO("runs/tomato/exp1/weights/best.pt") model.export(format="onnx", imgsz=640, opset=12, simplify=True)opset=12兼容性好,simplify=True会做图优化,推理快一点。导出后务必用同一张图对比 PyTorch 和 ONNX 的输出,确认框和类别一致,我见过导出后类别顺序错位的案例,排查了半天。
最后一个技巧:农业病害检测的置信度阈值不要用默认 0.25,建议在验证集上画 PR 曲线,选 recall 和 precision 交叉点附近的阈值。我自己的习惯是每次训完先跑 50 张现场图,人工核对漏检和误检,再决定要不要补数据。这套流程跑通一次,后面换数据集、换模型都只是改配置的事。希望帮到你。
本文还有配套的精品资源,点击获取