☰
葡萄叶片病害检测数据集:VOC/COCO/YOLO三格式标签与YOLOv8训练实战
2026/9/28 13:46:58 网站建设 项目流程

简介:本资源为面向目标检测初学者与农业图像研究者的YOLO葡萄叶片病害检测数据集,针对真实种植场景下病害识别样本不足、标注格式不统一的问题,提供可直接投入训练的完整数据方案。压缩包共2000个文件,约34.79MB,包含1000张真实场景图片及对应标注,涵盖xml、txt、json等格式,分别对应VOC、COCO与YOLO三种标签体系,另附yaml配置文件与Python划分脚本,便于按需生成训练集、验证集与测试集。资源同时提供Windows与Linux环境搭建说明、训练案例教程及数据集划分操作文档,帮助读者从环境配置到模型训练逐步跑通流程,理解标签转换与数据组织方式。目前已有457人学习下载,适合需要快速验证YOLO系列算法、开展葡萄病害检测实验或课程实践的用户参考使用。

1. 葡萄叶片病害检测数据集:1000 张图配三套标签,为什么值得先跑通再谈模型

葡萄叶片病害检测这件事,真正卡住大多数人的从来不是 YOLO 网络结构,而是数据。你手上有一份 1000 张葡萄叶片图片、同时带 VOC、COCO、YOLO 三种格式标签、还附划分脚本和训练教程的压缩包,这意味着一件事:从「拿到数据」到「跑出第一个 mAP」之间的路已经被铺平了大半。葡萄叶片病害常见的有黑腐病、轮斑病、褐斑病、霜霉病等几类,田间拍摄的叶片存在遮挡、光照不均、病斑面积小的问题,直接拿公开通用数据集训出来的模型往往在病斑上翻车。这份数据集的价值就在于它把标注格式的适配工作提前做完了,你不需要再写 XML 转 TXT 的脚本,也不用纠结 COCO 的 json 结构怎么对齐 YOLO 的 txt。适合谁?适合刚接触 YOLO 目标检测、想拿一个真实农业场景练手的人,也适合做智慧农业落地、需要快速验证病害识别可行性的工程师。下面按「数据长什么样 → 怎么划分 → 怎么配训练 → 坑在哪 → 怎么调优」的顺序讲透。

2. 三种标签格式到底差在哪:VOC、COCO、YOLO 的坐标逻辑与选型

2.1 同一张图,三种标签文件长什么样

先把这个数据集里三种格式的物理形态说清楚,不然后面转换和训练全是玄学。VOC 格式一张图对应一个 XML 文件,坐标是绝对像素值,记录xmin/ymin/xmax/ymax;COCO 格式是一个大的 json,所有图片和标注集中管理,坐标同样是绝对像素,但用[x, y, width, height]表示;YOLO 格式一张图对应一个 txt,每行是类别 id 中心x 中心y 宽 高,且这四个值全部归一化到 0~1 之间。

这三种格式不是随便选的,它们对应不同的训练框架和工具链。VOC 是早期 PASCAL 标准,很多标注工具默认导出它;COCO 是当前检测、分割、关键点通用的主流格式,mmdetection、detectron2 都吃它;YOLO 格式则是 Ultralytics 系列(YOLOv5/v8/v11)的原生输入。数据集同时给三套,本质是让你不用做格式转换就能对接任意一条训练流水线。

格式文件形态坐标类型典型框架
VOC每图一个 XML绝对像素 xmin/ymin/xmax/ymax早期 SSD、Faster R-CNN
COCO单个 json绝对像素 x/y/w/hmmdetection、detectron2
YOLO每图一个 txt归一化中心点+宽高YOLOv5/v8/v11

2.2 为什么 YOLO 训练必须用归一化坐标

很多人第一次看 YOLO 标签会懵:为什么坐标是 0.53 这种小数?因为 YOLO 在训练时把整张图缩放到固定输入尺寸(比如 640×640),如果标签是绝对像素,缩放后坐标就全错了。归一化之后,无论图片原始分辨率是 640×480 还是 1920×1080,标签都表示「目标在图片中的相对位置」,缩放不改变这个比例关系。

具体换算逻辑是:中心 x = (xmin + xmax) / 2 / 图片宽,中心 y = (ymin + ymax) / 2 / 图片高,宽 = (xmax - xmin) / 图片宽,高 = (ymax - ymin) / 图片高。这个公式看着简单,但实际转换时最容易在图片宽高读取上出错——如果用了错误的尺寸,标签会整体偏移,训练时 loss 降不下去,模型学到的全是错位置。

# VOC XML 转 YOLO txt 的核心逻辑 import xml.etree.ElementTree as ET from PIL import Image def voc_to_yolo(xml_path, img_path, class_map): tree = ET.parse(xml_path) root = tree.getroot() # 关键:必须从图片实际读取宽高,不能用 XML 里写的 size img_w, img_h = Image.open(img_path).size lines = [] for obj in root.findall('object'): cls_name = obj.find('name').text cls_id = class_map[cls_name] 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) # 归一化计算 cx = (xmin + xmax) / 2.0 / img_w cy = (ymin + ymax) / 2.0 / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h lines.append(f"{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") return lines

这段代码里有两个参数必须注意:class_map是类别名到 id 的映射,必须和后续训练时的data.yaml里names顺序完全一致,否则模型会把黑腐病认成褐斑病;Image.open(img_path).size返回的是(宽, 高),顺序别搞反,搞反了标签会转置。转换完成后建议随机抽 5 张图用可视化脚本画框验证,肉眼确认框的位置和类别没问题再进入训练。

2.3 划分脚本怎么用:train/val/test 的比例与随机种子

数据集附带的划分脚本通常做一件事:把图片和对应标签按比例分到images/train、images/val、images/test和对应的labels/目录下。常见比例是 8:1:1 或 7:2:1,1000 张图的话,8:1:1 就是 800 训练、100 验证、100 测试。

这里有个容易被忽略的点:随机种子。如果不固定 seed,每次运行划分脚本得到的数据集划分都不一样,你这次训出来的 mAP 和下次没法对比,实验就失去了可复现性。我一般会在划分脚本里固定random.seed(42),并且把划分结果的文件列表存下来,后续换模型做对比实验时直接用同一份划分。

# 典型的划分脚本调用方式(具体参数以脚本实际定义为准) python split_dataset.py \ --images_dir ./images \ --labels_dir ./labels \ --output_dir ./dataset \ --train_ratio 0.8 \ --val_ratio 0.1 \ --test_ratio 0.1 \ --seed 42

参数说明:--train_ratio等三个比例加起来必须等于 1,脚本一般会做校验;--seed固定后划分可复现;--output_dir下会生成 YOLO 训练所需的目录结构。划分完成后检查一下val和test里是否覆盖了所有病害类别,如果某个类别在验证集里一张都没有,那这个类别的评估指标就是空的,训练时也学不好。

3. 用 YOLOv8 跑通第一个葡萄病害检测模型:环境、配置与训练命令

3.1 环境搭建与预训练权重选择

训练之前先把环境弄干净。YOLOv8 用 Ultralytics 的包,Python 3.8 以上,PyTorch 按你的显卡 CUDA 版本装。如果你用的是 V100 或者消费级显卡,直接 pip 装就行,不用自己编译。

# 创建虚拟环境并安装依赖 conda create -n grape_yolo python=3.10 -y conda activate grape_yolo # 安装 PyTorch(以 CUDA 11.8 为例,其他版本去官网查对应命令) pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 ultralytics pip install ultralytics

预训练权重直接用yolov8n.pt或yolov8s.pt。n 是最小的,速度快适合先跑通流程;s 稍大,精度通常更好。葡萄叶片病害检测属于细粒度任务,病斑面积小,我建议先用 n 跑通确认流程没问题,再换 s 或 m 做精度提升。权重文件 Ultralytics 会自动下载,不需要手动找。

3.2 data.yaml 的写法与类别顺序陷阱

YOLO 训练的核心配置文件是data.yaml,它告诉框架去哪里找图片、有几个类别、类别名是什么。

# data.yaml path: ./dataset # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 test: images/test # 测试集图片相对路径 nc: 4 # 类别数量 names: # 类别名,顺序必须和标签里的 id 对应 0: black_rot # 黑腐病 1: esca # 轮斑病 2: leaf_blight # 褐斑病 3: downy_mildew # 霜霉病

这里最大的坑是类别顺序。YOLO 标签里的数字 id 是 0、1、2、3,names列表里的顺序必须和标注时用的顺序完全一致。如果你标注时 0 是黑腐病,但 yaml 里 0 写成了霜霉病,模型训练时会把所有黑腐病学成霜霉病,最后混淆矩阵会告诉你一切,但那时候已经浪费了几个小时。建议在转换标签之前就把类别映射表定死,写在一个单独的 json 里,转换脚本和 yaml 都从这个 json 读。

3.3 训练命令与关键参数怎么设

配置好了直接开训。YOLOv8 的命令行接口很简洁,但几个参数直接决定你能不能训出东西。

yolo detect train \ data=./data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ project=./runs/grape \ name=exp1

参数逐个说:epochs=100是训练轮数,1000 张图的数据集一般 100~200 轮够收敛;imgsz=640是输入尺寸,如果你的病斑特别小,可以提到 800 或 1024,但显存占用会涨;batch=16按显存调,8G 显存跑 640 尺寸大概能到 16,不够就降到 8;lr0=0.01是初始学习率,YOLOv8 默认用 SGD 时这个值比较稳,如果你换 Adam 可以降到 0.001;patience=20是早停耐心值,20 轮验证指标不涨就停,防止过拟合。

训练过程中重点看三个东西:box_loss是否稳定下降、mAP50是否在涨、验证集的cls_loss有没有反弹。如果box_loss降到某个值就不动了,可能是学习率太大或者标签有问题;如果mAP50一直很低但 loss 在降,大概率是类别顺序错了或者验证集里没有某个类别。

3.4 训练完成后的验证与推理

训练结束后,runs/grape/exp1/weights/下会有best.pt和last.pt。best.pt是验证集指标最好的那轮,推理用它。

# 在测试集上评估 yolo detect val model=./runs/grape/exp1/weights/best.pt data=./data.yaml # 单张图片推理 yolo detect predict model=./runs/grape/exp1/weights/best.pt source=./test_leaf.jpg save=True

验证输出里会给你每个类别的 precision、recall、mAP50、mAP50-95。葡萄病害检测里,如果某个类别 recall 特别低,说明漏检多,可能是这个类别的样本太少或者病斑太小;如果 precision 低,说明误检多,可能是背景里类似病斑的东西被框进来了。这些指标比 loss 更能告诉你模型到底行不行。

4. 葡萄叶片病害检测的避坑与排查:5 个真实踩坑记录

4.1 训练 loss 不降,mAP 一直是 0

现象:开训后box_loss在 1.0 附近震荡不降,mAP50始终是 0。原因:最常见的是标签路径不对,YOLO 找不到标签文件,把所有图当成无目标背景在训。解决:检查labels/train目录下是否有和images/train同名的 txt 文件,YOLO 是按文件名匹配的,leaf_001.jpg必须对应leaf_001.txt。另外确认data.yaml里的path是绝对路径或相对于运行目录的正确路径。

4.2 验证集 mAP 很高但实际推理全是错框

现象:训练日志里mAP50到了 0.9,但拿新图片推理时框的位置完全不对。原因:验证集和训练集划分时用了同一批图片,或者验证集图片和训练集高度相似(同一片叶子不同角度),模型过拟合了。解决:划分时确保同一片叶子的不同角度图片分到同一集合,不要跨集合。另外检查验证集的标签是否和训练集用了同一套类别映射。

4.3 某个病害类别完全检测不到

现象:混淆矩阵里某个类别(比如霜霉病)的检测数几乎为 0。原因:这个类别的训练样本太少,或者标注时这个类别的框画得太小、太模糊。解决:先统计每个类别的标注框数量,如果某个类别少于 50 个框,考虑做数据增强(旋转、亮度调整、 mosaic)或者过采样。如果标注框本身有问题,回去重新标。

4.4 训练到一半 BN 层崩溃,loss 变成 NaN

现象:训练若干轮后 loss 突然变成 NaN,报错涉及 BatchNorm。原因:batch size 太小(比如 2 或 4),BN 层统计量不稳定;或者学习率太大导致梯度爆炸。解决:把 batch 提到 8 以上,如果显存不够就减小imgsz;把lr0降到 0.001 试试;YOLOv8 默认用 SGD,如果换了 Adam 更容易出现这个问题,可以加梯度裁剪。

4.5 推理速度慢,达不到实时

现象:模型精度还行,但单张图推理要几百毫秒。原因:用了太大的模型(比如 yolov8x)或者输入尺寸设得太大。解决:葡萄叶片病害检测不需要 x 级别的模型,yolov8n 或 s 足够。把imgsz从 1024 降到 640,速度能快一倍以上。如果还不行,导出 ONNX 或 TensorRT 做推理加速。

5. 把 mAP 从 0.7 推到 0.9:数据增强、类别平衡与推理后处理技巧

跑通第一个模型之后,大部分人会发现 mAP50 卡在 0.7 左右上不去。这时候别急着换更大的模型,先把数据层面的事情做透。葡萄叶片病害检测的精度瓶颈通常不在网络容量,而在病斑太小、类别不均衡、背景干扰这三件事上。

第一招是针对性数据增强。YOLOv8 默认开了 mosaic、HSV 抖动、随机翻转,但对小病斑来说还不够。我一般会额外开copy_paste(把病斑复制粘贴到其他位置)和mixup,这两个对小目标检测提升明显。配置写在data.yaml同级目录的hyps.yaml里,训练时用hyp=./hyps.yaml加载。注意copy_paste对标注质量要求高,如果框画得不准,增强后会引入噪声。

第二招是类别平衡。先跑一遍统计脚本,看每个类别的框数量。如果最多的类别是最少类别的 5 倍以上,就要处理。简单做法是在data.yaml里给每个类别设权重,但 YOLOv8 不直接支持类别权重,更实际的做法是对少样本类别做过采样——把包含该类别图片的路径在训练列表里重复写几次。或者用albumentations做针对性的离线增强,把少样本类别扩到和其他类别一个量级。

第三招是推理后处理。YOLOv8 默认的 NMS 阈值是 0.7,对密集病斑场景可能偏低,导致相邻病斑被合并。可以调到 0.5 试试,看 recall 有没有提升。另外conf阈值默认 0.25,如果误检多就提到 0.4,如果漏检多就降到 0.15。这些参数在predict和val时都可以通过conf=和iou=指定。

调优手段适用场景预期提升
copy_paste 增强病斑小且分散mAP50 +3~5
少样本过采样类别不均衡少样本类别 recall +10%
NMS iou 调低病斑密集recall +2~4%
输入尺寸提到 800病斑极小mAP50 +2~3,速度降 40%

最后说一个我自己的习惯:每次调参只动一个变量,跑完记录 mAP 和各类别指标,攒够 5~6 组实验再对比。葡萄叶片病害检测这个任务,数据质量的上限比模型结构的上限高得多,把标注框画准、把类别分对、把验证集划好,比换什么模型都管用。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询