ARTICLE DETAIL

资讯详情

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

YOLO11cls水稻叶病虫害分类:数据集格式与训练实战指南

YOLO11cls水稻叶病虫害分类:数据集格式与训练实战指南 简介面向水稻叶病虫害分类任务这份资料提供了一套可直接投入实战的完整数据集配套说明。数据集包含5000张真实场景高质量水稻叶片图片覆盖细菌性叶枯病、褐斑病、健康叶片、叶瘟病、叶鞘腐病、窄褐斑病、穗颈瘟、稻飞虱、纹枯病、钨黄病毒病等10个类别已按对应分类文件夹整理标注质量高可直接用于YOLO11cls等分类训练。随附的YOLO11cls一键训练脚本及博主训练日志便于快速复现与调参参考。资源包共1个文件为PDF格式大小约2.46MB内含数据集基本情况介绍、缩略图预览及数据集获取方式适合需要开展水稻病虫害识别、农业智能监测项目或补充通用分类场景数据的开发者与研究人员。已有115人学习下载是快速搭建分类训练流程的实用参考。1. 目标分类不是目标检测这个水稻叶病虫害数据集和YOLO11cls的配合方式做水稻叶病虫害识别最麻烦的往往不是模型选型而是数据拿到手之后发现根本喂不进去。目标分类和水稻叶病虫害分类数据集这两个词放在一起说的就是把一件已经整理好的输入交给一个能直接跑的训练流程5000张图片按分类文件夹存放YOLO11cls读取这个目录就能开始训练。它对应YOLO11里的分类分支每个样本是一张叶片图和一个类别标签跟带框的目标检测完全不同。适合谁想快速验证水稻叶部病害识别效果、又不想从爬图、去重、标注重新开始的开发者和农学研究者。这也是我把这类数据叫“开箱型数据集”的原因。2. 数据集的目录本身就在定义任务5000张分类文件夹怎么对齐YOLO11cls的输入2.1 文件夹名即标签先把目录结构看懂再做任何操作拿到这个数据集后第一件事不是打开看图而是确认目录层级。YOLO11cls吃的分类数据格式非常明确数据集根目录下必须有train/和val/两个子目录各自的下一层是类别文件夹类别文件夹里面放图片。你不需要额外提供 label 文件因为类别名就是文件夹名。datasets/rice_disease/ ├── train/ │ ├── rice_blast/ # 稻瘟病 │ │ ├── 0001.jpg │ │ ├── 0002.jpg │ │ └── ... │ ├── rice_brown_spot/ # 褐斑病 │ │ ├── 0001.jpg │ │ └── ... │ └── rice_hispa/ # 铁甲虫危害 │ ├── 0001.jpg │ └── ... └── val/ ├── rice_blast/ │ └── ... ├── rice_brown_spot/ │ └── ... └── rice_hispa/ └── ...目录结构确认好后最值得做的事是统计每个类别的图片数量。5000张图看起来不少但平均到每个类别可能只有几百张类别之间如果差异太大训练出来的模型会偏向数量多的类准确率再高也是虚的。我一般会先跑一段脚本把每个类的图片数量打印出来再做是否扩增、是否加权采样的决定。# count_classes.py from pathlib import Path root Path(datasets/rice_disease) for split in [train, val]: split_dir root / split if not split_dir.exists(): print(f警告缺少 {split} 文件夹) continue print(f\n[{split}]) for class_dir in sorted(split_dir.iterdir()): if class_dir.is_dir(): n len(list(class_dir.glob(*.jpg))) print(f{class_dir.name}: {n} 张)这段代码只做了一个统计动作但它是后续所有调参的前提。你看到的是数字实际上是在判断哪个类别是少数类验证集有没有覆盖到全部类别以及某个文件夹是不是空目录。逻辑很简单但我在实际项目里每次都会跑一遍因为它能提前暴露“类别文件夹名拼写不一致”“val目录是空的”“有的文件夹里混进了非图片文件”这三类问题。2.2 5000张图属于小规模数据预训练权重和验证集划分是两条命说实话5000张图做图像分类只能算小规模。ImageNet级别是百万张农业公开数据集里PlantDoc、水稻病斑数据集也大多是几千到几万张的体量。小规模的好处是训练快、迭代快坏处是很容易过拟合。所以YOLO11cls默认加载预训练权重这件事不是你偷懒的理由而是必须保留的配置。pretrainedTrue意味着模型用ImageNet上预训练好的参数初始化你在这个基础上只学水稻叶片特征收敛速度和泛化能力都会好很多。验证集划分是第二个关键点。很多初学者直接把整个数据集的末尾10%当验证集结果训练集和验证集里出现了同一株水稻、同一批上传的图片准确率能到95%以上一下田立刻掉回60%。如果数据集本身已经分好了 train/val 文件夹先用起来没问题但如果只有 train 文件夹手动切分时要注意按采集来源或拍摄批次切不要按文件名排序切。文件名在同一个批次里通常是连续的按顺序切分等于把同一批照片一半给训练一半给验证。# split_data.py import random import shutil from pathlib import Path source Path(datasets/rice_disease_source) # 原始整理目录类别文件夹 图片 target_root Path(datasets/rice_disease) random.seed(42) val_ratio 0.15 # 我一般留 15% 做验证 for class_dir in source.iterdir(): if not class_dir.is_dir(): continue images list(class_dir.glob(*.jpg)) list(class_dir.glob(*.png)) random.shuffle(images) val_n max(1, int(len(images) * val_ratio)) train_target target_root / train / class_dir.name val_target target_root / val / class_dir.name train_target.mkdir(parentsTrue, exist_okTrue) val_target.mkdir(parentsTrue, exist_okTrue) for img in images[:val_n]: shutil.copy(str(img), str(val_target / img.name)) for img in images[val_n:]: shutil.copy(str(img), str(train_target / img.name))这段脚本值得注意一个细节均匀抽而不是随机全局抽。先按类别抽保证每个类别在验证集里都有代表shuffle之前设了随机种子保证你多次运行结果一致。val_ratio 我一般取0.15而不是0.2因为数据基数小验证集占比太高会让训练数据更少。复制而不是移动文件也是防止切分出错后没有后悔药可吃。2.3 数据增强什么时候手动加别一上来就上重口味如果统计完发现某类图片特别少比如只有100张那第一步不是疯狂调增强而是先想清楚怎么获取更多图。常见做法是去公开的水稻病害数据集里补充同类图片或者用旋转、裁剪等在线增强扩大样本空间。YOLO11cls训练时自带增强参数默认的hsv_h0.015、fliplr0.5等已经打开了一般不需要在数据层面再做离线增强。有个容易误用的点水稻叶片和别的东西不一样病斑位置和形态是诊断关键。如果你把degrees调得太大比如允许90度旋转叶片纹理方向和病斑形态都会被破坏。对于“稻瘟病”“纹枯病”这类病斑在叶片上的分布相对均匀的小角度旋转、翻转、色域扰动都安全。但如果类别里包含“稻曲病”这种只在穗部出现的病害或者病斑集中在叶尖旋转和裁剪就要克制。我一般会把degrees控制在15以内translate控制在0.1以内先跑一轮再看验证集的表现决定加不加重量级增强。3. 用YOLO11cls一键训练脚本跑通水稻叶病虫害代码拆解和运行边界3.1 为什么选YOLO11cls而不是自己写一个CNN分类器YOLO11cls 这个词容易让人误以为必须搭配检测流程用其实它就是 YOLO11 系列里的图像分类模型和 YOLO11n、YOLO11s 这些检测模型共享底层的 CSPDarknet 骨架但输出头不同。分类头比检测头简单得多网络最后接的是全局池化加全连接层直接输出每个类别的概率。选它不只是因为它新而是Ultralytics的训练、验证、导出链路高度统一从best.pt到 ONNX 再到部署几乎不用写胶水代码。如果你自己搭一个 ResNet 分类器光是预处理管线、学习率调整、混淆矩阵可视化就够你折腾一天。拿 YOLO11cls 和 ResNet18 比前者在相同参数量下的训练设定更现代化自动增强策略、自动混合精度、自动早停都是内置的。对于水稻叶病虫害这种背景杂、类间差异小的任务预训练模型加微调是性价比最高的路线而 YOLO11cls 的yolo11n-cls.pt体积小单张显卡就能跑CPU 也能勉强训练只是慢。一句话选它的理由是省心不是因为它一定比 ResNet 准。3.2 一键训练脚本的核心逻辑这个代码可以直接抄所谓一键训练脚本本质是把“设置随机种子、指定数据集路径、配置训练超参数、启动训练”这几件事固化成一段可重复执行的代码。下面是我常用的训练脚本结构简单但能保证相同代码在不同机器上得到近似结果。# train_yolo11cls.py import random import numpy as np import torch from pathlib import Path from ultralytics import YOLO def set_seed(seed42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) if torch.cuda.is_available(): torch.cuda.manual_seed_all(seed) def main(): set_seed(42) data_path Path(datasets/rice_disease) # 数据集根目录下必须存在 train 和 val 两个分类目录 assert (data_path / train).exists(), f找不到 {data_path / train} assert (data_path / val).exists(), f找不到 {data_path / val} # 用 nanoscale 版本先跑通流程之后可以换 yolo11s-cls.pt model YOLO(yolo11n-cls.pt) model.train( datastr(data_path), epochs150, # 最大训练轮数早停会在合适的时候打断 imgsz256, # 输入图片分辨率256 起步 batch32, # 批大小16G显存跑 32 没问题 patience30, # 30轮内验证集没提升就早停 optimizerauto, # 自动选优化器通常是 AdamW device0, # 单卡训练CPU 改成 cpu workers4, # 数据加载线程数 projectruns/classify, namerice_disease, pretrainedTrue, # 加载 ImageNet 预训练权重 seed42, verboseTrue, ) if __name__ __main__: main()这段脚本有几个地方需要展开说明。patience30是我调过的值对5000张图的数据集来说训练到第50轮左右基本收敛如果30轮没有提升早停会主动结束省时间也省显存。imgsz256不是默认的224原因后面专门讲。workers4在Windows上要注意如果运行时卡在数据加载阶段可以把 workers 改成 2 或 0这是 Windows 多进程数据加载的老问题。整个脚本的关键不在于它有多花哨而在于你随时能重跑重跑的结果和上次一致。3.3 命令行方式也是“一键”不写Python还能怎么训练除了写脚本Ultralytics 官方训练入口yolo classify train可以直接用命令行参数跑起来。我对“一键训练”的理解是参数写进命令里复制粘贴到终端也能得到同样效果。下面这条命令和上一节的 Python 脚本是等价的。yolo classify train \ datadatasets/rice_disease \ modelyolo11n-cls.pt \ epochs150 \ imgsz256 \ batch32 \ patience30 \ optimizerauto \ device0 \ projectruns/classify \ namerice_disease \ pretrainedTrue \ seed42命令行方式的好处是快坏处是参数多的时候容易漏写。漏写pretrainedTrue还好顶多从头训练漏写patience会让训练跑满150轮浪费时间。我的习惯是简单验证用命令行正式实验用脚本因为脚本里可以嵌套数据检查逻辑比如本节上面那段assert能在训练前发现目录错误。训练开始后日志里会输出每个 epoch 的top1_acc和top5_acc如果你的 val 目录有5个类别top1 至少要达到90%以上才说明模型真的在学。3.4 脚本运行的最低要求和边界不是所有机器都能一口气跑完一个容易忽略的问题是YOLO11cls 的device0默认要求 NVIDIA 显卡CUDA 版本和 PyTorch 版本对不上时会直接报错。没有 GPU 的机器把device改成cpu也能训练但5000张图、150轮可能要十几个小时。还有一点如果显存只有6Gbatch32加imgsz256有可能溢出脚本会在训练中途报CUDA out of memory。这种情况把 batch 降到 16或者把 imgsz 降到 224问题就解决了。脚本不是黑匣子报错信息都会指向具体参数关键是愿意读最后几行日志。4. YOLO11cls训练参数怎么调才不浪费这5000张图四个必调项4.1 batch size显存不够时先别骂脚本这是第一个要动的参数batch size 直接决定每个 step 里模型看到的样本数量。batch 越大梯度越稳定但显存消耗线性上升batch 越小训练波动越大但有时反而能从噪声里逃出局部最优。对于5000张图的规模batch32 是一个稳妥起点。如果训练进程直接报显存不足优先降 batch第一步降到16如果还不行再降到8。注意不要只降 batch 不降workers数据加载线程过多时 CPU 会成为瓶颈显卡利用率上不去训练慢得像在爬。我见过不少人在 6G 显存的卡上硬跑 batch64最后翻车在显存溢出。判断 batch 是否合理的标准不是看训练曲线而是打开任务管理器看 GPU 利用率。利用率稳定在80%以上才是健康的如果一直跳来跳去那就是workers太少、磁盘 IO 太慢或者做了不必要的验证集增强。4.2 imgsz水稻病斑是小纹理224未必够用分类任务里 imgsz 最容易被随手设成 224因为这是 ImageNet 时代的默认值。但水稻叶片病害的病斑尺寸很小比如稻瘟病的典型褐色斑点可能只占整张图的几个百分点224 分辨率下这些细节会被下采样抹掉。我一般会设成 256 以上。如果显存有富余512 更好。代价是训练时间约翻四倍因为像素数量是平方关系。有个折中方案先用 224 跑一轮快速验证确认代码流程没问题再用 256 或 512 正式训练。imgsz在验证阶段同样生效所以验证集准确率会随分辨率变化这个现象是正常的。需要注意的是如果你训练用 256推理时也必须用 256否则输入分布不匹配准确率会明显下降。参数建议值判断依据imgsz256显存够可到512病斑细节保留程度batch32显存小则16显卡显存与利用率optimizerauto自动选择AdamW或SGDmosaic0或1病害图不适合过分拼接4.3 epochs和早停固定次数还是自动停有些训练脚本会把 epochs 设成 300 然后不管了对于5000张小规模数据集这大概率浪费时间。YOLO11cls 的patience参数就是干这个事的如果连续 N 轮验证集 top1_acc 没有提升训练自动停止最好的权重已经保存在weights/best.pt。我建议 epochs 设成 150 或 200patience 设成 30。这样既给了模型充分收敛的时间又不会傻等。新手常犯的错误是关闭早停还炫耀“我跑满了300轮”。实际上最后一轮准确率和 best.pt 差很多因为模型过拟合后验证集指标开始滑坡。训练结束后看runs/classify/rice_disease/results.csv里的val/accuracy_top1列凡是连续30轮没有上升的说明早停确实应该触发。4.4 增强参数默认值能用但每个都需要理解YOLO11cls 默认开启的增强参数包括 HSV 扰动、左右翻转、平移缩放等。对于水稻叶片hsv_h0.015、hsv_s0.7、hsv_v0.4是安全的因为叶片颜色变化本身不会改变病害类别。fliplr0.5左右翻转对水稻叶片语义没有影响放心开。degrees我建议从 0 改成 15轻微旋转可以让模型适应田间拍摄时叶片角度不一致的情况。比较危险的参数是mosaic和mixup。这两个增强会把多张图拼接混合对检测任务很有效但分类任务里它们会把一张干净叶片图和一张病斑图拼在一起模型学到的可能是拼接边缘伪影。我在多分类植物病害实验里开启 mosaic 后验证集准确率反而掉了两个百分点。如果你用的是我上面的脚本YOLO11 默认在分类任务里 mosaic 关闭这反而是好事不要手动开。5. 水稻叶病虫害训练避坑五个高频翻车点和排查办法5.1 训练和验证集同源准确率虚高现象训练结束打印 top1_acc 达到97%换一批自己拍的照片测试准确率只有60%多。 原因数据集中同一类别文件夹的图片可能连续拍摄或来自同一公开来源按文件名顺序划分训练/验证集后验证集里全是训练集的“近亲”模型记住的其实是背景。 解决按采集批次、来源文件夹划分。如果数据只有一个来源至少保证训练集和验证集没有同文件名的图片并在划分后抽查验证集图片是否和训练集明显相似。最稳的是重新用split_data.py按随机种子重切切完人工看一眼几个类别的文件夹。5.2 类别文件夹名带中文或空格训练直接报错现象yolo classify train运行到 Resolving dataset 时卡住或者报错说Class names are not available。 原因项目里用了稻瘟病.jpg这样的中文文件名或rice blast文件夹名带空格。Ultralytics 的配置解析对路径中的空格和中文兼容性不够好尤其是导出 ONNX 时中文类别名会直接崩。 解决不管数据集原始文件夹叫什么统一改成英文或拼音小写比如rice_blast、brown_spot。这个操作不需要重命名图片只改目录名脚本里的 label 会跟着变。5.3 训练中途显存溢出前面几十轮白跑现象训练到第20轮突然报CUDA out of memory之前的进度全部丢失。 原因批大小、输入分辨率、数据加载线程三者叠加导致显存峰值超限另一个常见原因是同时打开了太多其他占显存的程序比如浏览器没关。 解决把 batch 降到16imgsz 降到224并在训练前用nvidia-smi检查显存占用。如果机器上还在跑别的训练任务先停掉。养成习惯训练脚本里加上torch.cuda.empty_cache()放在数据加载之后虽然不能根治但能清理缓存碎片。5.4 best.pt 一直没更新最终权重是最后一轮的现象训练结束后加载last.pt做推理效果比验证集结果差很多查看runs/classify/rice_disease/weights/发现只有last.pt没有best.pt。 原因训练命令里带了saveFalse或者验证集准确率从头到尾没提升过说明训练配置有问题。 解决确认训练命令里有默认的saveTrue如果 best.pt 缺失去results.csv里看验证准确率曲线如果一直在震荡没有上升问题多半出在增强过度或学习率设置上。可以试着把optimizer改成SGD配lr00.01对5000张图的小数据集往往比 AdamW 更稳。5.5 推理时所有图片都预测成同一个类别现象用训练好的模型预测单张叶片图不管输入什么病斑输出都是“稻瘟病”且置信度接近1。 原因类别严重不均衡且验证集中数量多的类别占了主导或输入的图片不是水稻叶模型把陌生背景归到了概率最高的类。 解决先看训练集类别统计确认数量差异不超过3倍如果少数类只有几十张建议补充数据而不是加大增强。推理时限制置信度阈值比如只接受0.7以上的结果低于阈值输出“无法识别”。这才是农业场景里可用的状态。6. 训练完先别急着部署用混淆矩阵和推理验证给模型做一次体检6.1 混淆矩阵比top1准确率更值得看训练结束后的第一件事不是拿模型去拍水稻田而是看验证集混淆矩阵。top1_acc 只告诉你整体正确率混淆矩阵能告诉你哪个类容易混成哪个类。比如“褐斑病”总是被误判成“稻瘟病”说明这两个类的病斑特征在模型看来过于接近要么增强数据要么考虑合并类别。6.2 用没进过数据集的真实图做一次推理我一般会单独留一个test_imgs/文件夹放从别的平台搜索的水稻叶片图或者自己手机拍的图。这些图绝不能出现在训练和验证目录里。跑一遍yolo classify predict看输出概率分布。如果真实图和验证集图片风格差异太大预测结果会诚实反映差距这是调整增强策略的最好依据。yolo classify predict \ modelruns/classify/rice_disease/weights/best.pt \ sourcetest_imgs/ \ imgsz256 \ save_txtTrue预测结果会写到runs/classify/predict/labels.txt或每个图片同名的 txt 文件里直接读文本就能看到类别和置信度我一直觉得这个输出格式比控制台打印更利于批量排查。6.3 导出ONNX后再验证一次部署才会稳部署场景里 .pt 文件不方便转成 ONNX 是常见动作。导出很简单但别以为导出完就万事大吉必须用 ONNX Runtime 或推理引擎跑一遍同样的测试图确认输出和 PyTorch 模型一致。不同引擎对算子的支持有差异转出来能加载和转出来能跑出正确结果是两回事。yolo export \ modelruns/classify/rice_disease/weights/best.pt \ formatonnx \ imgsz256导出后的模型输入是[1,3,256,256]的浮点张量需要先对图片做 resize 到 256再除以255做归一化。一旦推理结果和 .pt 版本偏差超过1%先检查预处理是否完全一致。我在一次项目里就因为忘记除以255把 ONNX 的推理准确率从90%拖到了50%后来才意识到问题出在输入分布而不是模型。那次之后我把“导出后必测”写成了自己的流程习惯。导出、检查、然后才交给部署组。希望帮到你。本文还有配套的精品资源点击获取
返回列表