ARTICLE DETAIL

资讯详情

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

YOLO11cls实战:1000张农作物病虫害图像分类训练指南

YOLO11cls实战:1000张农作物病虫害图像分类训练指南 简介一套面向农作物病虫害检测与图像分类任务的实用数据集聚焦腰果、木薯、玉米、番茄四大作物涵盖炭疽病、褐斑病、叶锈病、花叶病、草地贪夜蛾、叶蝉、枯萎病等22个常见类别共1000张真实场景高质量图片。全部图像按类别划分至独立文件夹目录结构清晰标注质量高无需额外转换即可直接用于YOLO11cls等分类模型的训练与验证。资源仅包含1个PDF文件大小约5.63MB内部详细说明数据集类别构成、样本分布与标注规范并提供百度网盘无损获取方式可解决大文件传输不便的问题。随PDF附赠的YOLO11cls一键训练脚本与博主实测训练日志涵盖数据加载、超参数配置、模型训练与指标输出等关键环节适合刚接触YOLO分类任务的开发者快速跑通流程并参照日志调整策略。这些数据可有效缓解实际项目中高质量标注样本稀缺的问题目前已有63人学习使用适合作为农作物病虫害项目落地前的数据支撑与算法验证参考。1. 用 YOLO11cls 给农作物病虫害做目标分类1000 张图到底够不够用手头攒了 1000 张带病斑的作物叶片照片已经按病害名字分文件夹整理好想直接训练一个能识别“这是什么病”的分类模型——这是农业方向做目标分类最常见的起步场景。很多人第一反应是上 YOLO 做检测画框但如果你只需要判断“这张叶子是稻瘟病还是叶锈病”YOLO11cls 这种纯分类模式才是更省事的路线。它不需要画标注框文件夹结构直接当标签用配套的 Ultralytics 训练命令把数据校验、增强、训练、评估都串成了一条流水线。这篇文章要解决的是三个实际问题1000 张图这种中小规模数据集能不能训出可用模型、分类文件夹怎么整理才不会让脚本报错、以及一键训练脚本里哪些参数值得调、哪些坑会反复踩。受众是有基础但不想看太多理论的开发者或农业信息化从业者——你不需要懂端侧部署也不需要会写自定义网络照着目录结构放图、改几个参数就能在本地 GPU 上把第一个模型跑出来。2. 数据集整理从“分类文件夹”到能被 YOLO11cls 直接吃进去的目录2.1 分类任务和检测任务的数据组织方式完全不同如果你之前用 YOLOv8 训练过自己的数据集一定熟悉那种“图片 txt 标签”的排列方式每张图对应一个标注文件标注里写类别序号和归一化坐标。YOLO11cls 不一样它是分类模型数据组织规则简单得多——每个类别一个文件夹文件夹里的图片全部属于这个类文件夹名就是类别名。网上能找到的不少农业公开数据集比如 PlantDoc、叶片病害数据集往往就是以这种“大文件夹套小文件夹”的形态发布的。这种设计的底层逻辑是分类模型的训练代码会遍历根目录下的子文件夹用子文件夹名生成类别标签索引。train 目录下有哪些子文件夹模型就认为有几个类别子文件夹名是“leaf_blast”模型预测输出的类别名就是这个字符串。这意味着文件夹命名直接决定标签内容不能有中文、空格、特殊符号连大小写都要保持稳定否则同一病害被拆成两个类别混淆矩阵会标得乱七八糟。我一般会把数据集根目录结构固定成下面这样datasets/ plant_disease/ train/ leaf_blast/ img_001.jpg img_002.jpg leaf_rust/ img_003.jpg val/ leaf_blast/ img_040.jpg leaf_rust/ img_041.jpgtrain 和 val 下面必须各自有一份完整的类别文件夹列表类别数量要一致。val 里缺了某个类训练时就会出错多了某个类验证指标会失真。这个结构看起来简单但实际整理时最容易翻车的点恰恰是“train 和 val 的类别没有对齐”。2.2 从原始分类文件夹生成 train/val 划分一份可复制的脚本假设你已经把所有照片按类别放在source/类别名/下下一步要做的是把它拆成训练集和验证集。1000 张图不多不推荐手动拖文件一方面容易漏另一方面比例不均匀。下面这份脚本会把每个类别内部按 85/15 的比例随机划分并自动打印出每类的样本数量方便你一眼看出哪些类样本太少import random import shutil from pathlib import Path random.seed(1234) source_root Path(./source) dest_root Path(./datasets/plant_disease) val_ratio 0.15 for cls_dir in sorted(source_root.iterdir()): if not cls_dir.is_dir(): continue images list(cls_dir.glob(*.jpg)) list(cls_dir.glob(*.png)) random.shuffle(images) val_count int(len(images) * val_ratio) val_images images[:val_count] train_images images[val_count:] print(f{cls_dir.name}: total{len(images)}, train{len(train_images)}, val{len(val_images)}) for split_name, split_images in [(train, train_images), (val, val_images)]: target_dir dest_root / split_name / cls_dir.name target_dir.mkdir(parentsTrue, exist_okTrue) for img_path in split_images: shutil.copy2(img_path, target_dir / img_path.name)代码逻辑分三段先遍历源目录只处理子文件夹不处理散落的图片文件再把每类图片随机打散按比例切出验证集最后在目标目录里重建 train/val 结构并复制文件。我特意用了copy2而不是move因为原始整理好的文件夹往往是唯一的底稿训练集做增强、清洗后文件可能越洗越少保留原图方便后悔时重新切。两个值得注意的细节。一是random.seed固定随机源每次跑脚本得到完全相同的划分这对复现实验结果很重要二是只匹配了.jpg和.png如果你手头有.jpeg、.bmp格式的图要提前统一转成 jpg 或加入对应后缀Ultralytics 训练时会按扩展名读图混入 TIFF 这种格式不一定报错但读取速度和训练稳定性都会受影响。2.3 清洗脏数据损坏图片与错误样本的批次检查数据清洗这一步绝大多数人都会跳过但对 1000 张的小数据集来说一两张坏图就能把训练过程搅乱。最典型的现象是训练到十几个 epoch 时 loss 突然变成 nan排查半天发现是某张超小尺寸或截断的图片喂给数据加载器后出了问题。建议在整理后、训练前批量跑一遍完整性检查from PIL import Image from pathlib import Path data_root Path(./datasets/plant_disease) bad_images [] for img_path in sorted(data_root.rglob(*)): if img_path.suffix.lower() not in [.jpg, .jpeg, .png]: continue try: with Image.open(img_path) as im: im.verify() width, height im.size if width 32 or height 32: bad_images.append((str(img_path), ftoo small: {width}x{height})) except Exception as e: bad_images.append((str(img_path), str(e))) for path, reason in bad_images: print(f[BAD] {path}: {reason})verify()只做解码校验不会读入完整像素速度很快1000 张图几秒就跑完。检查出问题后我一般优先删掉坏图而不是替换成空图因为分类任务里一张全是纯色的“占位图”会被模型当成一个固定模式学进去比缺失更隐蔽。最后可以打印每类图片数量如果某一类明显少于其他类要么补数据要么考虑合并相邻类别——这一步留在下面的训练策略里处理。3. YOLO11cls 一键训练脚本骨架、核心参数与第一次跑通3.1 为什么 1000 张图建议用预训练权重微调训练分类模型有三种常见起点从零随机初始化、加载 ImageNet 预训练权重、加载同分布预训练权重。1000 张图从零训网络基本必过拟合加载 Ultralytics 官方的yolo11s-cls.pt属于标准做法它在 ImageNet-1k 上做过预训练已经具备纹理、边缘、形状这些通用视觉特征我们只需要在后几层上做迁移。模型规模的选择同样要克制。YOLO11 分类系列里有yolo11n-cls.pt、yolo11s-cls.pt、yolo11m-cls.pt等数据集只有 1000 张时n 和 s 的差距不大但 s 的收敛稳定性通常更好直接上 m 或 l训练速度降低不说小数据带来的过拟合风险反而更大。我自己的经验是优先用 s跑通了以后如果验证集准确率还有余量再回头试 n 或 m这个顺序比一开始就追求大模型要省时间得多。3.2 一键训练脚本从数据校验到自动落盘把训练过程封装成一个 shell 脚本核心价值不在减少敲键盘次数而是把“验证数据集 → 选设备 → 训练 → 保存产物”这串步骤固定下来换数据集时只需要改顶部的路径变量。下面是我惯用的写法#!/bin/bash set -e DATA./datasets/plant_disease MODELyolo11s-cls.pt # 预训练权重首次会自动下载到本地缓存 EPOCHS100 IMGSZ224 BATCH32 PATIENCE15 DEVICE0 python -c from ultralytics import YOLO import os assert os.path.exists(/path/to/your/env/site-packages/ultralytics), 请先在当前环境安装 ultralytics yolo classify train \ model$MODEL \ data$DATA \ epochs$EPOCHS \ imgsz$IMGSZ \ batch$BATCH \ patience$PATIENCE \ device$DEVICE \ project./runs/classify \ nameplant_disease_exp1脚本开头加了set -e任何一行命令非零退出都会立刻终止避免训练中途报错还继续往下跑。中间那段 Python 断言是我用来提醒自己环境有没有装对的土办法——如果 ultralytics 没装好脚本会在训练前停下来而不是等 GPU 任务启动后才报 ModuleNotFoundError。这段脚本里真正值得调的是patience和imgszpatience15表示验证集指标连续 15 个 epoch 没有提升就自动停止训练1000 张图通常 30~50 个 epoch 就收敛了设太大纯属浪费算力imgsz224是分类任务的标准输入尺寸如果原图很大但病害区域较小可以提高到 320 或 384但要同时降低 batch不然显存会吃紧。训练结束后权重文件会保存在runs/classify/plant_disease_exp1/weights/best.pt这是验证集表现最好的权重日常推理用这个而不是last.pt。3.3 关键超参数怎么定epochs、batch size 与数据增强1000 张图的训练规模下超参数不需要做复杂搜索记住几个边界值就够了。epochs我习惯写 100 然后靠早停兜底而不是精确算出一个数值batch要看显存16GB 显卡用 32 基本没问题显存小于 8GB 就降到 16lr0保持默认的 0.01除非发现 loss 震荡剧烈才降到 0.005。Ultralytics 在分类训练中默认开启了随机裁剪、翻转、色彩抖动等增强策略小数据集可以明显缓解过拟合。如果训练集里同一类图片有大量重复背景比如都是从同一台相机拍的、角度高度一致可以把hsv_h、hsv_s这类色彩增强开大一点农作物病害识别里病斑颜色是很重要的判别特征但也要小心增强过度导致病斑颜色失真、模型反而学不到真实病理特征。这个平衡没有定量公式只能靠每轮训练后在验证集上观察 top1 准确率的变化来微调。另一个小技巧是第一次训练不急着把所有参数调到最优先用默认参数完整跑一轮记录验证集准确率、混淆矩阵和典型误判样本有了基线再调参。否则参数和数据同步修改出了新问题你根本不知道是哪一步引起的。4. 训练过程怎么看损失曲线、混淆矩阵与分类报告4.1 训练日志里哪些指标值得盯用yolo classify train跑起来后终端会实时刷新每个 epoch 的训练损失train/cls_loss和验证指标。对于分类任务最核心的是val/top1_acc——模型预测概率最高的类是否等于真实标签。top5 准确率在小数据集上参考意义不大但如果你发现自己训练的模型 top1 在 70% 左右、top5 却有 95%说明模型已经能把“病害大类”分开卡住的是类间相似度高的细粒度区分比如稻瘟病初期和生理性黄叶。损失曲线要区分看。训练损失持续下降、验证损失却回升是典型的过拟合信号这时早停会触发拿到的 best.pt 往往是验证损失最低点附近的一个权重不是训练损失最低的。我见过不少人在训练损失降到 0.05 时跑去测试结果泛化很差——这是混淆了“拟合训练集”和“学到可泛化特征”两个指标的区别。4.2 混淆矩阵与分类报告找到模型真正搞不定的类训练结束后Ultralytics 会在输出目录生成confusion_matrix.png和results.csv。混淆矩阵是分类任务里信息量最大的单张图——看它不要只看对角线上的数字重点找“非对角线的亮点”比如leaf_rust被识别成leaf_blast的概率达到了 20%这往往意味着这两类在颜色或纹理上高度相似。我有个习惯每次训练完先打开混淆矩阵再做两件事。一是在数据集中抽查那些被误判的图片看是样本本身模糊、拍摄距离过远还是两类本来就没有清晰边界二是把混淆严重的类对在训练集里单独拿出来统计各自的图片数量。如果某类只有 20 张训练图被误判几乎是必然的这时不是调参数而是要补数据或合并相似类。4.3 验证不止看报告用田间真实照片做一次推理报告指标再好也不如拿几张训练集之外的照片跑一次推理来得踏实。训练完成后在项目根目录执行yolo classify predict \ model./runs/classify/plant_disease_exp1/weights/best.pt \ source./samples/tomato_field_0221.jpg \ imgsz224 \ device0source可以传单张图片、一个文件夹甚至是一个摄像头设备的索引。预测结果会在原图上叠加类别名和置信度并保存到runs/classify/predict目录。我一般会特意挑几种场景试一张光线很暗的、一张叶片带泥土背景的、一张叶片有残缺的。分类模型对拍摄环境非常敏感训练集里如果全是实验室白背景到了大田里性能打七折是常态这一步能最快暴露这类问题。5. YOLO11cls 训练自己的农作物病虫害数据5 个最常见的坑5.1 过拟合训练集准确率 99%验证集只有 75%现象训练损失降到 0.01 以下验证准确率却一直上不去且训练后期验证损失开始回升。原因1000 张图对整个病害识别任务来说属于偏小的规模模型容量大于数据能提供的信息量网络开始“背诵”训练集里图片的噪声特征比如背景颜色、拍摄角度而不是病害本身。解决优先用更小的模型从 s 降到 n把 RandomResizedCrop 增强开到默认以上增加 dropout 或 weight_decay如果条件允许每个类别至少补到 50~80 张1000 张分到 20 个类的话每类只有 50 张类别偏远时模型几乎没有泛化空间。5.2 文件夹命名用了中文、空格或大小写混用现象训练能启动但打印出的类别名是乱码或者同一个类别在 train 和 val 中显示成两个独立类别导致准确率异常。原因Ultralytics 在构建分类数据集时直接用子文件夹名做类别名中文字符编码在不同系统间可能不一致空格会导致路径解析出错RiceBlast和riceblast会被视为两个完全不同的类。解决统一用英文小写加下划线命名比如leaf_blast、leaf_rust并在整理阶段跑一个检查脚本禁止任何文件夹名含非 ASCII 字符这一步能从根源上杜绝问题。5.3 图片尺寸悬殊部分小图被强制拉伸变形现象训练不报错但验证集里某些类别的准确率明显偏低把错分图打出来看发现叶片比例畸形。原因imgsz224会把所有图缩放到 224×224原图如果是一张 8000×6000 的田间大图缩小时病害纹理已经磨没了如果是一张只有 64×64 的病斑特写放大时会出现严重马赛克。解决在数据检查阶段过滤掉明显过小的图或者把imgsz提高到 320 并加大训练集增强强度让模型在更多尺度上见过病斑田间大图建议先做切片裁出病害区域再进训练集整图直接缩放到 224 等于把病害特征丢掉了。5.4 类别不平衡某一类只有十几张图现象训练过程一切正常但混淆矩阵里样本少的类几乎全被分到邻近大类。原因类别样本量差距过大时模型天然偏向多数类——即使把病斑的特征完全学对了概率输出也会被先验概率拉向高频类别。解决按 2.2 节的脚本重新统计每类数量对少样本类做复制增强注意不是简单复制而是配合随机翻转、色彩抖动生成变体如果实在补不了数据考虑合并语义相近的类别比如把两种症状相似的叶斑病合成一类训练成“叶斑病”而不是细分到具体病原菌。5.5 早停设置不当导致欠拟合现象训练只跑了 15~20 个 epoch 就自动停止top1 准确率还没到平台上就提前锁定最佳权重。原因patience15的触发条件是“连续 15 个 epoch 验证指标无提升”但小数据集在初始阶段损失波动大早停误判频率很高尤其在训练刚启动、增强策略刚生效时。解决第一轮训练把patience调到 30 或直接设 0 让它跑满拿到完整曲线后再根据收敛位置重新设早停正规做法是同时看val/loss和val/top1_acc两个指标都进入平台期再手动停。6. 识别准确率的上限瓶颈与两个提点技巧二次微调与推理期增强模型跑通只是第一步真想把准确率从 85% 拉到 92%我通常会花最后一轮时间做两件事二次微调和使用测试时增强。二次微调的核心逻辑是低学习率 更真实的数据分布——动用best.pt作为初始权重把lr0降到 0.001 甚至 0.0005在原始训练集上再跑 20 到 30 个 epoch。第一次训练时模型见过的都是增强后的图片二次微调用原图拟合一遍能有效把“增强域”拉回“真实域”。推理期增强的做法更取巧预测时传入稍大的imgsz让模型看到更多细节或者把同一张图做轻微翻转和缩放后预测多次取平均概率作为最终输出。Ultralytics 并没有直接暴露一个 “test-time augmentation” 开关但你可以用 Python 调YOLO.predict()循环预测三次再对概率取均值实测在病斑小、纹理弱的场景能稳定带来 1 到 2 个百分点的提升。这个提升看起来不大但对于卡在识别阈值边缘的样本往往就是“误报”和“正确告警”的区别。最后说一个我踩出来的习惯每次训练完不要急着删训练日志和 last.pt把 exp 目录整体打包存下来再清理。训练记录里有完整的超参数和每次验证的指标过两个月数据集补了图、想复现或对比时这份记录比你自己写的笔记可靠得多。希望帮到你也祝你第一版模型顺利跑通。本文还有配套的精品资源点击获取
返回列表