ARTICLE DETAIL

资讯详情

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

桑叶品种图像分类数据集:10类5000张标注图片的实战指南

桑叶品种图像分类数据集:10类5000张标注图片的实战指南 简介这份桑叶品种图像分类数据集面向从事计算机视觉与深度学习分类任务的开发者、学生及科研人员可用于品种识别模型训练、迁移学习对比实验或课程设计。数据已按类别完成标注共划分10个品种包括红王、白王、Chiang Mai 60、Buriram 60等具体类别名称可查阅包内json文件。资源已预先划分训练集与测试集各类别图片分别存放便于直接接入主流分类网络进行训练与评估。压缩包为7z格式共约2000个文件其中1998张jpg图像构成主体样本另含1个py脚本与1个json标注文件整体约730.15MB。包内提供的show脚本可用于快速可视化数据集分布与样本效果方便检查类别均衡与图像质量。目前已有76人学习下载适合希望快速获取真实标注数据、验证分类网络改进思路的读者参考使用。1. 桑叶品种图像分类数据集10 类约 5000 张已标注图片能直接跑什么拿到一个农业图像数据集第一反应往往不是能不能用而是标注到底靠不靠谱、类别均不均衡、能不能直接喂给模型。这份桑叶品种数据集就是冲着这三个问题来的约 5000 张实拍桑叶图像按 10 个品种分好类训练集和测试集已经切分完毕每类图片放在各自目录下还附带一个可视化脚本。类别包括红王、白王、Chiang Mai 60、Buriram 60 等具体名单在资源内的 json 文件里能查到。它适合谁做图像分类课程设计的学生、想验证 transformer 图像分类或轻量 CNN 改进效果的算法工程师、需要农业垂直场景数据做迁移学习验证的从业者。不适合谁想做目标检测或分割的人——这是纯分类数据集没有边界框和掩码标注。下面从目录结构、标注格式、可视化验证一路讲到训练接入和踩坑尽量让新手能照着跑通熟手能看到参数边界。2. 数据集结构与标注格式先搞清楚目录怎么摆、json 里存了什么2.1 目录组织与训练测试切分逻辑这类图像分类数据集最常见的组织方式是ImageFolder风格每个类别一个子目录目录名就是类别标签。训练集和测试集各自独立成树互不重叠。典型结构长这样dataset/ ├── train/ │ ├── 红王/ │ │ ├── IMG_20191214_140427.jpg │ │ └── ... │ ├── 白王/ │ ├── Chiang_Mai_60/ │ └── Buriram_60/ ├── test/ │ ├── 红王/ │ ├── 白王/ │ └── ... └── classes.json从项目正文给出的文件名看原始图片是手机拍摄的IMG_日期_时间.jpg格式说明数据采集端是移动设备没有经过重命名清洗。这带来一个直接后果文件名本身不携带类别信息类别完全靠所在目录区分。所以你在解压后第一件事不是急着写训练脚本而是确认目录层级有没有被压缩工具多套一层。classes.json通常存两类信息类别名称列表和类别到索引的映射。有的版本还会记录每类样本数。我一般会先读这个文件确认类别顺序因为后续混淆矩阵、分类报告的标签顺序全靠它对齐。如果 json 里类别顺序和目录遍历顺序不一致评估结果会出现标签错位——准确率看着正常但每一类的 precision 全乱。2.2 标注格式解析与类别索引对齐分类数据集的标注就是目录名但工程上必须把它转成模型能吃的索引。常见做法是用torchvision.datasets.ImageFolder它会按目录名排序自动生成class_to_idx。问题在于自动排序的结果未必和classes.json一致。中文类别名和英文类别名混排时排序规则按 Unicode 码点走Buriram_60会排在Chiang_Mai_60前面而红王这种中文名会排到所有 ASCII 之后。import json from pathlib import Path from torchvision import datasets # 读取官方类别映射 with open(dataset/classes.json, r, encodingutf-8) as f: meta json.load(f) print(json 中的类别:, meta[classes]) # ImageFolder 自动生成的映射 train_ds datasets.ImageFolder(dataset/train) print(ImageFolder 映射:, train_ds.class_to_idx) # 两者不一致时以 json 为准重建映射 assert set(train_ds.class_to_idx.keys()) set(meta[classes]), 类别名对不上 idx_map {name: i for i, name in enumerate(meta[classes])} train_ds.class_to_idx idx_map train_ds.classes meta[classes]这段代码的关键在最后三行强制用 json 的顺序覆盖 ImageFolder 的默认顺序。参数上注意encodingutf-8中文类别名不加这个在 Windows 上大概率报UnicodeDecodeError。assert那行是防线——如果目录名和 json 里的类别名有任何一个对不上比如多了空格、下划线变横线这里会直接拦下来而不是等到训练完才发现某类样本数为零。提示解压后先跑一遍find dataset/train -maxdepth 1 -type d看类别目录数量10 类就应该是 10 个不含 train 本身。少一个说明解压不完整或某类被合并了。3. 可视化脚本与数据质量核查show 脚本怎么用、要看什么3.1 运行 show 脚本做类别分布与样本抽查资源里带了 show 脚本作用通常是把每个类别抽样成网格图方便肉眼确认标注有没有串类。运行方式一般是python show.py --data_root dataset/train --samples_per_class 8 --save preview.png如果脚本没有 argparse 而是硬编码路径就打开改data_root变量。跑完重点看三件事一是每类抽出来的叶子形态是否一致如果红王里混进了明显不同叶形的图说明标注有噪声二是图片亮度差异手机拍摄在不同光照下色温差别很大这会影响模型对颜色的依赖三是看有没有非叶子图片混入比如误拍的手、地面、标签纸。我一般会把samples_per_class设成 8 到 12太少看不出分布太多图缩得太小看不清细节。保存成 png 而不是直接弹窗方便在服务器上跑完再下载看。3.2 用统计脚本量化类别均衡度可视化只能抽查量化还得靠统计。写个小脚本数每类图片数量输出分布表from pathlib import Path from collections import Counter root Path(dataset/train) counts Counter() for cls_dir in sorted(root.iterdir()): if cls_dir.is_dir(): n len(list(cls_dir.glob(*.jpg))) len(list(cls_dir.glob(*.png))) counts[cls_dir.name] n total sum(counts.values()) for name, n in counts.most_common(): print(f{name:20s} {n:5d} {n/total*100:5.1f}%) print(总计:, total, 类别数:, len(counts))逻辑很直白遍历每个类别目录统计 jpg 和 png 数量。参数上把两种扩展名都算上是因为手机截图可能是 png。输出里如果某一类占比低于 5% 或高于 25%就要考虑用加权采样或数据增强来平衡。约 5000 张分 10 类平均每类 500 张训练集大概 400 张上下这个量级做迁移学习够用从零训练偏少。检查项合格标准不达标时的处理类别数与 json 一致10 类检查解压是否丢目录单类样本训练集 ≥ 300 张加权采样或增强图片可读全部能 PIL 打开剔除损坏文件尺寸一致性记录 min/max 尺寸统一 resize 到 224 或 256标注噪声抽查串类率 5%人工清洗或降权注意统计脚本跑出来总数和简介里的约 5000 张对不上是正常的手机拍摄数据集常有少量损坏图被剔除差几十张不用慌差几百张就要查目录。4. 接入图像分类训练流程从 DataLoader 到迁移学习参数4.1 构建 DataLoader 与数据增强策略分类任务的标准接入方式是ImageFolderDataLoader。训练集做增强测试集只做 resize 和归一化这是铁律。桑叶图像的关键视觉特征是叶形轮廓和叶脉纹理所以增强策略要偏向几何变换颜色抖动幅度别开太大否则会把品种间的颜色差异抹掉。from torchvision import transforms, datasets from torch.utils.data import DataLoader train_tf transforms.Compose([ transforms.Resize((256, 256)), transforms.RandomResizedCrop(224, scale(0.7, 1.0)), # 几何增强为主 transforms.RandomHorizontalFlip(), transforms.RandomRotation(15), transforms.ColorJitter(brightness0.2, contrast0.2), # 颜色轻抖 transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), ]) val_tf transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), ]) train_ds datasets.ImageFolder(dataset/train, transformtrain_tf) test_ds datasets.ImageFolder(dataset/test, transformval_tf) train_loader DataLoader(train_ds, batch_size32, shuffleTrue, num_workers4) test_loader DataLoader(test_ds, batch_size32, shuffleFalse, num_workers4)参数说明RandomResizedCrop的scale(0.7, 1.0)表示随机裁取原图 70% 到 100% 的区域这个下限别低于 0.5否则叶子主体容易被裁掉。ColorJitter只开亮度和对比度没开 hue因为桑叶品种差异部分体现在色调上开 hue 抖动等于人为制造标签噪声。Normalize用的是 ImageNet 统计量做迁移学习时保持一致从零训练才需要换成数据集自身的均值和方差。4.2 迁移学习选型与训练参数设置约 5000 张图、10 类从零训练一个 ResNet 容易过拟合常见做法是加载 ImageNet 预训练权重做微调。选型上如果追求精度且算力够用convnext_tiny或swin_tiny这类 transformer 图像分类模型如果要在边缘设备部署mobilenet_v3或efficientnet_b0更合适。下面以 torchvision 的 resnet18 为例给一套可跑的微调配置import torch import torch.nn as nn from torchvision import models device torch.device(cuda if torch.cuda.is_available() else cpu) model models.resnet18(weightsmodels.ResNet18_Weights.IMAGENET1K_V1) model.fc nn.Linear(model.fc.in_features, 10) # 10 类 model model.to(device) # 主干用小学习率分类头用大学习率 optimizer torch.optim.AdamW([ {params: model.layer1.parameters(), lr: 1e-4}, {params: model.layer2.parameters(), lr: 1e-4}, {params: model.layer3.parameters(), lr: 5e-5}, {params: model.layer4.parameters(), lr: 5e-5}, {params: model.fc.parameters(), lr: 1e-3}, ], weight_decay1e-4) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max30) criterion nn.CrossEntropyLoss(label_smoothing0.1)关键参数分类头学习率设成主干的 10 倍是因为 fc 层是随机初始化的需要快速收敛而预训练主干只需微调。label_smoothing0.1对手机拍摄数据集特别有用能缓解个别标注噪声带来的过拟合。T_max30对应 30 个 epoch 的余弦退火这个数据集 20 到 40 个 epoch 基本收敛再多就过拟合了。训练循环里每轮在测试集上算准确率同时保存验证集最优权重。如果训练准确率冲到 99% 而测试卡在 80% 不动八成是过拟合或者训练测试集有分布差异先查数据增强是不是太弱再查两个集合的拍摄条件是否一致。5. 避坑与常见问题排查标注、路径、显存这几处最容易翻车5.1 类别名含中文导致路径报错现象ImageFolder初始化时报FileNotFoundError或类别名为乱码。原因是中文目录名在某些系统编码下读取异常或者压缩包解压时用了非 UTF-8 编码。解决先确认locale是 UTF-8Python 里显式指定encoding实在不行把目录名批量改成英文同时同步修改 json 里的类别名保持两边一致。5.2 训练测试集类别数不一致现象训练能跑评估时test_ds.classes比train_ds.classes少一类混淆矩阵维度对不上。原因是测试集某个类别目录为空或缺失。解决跑第 3 章的统计脚本分别统计 train 和 test对比类别集合缺的那类要么从训练集划一部分过去要么在评估时用train_ds.classes强制对齐并给缺失类补零。5.3 图片尺寸差异大导致 batch 报错现象stack expects each tensor to be equal size。原因是 DataLoader 里某张图没经过统一 resize通常是损坏图或格式异常图。解决在 Dataset 外面包一层校验用 PIL 打开失败的直接跳过同时确认transforms.Resize在ToTensor之前。手机拍摄的图长宽比不一Resize((224,224))会拉伸变形介意的话用Resize(256)CenterCrop(224)。5.4 显存溢出与 num_workers 设置现象CUDA out of memory或训练卡在第一个 batch。原因batch_size 太大或num_workers在 Windows 上开多了导致进程卡死。解决batch_size 从 32 降到 16 或 8配合梯度累积保持等效 batchWindows 下num_workers设 0 或 2Linux 下可以设 4 到 8。显存不够时还可以开混合精度torch.cuda.amp能省三成左右显存。5.5 测试集准确率虚高现象测试准确率 95% 以上但实际推理新图片一塌糊涂。原因训练集和测试集可能来自同一批拍摄分布高度相似模型学到了拍摄条件而非品种特征。解决自己另外拍一批不同光照、不同背景的桑叶图做外部验证如果外部验证掉得厉害说明数据增强不够加大几何增强和背景替换类增强。提示这五条里第 5 条最隐蔽也最值得花时间验证。内部测试集好看不代表模型能用农业场景尤其吃光照和背景。6. 进阶技巧用混淆矩阵定位难分类品种并做定向增强跑通训练只是起点真正决定这个数据集能不能产出可用模型的是你能不能定位到哪两个品种在互相混淆。10 类桑叶里红王和白王这种名字相近的品种视觉差异可能只在叶缘或叶脉细节上模型很容易在这两类之间反复横跳。我的习惯是训练完立刻画混淆矩阵而不是只看一个总准确率。import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import confusion_matrix, classification_report model.eval() all_preds, all_labels [], [] with torch.no_grad(): for imgs, labels in test_loader: imgs imgs.to(device) preds model(imgs).argmax(dim1).cpu().numpy() all_preds.extend(preds) all_labels.extend(labels.numpy()) cm confusion_matrix(all_labels, all_preds) print(classification_report(all_labels, all_preds, target_namestrain_ds.classes, digits3)) # 归一化后画图重点看非对角线上的高值 cm_norm cm / cm.sum(axis1, keepdimsTrue) plt.figure(figsize(10, 8)) plt.imshow(cm_norm, cmapBlues) plt.colorbar() plt.xticks(range(10), train_ds.classes, rotation45) plt.yticks(range(10), train_ds.classes) plt.xlabel(Predicted); plt.ylabel(True) plt.tight_layout(); plt.savefig(confusion.png, dpi150)看矩阵的方法对角线是正确率非对角线上的数值代表误分。如果红王行在白王列上有个 0.2 的值说明 20% 的红王被认成白王这两类就是重点。定位到之后定向增强比全局调参有效得多——把这两类的训练图单独抽出来做更强的旋转、局部裁剪或者用 CutMix 把两类叶子拼在一起逼模型学细节差异。混淆模式可能原因定向处理两类互相误分视觉特征接近CutMix 局部裁剪增强某类被大量误分到多类该类标注噪声大人工复查该类样本所有类均匀误分模型欠拟合加 epoch 或换更大主干测试好外部差分布偏移补拍外部数据做验证还有一个容易被忽略的点这个数据集带了一个 json 文件记录类别但没提是否记录了每张图的采集设备或时间。如果后续要写论文或做消融实验建议自己补一个元数据表把文件名、类别、拍摄日期记下来方便分析是不是某个时间段拍的图特别难分。我吃过这个亏——有次模型在测试集上表现很好结果发现测试集全是晴天拍的一到阴天样本就崩回头查元数据才发现训练集里阴天样本几乎为零。从那以后我每次拿到分类数据集都强制走一遍统计分布 → 可视化抽查 → 混淆矩阵 → 外部验证这四步一步都不省。这份桑叶数据集结构清晰、标注完整四步走下来能省掉大量返工。希望帮到你。本文还有配套的精品资源点击获取
返回列表