简介:这份资源面向从事农业图像识别、目标检测算法学习与落地的开发者及学生,提供烟草叶片病害检测的YOLOv5格式数据集,可直接用于模型训练与验证,省去繁琐的数据清洗与格式转换环节。压缩包共约2000个文件,以txt标注文件为主,另附一个可视化py脚本,整体大小约134.51MB,图像为640×640的RGB图片,边界框标注清晰、图像完整。数据集覆盖蛀虫、霉菌、细菌斑点等15个类别,训练集含2246张图片及对应标签,验证集含211张图片及对应标签,并附带15类别文本说明。资源还提供随机可视化脚本,传入图片即可绘制并保存边界框,无需修改即可运行,便于快速检查标注质量。目前已有521人学习下载,适合需要快速搭建病害检测基线、验证算法效果或开展课程实验的读者参考使用。
1. 烟草叶片病害检测数据集:15 类目标框标注,训练验证集开箱即用
烟草叶片病害检测这个方向,做的人不算多,但真落到田间地头,需求是实打实的。烟叶从苗期到采收,赤星病、黑胫病、花叶病这些病害一旦蔓延,整片地的收成就悬了。传统靠植保员肉眼巡田,一个人一天走不了几亩地,漏检、误判都是常事。这套 yolov5 目标检测数据集就是冲着这个场景来的:15 个病害类别,训练集和验证集已经切分好,标注格式直接适配 YOLO 系列,拿到手就能挂到 yolov5 或者 yolov8 上跑训练。适合谁用?做农业 AI 落地的算法工程师、搞智慧农业课题的研究生、想拿真实场景练手目标检测的开发者。它解决的不是"有没有数据"的问题,而是"数据能不能直接用、类别够不够细、标注质量扛不扛得住训练"的问题。下面我从数据组织、环境配置、训练调参到踩坑排查,把这份资源拆开讲透。
2. 数据集结构与 YOLO 格式适配:15 类标签怎么读、怎么切
2.1 目录组织与标注文件格式
拿到数据集先别急着写训练脚本,花十分钟把目录结构摸清楚,后面能省掉一堆路径报错的破事。这类烟草叶片病害数据集常见做法是按images和labels分开放,训练集和验证集各自独立,结构大致如下:
tobacco_leaf_disease/ ├── images/ │ ├── train/ # 训练集图片,jpg/png │ └── val/ # 验证集图片 ├── labels/ │ ├── train/ # 训练集标注,txt │ └── val/ # 验证集标注 └── data.yaml # 数据集配置文件标注文件是 YOLO 标准的 txt 格式,每行一个目标框,五个字段:class_id center_x center_y width height。注意后四个值都是归一化到 0~1 的相对坐标,不是像素值。这一点新手最容易翻车——直接拿像素坐标填进去,训练 loss 会大得离谱,模型根本学不动。
0 0.4523 0.6187 0.1234 0.0891 3 0.7210 0.3345 0.2015 0.1567第一列0和3就是类别索引,对应 15 个病害类别中的某一个。具体哪个索引对应哪种病害,得看data.yaml里的names列表。常见做法是赤星病、黑胫病、花叶病、野火病、角斑病等各占一个索引,但不同数据集编排顺序可能不一样,务必以实际data.yaml为准,别凭经验猜。
2.2 data.yaml 配置与类别映射
data.yaml是 YOLO 训练入口文件,路径和类别名都从这里读。一个典型的配置长这样:
path: ./tobacco_leaf_disease train: images/train val: images/val nc: 15 names: 0: brown_spot 1: black_shank 2: mosaic_virus 3: wild_fire 4: angular_leaf_spot 5: frogeye_leaf_spot 6: target_spot 7: powdery_mildew 8: downy_mildew 9: anthracnose 10: leaf_blight 11: root_knot 12: bacterial_wilt 13: vein_banding 14: healthync必须和names的条目数严格一致,写错了训练启动时就会报维度不匹配。path建议用相对路径,方便整个数据集目录迁移。如果你要把数据集挪到别的机器上跑,只改path一行就行,不用动训练脚本。
提示:改完
data.yaml后,用python -c "import yaml; print(yaml.safe_load(open('data.yaml')))"快速验证 YAML 语法,缩进错了会直接抛异常,比训练时报错好排查得多。
2.3 标注质量自检脚本
数据集标注质量直接决定模型上限。我一般拿到新数据集先跑一遍自检,看有没有越界框、零面积框、类别索引超范围的问题:
import os import glob def check_labels(label_dir, nc=15): issues = [] for txt_path in glob.glob(os.path.join(label_dir, "*.txt")): with open(txt_path, "r") as f: for line_no, line in enumerate(f, 1): parts = line.strip().split() if len(parts) != 5: issues.append(f"{txt_path}:{line_no} 字段数={len(parts)}") continue cls_id = int(parts[0]) cx, cy, w, h = map(float, parts[1:]) # 类别索引越界 if cls_id < 0 or cls_id >= nc: issues.append(f"{txt_path}:{line_no} 类别越界 cls={cls_id}") # 坐标越界 if not all(0 <= v <= 1 for v in (cx, cy, w, h)): issues.append(f"{txt_path}:{line_no} 坐标越界") # 零面积框 if w <= 0 or h <= 0: issues.append(f"{txt_path}:{line_no} 零面积框") return issues if __name__ == "__main__": problems = check_labels("labels/train") print(f"发现 {len(problems)} 个问题") for p in problems[:20]: print(p)这段脚本遍历标注目录下所有 txt,逐行检查字段数、类别索引范围、坐标归一化范围和框面积。nc参数要和data.yaml里的nc保持一致。跑完如果问题数为零,说明标注格式基本干净,可以进入训练环节;如果有问题,先修标注再训练,别指望模型能自己扛过去。
3. yolov5 环境配置与训练启动:从 conda 到第一个 epoch
3.1 环境搭建与依赖安装
yolov5 的环境配置不算复杂,但版本对不上就是各种玄学报错。我一般用 conda 建独立环境,避免和系统 Python 打架:
conda create -n yolov5_tobacco python=3.9 -y conda activate yolov5_tobacco git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txtPython 版本建议 3.8~3.10,太新了有些依赖轮子还没跟上。requirements.txt里锁定了 torch、torchvision、numpy 等核心库的版本范围,直接装就行。如果你机器有 CUDA,装完之后用python -c "import torch; print(torch.cuda.is_available())"确认一下 GPU 能不能用。返回True才说明 CUDA 和 cuDNN 都对上了,返回False就是 CPU 硬跑,训练速度差几十倍。
注意:如果你之前装过其他版本的 torch,先
pip uninstall torch torchvision清干净再装,残留的旧版本会导致ImportError或者 CUDA 初始化失败。
3.2 训练命令与关键参数
环境就绪后,把数据集目录放到 yolov5 项目同级或者任意位置,改好data.yaml里的path,然后启动训练:
python train.py \ --data ./tobacco_leaf_disease/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0 \ --project runs/train \ --name tobacco_exp1逐项说下参数含义。--data指向数据集配置文件,路径别写错。--weights指定预训练权重,yolov5s.pt是最小的模型,速度快、显存占用低,适合先跑通流程;如果精度不够再换yolov5m.pt或yolov5l.pt。--img 640是输入分辨率,烟草叶片病害的病灶区域有的比较小,640 是起步值,后面可以试 800 甚至 1024。--batch 16是批大小,显存不够就降到 8 或 4。--epochs 100是训练轮数,15 类病害的数据集一般 100~300 轮能看到收敛。--device 0指定第一块 GPU,CPU 训练就写--device cpu。
训练启动后,终端会打印每个 epoch 的 box_loss、obj_loss、cls_loss 和 mAP。前几个 epoch loss 下降快是正常的,后面会逐渐平缓。如果 loss 一直震荡不降,大概率是学习率太大或者标注有问题,先回去查标注。
3.3 训练过程监控与中断恢复
yolov5 训练过程中会在runs/train/tobacco_exp1/下生成results.csv、weights/和若干可视化文件。results.csv记录了每个 epoch 的详细指标,可以用 pandas 快速画曲线:
import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv("runs/train/tobacco_exp1/results.csv") df.columns = df.columns.str.strip() fig, axes = plt.subplots(1, 2, figsize=(12, 4)) axes[0].plot(df["epoch"], df["train/box_loss"], label="box_loss") axes[0].plot(df["epoch"], df["train/cls_loss"], label="cls_loss") axes[0].legend(); axes[0].set_title("Train Loss") axes[1].plot(df["epoch"], df["metrics/mAP_0.5"], label="mAP@0.5") axes[1].legend(); axes[1].set_title("Val mAP") plt.savefig("training_curve.png", dpi=150)results.csv的列名前后可能有空格,读进来先strip()一下。box_loss 反映边界框回归质量,cls_loss 反映分类准确度,mAP@0.5 是综合指标。正常情况下 box_loss 和 cls_loss 单调下降,mAP 单调上升,最后趋于平稳。如果 mAP 中途突然掉下去,检查是不是学习率调度或者数据增强太激进。
训练中断了也别慌,yolov5 支持断点续训:
python train.py \ --data ./tobacco_leaf_disease/data.yaml \ --weights runs/train/tobacco_exp1/weights/last.pt \ --resume--weights指向上次训练保存的last.pt,加上--resume就能从断点继续,优化器状态和学习率调度都会恢复。
4. 避坑与排查:烟草叶片病害训练里最容易翻车的五件事
4.1 现象:训练 loss 正常下降但 mAP 始终接近零
原因通常是类别索引和data.yaml里的names对不上。比如标注文件里0代表赤星病,但data.yaml里0写的是黑胫病,模型学到的分类头和验证集评估的类别完全错位,loss 能降但 mAP 上不去。解决方法是拿自检脚本把训练集和验证集的类别分布统计出来,和data.yaml逐项核对。统计命令:
for f in labels/train/*.txt; do awk '{print $1}' "$f"; done | sort | uniq -c输出每个类别索引的出现次数,如果某个索引在训练集里一次都没出现,说明这个类别没有标注样本,要么补标注要么从names里去掉。
4.2 现象:训练到一半 CUDA out of memory
原因一般是--batch或--img设太大,显存扛不住。yolov5 默认会开 AMP 混合精度,但 batch 大了照样爆。解决办法是先把--batch降到 8 或 4,再把--img从 640 降到 512 试试。如果还不行,加--workers 2减少数据加载进程数,或者用--device 0明确指定单卡,别让它自动选。另外,训练前关掉其他占显存的进程,nvidia-smi看一眼有没有残留。
4.3 现象:验证集 mAP 比训练集低一大截
这是典型过拟合。烟草叶片病害数据集如果训练集和验证集是从同一批图片里随机切的,分布差异小,过拟合不会太严重;但如果验证集来自不同地块、不同光照条件,域偏移就会很明显。解决办法有几个:一是加数据增强,yolov5 默认开了 mosaic、HSV 增强、随机翻转,可以再调大--hsv_h、--hsv_s的范围;二是减小模型容量,从yolov5m换回yolov5s;三是加早停,--patience 30表示 30 个 epoch 没提升就停。
4.4 现象:小目标病害漏检严重
烟草叶片上早期病斑可能只占几十个像素,640 分辨率下特征图上的响应很弱。常见做法是把--img提到 1024 甚至 1280,但显存和速度代价很大。另一个思路是改 anchor,用python utils/autanchor.py在你自己数据集上重新聚类 anchor 尺寸,让先验框更贴合小病斑。还可以在data.yaml同级加一个hyp.yaml,把anchor_t调小,放宽正样本匹配阈值。
4.5 现象:推理时框重叠严重、同一病斑出多个框
这是 NMS 后处理的问题。yolov5 默认--conf-thres 0.25、--iou-thres 0.45,对密集小目标可能偏松。推理时把--iou-thres降到 0.3~0.35,让重叠框合并得更狠一些。如果还是多框,检查训练时--label-smoothing是不是设太大了,标签平滑过度会让模型对同类目标的置信度分布变散,NMS 阶段就容易留多个框。
5. 进阶技巧:用验证集反推标注问题与模型选型
训练跑通只是第一步,真正决定这套数据集能不能落地的,是你能不能从验证结果里读出标注和模型的问题。我一般会在训练结束后做两件事:一是用验证集跑val.py输出每类 AP,二是把预测结果可视化出来逐类看。
python val.py \ --data ./tobacco_leaf_disease/data.yaml \ --weights runs/train/tobacco_exp1/weights/best.pt \ --img 640 \ --task val \ --save-json跑完终端会打印每个类别的 P、R、mAP@0.5、mAP@0.5:0.95。重点看两类:AP 特别低的类别和 AP 特别高的类别。AP 低的类别,要么是样本太少,要么是标注框画得太松或太紧。AP 高的类别反而要警惕——如果某个类别 AP 接近 1.0,但你看可视化结果发现模型把相似病害都归到这一类了,那说明类别间区分度不够,标注时可能把不同病害混标了。
可视化用detect.py批量跑验证集图片:
python detect.py \ --weights runs/train/tobacco_exp1/weights/best.pt \ --source ./tobacco_leaf_disease/images/val \ --img 640 \ --conf-thres 0.3 \ --save-txt \ --project runs/detect \ --name val_vis输出在runs/detect/val_vis/下,图片上会画出预测框和类别标签。逐张翻,重点看漏检的、误检的、框歪的。漏检多说明模型对这类病害特征学得不够,考虑补样本或者调 anchor;误检多说明背景干扰大,考虑加负样本或者提高--conf-thres。
模型选型上,yolov5s 适合快速验证流程,yolov5m 是精度和速度的平衡点,yolov5l 适合对精度要求高、能接受推理慢的场景。如果你后面要部署到树莓派或者边缘设备,建议直接用 yolov5s 训练,然后导出 ONNX 或者 TensorRT 做推理加速。导出命令:
python export.py \ --weights runs/train/tobacco_exp1/weights/best.pt \ --include onnx \ --img 640 \ --batch 1导出的 ONNX 模型可以用 onnxruntime 在 CPU 上跑,也可以用 TensorRT 在 GPU 上加速。注意导出时的--img要和训练时一致,否则推理精度会掉。
从那以后我每次拿到新的目标检测数据集,都强制先跑一遍标注自检脚本,再拿 yolov5s 快速训 20 个 epoch 看 mAP 曲线,确认数据没问题再上大模型和长训练。这套流程帮我省下了大量返工时间,也希望帮到你。
本文还有配套的精品资源,点击获取