
简介番茄病害识别目标检测数据集面向深度学习与计算机视觉方向的开发者、研究者可用于训练YOLO系列算法也可适配Faster Rcnn、SSD等检测框架解决番茄种植中斑萎病毒、早疫病、赤霉病以及健康果实的自动识别和边框定位问题。该数据集已将图片和标注划分为训练集、验证集与测试集同时提供YOLO格式的txt标签和VOC格式的xml标签并附有指定类别信息的yaml配置文件能够直接接入YOLOv5至YOLOv10等主流训练流程省去格式转换与手动分集的繁琐步骤。压缩包大小约139.11MB共2000个文件其中1999个为txt标注文件、1个为yaml文件数据对应2083张番茄图像涵盖不同时期与拍摄角度的病斑表现文件结构经过整理便于导入现有工程。已有368人学习/下载适合需要高质量农业标注数据进行模型训练、算法对比与迁移学习的开发者也可用于农业智能应用团队快速搭建番茄病害自动识别系统明显降低数据收集和人工标注成本。1. 番茄病害识别数据集2083 张图、两种标注下载完先别急着开训练先说结论这是一份拿到手就能直接喂给 YOLO 的农业目标检测数据。2083 张番茄叶部图像覆盖斑萎病毒、早疫病、健康番茄、番茄赤霉病四个类别图片和 txt 标签已经按训练集、验证集、测试集分好同时还保留 xml 标签和写好了类别信息的 yaml 配置YOLOv5 一直到 YOLOv10 系列都能直接接上。相比那些爬下来还得自己标注、自己切分的数据集这份资源省掉的是最脏最耗时的活适合第一次做目标检测入门的人也适合想快速验证作物病害识别方案的一线工程师。不过打开文件夹仔细看了一会儿发现有个容易被忽略的细节需要先厘清文件名里嵌了一长串.rf.哈希指纹每张图同时存在 txt、xml 两种标注而它们之间靠同名文件对应。如果没弄清楚这三类文件的关系后续训练大概率会在数据加载这一步就翻车。这篇文章就按我实际拆包的顺序把结构、训练、踩坑一次讲透。2. 数据集结构与标注格式txt、xml、yaml 三件套怎么对应2.1 目录结构train、valid、test 与图片/标签分离这份数据是最常见的导出布局图片放在 images 目录标签放在 labels 目录整体按 train、valid、test 三个文件夹切好。解压后你会看到类似下面这样的结构tomato-disease/ ├── train/ │ ├── images/ │ └── labels/ ├── valid/ │ ├── images/ │ └── labels/ ├── test/ │ ├── images/ │ └── labels/ ├── data.yaml └── 部分子目录还额外带 xml/ 文件夹图片是 jpg训练标签是 txt两者靠同名文件对应。文件名形如IMG_20220928_165429_jpg.rf.89ce95dcb92b80f677e4775f19bea1a4前面的日期时间像是现场采集时保留的原始文件名后面那 32 位十六进制是导出平台为了避免重名自动追加的指纹。这个指纹在图片、txt、xml 三个文件里完全相同复制文件时如果只搬了其中一部分后缀YOLO 训练就会报找不到对应文件。我拿到手的第一件事是各目录数一遍文件数量确认划分没丢东西for d in train valid test; do echo $d: $(find $d/images -type f | wc -l) images, $(find $d/labels -type f | wc -l) labels done老实用例里这一步能直接暴露两种问题一是某个子目录标签数量对不上图片数量二是标签被多套了一层文件夹导致路径对不齐。常见导出比例大概是 70/20/10 或 80/10/10训练集占大头test 目录图片少是正常的不用慌真正要警惕的是 valid 太小后续调参时会发现验证集的 loss 曲线抖得厉害指标看似在动实际缺乏统计意义。提示ruff是导出平台的惯用机制文档对应不是病毒但如果你在 Windows 上额外复制这套文件超长路径有被压缩工具截断的风险尽量保留原目录结构操作。2.2 两种标注的定位txt 给训练器xml 给调试器同一个目标框在这份数据里有两套坐标写法容易混用。第一套是 YOLO 的 txt 标签在labels/目录下每张图对应一个同名 txt每一行代表一个目标框class_id x_center y_center width height坐标全部是相对图像的归一化值范围在 0 到 1 之间。举个例子某行的内容是1 0.4598 0.5733 0.1864 0.2417含义是类别索引为 1目标框中心点在图像横向 45.98%、纵向 57.33% 的位置框的宽和高分别占整张图的 18.64% 和 24.17%。第二套是 xml 标签VOC 风格写的是绝对像素坐标object nameEarly_blight/name bndbox xmin214/xmin ymin160/ymin xmax402/xmax ymax280/ymax /bndbox /object两套数据描述的是同一个框。训练时读 txt做可视化调试或者要转成别的检测框架时读 xml。很多人拿 VOC 的项目迁到 YOLO 会单独写转换脚本这资源直接帮你省掉了这一步。第三个关键文件是 data.yaml它是训练器的入口配置。YOLO 系训练器通过这个文件确认数据集路径、类别数量和类别名字内容大致如下path: E:/datasets/tomato-disease train: train/images val: valid/images test: test/images nc: 4 names: [Tomato_Spotted_Wilt_Virus, Early_blight, Tomato_healthy, Fusarium_wilt]names列表的排序就是 txt 里class_id数字的对应依据。平台导出时类别顺序可能按字母排也沿用了某些公共数据集自带命名。所以拿到数据先打开 yaml 看 names再回 txt 对索引别自己猜类别顺序猜错就是整套标签错位。文件内容谁在使用.jpgRGB 原始图训练、推理.txtYOLO 相对坐标标签YOLO 系列训练直接读.xmlVOC 像素坐标标签调试可视化、迁移到其他框架.yaml路径与类别配置训练入口2.3 四类番茄叶部病害的辨识要点类别含义可以参照下面这张对应关系具体英文名以你下载到的 yaml 里写的为准类别常见英文名叶片表现斑萎病毒Tomato Spotted Wilt Virus坏死斑、环状斑纹后期整叶枯萎早疫病Early blight褐色同心轮纹状病斑边缘清晰健康番茄Tomato healthy无明显病斑的正常绿叶番茄赤霉病Fusarium wilt整体黄化、萎蔫后期可能覆盖粉层四类里最容易互相干扰的是早疫病和斑萎病毒两者病斑都是不规则坏死区域颜色也接近。标注员如果没有对照样卡同一块区域经常出现两个框重叠但类别相反的标签。训练前把这部分样本抽出来肉眼过一遍比调什么损失函数都有效。另外注意健康叶片的占比在不同数据集版本里差异很大数量偏高时模型很容易偷懒把轻症叶片全判成健康。3. 直接用 YOLOv8 跑通训练环境、yaml、参数一条龙3.1 环境搭建一个包覆盖 YOLOv8 到 YOLOv11YOLOv8 之后的版本统一由 Ultralytics 维护装一次包就能用。建议先单独建一个 Python 环境避免和项目里其他依赖打架conda create -n yolo python3.10 -y conda activate yolo pip install ultralytics装完顺手确认版本和硬件python -c import ultralytics; print(ultralytics.__version__) nvidia-smi如果nvidia-smi能输出显卡信息但训练时 PyTorch 还报 CPU基本就是 CUDA 版本不匹配重装对应版本的 PyTorch 比折腾 ultralytics 本身更优先。这个数据集一共只有 2083 张图即使用 CPU 训练也能跑完只是时间以小时计。3.2 修改 data.yaml路径和类别顺序是第一步解压后的第一口饭是改 yaml 里的 path。平台导出时写入的是当时机器上的绝对路径到你本机十有八九对不上。把 path 改成存放数据集的那一层目录train、val、test 保持相对路径写法最稳path: E:/datasets/tomato-disease train: train/images val: valid/images test: test/images nc: 4改完别急着开训练先用这段代码验证数据集能不能被正确加载from ultralytics.data import YOLODataset ds YOLODataset(data.yaml) print(floaded {len(ds)} images)如果train/images路径写错这里会直接抛错如果没抛但数量和你find出来的不一致优先检查是不是有图片没有对应 txt设置路径的核心原则就一条让训练器跑起来时永远不去触碰不明确的上级路径。3.3 训练命令与参数取值数据只有 2000 多张四分类任务起点模型我建议用 yolov8s不需要一上来就上 x 或者 l。这种规模的数据量下大模型的收益远远不如数据质量来得直接大模型反而更容易过拟合。训练命令如下yolo detect train datadata.yaml modelyolov8s.pt epochs150 batch16 imgsz640 device0等价写成 Python 更直观from ultralytics import YOLO model YOLO(yolov8s.pt) model.train( datadata.yaml, epochs150, batch16, imgsz640, device0, patience20, )几个关键参数我按实际经验重点说一下epochs150偏保守。数据量小训练到 80 代左右 mAP 往往进平台期多出来的轮次通常靠早停拦住。如果你的验证指标在中期已经稳定可以提前停止。batch16默认值显存充足可以加到 32。batch 加大的同时必须盯住 val loss四分类小数据集上 batch 过大会提前收敛到次优解。imgsz640番茄叶片病害的病斑最小目标一般不会小于 20 个像素640 够用。试验阶段没必要一上来就用 1280训练时间翻倍收益不一定肉眼可见。patience20连续 20 个 epoch 验证集指标不涨就早停。这是后悔药训练中断或者效果不理想回到这条命令换参数重跑的成本很低。device0指定第一张显卡。没有显卡写cpu训练时间会明显拉长但不会报错。3.4 训练产物在哪看、看什么训练结束后所有输出在当前目录的runs/detect/train/下第二次运行会变成 train2、train3。最需要关注的是这几个文件文件看什么results.pngtrain loss、val loss、mAP 曲线一页看完confusion_matrix.png四类之间的误判情况weights/best.pt验证集上指标最优的权重weights/last.pt最后一轮权重我习惯先看results.png里 val/box_loss 的曲线形态一路向下说明数据干净、训练配置合理如果后段翘头多半是过拟合回第 4 章检查增强和类别分布。接着点开confusion_matrix.png重点看早疫病和斑萎病毒两行非对角线格子里的数字这两个类互相串味再正常不过数字大就回去查原始标注看是不是一批坏框。4. 番茄病害训练避坑指南标签、坐标、类别失衡的实战记录4.1 坑一训练日志报 no labels但 txt 文件确实存在现象训练刚开始就打出WARNING no labels found in train/images或者某个 epoch 结束 mAP 一直是 0。原因最常见的是目录层级不对。YOLO 训练器根据 data.yaml 里train字段推导标签目录你写train: train/images它默认去train/labels找 txt。有些平台导出包会在中间多套一层 annotations 之类的目录txt 根本不在预读位置。另一个高频原因是图片和标签的文件名做了截断哈希尾缀对不齐。解决先把标签目录对齐到训练器的预读位置再用自检脚本检查对应关系import os image_dir train/images label_dir train/labels for f in sorted(os.listdir(label_dir)): if not f.endswith(.txt): continue base f[:-4] img os.path.join(image_dir, base .jpg) if not os.path.exists(img): print(missing image:, f)输出为空说明对应关系完整有输出就把缺失图片补齐或者换用短文件名重命名。这一步是我每次拿到新数据集的流水线第一环。4.2 坑二txt 坐标读错推理时框全部偏移现象训练能跑、loss 也降但用 best.pt 到单张图上推理时预测框总是整体往右下或左上漂移边界框完全没压在叶片上。原因txt 里五个值全是对 0~1 的相对坐标x_center 是中心点的横向位置不是左上角。有人习惯性按 VOC 格式把第一个数当成 xmin或者把中心坐标和宽高搞混画出来的框自然风马牛不相及。还有一个坑是按四舍五入只保留两位小数归一化坐标在 0.5 附近的框错位 0.01等于 640 图像里偏 6 个像素小病斑框直接舍掉一半。解决写一小段可视化脚本在原始图上把第一个 txt 的框画出来import cv2 img cv2.imread(train/images/IMG_20220928_165429_jpg.rf.7b25e280e9a0884f573233b267898917.jpg) h, w img.shape[:2] with open(train/labels/IMG_20220928_165429_jpg.rf.7b25e280e9a0884f573233b267898917.txt) as f: parts f.readline().strip().split() cls, cx, cy, bw, bh map(float, parts) x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imwrite(check.jpg, img)check.jpg 里红框如果和叶片贴合说明读取逻辑没问题如果整体偏了去查脚本里是不是把 cx 当成了 xmin或者换算中心点时忘了减半宽。4.3 坑三增强机制把边缘标签框吃掉了现象开了默认增强训练train loss 降得很快但 val loss 后段反弹。翻训练预览图能看到不少病斑框落在 mosaic 拼接图的边界附近目标只剩半截甚至被裁没。原因YOLOv8 的 mosaic 增强会把四张图拼成一张新图拼接时处于画布边缘的标注框会被裁剪中心点越出画布的框直接丢弃。训练日志里经常出现的WARNING labels with center outside the image就是这里来的大量出现时会影响 mAP 上限。解决先统计有多少框是贴着图像边缘的用 awk 快速扫一遍awk $20.02 || $30.02 || $20.98 || $30.98 train/labels/*.txt | wc -l数字很小就不用管属于增强噪声的正常范围。数字很大说明原始标注习惯就是贴着图缘走这种框在训练时特别脆弱。缓解办法是把 mosaic 概率调低比如 0.5代价是训练时间变长model.train( datadata.yaml, epochs150, mosaic0.5, )4.4 坑四类别不平衡健康叶占比过高现象四类里如果健康叶占了接近一半训练出来的模型会把大量轻症叶片全判成 healthy。看指标时 precision 高得吓人recall 低得离谱因为少数类病斑几乎没被召回。原因目标检测的类别不平衡在小数据集上尤其致命模型只需要学“健康叶”一个模式就能把损失压得很低少数类病斑特征被整体淹没不是调个加权损失就能救回来。解决先按 txt 统计各类框的数量cut -d -f1 train/labels/*.txt | sort | uniq -c严重失衡时我一般做两件事。第一从训练集随机删掉一部分健康叶的同名图让比例往 2:1 内靠第二对少数类病斑框做简单复制增强把该病斑区域贴到同一张图的空闲位置。提示对少数类做复制粘贴增强时注意让病斑区域和背景过度自然避开叶片边缘和叶脉密集区不然模型会额外学到矩形贴边的分布特征。4.5 坑五超长文件名在复制到别的机器时被截断现象本地训练一切正常把数据集压缩发给别人后对方报大量 missing image或者你自己换到 Windows 机器后部分 jpg 和 txt 对不上号。原因Roboflow 导出文件名等于原始文件名加.rf.再加 32 位哈希总长度经常接近 80 字符。较老版本的压缩工具和网盘同步工具在 Windows 上处理超长路径时会出现截断哈希尾缀被砍掉几位之后图片和标签就变成两条平行线。解决解压后先跑 4.1 的自检脚本确认没问题再归档。一旦发现截断统一重命名是最省事的方案我给这类数据用过批处理n1 for f in train/images/*.jpg; do mv $f train/images/tomato_$(printf %04d $n).jpg n$((n1)) done图片改名后必须同步改同一轮图片对应的 txt 和 xml不然又是一次新的错位。改完记得更新 data.yaml我一般会在目录下保留一张对照表把旧名和新名的映射存下来后面想溯源仍能找回。5. 最后验证与调参的三个实用习惯5.1 先看混淆矩阵别被综合 mAP 骗了训练结束打印的 mAP 是一个四类平均的综合分。健康叶样本多、病斑样本少时模型只要做好健康叶一类就能把 mAP50 拉到 0.9 以上但少数病斑类的召回可能只有 0.4综合分看着很高实际完全没有诊断能力。所以我拿到 best.pt 的第一件事是打开runs/detect/train/confusion_matrix.png盯着早疫病和斑萎病毒两行的非对角线格子。如果它们互相混在一起优先回查标注别急着调超参数。5.2 单独把 test 目录拉出来做一次验收训练时用的 valid 是陪训的连续 20 个 epoch 不涨就会触发早停存在过拟合到验证集的风险。最终验收应该独立跑一遍 test 目录得到迁移到未知图像后的真实手感from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) model.val(datadata.yaml, splittest, imgsz640)日志末尾会单独打印 test 集上的 mAP50 和 mAP50-95。如果 test 明显低于 val说明模型在记忆而非泛化优先回第 4 章关掉部分增强或者换小模型降低过拟合空间。这个习惯我保持了很久拦下了不少你以为效果很好、实际换个环境就打回原形的中间产物。5.3 固定一个基线版本参数每次只动一项2000 多张图的数据集调优上限本就不高最怕每次改两个变量翻车后说不清是谁的问题。我通常的流程是先按第 3 章的参数跑一版作为基线记录 val mAP接着把 imgsz 从 640 拉到 960 跑一版看病斑小目标召回有没有变化再决定要不要动 mosaic 或者 batch。每个改动只调一个变量runs 目录里的 train、train2、train3 按顺序留下来回头能直接对比曲线。从那以后我每换一份数据集都会强制走一遍同样的流程先数目录和标签数量再画一张框出来核对坐标最后统计一遍类别分布全部通过才按下训练键。这套流程救了我很多次从零 mAP 的尴尬开局。希望帮到你。本文还有配套的精品资源点击获取