简介本资源为玉米叶部病害识别数据集面向从事农业图像分类、目标检测的算法工程师与高校研究者可用于训练和验证玉米叶枯病、普通锈病、灰叶斑病及健康叶片的识别模型。数据采用VOC格式人工标注共10884张图片压缩包内包含2000个XML标注文件整体约520.9MB标注信息与图像一一对应便于直接接入YOLO、Faster R-CNN等主流检测框架。已有377人学习下载适合需要快速构建玉米病害识别基线或扩充训练样本的读者。借助该数据集可完成从数据加载、类别平衡到模型训练与精度评估的完整流程参考标注准确率可达95.7%以上为病害早期诊断与田间智能监测提供可靠的数据支撑。1. 玉米叶病预测数据集10884 张 VOC 标注图为什么值得先跑一遍再谈模型如果你正在做作物病害识别大概率遇到过这种局面网上能找到的玉米叶病数据要么只有几百张、类别残缺要么标注格式是分类文件夹想训检测模型还得自己画框。这个数据集直接给到 10884 张图片全部按 VOC 格式人工标注覆盖叶枯病、普通锈病、灰叶斑病和健康叶片四类官方给出的准确率参考值在 95.7% 以上。它解决的不是“有没有数据”的问题而是“标注质量能不能直接进训练管线”的问题。适合两类人一类是想快速验证检测模型效果、不想在数据清洗上耗两周的算法工程师另一类是拿它做课程设计或论文实验、需要一份格式规范、类别清晰的数据底座的开发者。VOC 格式意味着每张图对应一个 XML框坐标、类别名、图像尺寸都在里面转 YOLO、COCO 或者直接喂给 SSD、Faster R-CNN 都有成熟脚本可走省掉的是最枯燥的那段手工活。2. VOC 标注结构拆解10884 张图到底怎么组织、怎么读2.1 目录结构与 XML 字段含义拿到压缩包后常见做法是先别急着写 DataLoader而是把目录树打印出来看一眼。VOC 风格的数据集通常长这样# 查看数据集目录结构示例实际以压缩包内为准 tree -L 2 ./corn_leaf_voc/ # 输出大致为 # corn_leaf_voc/ # ├── Annotations/ # 存放所有 .xml 标注文件 # ├── JPEGImages/ # 存放所有 .jpg 原图 # ├── ImageSets/ # │ └── Main/ # 存放 train.txt / val.txt / test.txt 划分文件 # └── SegmentationClass/ (可选本数据集以检测为主可能不存在)Annotations和JPEGImages是核心。每张图xxx.jpg对应一个同名xxx.xml。XML 里几个字段必须盯住size下的width、height决定坐标是否越界object下的name是类别字符串直接决定你后面类别映射表怎么写bndbox里的xmin/ymin/xmax/ymax是左上角和右下角绝对坐标不是归一化值。人工标注的数据集最容易出问题的地方就在bndbox框超出图像边界、宽高为 0、坐标写成浮点数。先写个脚本扫一遍比训到一半 loss 不降再回头查要省事得多。import os import xml.etree.ElementTree as ET from collections import Counter ann_dir ./corn_leaf_voc/Annotations img_dir ./corn_leaf_voc/JPEGImages class_counter Counter() bad_boxes [] for xml_file in os.listdir(ann_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(ann_dir, xml_file)) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) for obj in root.findall(object): name obj.find(name).text.strip() class_counter[name] 1 box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 检查越界和无效框 if xmin 0 or ymin 0 or xmax w or ymax h or xmax xmin or ymax ymin: bad_boxes.append((xml_file, name, xmin, ymin, xmax, ymax)) print(类别分布, class_counter) print(异常框数量, len(bad_boxes)) for item in bad_boxes[:10]: print(item)这段脚本做三件事统计四类目标的框数量判断类别是否均衡检查坐标是否越界或宽高非法把异常样本路径打出来。参数上唯一需要改的是ann_dir和img_dir两个路径。如果bad_boxes数量在几十以内可以直接在转格式时过滤掉如果上百说明标注环节有系统性问题得考虑是否重新清洗或只取子集训练。类别分布那行输出尤其重要——健康叶片如果占比过高后面训练时分类头会偏向多数类mAP 看着还行但病害漏检会很难看。2.2 从 VOC 到 YOLO转换脚本与类别映射VOC 转 YOLO 是这套数据最常走的一步。YOLO 要求每张图一个.txt每行class_id x_center y_center width height全部归一化到 0~1。类别映射必须固定顺序否则训练和推理对不上。import os import xml.etree.ElementTree as ET # 类别映射顺序一旦确定训练和推理必须一致 classes [叶枯病, 普通锈病, 灰叶斑病, 健康] class_to_id {name: idx for idx, name in enumerate(classes)} ann_dir ./corn_leaf_voc/Annotations label_out ./corn_leaf_yolo/labels img_out ./corn_leaf_yolo/images os.makedirs(label_out, exist_okTrue) os.makedirs(img_out, exist_okTrue) for xml_file in os.listdir(ann_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(ann_dir, xml_file)) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in class_to_id: continue # 跳过未定义类别避免训练时索引错位 cls_id class_to_id[name] box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 归一化并限制在 [0,1] x_center min(max((xmin xmax) / 2.0 / w, 0.0), 1.0) y_center min(max((ymin ymax) / 2.0 / h, 0.0), 1.0) bw min(max((xmax - xmin) / w, 0.0), 1.0) bh min(max((ymax - ymin) / h, 0.0), 1.0) lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) if lines: txt_name xml_file.replace(.xml, .txt) with open(os.path.join(label_out, txt_name), w) as f: f.write(\n.join(lines)) # 图片软链或复制到 YOLO 目录这里用软链省空间 img_name xml_file.replace(.xml, .jpg) src os.path.join(./corn_leaf_voc/JPEGImages, img_name) dst os.path.join(img_out, img_name) if os.path.exists(src) and not os.path.exists(dst): os.symlink(os.path.abspath(src), dst)逻辑说明先按固定classes列表建映射遇到不在表里的类别直接跳过防止后面cls_id越界。归一化时用min/max夹到 0~1处理掉少量越界框。图片用软链而不是复制10884 张图如果每张几 MB复制一份会多占几十 GB软链在 Linux 下训练读取没问题Windows 下建议改成shutil.copy。参数上classes顺序可以改但改完必须同步改 YOLO 的.yaml配置文件里的names否则训练出来的模型会把叶枯病认成健康。转完后抽查几个.txt用cat看一眼数值是否在 0~1 之间这是最便宜的验证。3. 训练管线搭建从划分数据集到跑通第一个 baseline3.1 训练集/验证集/测试集划分VOC 自带的ImageSets/Main不一定有现成划分常见做法是自己按 8:1:1 切。注意不能随机切完就完事——同一片叶子可能被拍了好几张如果这些图分散到训练和验证集验证指标会虚高。更稳的做法是按“拍摄批次”或“文件前缀”分组切但数据集没给批次信息时至少用固定随机种子切一次保证可复现。import os import random random.seed(42) # 固定种子保证每次划分一致 all_files [f.replace(.xml, ) for f in os.listdir(./corn_leaf_voc/Annotations) if f.endswith(.xml)] random.shuffle(all_files) n len(all_files) train_end int(n * 0.8) val_end int(n * 0.9) splits { train: all_files[:train_end], val: all_files[train_end:val_end], test: all_files[val_end:] } for split, files in splits.items(): with open(f./corn_leaf_yolo/{split}.txt, w) as f: for name in files: f.write(f./images/{name}.jpg\n) print(split, len(files))参数说明random.seed(42)是后悔药换种子会得到不同划分指标波动可能到一两个点论文实验里必须固定。0.8/0.1/0.1是检测任务的常见比例如果数据量少可以调成 7:2:1。输出文件里写的是相对路径YOLO 训练时从data.yaml里的path根目录开始找路径写错会直接报No such file。3.2 YOLO 配置文件与启动命令以 YOLOv8 为例先写corn_leaf.yaml# corn_leaf.yaml path: ./corn_leaf_yolo train: train.txt val: val.txt test: test.txt names: 0: 叶枯病 1: 普通锈病 2: 灰叶斑病 3: 健康names的顺序必须和转换脚本里的classes完全一致差一个位置训练时标签就全错。启动训练yolo detect train \ datacorn_leaf.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/corn_leaf \ namebaseline参数逐个说modelyolov8n.pt是最小模型先跑通再换s或mimgsz640是检测常用输入尺寸如果显存不够降到 512但小病斑可能被缩没batch16在 8GB 显存上比较稳爆显存就减半lr00.01是初始学习率YOLO 默认值数据量上万时一般不用大改patience20表示 20 轮验证指标不升就早停省时间。跑完后看runs/corn_leaf/baseline/results.csv重点盯metrics/mAP50-95和每类的metrics/mAP50。如果健康类很高但灰叶斑病很低说明该类样本少或病斑小后面再针对性补数据或调 anchor。4. 避坑与排查标注、转换、训练里最容易翻车的五件事4.1 类别名带空格或大小写不一致现象转换脚本跑完class_counter里出现“叶枯病”和“叶枯病 ”两个键或者“健康”和“healthy”混用。原因人工标注时不同人输入习惯不同XML 里name文本没统一。解决在读取时统一strip()并做一次映射归一化比如把所有别名指向同一个标准名再写进class_to_id。这个坑不查训练时类别数会莫名多出来模型学得四不像。4.2 图片和 XML 文件名对不上现象转 YOLO 时提示某张图找不到或者生成的.txt没有对应图片。原因VOC 数据集常见.JPG和.jpg混用或者 XML 有但图片缺失。解决转换前先做一次集合比对把Annotations里的文件名去掉后缀和JPEGImages里的做交集只保留两边都有的样本。缺失的图片直接丢弃对应 XML别硬凑。4.3 框坐标越界导致 loss 变 NaN现象训练几个 epoch 后 loss 突然变nan。原因个别bndbox的xmax大于图像宽度归一化后宽高为负YOLO 计算 IoU 时出问题。解决转换脚本里已经用min/max夹住但更彻底的做法是在 2.1 的扫描脚本里把异常框直接过滤不写进.txt。如果已经开训回滚到上一个 checkpoint清洗后重跑。4.4 验证集指标虚高现象验证集 mAP 到 0.98测试集一跑掉到 0.85。原因划分时同一片叶子的多张图被分到训练和验证两边模型见过近似样本。解决按文件前缀或拍摄时间分组切分确保同一组图只出现在一个 split 里。没有分组信息时至少把random.seed固定并记录换种子多跑几次看波动范围。4.5 显存不足误判为模型问题现象batch16时报 CUDA out of memory改成batch8后训练正常但指标下降。原因不是模型不行是 batch 小了 BN 统计不稳。解决优先用梯度累积模拟大 batch或者换更小的输入尺寸imgsz512再不行才换yolov8n。别一报错就怀疑数据先看显存占用和nvidia-smi。5. 进阶技巧用 95.7% 这个参考值反推你的模型差在哪官方给的 95.7% 以上准确率是个锚点但别直接拿它当及格线——不同模型、不同输入尺寸、不同划分方式都会让数字漂移。我一般会做三件事来定位差距。第一按类别拆开看 mAP。如果叶枯病和普通锈病都到 0.95 以上灰叶斑病只有 0.8那问题在灰叶斑病样本少或病斑小可以针对性做 mosaic 增强或复制该类样本。第二看混淆矩阵。健康叶片被误判成灰叶斑病通常是背景纹理相似加一些负样本或调cls损失权重。第三用测试集跑一次yolo detect val把conf阈值从 0.25 调到 0.4 再跑看 mAP 变化。如果掉得厉害说明模型置信度分布散需要更多数据或更长训练。# 用不同置信度阈值验证观察 mAP 稳定性 yolo detect val \ modelruns/corn_leaf/baseline/weights/best.pt \ datacorn_leaf.yaml \ splittest \ conf0.4 \ iou0.6conf0.4比默认 0.25 更严iou0.6是 NMS 阈值。如果conf0.4时 mAP 只掉一两个点说明模型输出比较自信可以上线如果掉十个点以上回去补数据或加训。还有一个习惯每次改完数据或配置先跑 10 个 epoch 的小实验看趋势别一上来就 300 epoch电费和时间的血泪经验。从那以后我每次拿到新数据集都强制先跑一遍标注扫描和类别分布再动训练脚本。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
Python数据挖掘实战:作者归属文本分类与字符N元语法特征工程 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 1:55:36
浦城做网站备案不头大,一文搞懂设计到上线 浦城做网站备案不头大,一文搞懂设计到上线 很多浦城老板刚接手网站项目,盯着浏览器空白页发呆,心里慌得一批。最怕的就是 备案流程一头雾水… · 2026/9/27 1:55:30
ROS2 Executor 与回调组完全指南:三组对照实验讲透串行与并行 ROS2 Executor 与回调组完全指南:三组对照实验讲透串行与并行
一、核心概念 MultiThreadedExecutor:维护一个可配置大小的线程池,用于并行处理多个节点的回调函数,避免单线程阻塞。 CallbackGroup:精细控制哪些回调可以并行、哪些必须串行。互斥回调组不允许回调并行执行… · 2026/9/27 1:55:24
Visual C++ 14.0 以上版本安装包:解决 Python 包编译失败与运行时缺失 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 3:23:56
RK3566泰山派LVGL深度适配:硬件驱动、交叉编译与DCU直驱实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 3:23:50
瑞芯微RV1126B SDK移植实战:从DDR配置到USB调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 3:23:50
消费品BI选型PoC设计:贴合核心业务场景的验证方案 导语
消费品行业正在从增量竞争转向存量竞争,越来越多企业希望通过BI搭建敏捷数据能力支撑精细化运营,但在选型过程中,PoC(概念验证)环节往往容易走形式,要么只测通用功能不贴合核心业务,要么没… · 2026/9/27 3:23:38
告别拖延症:网站优化知识速查手册,3步搞定核心瓶颈 告别拖延症:网站优化知识速查手册,3步搞定核心瓶颈 改个需求建站公司拖一周,后台数据跌得你心惊肉跳,这种憋屈感创业团队负责人最懂。别急着换供应商,很多时候不是人不行,是你没给对“说明书”。今天这份 网站优化知识… · 2026/9/27 3:23:38
朱雀仿宋笔形细节大赏:重心、中宫、撇捺与粗细对比的仿宋设计逻辑 朱雀仿宋笔形细节大赏:重心、中宫、撇捺与粗细对比的仿宋设计逻辑 【免费下载链接】朱雀仿宋 开源仿宋字库计划 项目地址: https://gitcode.com/TrionesType/zhuque
朱雀仿宋(Zhuque Fangsong)是璇玑造字推出的开源仿宋字体࿰… · 2026/9/27 3:23:38
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01