玉米黄曲霉素识别数据集:YOLOv8人工标注与93.8%准确率实战
简介这份玉米黄曲霉素识别数据集面向从事农业病害检测、粮食安全质检及计算机视觉方向的学习者与开发者用于训练和验证玉米穗腐病等霉变类别的目标检测模型。数据均基于原始图片经YOLOv8人工标注验证准确率可达93.8%以上可直接用于模型训练、迁移学习或算法对比实验。压缩包共865个文件包含432张jpg原始图像、432个同名txt标注文件及1个yaml数据配置文件整体约27.58MB标注与图像一一对应yaml文件便于快速接入YOLO系列训练流程。图像覆盖镰刀菌穗腐、赤霉穗腐等多种病害类别样本命名规范适合作为分类与检测任务的基准数据。目前已有372人学习下载可为农业AI项目提供开箱即用的标注数据帮助读者省去繁琐的采集与标注环节快速验证模型效果并迭代优化。1. 玉米黄曲霉素识别数据集从原始图片到 YOLOv8 人工标注的落地路径玉米穗腐病里最难缠的一类是黄曲霉素和镰刀菌、赤霉菌混发的情况。这三种病害在果穗上的早期症状高度相似肉眼区分依赖籽粒颜色、霉层颜色和穗轴腐烂位置但田间光照一变、拍摄角度一偏人眼判断的准确率就往下掉。这份玉米黄曲霉素识别数据集走的是 YOLOv8 目标检测路线所有图片都是原始拍摄图没有经过合成增强或风格迁移标注全部由人工完成验证集准确率可以做到 93.8% 以上。它适合两类人一类是想做农作物病害检测但手里没有干净标注数据的算法工程师另一类是已经跑通 YOLOv8 通用流程、想换一个真实农业场景验证模型泛化能力的从业者。数据集里包含 fusarium-ear-rot、gibberella-ear-rot、fusarium-diseases 等多个类别文件名保留了原始采集编号方便追溯每张图的来源和标注一致性。2. 数据集结构与标注格式先看清目录再动手2.1 图片命名规则与类别映射拿到压缩包后第一件事不是急着解压训练而是先看文件名。这份数据集的图片命名格式是「类别名编号_jpeg.rf.哈希值.jpg」比如fusarium-ear-rot5_jpeg.rf.74cba18136688a9a886ae2c38c8dd0b9.jpg和gibberella-ear-rot27_jpeg.rf.21c6ba8255d297251374e342a24e62e0.jpg。类别名直接写在文件名前缀里fusarium-ear-rot 对应镰刀菌穗腐gibberella-ear-rot 对应赤霉菌穗腐fusarium-diseases 是镰刀菌属相关病害的统称。哈希值那一段是采集平台生成的唯一标识不影响训练但建议保留因为后续做数据溯源或增量标注时这个哈希能帮你快速定位原图。常见做法是先用脚本把文件名里的类别前缀抽出来生成一份类别映射表。我一般会跑下面这段 Python把目录下所有图片按类别归拢顺便检查有没有命名异常的文件import os import re from collections import defaultdict img_dir ./corn_dataset/images class_map defaultdict(list) # 匹配「类别名编号_jpeg.rf.哈希.jpg」结构 pattern re.compile(r^([a-zA-Z-]?)(\d)_jpeg\.rf\.[a-f0-9]\.jpg$) for fname in os.listdir(img_dir): match pattern.match(fname) if match: cls_name match.group(1) class_map[cls_name].append(fname) else: print(f命名不符合预期: {fname}) for cls, files in class_map.items(): print(f{cls}: {len(files)} 张)这段代码的逻辑很直接用正则把类别名和编号拆开类别名作为 key 归入字典。参数上唯一需要改的是img_dir指向你解压后的图片目录。跑完之后你会得到每个类别的图片数量如果某个类别只有个位数那就要警惕了——YOLOv8 虽然对小样本有一定容忍度但单类少于 50 张时验证集准确率波动会非常大93.8% 这个数字大概率是在类别均衡的前提下测出来的。2.2 YOLOv8 标注格式与目录组织YOLOv8 用的是 YOLO 格式的 txt 标注每张图对应一个同名 txt 文件内容格式是「类别索引 中心x 中心y 宽 高」坐标全部归一化到 0~1 之间。这份数据集既然是人工标注标注质量主要看两点框是否贴紧病斑区域、类别索引是否和 data.yaml 里的 names 顺序一致。我见过太多人直接拿标注文件训练结果 mAP 死活上不去最后发现是 names 列表顺序和标注里的索引对不上这种坑后面会专门讲。目录组织建议按下面这个结构来YOLOv8 官方推荐的就是 images/labels 分离train/val 再分corn_dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml 的内容需要根据你实际的类别数来写。假设数据集里只有 fusarium-ear-rot 和 gibberella-ear-rot 两类那 yaml 就是path: ./corn_dataset train: images/train val: images/val names: 0: fusarium-ear-rot 1: gibberella-ear-rot这里有个细节names 的索引必须从 0 开始连续不能跳号。如果你把 fusarium-diseases 也单独列一类那就要确认标注文件里确实有对应的索引值否则训练时 YOLOv8 会直接报「Label class out of range」然后中断。人工标注的数据集尤其容易出这个问题因为不同标注员可能对同一张图给了不同的类别标签合并的时候索引就乱了。3. YOLOv8 训练全流程从环境配置到 93.8% 准确率复现3.1 环境配置与依赖安装YOLOv8 的环境配置不算复杂但版本兼容性是个玄学。我一般用 Python 3.9 或 3.10太新的版本反而容易和 torch 的 CUDA 版本打架。下面这套命令在 Ubuntu 和 Windows WSL 下都跑通过conda create -n corn_yolo python3.10 -y conda activate corn_yolo # 安装 PyTorch根据你的 CUDA 版本选对应命令 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 ultralytics pip install ultralytics # 验证安装 yolo checksyolo checks会输出当前环境的信息重点看 CUDA 是否可用、torch 版本和 ultralytics 版本是否匹配。如果你用的是 GTX 1660 Ti 这类 6GB 显存的卡训练时 batch size 要往下压后面参数部分会讲。常见做法是先跑一遍yolo checks确认没有报错再开始训练不然训练到一半崩了排查成本更高。3.2 训练命令与关键参数设置YOLOv8 的训练入口是yolo detect train最简命令只需要指定 data.yaml 和模型权重yolo detect train \ data./corn_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ project./runs/corn \ nameexp1这段命令里每个参数都值得说清楚。modelyolov8n.pt用的是 nano 版本参数量最小适合先跑通流程如果你追求更高准确率可以换成yolov8s.pt或yolov8m.pt但显存占用会明显上升。imgsz640是输入分辨率玉米穗腐的病斑在果穗上占比不大640 够用但如果你有大量远距离拍摄的整株图可以考虑提到 1280代价是训练速度减半。batch16在 6GB 显存上比较稳8GB 以上可以试 32。epochs100是起步值这份数据集如果类别均衡、标注干净100 轮左右验证集准确率就能到 90% 以上但想稳定复现 93.8%建议加到 200 轮并开早停。训练过程中最该盯的是runs/corn/exp1/results.csv里的 losses 和 metrics。YOLOv8 默认会画损失函数曲线图但那个图是存在results.png里的如果你想自己用 matplotlib 画更细的曲线可以读 csv 文件import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(./runs/corn/exp1/results.csv) df.columns df.columns.str.strip() plt.figure(figsize(10, 5)) plt.plot(df[epoch], df[train/box_loss], labelbox_loss) plt.plot(df[epoch], df[train/cls_loss], labelcls_loss) plt.plot(df[epoch], df[metrics/mAP50(B)], labelmAP50) plt.xlabel(epoch) plt.legend() plt.savefig(./loss_curve.png, dpi150)这段代码读的是训练日志 csv列名里可能有空格所以先 strip 一下。box_loss 和 cls_loss 是训练损失mAP50 是验证集指标。正常情况下 box_loss 应该稳步下降如果它震荡剧烈或者反弹大概率是学习率太大或者标注框质量有问题。3.3 验证集评估与准确率复现训练结束后用yolo detect val在验证集上跑一遍yolo detect val \ model./runs/corn/exp1/weights/best.pt \ data./corn_dataset/data.yaml \ imgsz640 \ batch16输出里会给出 mAP50、mAP50-95、precision、recall 等指标。93.8% 这个数字如果对应的是 mAP50那说明模型在 IoU0.5 时的平均精度已经很高了如果对应的是 precision那还要看 recall 是否均衡。我一般会同时看 precision 和 recall两者差距超过 10 个百分点就说明模型在某类上偏了。比如 fusarium-ear-rot 的 precision 很高但 recall 低意味着模型只对特别明显的病斑有响应早期症状漏检严重。想进一步看每类的表现可以加verboseTrue或者直接看混淆矩阵。YOLOv8 验证时会自动生成confusion_matrix.png那个图比数字更直观。如果某一类的对角线颜色很浅说明该类召回率不行要么加数据要么检查标注是否把该类标成了别的类。4. 避坑与排查人工标注数据集最容易翻车的五个点4.1 类别索引与 names 顺序不一致现象训练启动后报Label class 2 is out of range或者训练能跑但 mAP 极低。原因标注 txt 里的类别索引是 2但 data.yaml 的 names 只定义了 0 和 1。人工标注时不同批次可能用了不同的索引方案合并后没统一。解决写个脚本扫一遍所有 label 文件统计出现的索引值和 names 列表比对。下面这段代码可以直接用import os label_dir ./corn_dataset/labels/train idx_set set() for fname in os.listdir(label_dir): if fname.endswith(.txt): with open(os.path.join(label_dir, fname)) as f: for line in f: if line.strip(): idx_set.add(int(line.split()[0])) print(标注中出现的类别索引:, sorted(idx_set))跑完之后看输出如果索引集合和 names 的 key 集合不一致就要么改 names要么批量改标注文件里的索引。4.2 图片与标注文件不配对现象训练时提示No labels found或者某张图被跳过。原因图片是 jpg标注是 txt但文件名前缀不一致比如图片叫fusarium-ear-rot5_jpeg.rf.xxx.jpg标注却叫fusarium-ear-rot5.txtYOLOv8 找的是同名文件。解决批量重命名标注文件把哈希那段去掉只保留和图片一致的前缀。或者反过来把图片名里的哈希去掉。我一般用 shell 脚本批量处理cd corn_dataset/labels/train for f in *.txt; do # 去掉 _jpeg.rf.哈希 部分只保留类别编号 newname$(echo $f | sed s/_jpeg\.rf\.[a-f0-9]*\.txt/.txt/) mv $f $newname done注意先备份重命名操作不可逆。4.3 验证集准确率虚高数据泄漏现象验证集准确率 93.8%但换一批新图测试就掉到 70% 以下。原因同一张原始图片经过裁剪或旋转后一部分进了训练集一部分进了验证集。人工标注数据集尤其容易出这个问题因为标注员可能对同一张图的不同区域分别标注生成多个文件。解决按原始图片的哈希值分组同一哈希的图片只能出现在训练集或验证集之一。如果数据集里已经有 train/val 划分先检查两边有没有相同哈希前缀的文件。4.4 小目标病斑漏检严重现象整穗腐烂的图检测很好但早期小病斑的图 recall 很低。原因YOLOv8 默认 anchor 对中等目标更友好病斑在 640 分辨率下可能只有几十个像素。解决提高输入分辨率到 1280或者在 data.yaml 里加rectTrue做矩形训练减少 padding 带来的无效计算。另外可以试yolov8m.pt或yolov8l.pt大模型对小目标的特征提取能力更强。4.5 训练中断后无法续跑现象训练到第 80 轮断电了重新跑又从第 1 轮开始。原因没加resumeTrue。YOLOv8 支持断点续训但需要指定 last.pt 的路径yolo detect train resume model./runs/corn/exp1/weights/last.pt注意 resume 时不需要再传 data 和 epochs这些参数会从 last.pt 里读。但如果你改了 data.yaml 的路径resume 会失败所以训练中途不要动配置文件。5. 进阶技巧用热力图和 RK3588 部署验证模型真实能力训练指标好看不代表模型能用。我一般会做两件事来验证一是可视化热力图看模型到底在关注果穗的哪个区域二是把模型导出到 RK3588 这类边缘设备上跑一遍看推理速度和实际检测效果。热力图用 YOLOv8 的model.predict加 Grad-CAM 就能做核心是拿到最后一层卷积的特征图然后对目标类别做梯度加权。下面是一个简化版实现import cv2 import numpy as np import torch from ultralytics import YOLO model YOLO(./runs/corn/exp1/weights/best.pt) img cv2.imread(./test.jpg) results model(img, imgsz640) # 取第一个检测框的类别和坐标 box results[0].boxes[0] cls_id int(box.cls) xyxy box.xyxy[0].cpu().numpy().astype(int) # 裁剪病斑区域并叠加热力示意 roi img[xyxy[1]:xyxy[3], xyxy[0]:xyxy[2]] heatmap cv2.applyColorMap(cv2.convertScaleAbs(roi, alpha2), cv2.COLORMAP_JET) overlay cv2.addWeighted(roi, 0.6, heatmap, 0.4, 0) cv2.imwrite(./heatmap_roi.jpg, overlay)这段代码不是严格的 Grad-CAM但能快速看出模型检测框是否落在病斑上。如果框偏了说明标注本身就有问题这时候回头查标注比调模型更有效。RK3588 部署 YOLOv8 的流程是先把 pt 导出成 onnx再用 rknn-toolkit2 转成 rknn 模型最后用 rknn-toolkit-lite2 在板子上推理。导出命令yolo export model./runs/corn/exp1/weights/best.pt formatonnx imgsz640转 rknn 的脚本网上有很多模板核心是配置mean_values和std_values要和训练时的预处理一致。RK3588 的 NPU 对 YOLOv8 支持不错640 分辨率下单帧推理能到 30fps 以上但前提是量化校准集要覆盖各类病斑否则 int8 量化后小目标召回会掉得很厉害。从那以后我每次拿到新数据集都强制先跑一遍类别索引检查和图片标注配对检查再开始训练。这两个检查花不了十分钟但能省掉后面几小时的无效训练。希望帮到你。本文还有配套的精品资源点击获取