
简介这份资源面向水稻叶病虫害分类项目开发者与图像分类算法学习者提供一套可直接用于YOLO11cls等图像分类模型训练的真实场景数据集。数据涵盖细菌性叶枯病、褐斑病、叶瘟病、纹枯病、稻飞虱、钨黄病毒病等10个常见类别共5000张图片并采用分类文件夹形式整理标注规范、类别覆盖较全面能够支撑实际农业场景中的病虫害识别任务。由于数据集体量较大资源以PDF文档交付内含数据集概况、目录结构说明及百度网盘获取方式包体仅1个PDF文件、大小约2.46MB下载与查看都很轻量。文档还附赠博主提供的YOLO11cls一键训练脚本及训练结果日志可作为配置环境、设置参数与评估指标的参考。当前已有114人学习适合需要快速搭建水稻叶病害分类流程、开展算法实训或扩充分类数据的开发者使用。1. 从裸图到可训练数据这个标题在解决什么很多人拿到“5000 张水稻叶病虫害图 分类文件夹”后的第一反应是打开标注软件这恰恰是误区。目标分类image classification里文件夹就是标签train/稻瘟病/xxx.jpg这样的目录结构本身就是 YOLO11cls 能直接吞进去的数据集格式。这个标题真正解决的问题是把图集、标签和训练脚本三者之间的衔接成本压到最低——你不需要 XML、不需要 COCO 转 YOLO、不需要手工划分训练集目录归好类之后一切交给脚本。本文面向两类人一是刚接触视觉分类、想用现成数据集跑通训练流程的学生和工程师二是农企或科研单位里要做水稻叶病虫害自动识别的算法岗后者往往更关心“这个数据集怎么整理才不会在训练时报一堆路径错”。2. 水稻叶病虫害分类数据集的目录规范与训练前规整2.1 先搞清“对应分类文件夹整理”到底要整成什么样YOLO11 的分类任务classify沿用了 ImageFolder 的约定根目录下每个子文件夹名就是类别名图片按类别放进去即可。数据集对应的类别至少应覆盖常见水稻叶部病害比如稻瘟病、白叶枯病、纹枯病、稻曲病再加一个健康叶片作为负样本这是目标分类里最常见的 5 类划分方式。整理后的标准结构如下datasets/ └── rice_leaf/ ├── train/ │ ├── rice_blast/ # 稻瘟病 │ │ ├── img_0001.jpg │ │ └── ... │ ├── bacterial_blight/ # 白叶枯病 │ ├── sheath_blight/ # 纹枯病 │ ├── false_smut/ # 稻曲病 │ └── healthy/ # 健康叶片 ├── val/ │ └── (同 train按比例抽图) └── test/ └── (用于最终验证可选)表格里是推荐保留的原始字段信息整理成 CSV 也方便后续用 pandas 做分布分析字段示例用途image_idIMG_20230915_001.jpg与文件夹内文件名一一对应label_cn稻瘟病中文展示、生成报告用label_enrice_blast作为类目文件夹名避免中文路径编码问题source田间/温室/网络采集排查数据泄漏时的重要线索这里有一个容易被忽略的细节文件夹名建议用英文或拼音。YOLO11 读取类别时按文件夹名的字母序生成 class id如果混入中文目录名在部分 Windows 环境下编码会出问题且后续results.csv里的类别列看着也乱。2.2 用 shell 命令快速体检数据集并划分 train/val拿到整理好的原始 5000 张图后第一件事是核对每类图片数量是否均衡以及是否存在空白或损坏文件。以下命令可以直接在项目根目录执行# 1. 统计每个分类文件夹下的图片数量 find datasets/rice_leaf/train -type f | sed s/.*\/// | cut -d_ -f1 | sort | uniq -c # 2. 按 8:1:1 做 train/val/test 划分以稻瘟病为例 mkdir -p datasets/rice_leaf/{train,val,test}/rice_blast ls datasets/rice_leaf/train/rice_blast/*.jpg | shuf -n 100 | xargs -I {} cp {} datasets/rice_leaf/val/rice_blast/第一条命令用sed去掉路径、cut截取文件名的类别前缀再uniq -c计数能一眼看出哪个类图片太少第二条命令用shuf随机抽 100 张作为验证集注意这里演示的是单个类目的划分动作真实使用时应写成循环且划分后原 train 中的这些图片要么删除、要么移动到另一个目录避免同一张图既在 train 又在 val。如果愿意用 Python 做更可控的划分sklearn.model_selection.train_test_split配合shutil.copy2是最常见的做法。要特别强调的是划分必须基于文件名列表做随机抽样绝不能直接按文件夹顺序前 80% 作训练集——采集时图片往往是按时间或地块顺序命名的顺序切分会让训练集和验证集存在地块相关性导致验证精度虚高这一点在农业数据里非常常见。2.3 过滤损坏图片与统一格式的预处理脚本手机拍摄、无人机下传、扫描仪翻拍混在一起的数据集里最容易出现的问题是扩展名是.jpg但实际是 PNG 编码或者文件头损坏导致 OpenCV 读不出来。YOLO11 训练时遇到这类图会直接中断所以训练前需要跑一次完整校验下面的脚本覆盖校验和解码两个步骤import os from PIL import Image from pathlib import Path base Path(datasets/rice_leaf) bad_list [] for label_dir in (base / train).iterdir(): if not label_dir.is_dir(): continue for img_file in label_dir.iterdir(): try: with Image.open(img_file) as im: im.load() # 强制解码能发现伪 jpg if im.mode ! RGB and im.mode ! RGBA: im.convert(RGB) except Exception as e: bad_list.append((img_file, str(e))) # 自动把损坏图片移到 backup 目录 for f, err in bad_list: dst Path(datasets/rice_leaf) / backup / f.name dst.parent.mkdir(parentsTrue, exist_okTrue) f.rename(dst) print(f[moved] {f.name}: {err})校验逻辑通过im.load()把图片真正解码到内存能捕获文件头伪造这类 OpenCV 不报错但训练时崩溃的情况统一RGB模式则避免后续模型输入维度不一致。跑完这个脚本后再执行一次 2.2 中的计数命令确认类别数量没有被异常波动再进入训练环节。3. YOLO11cls 一键训练脚本命令、超参与执行路径3.1 YOLO11cls 为什么不需要 labels 文件YOLO11 的 classify 模型结构可以理解为“backbone 全局平均池化 全连接分类头”。它跟 detect 系列最大的区别在于检测要输出 bounding box需要 txt 标注文件分类只需要输出类别概率所以标签信息完全由目录结构承载也就是标题里“对应分类文件夹整理”这部分的生物学意义。模型通过yolo11s-cls.yaml这样的配置实例化训练时框架会用ImageFolder自动扫描目录按字母序生成names列表class id 从 0 开始递增。训练入口是统一的yolo classify train命令参数体系和yolo detect train高度一致因此从 YOLOv5/YOLOv8 转过来的人几乎零成本上手。数据路径参数data指向的是数据集根目录含 train/val 的上一级而不是 train 本身这是分类任务和检测任务最容易混淆的地方之一。3.2 一个可直接抄写的 train_rice_cls.sh所谓“一键训练脚本”本质是把环境检查、数据校验、训练命令和日志输出串成一串让任何一台有显卡的机器都能从头跑完。下面这个 bash 脚本是标题里 YOLO11cls 一键训练脚本的常见落地形态#!/usr/bin/env bash set -e DATASET_DIR${1:-datasets/rice_leaf} EPOCHS${2:-60} IMGSZ${3:-224} BATCH${4:-16} # 1. 检查 python 与 pip command -v python3 /dev/null || { echo python3 not found; exit 1; } # 2. 安装/更新 ultralytics pip install -q ultralytics # 3. 启动训练 yolo classify train \ modelyolo11s-cls.pt \ data$DATASET_DIR \ epochs$EPOCHS \ imgsz$IMGSZ \ batch$BATCH \ projectruns/classify \ namerice_cls \ device0 \ patience15 \ pretrainedTrue脚本前三行把数据集路径、训练轮数、图像尺寸和批次大小抽成位置参数不传参时都有默认值这是“一键”的真正含义你只需要保证目录结构符合 2.1剩下的命令参数按默认即可。set -e保证任一步骤失败立即退出避免坏图导致训练中断后脚本还继续跑。modelyolo11s-cls.pt预训练权重首次执行会自动下载没有网络时可以先手动准备好权重文件再改成本地路径。imgsz224分类任务常用输入尺寸YOLO11cls 不强制 640用 224 能显著降低显存占用并加快迭代。device0指定第一块 GPUCPU 环境改cpu但 5000 张图 60 轮在 CPU 上可能需要十小时以上不建议。训练结束后runs/classify/rice_cls/weights/best.pt就是精度最高的权重last.pt是最后一轮权重。日志目录下还会自动生成results.pngloss 和精度曲线、confusion_matrix.png和results.csv这几份产物直接对应后面第 5 章的分析。3.3 Python 方式封装训练便于二次定制有些项目需要在训练过程中动态调整参数或者把训练嵌入已有的数据处理管线此时用 Python 脚本调用更顺手。在 Jupyter 或 IDE 里直接运行以下代码的效果与 bash 脚本一致from ultralytics import YOLO model YOLO(yolo11s-cls.pt) results model.train( datadatasets/rice_leaf, epochs60, imgsz224, batch16, projectruns/classify, namerice_cls, patience15, pretrainedTrue, device0, )两种脚本方式选一种即可。区别在于 bash 适合服务器后台执行加nohup或tmuxPython 方式适合需要动态读取类别列表后再设置参数的场景例如先跑一遍 2.3 的校验代码然后把通过校验的目录路径传入train()。4. 训练参数调优与排错从 loss 曲线到报错定位4.1 首次训练推荐的超参数表分类任务的超参数比检测任务少能动的也就 10 个左右。下表给出的是基于 5000 张图、单卡训练场景的推荐区间标红的场景可以优先调整参数推荐值调整方向imgsz224图片细节不足时升到 256但训练时间约增加 30%epochs60early stop 触发早则降验证集精度仍在涨则加batch16 / 8显存不足时报错就减半batch 太小要同步调低 lrlr00.01loss 震荡时降到 0.005迁移学习场景可保持 0.01patience15验证精度连续 15 轮不升则停止避免过拟合浪费算力optimizerauto一般维持 auto它会根据 batch 自动选 SGD 或 AdamWdropout0.0数据量小或严重过拟合时设为 0.1 试一次augmentTrue默认开启随机裁剪、翻转、色调抖动不适合精细纹理识别时关闭batch 和 lr 是需要联动的一对参数把 batch 从 16 减到 8 时梯度估计噪声变大学习率保持 0.01 容易发散正确做法是同步把 lr0 降到 0.005 左右。另一个容易被忽视的参数是cache默认 False 时每轮都从磁盘读图对于 5000 张图这种规模设cacheTrue把图加载进内存训练一轮的时间可能从 3 分钟压到 40 秒。4.2 三 modal loss 曲线图怎么看训练过程中results.png里会画 train_loss、val_loss、top1_acc 和 top5_acc 四条曲线判断模型状态的依据就两条训练 loss 和验证 loss 的距离、top1_acc 的收敛位置。以下几种状态需要 ( \text{专门处理})训练 loss 持续下降、验证 loss 先降后升top1_acc 在 30 轮左右触顶然后回落典型过拟合。对策是调大patience让 early stop 生效或者把dropout从 0 提到 0.1再不行就回到数据层面做增强。训练 loss 和验证 loss 都降得很慢top1_acc 一直在 90% 以下徘徊大概率是 lr 太小或类别不平衡。先看 2.2 的统计结果某个类少于 300 张就要考虑做裁剪/翻转的过采样而不是盲目加轮数。训练 loss 前 5 轮突降、然后长时间不降且验证精度抖动剧烈通常是 batch 太小导致梯度不稳定把 batch 调大一倍并同步加大 lr0 试试。4.3 三个高频报错的定位方法训练前 80% 的报错集中在数据路径和类别不匹配上下面按出现频率列出定位手段。报错一AssertionError: train dataset not found。原因基本是 data 参数指到了 train 子目录正确应指向包含 train/val 的根目录。排查时在训练前先跑一句ls datasets/rice_leaf/train确认路径存在且能列出类别。报错二CUDA out of memory。先把 batch 从 16 降到 8再降就设 4。分类任务用 imgsz224 时单卡 8G 显存跑 yolo11s-cls 是绰绰有余的出现 OOM 多半是同时开了多个进程占用显存用nvidia-smi查一下谁占着卡。报错三RuntimeError: No labels found in ...这个报错其实很少出现在分类任务里但如果混入了检测思路在项目下建了 labels 目录反而会干扰框架解析。分类任务只要保证图片在类别文件夹下即可任何 txt/json 标注文件都用不上。提示训练中断后想接着跑直接把modelruns/classify/rice_cls/weights/last.pt作为 model 参数即可数据和其余参数保持不变框架会自动续训。5. 验证、混淆矩阵与导出部署的最后一个细节5.1 用 best.pt 批量验证并统计 top-1 指标训练结束后不要只盯着results.csv看那只能反映训练轨迹。真实衡量模型水平的做法是在没参与训练的 test 划分上跑预测并统计每个类别的精确率和召回率。下面这段代码读取 test 目录逐张预测后输出分类报告from ultralytics import YOLO from pathlib import Path from collections import defaultdict model YOLO(runs/classify/rice_cls/weights/best.pt) test_root Path(datasets/rice_leaf/test) hit {p.name: [0, 0] for p in test_root.iterdir()} # [correct, total] for label_dir in test_root.iterdir(): for img_path in label_dir.iterdir(): res model.predict(sourcestr(img_path), imgsz224, verboseFalse)[0] pred_name res.names[res.probs.top1] hit[label_dir.name][1] 1 if pred_name label_dir.name: hit[label_dir.name][0] 1 for cls, (correct, total) in hit.items(): print(f{cls}: acc{correct/total:.3f} ({correct}/{total}))res.probs.top1返回预测类别 idres.names是 id 到文件夹名的映射这两个属性是分类任务推理时最需要记住的 API。逻辑上先按文件夹名分组再把预测结果和真实文件夹对比最后输出每类 top-1 精度。如果某一类精度明显低于其他类直接打开train/runs/classify/rice_cls/confusion_matrix.png看它被误判成了谁这一步比调参更能发现数据问题。5.2 导出到 ONNX 并适配部署端的输入尺寸验证通过后下一步往往是把best.pt转成部署格式。分类模型导出 ONNX 的命令非常简单yolo export modelruns/classify/rice_cls/weights/best.pt formatonnx imgsz224这里有一个容易踩的坑训练时用 224导出也用 224 没问题但如果部署端是树莓派或手机想改成 192 或 160 来提速需要明确导出时的imgsz会固化进计算图导出后输入尺寸就固定了。常见的做法是先按 224 导出在端上实测单帧推理耗时确认延迟超标后再重新导出一次小尺寸版本而不是在推理代码里resize那只会白白增加一次 CPU 开销。最后一个建议是保留训练时的names顺序导出 ONNX 后的模型只输出概率值不会自带类别名你在端上做后处理时得把输出的第 0 维映射回[rice_blast, bacterial_blight, sheath_blight, false_smut, healthy]这个映射顺序必须和训练时文件夹的字母序一致很多线上事故都是因为后处理里类别列表写错了顺序导致的。本文还有配套的精品资源点击获取