简介:这份玉米黄曲霉素识别数据集面向从事农业病害检测、粮食安全筛查的算法工程师与深度学习学习者,用于训练和验证玉米穗腐病等霉变目标的检测模型。数据均基于原始田间图片,采用YOLOv11完成人工标注,官方验证准确率可达93.8%以上,可直接用于目标检测训练、模型微调与精度对比实验。压缩包共865个文件,包含432张jpg原始图像、432个同名txt标注文件及1个yaml数据配置文件,整体约27.58MB,标注与图像一一对应,yaml文件便于快速接入训练流程。内容覆盖镰刀菌穗腐、赤霉穗腐等多种病害类别,样本命名规范、类别清晰,适合作为小样本农业检测任务的基线数据。目前已有427人学习下载,可作为病害识别项目的数据支撑与效果验证参考。
1. 玉米黄曲霉素识别数据集:从原始图片到 YOLOv11 人工标注的落地路径
玉米穗腐病里最让人头疼的不是肉眼可见的霉层,而是黄曲霉素这类看不见的次级代谢产物——等你发现籽粒发绿、发灰、发粉,往往已经错过了最佳防控窗口。这份玉米黄曲霉素识别数据集,走的是另一条路:用原始田间图片做 YOLOv11 人工标注,把"哪种穗腐、什么症状、在果穗哪个位置"变成可训练的目标框,官方给出的验证准确率在 93.8% 以上。它解决的不是"能不能识别"的问题,而是"有没有一份标注干净、类别明确、能直接喂给 YOLOv11 训练"的农业病虫害识别数据。适合做农业 AI 落地、植保图像算法、以及想拿真实作物数据跑通 YOLOv11 全流程的从业者。文件名里反复出现的 fusarium-ear-rot、gibberella-ear-rot,就是镰刀菌穗腐和赤霉穗腐这两类核心标注对象。
2. 数据集结构与标注逻辑:先看懂 fusarium 和 gibberella 的类别边界
2.1 从文件名反推数据组织方式
拿到压缩包解压后,第一眼看到的是一堆形如fusarium-ear-rot5_jpeg.rf.74cba18136688a9a886ae2c38c8dd0b9.jpg的文件。这个命名不是随便起的,它至少透露了三层信息:类别前缀(fusarium-ear-rot / gibberella-ear-rot / fusarium-diseases)、序号(5、27、36)、以及一段哈希后缀。哈希后缀通常是导出或去重时生成的,说明这批图在整理阶段做过唯一性处理,避免同名覆盖。
常见做法是:图片放images/,同名.txt标注放labels/,类别映射写进data.yaml。YOLOv11 沿用 Ultralytics 的目录约定,所以你需要先把散落的 jpg 归位。下面这段脚本干的就是"按类别前缀分桶 + 生成 YOLO 目录结构"这件事:
import os import shutil import re SRC_DIR = "raw_images" # 解压后图片所在目录 DST_DIR = "dataset" # 输出数据集根目录 CLASSES = ["fusarium-ear-rot", "gibberella-ear-rot", "fusarium-diseases"] # 建立 YOLO 标准目录 for split in ["train", "val"]: os.makedirs(f"{DST_DIR}/images/{split}", exist_ok=True) os.makedirs(f"{DST_DIR}/labels/{split}", exist_ok=True) def parse_class(filename): # 按前缀匹配类别,长前缀优先,避免 fusarium-ear-rot 被 fusarium-diseases 误吞 for cls in sorted(CLASSES, key=len, reverse=True): if filename.startswith(cls): return cls return None count = {c: 0 for c in CLASSES} for fname in os.listdir(SRC_DIR): if not fname.lower().endswith((".jpg", ".jpeg", ".png")): continue cls = parse_class(fname) if cls is None: continue # 简单按 8:2 切分,实际项目建议先分层再随机 split = "val" if count[cls] % 5 == 0 else "train" shutil.copy(os.path.join(SRC_DIR, fname), os.path.join(DST_DIR, "images", split, fname)) count[cls] += 1 print(count)逻辑说明:parse_class用"长前缀优先"排序,是因为fusarium-ear-rot和fusarium-diseases共享fusarium开头,如果按短前缀匹配,fusarium-diseases1可能被错误归到 ear-rot 类。参数上,count[cls] % 5 == 0是个偷懒的切分方式,真实项目里应该先按类别分层,再在每类内部随机抽 20% 进 val,否则小类别可能全进 train,验证集里一个样本都没有,准确率就是玄学。
2.2 类别定义与标注粒度
这份数据集的核心类别是镰刀菌穗腐(fusarium-ear-rot)和赤霉穗腐(gibberella-ear-rot),另外还有 fusarium-diseases 这个更宽泛的标签。标注粒度上,YOLOv11 做的是目标检测,所以每个标注框对应果穗上的病斑区域或整穗。这里有个容易翻车的点:如果标注时一会儿框整穗、一会儿框病斑,模型学到的就是混乱的尺度先验,验证准确率会虚高但实际推理时框飘。
| 类别前缀 | 含义 | 建议标注粒度 |
|---|---|---|
| fusarium-ear-rot | 镰刀菌穗腐 | 病斑区域或整穗,全数据集统一 |
| gibberella-ear-rot | 赤霉穗腐 | 同上,与上一类保持同一策略 |
| fusarium-diseases | 镰刀菌属病害泛类 | 仅当无法细分时使用,避免与 ear-rot 混标 |
提示:如果你的任务只是"有没有穗腐"的二分类,可以把两类合并;但如果要做病害区分,就别把 gibberella 和 fusarium 混进同一个框,否则模型永远学不会区分。
3. YOLOv11 训练环境配置与 data.yaml 写法
3.1 环境安装与版本对齐
YOLOv11 通过 Ultralytics 包分发,环境配置本身不复杂,坑在于 CUDA、PyTorch、Ultralytics 三者的版本对齐。我一般会先锁 PyTorch,再装 Ultralytics,避免它自动拉一个不匹配的 torch 版本。
# 建议在独立虚拟环境里操作 conda create -n yolo11 python=3.10 -y conda activate yolo11 # 先装与显卡驱动匹配的 PyTorch,这里以 CUDA 12.1 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 再装 Ultralytics pip install ultralytics # 验证环境 yolo checksyolo checks会打印出 PyTorch 版本、CUDA 是否可用、以及 Ultralytics 自身版本。如果 CUDA available 显示 False,别急着怀疑数据集,先回去查驱动和 torch 的 CUDA 版本是否对得上。这一步是后面所有训练的前提,环境没通,后面全是黑匣子。
3.2 data.yaml 的字段与路径陷阱
YOLOv11 训练靠data.yaml告诉它去哪找图、有几类、类名是什么。这份数据集三类,写法如下:
path: /abs/path/to/dataset # 数据集根目录,建议写绝对路径 train: images/train val: images/val names: 0: fusarium-ear-rot 1: gibberella-ear-rot 2: fusarium-diseases参数说明:path用绝对路径能避开"相对路径随工作目录漂移"的经典坑;train和val是相对path的子路径;names的索引必须和标注 txt 里的类别 id 严格对应,0 对应第一个类,写反了模型就把镰刀菌认成赤霉。标注 txt 每行格式是class_id x_center y_center width height,且坐标是归一化到 0~1 的,如果你拿到的标注是像素坐标,得先转换,否则训练 loss 会大得离谱。
3.3 启动训练与关键参数
yolo detect train \ data=data.yaml \ model=yolo11n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ patience=20 \ project=runs/corn \ name=exp1逻辑说明:model=yolo11n.pt是 nano 版预训练权重,适合先跑通流程;imgsz=640是 YOLO 系列常用输入尺寸,农业病害图如果病斑小,可以提到 960 或 1280,但显存占用会涨;patience=20表示 20 轮验证指标不升就早停,防止过拟合。batch=16要按显存调,爆显存就降到 8 或 4。训练日志里重点看mAP50和mAP50-95,官方说的 93.8% 准确率通常对应 mAP50 这个量级,别拿它当 mAP50-95 理解。
4. 避坑与排查:标注、路径、过拟合三类高频翻车
4.1 现象:训练 loss 正常下降,但验证 mAP 一直卡在 0.3 以下
原因:最常见的是标注类别 id 和data.yaml的names顺序不一致,或者标注文件根本没被读到——YOLO 找不到对应 label 时会静默跳过,你看到的是"在训练",实际学的是空标签。另一种是图片和 label 文件名没对齐,比如图片叫xxx.jpg,label 叫xxx_jpeg.txt。
解决:先跑一遍配对检查,确认每张 train 图都有同名 txt,且 txt 里的 class_id 不越界。
import os img_dir = "dataset/images/train" lbl_dir = "dataset/labels/train" missing, bad_id = [], [] for img in os.listdir(img_dir): stem = os.path.splitext(img)[0] lbl = os.path.join(lbl_dir, stem + ".txt") if not os.path.exists(lbl): missing.append(img) continue with open(lbl) as f: for line in f: cid = int(line.split()[0]) if cid not in (0, 1, 2): bad_id.append((lbl, cid)) print("缺标注:", len(missing), "越界类别:", len(bad_id))4.2 现象:训练一开始就报 "No labels found"
原因:data.yaml里的path写成了相对路径,而你在别的目录下执行yolo train,导致它去错误的位置找images/train。或者目录名写成了image而不是images,YOLO 对目录名是敏感的。
解决:把path改成绝对路径,并用ls确认path/images/train下确实有图。别嫌麻烦,这一步省下的时间比调参多得多。
4.3 现象:训练集 mAP 0.98,验证集只有 0.6,差距巨大
原因:切分时没做分层,小类别样本几乎全进了训练集,验证集里 gibberella 只有一两张,模型没见过自然测不准。另一个原因是同一穗的多角度图被同时分进 train 和 val,造成数据泄漏,验证指标虚高。
解决:按类别分层切分,并尽量保证同一果穗的图片只出现在一个 split 里。如果原始数据没有果穗 id,至少按文件名序号做分组切分,别纯随机。
4.4 现象:推理时框出一堆重叠框,置信度都很低
原因:训练轮数不够或学习率过大,模型还没收敛;也可能是imgsz和标注时参考的尺度差异太大,小病斑在 640 下几乎不可见。
解决:先看训练曲线是否收敛,再考虑把imgsz提到 960,或在data.yaml同目录加hyp.yaml调低学习率。YOLOv11 的小目标优化本身有增强策略,但前提是你的输入分辨率别把病斑压没了。
5. 验证与进阶:用混淆矩阵和单图推理确认 93.8% 是不是真的
训练跑完,runs/corn/exp1/下会生成confusion_matrix.png、results.png和weights/best.pt。别只看一个 mAP 数字就下结论,混淆矩阵能告诉你 fusarium 和 gibberella 之间有没有互相误判——如果这两类的非对角线格子很深,说明标注边界本身模糊,93.8% 可能只是"穗腐 vs 健康"的粗粒度准确率。
单图推理验证:
yolo detect predict \ model=runs/corn/exp1/weights/best.pt \ source=test_images/ \ conf=0.25 \ save=Trueconf=0.25是置信度阈值,调高会减少误检但可能漏检,农业场景里漏检一个病穗的代价通常比误检大,所以我一般先设 0.25 看召回,再按业务调。推理结果默认存到runs/detect/predict/,对照原图看框的位置是否贴合病斑。
一个我踩过的坑:有次验证集 mAP 很高,但拿到田间新图上一跑,模型把阴影和枯叶也框成病斑。后来发现训练集里几乎没有阴影样本,模型学的是"深色区域=病斑"这种捷径。从那以后我每次拿到农业数据集,都强制先抽 20 张不同光照、不同角度的图做一轮盲测,再决定要不要补数据。这份数据集用的是原始图片,场景多样性比摆拍图好,但盲测这一步不能省。希望帮到你。
本文还有配套的精品资源,点击获取