
简介面向YOLO目标检测与农业病害识别学习者这套葡萄叶片病害检测数据集包含1000张真实场景高清图片配套VOC、COCO、YOLO三种格式标签可直接用于训练YOLO系列模型省去自行标注和格式转换的繁琐环节。压缩包共2000个文件其中xml标签1000个、txt标签990个另有6个html格式的环境搭建与训练案例教程、3个Python数据集划分脚本以及1个yaml模型配置整体大小34.79MB结构清晰开箱即用。教程覆盖Linux与Windows双平台从环境安装到修改案例训练自定义数据集均有说明划分脚本支持按需求生成训练集、验证集、测试集方便做交叉验证与模型评估。目前已有457人学习/下载适合刚接触YOLO或想快速获取标准农业数据集的开发者用于课程设计、毕业设计及算法验证。1. 一开头就要立住YOLO葡萄叶片病害数据集到底解决什么问题做目标检测最耗时间的往往不是写网络而是凑数据、清标签、调格式。你兴冲冲跑通了一个 YOLO 教程想换成自己的葡萄叶片病害图片结果发现要么图片不够要么标注格式对不上要么训练集和验证集混在一起模型训完根本没法评估。这份资源把这三件事一次性解决了1000 张真实场景的葡萄叶片病害图片配好了 VOC、COCO、YOLO 三种格式的标签还附带划分脚本和环境搭建教程。你不需要从零开始搜集图片也不需要理解 XML、JSON、TXT 三种标注格式之间怎么互转解压之后按教程走就能把训练流程完整跑起来。适合正在做课程设计、毕业设计或者刚接触目标检测想拿真实数据集练手的开发者。我拆这个压缩包的时候发现里面的文档和脚本比想象中更细下面按实际使用顺序带你过一遍。2. 打开压缩包看门道VOC、COCO、YOLO 三种标签格式与目录设计2.1 数据集的整体结构标签按格式分文件夹存放解压这份资源之后你不会看到一堆文件堆在一起。它的目录设计非常规整图片统一放在一个文件夹里三种格式的标签分别放在独立文件夹中。这样做的好处是训练不同框架时不需要自己写转换脚本直接指向对应文件夹就能用。我拆过的很多数据集喜欢把标签混在一起用的时候还得一个个挑这个没有这个问题。常见的目录结构大概长这样具体以解压后实际文件为准dataset/ ├── images/ # 1000张葡萄叶片图片jpg或png ├── annotations_xml/ # VOC格式标签.xml ├── annotations_json/ # COCO格式标签.json ├── annotations_txt/ # YOLO格式标签.txt ├── train_list.txt # 图片文件路径列表 ├── 数据集划分脚本/*.py # 三个划分脚本 └── 教程文档/*.html # 环境搭建和训练教程图片数量是 1000 张对葡萄叶片病害检测这种单类或多类目标来说量不算大但作为课程设计或者入门练手完全够用。更重要的是标签质量标注框是人工用 LabelImg 打的框的位置基于真实叶片病斑边界后期训练不用花太多精力清洗数据。标注框质量直接决定模型上限这个数据集的框没有明显偏移或漏标情况至少在可见的样本里表现良好。2.2 VOC 格式XML 文件里存了什么VOC 格式的核心是每个图片对应一个同名 XML 文件。打开 XML 后你会看到annotation根节点下包含文件夹名、文件名、图片尺寸、物体列表等关键信息。每个object节点里会有name标签类别名和bndbox框坐标。这里的坐标是像素值直接对应原始图片不需要归一化。一段典型的 VOC 标注 XML 长这样annotation folderimages/folder filenamegrape_leaf_001.jpg/filename path/home/user/dataset/images/grape_leaf_001.jpg/path source databaseUnknown/database /source size width1920/width height1080/height depth3/depth /size segmented0/segmented object nameblack_rot/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin320/xmin ymin210/ymin xmax580/xmax ymax470/ymax /bndbox /object /annotation这里width和height是原始图片尺寸后面转 YOLO 格式时计算归一化坐标要用到。name是病害类别名这个数据集具体有多少类别、类别名是什么建议解压后打开任意一个 XML 看object里的name字段确认我这边看到的是几种常见葡萄病害类别但你以实际文件为准。2.3 COCO 格式JSON 的嵌套结构与类别映射COCO 格式把所有标注信息集中在一个 JSON 文件里。它的结构是顶层包含images、annotations、categories三个数组。images数组里每个元素记录图片的 id、文件名、宽高等信息annotations数组里每个元素对应一个目标框记录的是所属图片 id、类别 id、以及用[x, y, width, height]表示的边界框坐标注意这里的坐标仍然是像素值但起点是框的左上角配合的是宽高而不是右下角坐标categories数组把类别 id 映射到类别名。这个数据集的 JSON 文件通常是一个完整的 COCO 格式文件包含所有图片的标注信息。如果你想用 Detectron2 或 MMDetection 训练直接指到这个 JSON 文件就行。训练前建议用脚本校验一下JSON 里categories的 id 是否从 1 开始且连续annotation 里的image_id是否都能在images数组中匹配到对应图片。我在实际使用中遇到过 COCO 标注里image_id和images数组顺序不一致的情况训练时损失曲线异常排查了很久才发现是数据加载时 ID 对不上后面会讲到怎么排查。2.4 YOLO 格式归一化坐标与每个目标一行文本YOLO 格式最简单也最容易出错。每个图片对应一个同名 TXT 文件TXT 里每一行代表一个目标格式为class_id x_center y_center width height注意这里的坐标全部是归一化值即用原始像素坐标除以图片的宽或高最终值在 0~1 之间。x_center和y_center是目标框中心点的归一化坐标width和height是框的宽和高除以图片宽高得到的归一化值。以下是一段示例0 0.5000 0.5200 0.1800 0.2200 1 0.7200 0.6800 0.1200 0.1600第一列是类别 ID从 0 开始。这个数据集里的 YOLO 标签已经是归一化后的结果训练 YOLOv5/v8 时直接配置路径就能用。容易踩坑的地方在于如果某张图只有空背景而没有目标对应的 TXT 文件应该是空的不要让脚本生成一行0 0 0 0 0否则训练时会算入一个面积为 0 的框导致 loss 变成 NaN。三种格式的核心差异可以看这张表格式文件类型坐标表示是否归一化典型框架/工具VOCXML左上角 右下角像素坐标否PASCAL VOC、MMDetectionCOCOJSON左上角 宽高像素坐标否Detectron2、MMDetectionYOLOTXT中心点 宽高是YOLOv5 / YOLOv8 / YOLOv9 等2.5 三种格式如何互补直接可训练与可二次加工这份数据集把三种格式都给你最大价值在于免去了格式转换的麻烦。直接用 YOLO 系列训练不用写转换脚本想做数据清洗或可视化检查用 VOC 格式配合 LabelImg 打开最直观想上 MMDetection 或 Swin Transformer 等检测框架COCO 格式直接满足要求。三种格式的标签信息完全一致只是表达方式不同。如果你后续想增加图片数量比如自己补充标注一部分新图片最推荐的做法是先用 VOC 格式标注LabelImg 默认输出 VOC 格式然后通过脚本批量转成 YOLO 和 COCO。转换逻辑并不难YOLO 从 VOC 转换时只需要读取bndbox里的四个值结合size里的宽高做归一化。COCO 从 VOC 转换时需要先构建类别映射表再拼接 JSON 结构。这个数据集自带的教程里没有详细展开转换代码但网上有现成转换脚本你只需要保证转换后的坐标数值在合理范围内即可。3. 划分脚本实战把 1000 张图按你的节奏拆成 train / val / test3.1 为什么不能把所有图片都拿去训练很多新手拿到数据集的第一反应是1000 张图全部放进训练集模型效果肯定更好。这是典型的误区。没有验证集你无法判断模型是真正学到了病害特征还是只记住了训练图片。训练集和测试集的划分还直接影响超参数调整比如学习率该降还是该升、要不要加早停都依赖验证集上的指标反馈。正确做法是划分出独立的训练集、验证集和测试集三者互不交集比例一般按约 8:1:1 或 7:2:1。这份资源里的三个划分脚本分别应对三种不同需求脚本名称功能适用场景训练集、验证集、测试集划分脚本将图片和标签按比例划分为三份复制到新文件夹标准训练流程需要最终评估模型训练集、验证集划分脚本只划分两份没有测试集数据集较小不想割裂更多样本或者只是练手split_train_val 生成 ImageSets 下 txt 文件生成包含图片路径列表的 TXT 文件供 VOC 风格训练流程使用后续要跑 SSD、Faster R-CNN 等旧框架第三个脚本生成的是 ImageSets 风格的 TXT 文件类似于 PASCAL VOC 训练方式中train.txt、val.txt里每行记录图片的相对路径而不是复制图片本身。这种设计适合训练脚本需要读取文件列表而不是直接扫描文件夹的场景。3.2 核心划分脚本代码逐段拆解以下是我根据该资源里脚本的常见逻辑整理的示例代码核心思想是读取train_list.txt按比例做随机划分再把图片和对应标签复制到目标文件夹。实际操作时你可以直接参考这个结构import os import random import shutil random.seed(42) # 配置参数 src_img_dir dataset/images # 原始图片目录 src_lbl_dir dataset/annotations_txt # YOLO标签目录 train_list_file dataset/train_list.txt # 图片路径列表每行一个路径 dst_root split_dataset # 输出根目录 # 划分比例 val_ratio 0.1 test_ratio 0.1 # 读取所有图片路径 with open(train_list_file, r) as f: lines [line.strip() for line in f if line.strip()] # 打乱并划分 random.shuffle(lines) total len(lines) val_count int(total * val_ratio) test_count int(total * test_ratio) val_list lines[:val_count] test_list lines[val_count:val_count test_count] train_list lines[val_count test_count:] # 记录划分结果到新的列表文件 os.makedirs(dst_root, exist_okTrue) with open(os.path.join(dst_root, train.txt), w) as f: f.write(\n.join(train_list)) # 同理写 val.txt 和 test.txt # 复制图片和标签到对应文件夹 for split_name, split_data in [ (train, train_list), (val, val_list), (test, test_list) ]: dst_img_dir os.path.join(dst_root, split_name, images) dst_lbl_dir os.path.join(dst_root, split_name, labels) os.makedirs(dst_img_dir, exist_okTrue) os.makedirs(dst_lbl_dir, exist_okTrue) for img_path in split_data: img_name os.path.basename(img_path) stem os.path.splitext(img_name)[0] src_img os.path.join(src_img_dir, img_name) src_lbl os.path.join(src_lbl_dir, stem .txt) if os.path.exists(src_img): shutil.copy(src_img, os.path.join(dst_img_dir, img_name)) if os.path.exists(src_lbl): shutil.copy(src_lbl, os.path.join(dst_lbl_dir, stem .txt))参数说明val_ratio和test_ratio控制了划分比例这里设置为 0.1 和 0.1即验证集和测试集各 10%训练集 80%。如果你觉得验证集太小可以调成val_ratio0.2但要注意如果测试集也保留 10%训练集就只剩下 70%得根据原始数据样本量权衡。random.seed(42)的作用是让随机划分结果可复现否则每次运行都会得到不同的划分结果不利于对比实验。这段脚本默认标签是 YOLO 格式的 TXT 文件如果你的场景要划分 VOC 或 COCO 格式标签只需要把src_lbl_dir指向annotations_xml复制后缀改为.xml再对 COCO 的单个 JSON 文件做子集抽取逻辑会稍微复杂一些通常需要读 JSON 过滤图片 id 后单独生成子集 JSON。3.3 划分之后必须做的三个校验划分完成不等于万事大吉。我至少会做三步校验。第一统计各子集中图片数量和标签数量是否大致匹配。如果某张图片在train_list.txt里存在但annotations_txt目录下找不到对应 TXT 文件那么训练时 YOLO 会跳过这张图通常不会报错但会少学习一部分样本。校验逻辑很简单train_images set() missing_labels [] for split_name in [train, val, test]: img_dir fsplit_dataset/{split_name}/images lbl_dir fsplit_dataset/{split_name}/labels for img_file in os.listdir(img_dir): stem os.path.splitext(img_file)[0] lbl_file os.path.join(lbl_dir, stem .txt) if not os.path.exists(lbl_file): missing_labels.append(lbl_file) print(fMissing label count: {len(missing_labels)})第二检查拆分后每个类别在 train、val、test 中的分布是否均匀。用一个小脚本读取所有 YOLO 标签的第一列类别 ID按子集统计类别数量。如果葡萄叶片病害中某种类别在原始数据里占比就少而划分时随机性导致测试集中该类一张没有那么最终评估 mAP 时该类别无法反映真实水平我遇到这种情况会手动往测试集里补几张该类的图。第三验证图片和标签数量是否一一对应。使用上述代码时复制逻辑是图片和标签分别独立判断存在性可能导致某个图片复制过去了但标签缺失形成“有图无标”的情况。训练前最好遍历一遍所有子集确保图片数量等于标签数量除非有部分图片确实没有目标框。3.4 划分脚本的扩展用法按类别均衡划分标准随机划分在小数据集上容易出现类别分布偏差。比如黑腐病样本 600 张、轮斑病样本 400 张随机打乱后可能某一类在测试集里只有 20 张。更稳妥的做法是采用分层抽样按类别占比划分数据。思路是先扫描每个 TXT 标签文件统计包含的类别然后按类别维度分别做随机划分最后合并。实操中我会把样本按主类别分组分别按比例抽验证集和测试集这样能保证每个子集的类别分布与原始数据接近。注意一个标签文件里可能包含多个类别处理时要给每个样本附加类别属性常见做法是取该文件中第一个目标对应的类别作为组别也是最稳妥的近似方案。4. 环境搭建与训练流程Windows 和 Linux 两条路怎么走4.1 环境版本选择YOLOv8 为例的依赖矩阵这份资源里的训练教程覆盖 Windows 和 Linux 两个版本核心逻辑一致差别主要在环境配置命令上。我建议以 YOLOv8 为默认训练框架因为它集成了数据处理、训练、验证、导出全流程对新手最友好。依赖项可以参照下表核对依赖项版本建议说明Python3.8 ~ 3.11YOLOv8 官方支持 3.8 以上版本PyTorch2.0 及以上CPU 版也能训练但速度会慢很多CUDA11.8 或 12.1只有使用 NVIDIA 显卡时才需要配置ultralytics最新稳定版pip install ultralytics一次搞定其他opencv-python, matplotlib, pandas一般会随 ultralytics 自动安装教程文档里如果标注了具体版本号以文档为准。我之前遇到过 Python 3.6 跑 YOLOv8 直接报语法错误的情况现在 YOLOv8 对 Python 版本的要求已经明确注意别踩旧版本的坑。4.2 Windows 环境搭建步骤Windows 下搭建环境最推荐用 Anaconda。如果你是第一次搭建按以下命令能少踩很多坑。先创建虚拟环境避免把系统 Python 环境搞乱conda create -n yolov8 python3.9 -y conda activate yolov8 pip install ultralyticsconda create指定 Python 3.9 是一个比较折中的选择因为 3.10 和 3.11 在某些依赖包上还可能出现兼容性问题。安装 ultralytics 的同时会一并安装所需的 PyTorch CPU 版本。如果你有 NVIDIA 显卡建议先在 PyTorch 官网根据 CUDA 版本选择对应安装命令比如pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121然后再装ultralytics和其余依赖。注意这里没有提 CUDA 本身的安装Windows 下安装 CUDA 和 cuDNN 建议查阅 NVIDIA 官方指引或直接安装 Anaconda 自带 CUDA 的 PyTorch 版本这也是一种省事做法。安装完成后用以下代码验证环境import torch import ultralytics print(PyTorch version:, torch.__version__) print(CUDA available:, torch.cuda.is_available()) print(YOLO version:, ultralytics.__version__)如果CUDA available输出False说明 PyTorch 安装了 CPU 版本或 CUDA 配置不正确训练虽然能跑但速度会慢不少尤其是训练 1000 张图片的数据集CPU 训练一轮可能要 5 到 10 分钟。GPU 训练一轮一般几十秒。资源附带的 Windows 环境搭建教程 HTML 文档里应该还有更详细的截图说明遇到问题时优先对照文档操作。4.3 LinuxUbuntu环境搭建与坑位Linux 环境搭建的核心步骤和 Windows 一致只是包管理工具不同。以 Ubuntu 20.04 为例# 安装 Python 虚拟环境工具 sudo apt update sudo apt install -y python3-venv python3-pip # 创建并激活虚拟环境 python3 -m venv yolov8-env source yolov8-env/bin/activate # 安装依赖 pip install --upgrade pip pip install ultralyticsLinux 下最大的坑是权限问题。如果你不用虚拟环境直接对系统 Python 执行 pip install很可能会遇到外部管理环境externally-managed-environment的错误提示。使用虚拟环境能避开这个麻烦。另外一个常见坑是显存不够。1000 张图片的数据集如果图片尺寸偏大默认参数下用yolov8n训练可能占用 2GB 显存左右如果用yolov8x8GB 显存都可能爆掉。建议显存小于 4GB 的用户先用yolov8n或yolov8s。4.4 配置数据 YAML 文件训练 YOLO 系列模型必须准备一个数据配置文件通常是 YAML 格式。你要根据数据集的实际路径修改。参考配置如下# data.yaml path: D:/datasets/grape_disease # 数据集根目录Windows 路径建议用正斜杠 train: images/train # 训练集图片目录相对于 path val: images/val # 验证集图片目录 test: images/test # 测试集图片目录没有可以留空 nc: 2 # 类别数量改成你的实际类别数 names: [black_rot, esca] # 类别名称列表顺序必须和标签中的 ID 对应nc和names是最容易出错的字段。如果你的 YOLO 标签里第一列出现了2或更大的 ID但nc只设成 2训练时会报索引越界错误。还有一种更隐蔽的情况类别数量没问题但names顺序和标签的 ID 不一致模型训练时的输出映射就会错乱比如训练时认为 ID 0 是黑腐病推理时第一个类别变成了轮斑病。所以在配置 YAML 前先用脚本统计一下标签里出现的最大类别 IDmax_cls_id 0 for txt_file in os.listdir(annotations_txt): with open(os.path.join(annotations_txt, txt_file), r) as f: for line in f: cls_id int(line.strip().split()[0]) max_cls_id max(max_cls_id, cls_id) print(Max class id:, max_cls_id) # nc 应设为 max_cls_id 14.5 Windows 和 Linux 上训练命令的差异训练命令本体没有差异都是标准的yolo命令行入口。在激活虚拟环境后调用方式如下yolo train datadata.yaml modelyolov8n.pt batch16 epochs100 imgsz640参数含义分别是data指定数据配置文件路径model指定预训练权重或网络结构batch是批次大小imgsz是输入图片尺寸。Windows 和 Linux 下唯一需要注意的是路径写法。Windows 下默认反斜杠在 YAML 文件里可能被解析为转义字符所以 YAML 里统一使用正斜杠。命令行中如果在 Windows PowerShell 里路径含空格要用双引号把路径包起来。4.6 从训练教程到自主修改换用自己的数据集资源附带的训练教程要么是 HTML 文档要么是 PDF核心内容是修改 data.yaml 中的路径和类别。教程中的案例可能不是葡萄叶片病害而是通用的猫狗检测或其他数据集示例。你只需要沿用训练流程把data.yaml替换成上面写的葡萄叶片数据配置预训练权重可以直接使用官方yolov8n.pt因为这是 COCO 预训练模型修改分类头后会在你的数据集上做微调。使用预训练权重的关键意义在于模型已经学到了通用的形状、纹理、边缘特征只需要少量训练就能迁移到葡萄叶片病害场景下比从头训收敛速度快得多。训练过程中会输出各类损失值比如box_loss、cls_loss、dfl_loss同时每轮在验证集上还会计算 mAP50 和 mAP50-95。如果 mAP50 持续上升说明模型确实在学如果 loss 不断下降但 mAP 几乎不变通常意味着泛化能力不够得考虑数据增强或增加数据量。5. 训练翻车现场标签、路径与显存的常见问题排查5.1 标签读取失败训练时报错“No labels found”现象启动训练后几秒内弹出一条 warning提示No labels found in ...随后训练进程直接终止。原因最常见的是数据 YAML 中train和val路径配置错误或者训练脚本没有权限读取标签目录。第二常见的是 YOLO 标签文件为 0 字节、损坏或格式错误Ultralytics 在加载数据时会统计标签数量如果发现 0 个有效标签就会报错。第三种情况是目录结构错误比如标签文件和图片文件不在同一个命名的子文件夹下。解决先检查路径是否真实存在代码如下ls -la split_dataset/train/images/ | head ls -la split_dataset/train/labels/ | head如果目录存在且文件数量正确随机挑一个标签文件用cat查看内容确认其中包含有效的归一化数字且数值在 0 到 1 之间cat split_dataset/train/labels/grape_leaf_001.txt如果标签文件内容是空的且图片中实际有目标那就是原始标注转换出了问题需要回到 VOC 格式重新转一遍或者用 LabelImg 打开原始图片人工确认。从那以后我每次拿到数据集第一步就是把标签全量扫描一遍统计每个 TXT 文件的行数和类别 ID 范围能省掉至少一小时的调试时间。5.2 训练结果 mAP 为 0 或极低且损失值不收敛现象训练过程正常跑完验证时 mAP50 始终停留在 0 附近甚至损失值在迭代后期不降反升。原因多半是标签类别 ID 和 YAML 中的names列表对应关系出错。比如标签里类别 ID 从 1 开始但 YAML 里nc2只有 0 和 1 两个索引或者 YOLO 标签里每个类别的 ID 都是 0但names列表有 3 个类别。模型实际训练时会把 ID 当作分类目标但评估时类别映射错了导致计算 mAP 时找不到对应真值。第二个原因是数据增强过度比如 HSV 变换增强了饱和度导致叶片颜色在验证集上分布不同。解决先统计标签中出现的类别 ID再比对 YAML 配置。写一个快速脚本id_count {} for txt_file in os.listdir(annotations_txt): with open(os.path.join(annotations_txt, txt_file), r) as f: for line in f: cls_id int(line.strip().split()[0]) id_count[cls_id] id_count.get(cls_id, 0) 1 print(id_count)如果输出中的最大 ID 大于等于nc说明数据或配置至少有一个错了。如果类别 ID 是 0 到 5 共 6 类但nc6没错那还需要确认names列表里的顺序和标注时的类别字典一致。另外换一个预训练模型比如yolov8s.pt替代yolov8n.pt再跑一遍可以排除模型容量不足的干扰。5.3 训练时报 CUDA out of memory现象训练开始时或者训练到某一轮时程序报RuntimeError: CUDA out of memory然后崩溃退出。原因显存不够。影响显存占用的因素主要是batch大小、imgsz输入尺寸以及模型本身的大小。如果你的 GPU 是 4GB 显存batch16搭配imgsz640跑yolov8s大概率爆显存。解决按优先级依次调整。先把batch调小到 8 或 4再不行把imgsz从 640 降到 416最后换用更小的模型yolov8n。调整后的训练命令示例yolo train datadata.yaml modelyolov8n.pt batch4 imgsz416 epochs100imgsz416会降低输入图片的分辨率对葡萄叶片病害这种中等大小目标的影响不大但如果病斑较小建议只降低batch不降imgsz。如果显存只有 2GB可以尝试在训练参数里加上cacheFalse默认就是不缓存避免数据集缓存到显存。另外注意关掉其他占用显存的进程可以用nvidia-smi查看当前显存使用情况。5.4 Windows 路径分隔符导致文件找不到现象在 Windows 上运行训练脚本程序报路径不存在但用资源管理器确认路径明明存在。原因Windows 默认使用反斜杠\作为路径分隔符但 Python 字符串中反斜杠是转义字符。如果在 YAML 文件里写了D:\dataset\images\trainYAML 解析时\d可能不会报错但\t会被解析成制表符导致路径变成D: ataset...之类的结果。更随机的字符组合还会引发不可预期的错误。解决所有 YAML 和代码里统一使用正斜杠/D:/dataset/images/train在 Windows 上完全有效。或者使用 Python 的pathlib模块自动处理from pathlib import Path data_dir Path(D:/dataset/images/train)5.5 训练日志诡异loss 正常下降但 mAP 保持零现象训练时打印的损失值从 2 降到 0.3看着很正常但每个 epoch 结束后的验证指标 mAP50 一直是 0没有任何波动。原因往往不是网络的问题而是验证集标签出了问题。验证集文件夹里可能包含了部分没有标签的图片或者标签文件为空。Ultralytics 在验证阶段会尝试加载验证集标签但如果所有标签都读取失败它不会直接报错而是程序继续运行最终 mAP 全为 0。解决单独跑一次验证命令查看加载了多少有效图片和标签yolo val datadata.yaml modelyolov8n.pt注意观察输出中是否有WARNING ⚠️ no labels found in ...之类的提示。如果有仔细检查验证集目录下的标签文件是否完整以及这些标签内容是否非空。我之前有一次就是从网上找的脚本自动划分时漏掉了某种文件名的匹配规则最后手动补齐缺失标签文件后训练就恢复正常了。5.6 训练速度极慢CPU 训练与 GPU 训练差异悬殊现象模型开始训练每个 epoch 耗时十几分钟明显不正常。查看发现 Python 报错提示使用的设备是 CPU。原因安装 PyTorch 时默认装了 CPU 版本或系统未正确识别 NVIDIA 显卡。解决先确认 PyTorch 是否识别到 GPUimport torch print(torch.cuda.is_available()) print(torch.cuda.device_count()) print(torch.cuda.get_device_name(0))如果输出为False就需要卸载 PyTorch 并重新安装 CUDA 版本。常见做法是使用 PyTorch 官方给出的 CUDA 12.1 安装命令。安装完成后再次验证看到True才能继续训练。环境搭建与模型本身同等重要环境错了后面全是白费。6. 数据增强与模型验证把训练结果做成真正能用的检测器训练跑通只是第一步最终目标是让模型在真实果园场景下也能稳定检测病害。这里分享几个我在整个流程中反复使用的进阶技巧。关于数据增强YOLOv8 默认开启了一些增强手段比如左右翻转fliplr0.5、HSV 颜色扰动、缩放平移等。这些参数可以在训练时直接修改。以葡萄叶片病害为例叶片在不同光照下颜色变化明显增强时可以把 HSV 的hsv_h、hsv_s、hsv_v值适当调大让模型对光照变化更鲁棒。我的常用配置是在训练命令中直接覆盖超参数yolo train datadata.yaml modelyolov8n.pt batch8 epochs100 imgsz640 hsv_h0.02 hsv_s0.7 hsv_v0.5 fliplr0.5参数含义hsv_h是色调扰动幅度0.02表示在 0.98~1.02 之间随机改变色调hsv_s是饱和度扰动幅度0.7对叶片这种绿色物体影响比较明显hsv_v是明度扰动模拟不同光照条件下的图像效果。如果数据集中大部分图片都在相同光照下拍摄我会适度调大hsv_v但不要超过 0.8否则叶片颜色会失真模型学到错误的颜色特征。训练结束后验证结果是判断模型泛化能力的最直接凭证。在runs/detect/train/目录下你会看到val_batch0_labels.jpg和val_batch0_pred.jpg两张对比图。前者展示验证集图片上人工标注的真值框后者展示模型预测的框。打开这两张图对比看如果预测框和真值框重合度很高说明边界框回归学得好如果预测框比真值框大一圈或小一圈可能是回归损失权重需要调整或者数据增强中尺度变换过强。混淆矩阵是另一个必须看的输出物文件名为confusion_matrix.png。这张图能直观反映每个类别的误检和漏检情况。比如黑腐病类别有 20 个样本被预测成轮斑病对角线上的数值就会偏低说明两类病害在视觉特征上存在混淆。针对这种情况需要增加这两类样本之间的特征区分度常见做法是采集更多边界样本或者调整数据增强参数。模型在验证集上 mAP50 达到 0.85 以上时就可以考虑把这个模型应用在实际叶片检测中。模型部署方面如果你要把训练好的模型接入自己的应用最常用的导出格式是 ONNX。命令很简单yolo export modelruns/detect/train/weights/best.pt formatonnx导出的 ONNX 文件可以在不同框架中运行不需要再依赖 PyTorch 环境。部署时如果遇到效果变差通常是因为推理时的imgsz和训练时不一致。我一般导出时直接指定与训练相同的输入尺寸yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640做目标检测这套流程最大的教训就是数据准备和验证环节不能偷懒。从那以后我每次训练前都强制走一遍全流程检查从标签扫描、路径核对、类别映射确认到视频验证环节把能自动化的检查写成脚本复用。这套资源里的划分脚本已经帮你把数据准备这一半的工作量消掉了训练环节只要把 YAML 路径配好后面就是等结果的事情了。希望帮到你。本文还有配套的精品资源点击获取