
简介面向农作物害虫识别与图像分类任务的现成数据集含蛀虫、健康无虫、螨虫等4个类别训练集与验证集已按文件夹划分可直接配合ImageFolder加载使用也适配yolov5的分类训练流程。全套共676个文件以673张jpg图像为主另附1个json分类字典、1个Python可视化脚本和1张说明预览图压缩后约53.89MB其中训练集620张、验证集53张目录结构简洁无需额外预处理。资源已吸引277人浏览学习适合刚接触图像分类数据集整理或需要快速验证模型效果的开发者。除图像数据外json文件给出了4个类别的映射关系可视化脚本无需修改即可随机抽取4张图片并保存展示结果便于快速核对样本与标签是否对应。整体包体小而规整既能作为入门级分类实战数据也可作为害虫识别算法评测的补充数据省去自行采集标注的耗时环节。1. 庄稼害虫分类数据集4 分类 673 张图拿来就能跑通的图像分类起点做图像分类项目最烦的不是写模型而是先花两三天整理数据。手工从网上抓图、去重、改文件名、按类别分文件夹一套下来比训模型还累。这个 4 种庄稼害虫分类数据集走的是另一个路子下载解压就是现成的 ImageFolder 结构train 620 张、test 53 张打开就能训省掉的正是整理数据这步最磨人的活。数据覆盖的 4 个类别是蛀虫、健康无虫、螨虫这几类实际农田里常见的状态。对刚入门图像分类或者想快速验证某个分类网络效果的开发者来说这份数据能直接当实验台用对做农业植保相关项目的工程师它也可以作为预训练前的起点数据。另外作者还配了一个可视化脚本和一个 4 分类的字典 json方便你第一时间确认数据长什么样。下面我把这份资源从头到尾拆一遍包括目录怎么组织、ImageFolder 怎么对接、有哪些用起来的注意事项以及最容易踩的几个坑。2. 看一眼数据长什么样目录结构、文件名规则和类别划分逻辑2.1 从 Roboflow 导出的命名规则说起文件名里有23327_jpg.rf.809a1904da5ba707827adc7343253f26.jpg这种带.rf.的格式说明这批图最初是从 Roboflow 平台导出的。.rf.后面那串是图片的唯一哈希 ID用来保证导出过程中不会重名。这种命名习惯在实际项目里很常见但它对人对不友好——你没法只看文件名判断这张图属于哪个类因为类别信息全在文件夹路径上不在文件名里。data/ ├── train/ │ ├── 蛀虫/ │ │ ├── 23327_jpg.rf.809a1904da5ba707827adc7343253f26.jpg │ │ └── 23327_jpg.rf.9614ec7b0e4c86fcc7135ea6d1a654a5.jpg │ ├── 健康无虫/ │ │ └── ... │ └── 螨虫/ │ └── ... └── test/ ├── 蛀虫/ │ └── ... ├── 健康无虫/ │ └── ... └── 螨虫/ └── ...这种按文件夹划分的组织方式恰好是 PyTorch 的torchvision.datasets.ImageFolder最标准、最省事的输入格式。你不需要写一堆数据加载逻辑直接一句ImageFolder(rootdata/train)就能把所有图片按子文件夹名自动标好类别。2.2 训练集验证集划分比例620 比 53 偏小但足够跑通流程train 620 张、test 53 张总量 673 张在图像分类数据集里属于轻量级。这个体量你去训 ResNet 从零开始肯定过拟合但用来做三件事非常合适第一验证你的训练代码和评估流程正确性数据小意味着单 epoch 跑得快调试效率高第二做迁移学习实验用 ImageNet 预训练权重微调这个 4 分类任务620 张图虽然不算充裕但配合数据增强也能收敛到可接受的水平第三当作 YOLOv5 或 YOLOv8 分类模型的入门数据跑通命令行训练再换大数据集。有一点需要留意train 和 test 的类目分布是否均衡描述里没有明确给出。我在实际使用这类 Roboflow 导出的数据时发现目录结构是手工整理过的测试集还好但如果当初是随机按比例切分小数据集容易出现某个类在 test 里只有几张图的情况。拿到数据后先统计一下每个子文件夹的文件数再动手训练这一步花不了两分钟能帮你避免后续 evaluation 结果失真。2.3 数据能用在哪纯分类、YOLO 分类子任务和教学演示这套数据的核心用途就是图像分类但它的适用面不限于 PyTorch。因为目录结构是train/类别名/图片这种通用组织方式Keras 的image_dataset_from_directory、FastAI 的ImageDataLoaders.from_folder、以及 YOLO 系列自带的分类训练命令都能直接吃进这个结构。我在做作物病虫害相关项目时有过一个感受农田里拍回来的虫害照片绝大多数问题不是模型选得不够好而是数据本身样本不一致——有些叶子背面才有虫有些光线极暗有些图里虫只占画面的百分之几。这套数据虽然没标检测框但作为分类任务的实验数据它能帮你先验证一个问题在正常拍摄条件下4 分类能不能分得开。先跑出基线再考虑该不该上检测模型这个思路比一上来就 YOLO 更稳。3. 用 ImageFolder 直接打开三行代码把数据喂进 PyTorch3.1 标准加载代码与参数说明描述里明确说了“用 ImageFolder 打开无需额外处理”那这段代码就是整个数据集复现的核心。我一般会加上train_test_transforms和 DataLoader 的配置凑成一个可以直接跑的脚本import torch from torchvision import datasets, transforms from torch.utils.data import DataLoader # 训练集和测试集用不同的预处理策略 train_transforms transforms.Compose([ transforms.Resize((224, 224)), # 统一尺寸ResNet 系列输入要求 transforms.RandomHorizontalFlip(), # 水平翻转针对 4 分类数据增强 transforms.RandomRotation(10), # 小角度旋转模拟拍摄角度抖动 transforms.ToTensor(), # 转张量像素值归一到 [0,1] transforms.Normalize(mean[0.485, 0.456, 0.406], # ImageNet 均值 std[0.229, 0.224, 0.225]) # ImageNet 方差 ]) test_transforms transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) # ImageFolder 自动把子文件夹名映射为类别索引 train_dataset datasets.ImageFolder(root./data/train, transformtrain_transforms) test_dataset datasets.ImageFolder(root./data/test, transformtest_transforms) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue, num_workers4) test_loader DataLoader(test_dataset, batch_size32, shuffleFalse, num_workers4) print(训练集类别映射:, train_dataset.class_to_idx) print(训练集样本数:, len(train_dataset)) print(测试集样本数:, len(test_dataset))这段代码里ImageFolder做的事是遍历root下的所有子文件夹把每个文件夹名当作类别名按字母序生成索引然后返回(image, class_index)的样本对。class_to_idx在训练类别不多且英文名规范时顺序尚可但如果子文件夹是中文名比如这里的「蛀虫」「健康无虫」你训练时就看不到类别名只能看到数字索引后面推理阶段得靠 json 字典对应回来。这里有个小细节normalize用的均值和方差是 ImageNet 预训练模型的默认值不是这套数据自己的统计值。你如果从零训练理论上应该用数据集的真实均值和方差。不过你如果打算微调预训练模型那就保持 ImageNet 的归一化参数别改。常见错误是一套代码同时在两种训练模式里复用导致从零训练时归一化分布和输入分布不一致损失曲线抖动得厉害。3.2 验证可直接运行先用统计代码确认数据完整性拿到数据的第一步除了跑训练代码我更建议先跑一个纯统计脚本不加载图片只数文件数确认目录对得上再往下走find data/train -type f -name *.jpg | wc -l find data/test -type f -name *.jpg | wc -l另外看看每个子类的文件个数是否接近这一步能提前暴露数据切分不均的问题。我在一个实际项目中遇到过类似情况——某个稀有类别在训练集里近 200 张但测试集只有 3 张这种比例偏差会让准确率波动极大。如果碰到这种问题解法一般是按类别分层切分测试集或者用 K 折交叉验证代替单次划分。3.3 不开代码直接看数据可视化脚本的用法这个数据集附带的可视化 py 脚本是「随机传 4 张图展示并保存到当前目录」省去了自己写 matplotlib 拼接的功夫。它的基本原理是读取一堆图、随机挑 4 张、用plt.subplot(2,2)拼成一张大图后savefig保存。运行它会输出类似visualize.png的文件到当前目录。python visualize.py这一步强烈建议放到加载训练之前先做一遍。原因很简单图像分类数据集的标签可信度是所有后续工作的前提。如果某个类别的图片里混入了其他类别的图或者某张图本身是损坏的、全黑的、带水印的这些都会干扰训练。可视化脚本存在的意义就是让你用几秒钟添加人眼先验把明显的脏数据在训练前剔除掉。4. 把这份数据用到 YOLO 分类任务里格式转换与训练命令4.1 YOLO 分类数据格式本质是目录结构不需要转成 txt网上搜「yolov5 训练自己的数据集」大部分教程在讲检测任务的标注格式每张图配一个 txt内容是class_id cx cy w h。但你要做的是图像分类的话事情简单得多——YOLO 官方分类训练直接吃目录结构和 ImageFolder 完全同构。所以这份数据的 Roboflow 导出结构已经可以直接供给 YOLO 分类任务用你唯一要做的只是确认类别名不要有空格和特殊字符。# YOLOv5 分类任务目录要求 # datasets/庄稼害虫/ # ├── train/ # │ ├── 蛀虫/ # │ ├── 健康无虫/ # │ └── 螨虫/ # └── val/ # ├── 蛀虫/ # ├── 健康无虫/ # └── 螨虫/ # 注意YOLO 分类任务期望验证集目录名是 val不是 test cd data mv test val这里有一个谁都会忽略的坑torchvision.ImageFolder对验证集目录名没有要求你叫test叫val都行但 YOLO 系列跑分类训练时命令行里--data参数默认指向的是{data_dir}脚本内部会去找{data_dir}/train和{data_dir}/val这两个子目录。如果你直接把这个数据集的test文件夹原封不动拿给 YOLO 用训练时就会报错「val split not found」。这是最典型的格式假设不一致问题解决方式就是上面那样把test重命名成val或者用--val参数显式指定。4.2 用 YOLOv5 分类命令训练与关键参数说明假设你已经把目录调整成上面的结构训练命令如下python classify/train.py \ --model resnet18 \ --data /path/to/庄稼害虫 \ --epochs 30 \ --img 224 \ --batch-size 32 \ --pretrained对这份 620 张的数据来说我建议epochs给 30~50 之间多了几乎肯定过拟合batch-size看显存32 是一个起点显存不够降到 16--pretrained强烈建议打开因为你的训练样本数量级不足以支撑从零收敛出一个深层网络。如果用 YOLOv8命令等价为yolo classify train modelyolov8n-cls.pt data/path/to/庄稼害虫 epochs30 imgsz224 batch32YOLOv8 的yolov8n-cls.pt是一个轻量级分类模型参数量大约 3M 出头记不太清了但它小到 CPU 也能跑推理在 600 张图的数据量上收敛很快训练时间按分钟计。这类小模型反而适合这份数据因为数据量本身就撑不起大模型的容量。逻辑上YOLO 分类训练的本质和 torchvision 里跑的 ResNet 微调没有区别都是加载预训练权重然后把最后一层全连接换成 4 分类输出。你选择用 YOLO 而不是纯 PyTorch 脚本的原因主要是两条一是命令行方便免写训练循环二是未来想从分类升级到检测任务时模型系列和工具链能统一起来。4.3 关于类别名建议训练前先转成英文一个容易忽略的细节这份数据的类别名是中文比如「蛀虫」「健康无虫」「螨虫」。直接拿中文目录名去训练在 Windows 上可能没事但在 Linux 服务器上跑 YOLO 时的部分第三方库对非 ASCII 路径支持不算好轻则日志打印乱码重则在某些数据加载环节出编码异常。稳妥做法是先做一层软链接或目录复制把中文类别名映射成英文字母cd 庄稼害虫 mkdir train_en mv train/蛀虫 train_en/borer mv train/健康无虫 train_en/healthy mv train/螨虫 train_en/mite # 继续处理其他类别类别名转完英文还有个额外好处后面看混淆矩阵、分析分类错误时英文标签在绘图时的排版和可读性都明显好于中文。train/test 的 json 字典文件也一并改成新的映射关系别只改目录名不改字典不然推理后处理时类别 ID 对不上。5. 避坑指南我在这类小数据集上翻过的四个车5.1 类别不均衡导致准确率虚高现象训练完看准确率挺高90% 以上但仔细看测试集每个类别的召回率发现某个类接近 100%另一个类只有 50% 多。原因train 和 test 的类别分布不一致或者训练集里某个类样本过多模型直接学会偏向多数类。这个数据集共 673 张图类别一多平均到每个类就 150 张上下某类多 50 张少 50 张差别就非常显著。解决训练前用Counter(Counter(train_dataset.targets))打印每个类的数量再打印 test 的分布。多数类给欠采样或降低 loss 权重少数类做额外增强比如旋转角度加大、加色彩抖动。对一个 4 分类任务最理想的情况是每个类样本数量在一个量级上最好相差不超过 20%。5.2 图像损坏导致的「随机」训练崩溃现象跑着跑着 loss 突然跳到 NaN或者 DataLoader 报EOFError、Cannot identify image file。原因Roboflow 导出的图片本身基本是完整的但如果你下载解压时中间断了、或者手动从网盘转存之后文件损坏就会出现某张图只有文件头没有数据。ImageFolder 加载时并不验证文件完整性是训练到那个 batch 时解码才炸。解决拿到数据后先跑一遍 PIL 解码验证把坏文件筛出来from PIL import Image from pathlib import Path for img_path in Path(./data).rglob(*.jpg): try: with Image.open(img_path) as im: im.load() except Exception as e: print(f损坏文件: {img_path} - {e})我一般习惯把这一步和可视化脚本放在一起执行一次就把数据集完整性检查和内容抽查做掉。5.3 中文目录名在 Linux 环境下的编码坑现象在 Windows 上训练正常把数据传到 Linux 服务器后训练时某些图片加载报 FileNotFoundError路径打印出来是乱码。原因中文目录名在文件系统层是 UTF-8 编码和系统 locale 设置不一致时Python 的os.listdir拿到的是解码后的字符串而文件系统接口用的是字节串一旦 locale 不是 UTF-8 就会出现「看起来存在但打不开」的诡异现象。解决这类数据我现在的习惯是一律先转英文目录名再训练不做任何心存侥幸的尝试。还有一招是设置环境变量PYTHONUTF81能缓解一部分问题但根治不了。5.4 YOLO 分类任务里把 test 目录当 val 用现象按 YOLO 命令训练刚启动就报错AssertionError: Train: ... does not exist或 val 相关的路径错误但明明数据目录里文件都在。原因YOLO 分类脚本内置的数据集目录搜索逻辑默认拼接data_dir / train和data_dir / val这套数据的验证集目录叫test所以找不到。解决要么把test文件夹重命名为val要么在 YOLO 的命令行里手动指定--val参数对应到 test 目录。这个坑特别容易发生在从 torchvision 生态转过来的人身上因为它俩对「验证集目录叫什么名字」的约定完全不同。6. 验证你训出来的模型从准确率到「它真的认虫」的三步检查6.1 第一步用脚本输出每类别的精确率和召回率光看整体准确率对 4 分类任务是不够的——如果某类占比高模型全猜这个类都能有很高准确率。标准做法是用classification_report把每个类的精确率、召回率、F1 都打出来from sklearn.metrics import classification_report import numpy as np all_preds [] all_labels [] model.eval() with torch.no_grad(): for images, labels in test_loader: outputs model(images) _, preds torch.max(outputs, 1) all_preds.extend(preds.numpy()) all_labels.extend(labels.numpy()) print(classification_report(all_labels, all_preds, target_nameslist(test_dataset.class_to_idx.keys())))我一般会盯着两个数字看召回率最低的那个类以及它和最高类的差距。如果差距在 10 个点以内这套数据的基础质量是过关的如果某个类召回率明显塌陷通常不是模型问题而是数据里那个类的成像条件太混乱——阴影、遮挡、景深不一致这类问题加数据增强往往改善有限要找原始拍摄数据来补。6.2 第二步跑一张没见过的照片做端到端验证分类准确率是说给实验听的最终你还要回答一个问题这个模型到田里拍一张照能不能给出符合直觉的判断。我会用训练时同一套 transform 的推理代码传一张训练集和测试集之外的实拍图看一眼输出概率分布def predict_single_image(image_path, model, class_names, transform): img Image.open(image_path).convert(RGB) img_tensor transform(img).unsqueeze(0) model.eval() with torch.no_grad(): outputs model(img_tensor) probs torch.softmax(outputs, dim1).squeeze() for name, prob in zip(class_names, probs.numpy()): print(f{name}: {prob:.4f})关键不是看 top1 对没对而是看概率分布是不是「犹豫」——如果前两个类别的概率都在 0.4 左右说明模型在特征空间里没把这两个类分开这时候回头看数据里这两个类的样本差异才是正道。6.3 第三步顺手做一个最朴素的过拟合测试在 600 张图上做一个快速冒烟测试选训练集的子集比如每个类 10 张训 20 个 epoch看训练集本身的准确率能不能收敛到 95% 以上。如果连这个小实验都学不动那问题大概率不在数据量上而是代码、学习率、模型结构配置里至少有一处是错的。这个测试 10 分钟就能跑完但它能在你花一小时调超参数之前就帮你排除掉最大的不确定性。我自己的习惯是每次拿到新的分类数据不管项目多急都会强制把这个流程走一遍——统计分布、看可视化、跑冒烟测试、训练验证集评估。这套流程不复杂但它帮我拦截过坏图、类别不均衡、目录名编码三四个大坑。这套 673 张的庄稼害虫数据虽然小但结构清晰、开箱即用拿它把整套流程跑顺一遍之后换大数据集时你会特别感谢现在这个动手验证的习惯。希望这篇拆解能帮你把数据真正用起来少走几步弯路。本文还有配套的精品资源点击获取