news 2026/10/5 4:05:59

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
玉米黄曲霉素识别数据集: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_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 checks

yolo 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=True

conf=0.25是置信度阈值,调高会减少误检但可能漏检,农业场景里漏检一个病穗的代价通常比误检大,所以我一般先设 0.25 看召回,再按业务调。推理结果默认存到runs/detect/predict/,对照原图看框的位置是否贴合病斑。

一个我踩过的坑:有次验证集 mAP 很高,但拿到田间新图上一跑,模型把阴影和枯叶也框成病斑。后来发现训练集里几乎没有阴影样本,模型学的是"深色区域=病斑"这种捷径。从那以后我每次拿到农业数据集,都强制先抽 20 张不同光照、不同角度的图做一轮盲测,再决定要不要补数据。这份数据集用的是原始图片,场景多样性比摆拍图好,但盲测这一步不能省。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 4:04:42

跨境必备:动态住宅IP从原理到实战的完整指南

做跨境这几年,我几乎每天都要跟“动态住宅IP”打交道。刚开始接触时一脸懵,觉得不就是换个IP吗,有什么好研究的。直到自己操盘的店铺因为IP关联被平台警告、广告账号因为环境异常被限制,才真正意识到:动态住宅IP不是“…

作者头像 李华
网站建设 2026/10/5 4:04:10

38毫秒:Cloudflare 开源的 Clef 决策模型,本地 6GB 就能跑

让大模型做判断题,它总想给你写小作文。Cloudflare 开源的 Clef 干脆不生成文字:一次前向传播,直接返回每个选项的概率。本文用 Clef-Flash Q4_K_M 量化版在本地跑了一遍,还写了个 .NET 控制台来测它。 1. 引言 做 Agent 或者工作…

作者头像 李华
网站建设 2026/10/5 4:04:08

CSS入门 从样式到选择器

一、样式优先级行内样式优先级高于内部、外部样式 内部样式和外部样式同级,规则:后来者居上 同一个样式内部优先级:后面属性覆盖前面同名属性CSS 语法组成:选择器 {声明块}书写规范代码空格书写规范,合理留白CSS 注释&…

作者头像 李华
网站建设 2026/10/5 4:04:04

STM32F407修改时钟频率后串口乱码:HAL库下时钟树与波特率深度解析

凡是玩过 STM32F407 而且用 HAL 库写过串口的人,大概率都遇到过这么一件怪事:程序明明逻辑没啥问题,只是把系统主频从默认的 168MHz 改成了别的值,或者把外部晶振从 8MHz 换成了 25MHz,串口助手里的数据就变成了一堆完…

作者头像 李华
网站建设 2026/10/5 4:03:44

DeepSeek-Coder v2.5在ERP二次开发中的本地化代码生成实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/5 4:02:52

考虑充电负荷空间可调度特性的分布式电源与充电站联合配置

1. 为什么分布式电源和充电站必须“联合配置”而不是各自为政做配电网规划的朋友应该都有体会,分布式光伏、风电这类东西和电动汽车充电站,前几年还是两个独立的研究方向。做DG优化的只管在哪装、装多大,做EV研究的只管充电站选址定容&#x…

作者头像 李华