十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

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

玉米黄曲霉素识别数据集:YOLOv8人工标注与训练全流程 简介这份玉米黄曲霉素识别数据集面向从事农业病害检测、粮食安全质检及计算机视觉应用的研究者与开发者尤其适合需要快速搭建目标检测模型、验证算法效果的技能进阶人群。资源以原始玉米穗图像为基础采用YOLOv8完成人工标注验证准确率可达93.8%以上可用于黄曲霉素污染区域定位、病害分类识别等任务。压缩包共865个文件包含432张jpg原始图片、432个txt标注文件及1个yaml配置文件整体约27.58MB图片与标注一一对应yaml文件便于直接接入训练流程。内容覆盖镰刀菌穗腐病、赤霉穗腐病等多种玉米病害样本标注质量经过人工校验能有效支撑模型训练与评估。目前已有372人学习下载适合作为病害识别项目的基线数据帮助读者省去数据采集与标注成本快速投入模型迭代与效果验证。1. 玉米黄曲霉素识别数据集从原始图片到 YOLOv8 人工标注的完整落地路径玉米黄曲霉素污染是粮食收储环节最头疼的问题之一肉眼根本分辨不出来等发现霉变往往已经整仓报废。这个数据集的核心价值在于用原始玉米粒图片做 YOLOv8 人工标注把“哪颗玉米发霉了、霉斑在哪个位置”变成可训练的目标检测任务验证准确率能到 93.8% 以上。它适合三类人做粮食质检自动化的工程师、拿 YOLOv8 做毕业设计的学生、以及想把视觉检测落到农业场景的算法同学。数据集本身不复杂但“原始图片 人工标注 YOLOv8 训练”这条链路里每一步都有容易翻车的地方下面按实际落地顺序拆开讲。2. 数据集拆解与 YOLOv8 标注格式的对应关系2.1 原始图片为什么比增强图更适合做黄曲霉素识别黄曲霉素在玉米粒上的表现是局部霉斑、颜色从浅黄到墨绿不等边缘模糊和正常玉米的胚芽阴影容易混淆。很多公开数据集为了“好看”会做大量亮度增强、旋转、裁剪结果模型学到的是增强后的纹理换一批新玉米就崩。这个数据集坚持用原始图片好处是保留真实光照、真实背景、真实霉斑形态训练出来的模型迁移到实际产线时不需要再“猜”原始分布。但原始图片也有代价样本不均衡。正常玉米粒远多于霉变粒如果直接丢给 YOLOv8模型会倾向于全部预测成背景。常见做法是在标注阶段就控制每张图里霉变粒的数量或者训练时用copy_paste增强把霉变粒复制到正常图上。我一般会先统计一下每类目标的实例数如果霉变粒占比低于 15%就在训练配置里把cls损失权重调高或者用focal_loss替代默认的 BCE。2.2 YOLOv8 标注格式从 LabelImg 到 txt 的转换细节YOLOv8 用的是 YOLO 格式的 txt 标注每行class_id x_center y_center width height全部归一化到 0~1。人工标注时常用 LabelImg 或 Labelme但 Labelme 默认输出 JSON需要转一道。下面这个脚本是我实际用的转换逻辑处理了 Labelme 的矩形标注和 YOLO 格式的映射import json import os from pathlib import Path def labelme_to_yolo(json_dir, output_dir, class_map): json_dir: Labelme 标注文件目录 output_dir: 输出 YOLO txt 的目录 class_map: {霉变粒: 0, 正常粒: 1} 这种映射 json_dir Path(json_dir) output_dir Path(output_dir) output_dir.mkdir(parentsTrue, exist_okTrue) for json_file in json_dir.glob(*.json): with open(json_file, r, encodingutf-8) as f: data json.load(f) img_w data[imageWidth] img_h data[imageHeight] lines [] for shape in data[shapes]: label shape[label] if label not in class_map: continue cls_id class_map[label] points shape[points] # Labelme 矩形只有两个点左上、右下 x1, y1 points[0] x2, y2 points[1] # 确保顺序正确 x_min, x_max min(x1, x2), max(x1, x2) y_min, y_max min(y1, y2), max(y1, y2) x_center (x_min x_max) / 2.0 / img_w y_center (y_min y_max) / 2.0 / img_h width (x_max - x_min) / img_w height (y_max - y_min) / img_h # 过滤掉宽高为 0 的脏标注 if width 0 or height 0: continue lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) txt_path output_dir / (json_file.stem .txt) with open(txt_path, w) as f: f.write(\n.join(lines)) if __name__ __main__: labelme_to_yolo( json_dir./raw_annotations, output_dir./labels, class_map{霉变粒: 0, 正常粒: 1} )逻辑说明先读 JSON 里的imageWidth和imageHeight做归一化分母再把 Labelme 的两个角点转成中心点加宽高。参数上class_map必须和后续data.yaml里的names顺序一致否则类别会错位。width 0的过滤是血泪经验人工标注时手抖拉出零面积框很常见不滤掉训练时 loss 会直接 NaN。2.3 数据集划分训练集、验证集、测试集的比例与坑YOLOv8 默认按 8:1:1 划分但黄曲霉素识别这种细粒度任务验证集太小会导致mAP波动大。我一般按 7:2:1 分并且保证每个子集里霉变粒的实例数比例接近。划分脚本不要用random.shuffle直接切要按图片级别切否则同一张图的目标被拆到训练和验证集准确率会虚高。import random from pathlib import Path import shutil def split_dataset(img_dir, label_dir, output_root, ratios(0.7, 0.2, 0.1)): img_dir Path(img_dir) label_dir Path(label_dir) output_root Path(output_root) images sorted(img_dir.glob(*.jpg)) sorted(img_dir.glob(*.png)) random.seed(42) random.shuffle(images) n len(images) n_train int(n * ratios[0]) n_val int(n * ratios[1]) splits { train: images[:n_train], val: images[n_train:n_train n_val], test: images[n_train n_val:] } for split, files in splits.items(): (output_root / split / images).mkdir(parentsTrue, exist_okTrue) (output_root / split / labels).mkdir(parentsTrue, exist_okTrue) for img_path in files: shutil.copy(img_path, output_root / split / images / img_path.name) label_path label_dir / (img_path.stem .txt) if label_path.exists(): shutil.copy(label_path, output_root / split / labels / label_path.name) if __name__ __main__: split_dataset(./images, ./labels, ./dataset, ratios(0.7, 0.2, 0.1))参数说明random.seed(42)保证可复现ratios按需调如果霉变粒总数少于 500 个实例建议改成 8:1:1 并增加训练轮数。注意label_path.exists()的判断人工标注漏标是常态缺 label 的图片直接跳过比报错好。3. YOLOv8 训练环境搭建与黄曲霉素数据集的配置3.1 Ubuntu 20.04 下 CPU 版本 YOLOv8 环境的最小安装命令很多同学手头只有 CPU 机器或者显卡是 GTX 1660 Ti 这种 6G 显存的跑 YOLOv8 不是不行但要选对版本和 batch size。Ubuntu 20.04 上我一般用 conda 建环境避免和系统 Python 打架conda create -n yolo_corn python3.9 -y conda activate yolo_corn pip install ultralytics8.0.200 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cpu逻辑说明ultralytics是 YOLOv8 的官方包8.0.200这个版本对 CPU 推理比较友好不会强制要求 CUDA。torch的 CPU 版本从官方 index 装避免 pip 默认源拉到 GPU 版导致依赖冲突。装完用yolo checks验证如果显示CPU就对了。GTX 1660 Ti 的话把--index-url换成cu118的源batch size 设 8 或 16再大就 OOM。3.2 data.yaml 的写法与类别名映射YOLOv8 训练前必须有一个data.yaml指定训练、验证、测试路径和类别名。黄曲霉素数据集一般就两类霉变粒和正常粒。写法如下path: /home/user/corn_dataset train: train/images val: val/images test: test/images names: 0: moldy_corn 1: normal_corn注意path用绝对路径train等用相对路径YOLOv8 会自动拼接。names的 key 必须从 0 开始连续和标注时的class_id一一对应。如果标注时用了中文类别名这里要改成英文否则训练时names解析会报编码错误。我一般会在data.yaml同目录放一个classes.txt内容就是moldy_corn和normal_corn方便后续推理时对照。3.3 训练参数epochs、imgsz、batch 怎么设才不浪费算力CPU 训练黄曲霉素数据集imgsz设 640 就够再大速度指数级下降。epochs设 100 起步如果验证集mAP50在 50 轮后还在涨就加到 200。batch在 CPU 上设 4 或 8GTX 1660 Ti 设 16。关键参数是patience设 20 表示 20 轮验证指标不提升就早停省时间。yolo detect train \ data/home/user/corn_dataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch8 \ patience20 \ devicecpu \ projectcorn_runs \ nameexp1逻辑说明modelyolov8n.pt是最小的 nano 模型CPU 上也能跑如果准确率不够再换yolov8s.pt。devicecpu显式指定避免有显卡但驱动不对时自动选 GPU 报错。project和name控制输出目录跑完在corn_runs/exp1/weights/best.pt拿最优权重。训练过程中用tensorboard看 loss 曲线如果box_loss震荡厉害把学习率从默认 0.01 降到 0.001。4. 黄曲霉素识别模型训练中的避坑与排查4.1 现象训练 loss 正常下降但 mAP 始终为 0原因标注文件里的class_id和data.yaml的names顺序不一致或者标注 txt 里出现了class_id大于类别数的行。YOLOv8 不会报错但会把所有预测当背景。解决用下面这段脚本检查所有 label 文件里的类别 id 分布from pathlib import Path from collections import Counter label_dir Path(./dataset/train/labels) counter Counter() for txt in label_dir.glob(*.txt): with open(txt) as f: for line in f: if line.strip(): counter[int(line.split()[0])] 1 print(counter)如果输出里出现2或更大的 id说明标注时类别映射错了回去改class_map重新生成。4.2 现象验证准确率虚高到 99%但实际推理一塌糊涂原因训练集和验证集里有同一张图片的不同增强版本或者同一颗玉米的多个角度被分到了两个集合。数据泄露是准确率虚高的头号元凶。解决划分数据集时按“玉米粒个体”分组同一颗玉米的所有图片必须进同一个子集。如果原始图片是按拍摄批次命名的按批次前缀分组再随机划分。另外验证集不要做任何增强val的augment参数设False。4.3 现象CPU 训练到一半被 kill内存爆了原因batch设太大或者workers默认 8 导致多进程读图占满内存。CPU 训练时workers设 2 就够batch超过 16 在 16G 内存机器上很容易 OOM。解决在训练命令里加workers2batch4并且用cacheFalse关闭缓存。如果还爆把imgsz降到 416准确率掉 1~2 个点但能跑完。4.4 现象霉变粒漏检严重正常粒误检多原因正负样本极度不均衡霉变粒实例太少。YOLOv8 默认的cls损失对少数类不友好。解决在data.yaml同级建一个hyp.yaml调cls1.5默认 0.5box7.5保持dfl1.5。或者用copy_paste0.3把霉变粒复制到正常图上增加少数类实例。实测cls调到 1.5 后霉变粒召回率能从 0.72 提到 0.89。4.5 现象推理时框的位置对但类别全反了原因names里 0 和 1 的顺序和标注时相反。标注时霉变粒是 0data.yaml里写成了0: normal_corn。解决打开data.yaml和classes.txt逐行对照确保0对应霉变粒。推理时用model.names打印一下映射关系确认无误再部署。5. 从 93.8% 准确率到产线落地验证方法与调优技巧5.1 用混淆矩阵和 PR 曲线定位 93.8% 背后的短板93.8% 的验证准确率听起来不错但要看是mAP50还是precision。如果是mAP50说明模型在 IoU0.5 时综合表现好如果是precision可能召回率很低。跑完训练后YOLOv8 会在corn_runs/exp1/下生成confusion_matrix.png和PR_curve.png。重点看混淆矩阵里moldy_corn被预测成normal_corn的数量这个数如果超过总霉变粒的 10%说明模型对早期霉斑不敏感。我一般会额外跑一次val并指定conf0.3因为默认conf0.25会滤掉很多低置信度的霉变粒。命令yolo detect val \ modelcorn_runs/exp1/weights/best.pt \ data/home/user/corn_dataset/data.yaml \ conf0.3 \ iou0.5 \ devicecpu参数说明conf0.3提高召回iou0.5是 NMS 的阈值霉变粒密集时调到 0.4 避免框被合并。输出里看mAP50-95如果这个值低于 0.6说明框的定位精度不够需要增加标注的精细度或换yolov8s。5.2 用 TensorBoard 看损失曲线判断该不该继续训练YOLOv8 训练时自动写 TensorBoard 日志在corn_runs/exp1/下执行tensorboard --logdir .就能看。重点看三条线train/box_loss、train/cls_loss、val/cls_loss。如果train还在降但val已经平了甚至上升就是过拟合该早停。如果val/cls_loss一直震荡把学习率降一半再跑 50 轮。我习惯在patience20的基础上手动看val/cls_loss连续 10 轮不降就停比等早停省时间。另外lr/pg0曲线能看出学习率调度是否正常如果一开始就掉到 0说明warmup没生效检查warmup_epochs是不是设成了 0。5.3 模型导出与 CPU 推理速度优化训练完的best.pt可以直接用但 CPU 推理慢。导出 ONNX 能提速 20%~30%yolo export \ modelcorn_runs/exp1/weights/best.pt \ formatonnx \ imgsz640 \ simplifyTrue \ opset12逻辑说明simplifyTrue会做图优化opset12兼容性好。导出后在 Python 里用onnxruntime推理单张 640x640 图片在 i5 上大概 80~120ms。如果还要快把imgsz降到 416速度翻倍准确率掉 1~2 个点。产线上如果要求实时建议用yolov8n加 416 输入配合conf0.35平衡速度和召回。5.4 一个具体技巧用 TTA 把准确率再拉 1~2 个点TTA测试时增强在推理时对图片做翻转、缩放然后合并预测框。YOLOv8 的val和predict都支持augmentTrueyolo detect predict \ modelcorn_runs/exp1/weights/best.pt \ source./test_images \ augmentTrue \ conf0.3 \ saveTrue注意 TTA 会让推理时间变成 3 倍左右适合离线质检不适合产线实时。实测在黄曲霉素数据集上TTA 能把mAP50从 0.938 提到 0.951但速度从 100ms 涨到 300ms。如果产线节拍允许这个技巧值得加。我自己的习惯是先跑一版yolov8n加 640 输入拿到 baseline再根据混淆矩阵决定是加数据、调损失权重还是换模型。不要一上来就上yolov8xCPU 上跑不动GPU 上也不一定比yolov8s好多少。黄曲霉素识别这种细粒度任务标注质量比模型大小重要得多。希望帮到你。本文还有配套的精品资源点击获取
返回列表