ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

玉米黄曲霉素识别数据集:YOLOv11人工标注与训练全流程

玉米黄曲霉素识别数据集:YOLOv11人工标注与训练全流程 简介这份玉米黄曲霉素识别数据集面向从事农业病害检测、粮食安全筛查的算法工程师与深度学习学习者用于训练和验证玉米穗腐病等霉变目标的检测模型。数据均基于原始田间图片采用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_okTrue) os.makedirs(f{DST_DIR}/labels/{split}, exist_okTrue) def parse_class(filename): # 按前缀匹配类别长前缀优先避免 fusarium-ear-rot 被 fusarium-diseases 误吞 for cls in sorted(CLASSES, keylen, reverseTrue): 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 python3.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 \ datadata.yaml \ modelyolo11n.pt \ epochs100 \ imgsz640 \ batch16 \ patience20 \ projectruns/corn \ nameexp1逻辑说明modelyolo11n.pt是 nano 版预训练权重适合先跑通流程imgsz640是 YOLO 系列常用输入尺寸农业病害图如果病斑小可以提到 960 或 1280但显存占用会涨patience20表示 20 轮验证指标不升就早停防止过拟合。batch16要按显存调爆显存就降到 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.jpglabel 叫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而不是imagesYOLO 对目录名是敏感的。解决把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 \ modelruns/corn/exp1/weights/best.pt \ sourcetest_images/ \ conf0.25 \ saveTrueconf0.25是置信度阈值调高会减少误检但可能漏检农业场景里漏检一个病穗的代价通常比误检大所以我一般先设 0.25 看召回再按业务调。推理结果默认存到runs/detect/predict/对照原图看框的位置是否贴合病斑。一个我踩过的坑有次验证集 mAP 很高但拿到田间新图上一跑模型把阴影和枯叶也框成病斑。后来发现训练集里几乎没有阴影样本模型学的是深色区域病斑这种捷径。从那以后我每次拿到农业数据集都强制先抽 20 张不同光照、不同角度的图做一轮盲测再决定要不要补数据。这份数据集用的是原始图片场景多样性比摆拍图好但盲测这一步不能省。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进