新闻详情

新闻详情

首页 / 资讯中心 / 详情

果蔬分类数据集实战:36类4200张图像分类训练与避坑指南

发布时间:2026/9/28 22:32:05来源:尧图网络
果蔬分类数据集实战:36类4200张图像分类训练与避坑指南
简介本资源为常见果蔬多类别图像分类数据集面向从事图像分类、分割网络改进及计算机视觉项目实践的学习者与开发者可用于模型训练、算法验证与课程实验。数据集共36类涵盖香蕉、苹果、梨、葡萄、橙子、黄瓜、胡萝卜、辣椒、洋葱、土豆等常见果蔬已完成标注与预处理可直接作为分类网络输入。压缩包为7z格式内含约2000个文件以1998张jpg图像为主体另附1个py脚本与1个json标注文件整体约364.87MB并已划分训练集、测试集与验证集各类图片分目录存放便于直接读取。资源中提供show脚本可快速可视化数据分布与样本情况帮助检查类别均衡与图像质量。目前已有119人学习下载适合需要快速搭建果蔬分类基线、开展迁移学习或改进分割网络的读者参考使用。1. 果蔬分类数据集怎么选36 类、4200 张、已划分的现成货做图像分类项目最耗时的往往不是搭网络而是找一批干净、标注到位、类别均衡的数据。这份常见果蔬多类别图像分类数据集约 4200 张图覆盖 36 个类别香蕉、苹果、梨、葡萄、橙子、黄瓜、胡萝卜、辣椒、洋葱、土豆这些日常果蔬都在里面具体类别清单在资源包的 json 文件里能查到。它最大的价值是省掉了从零采集和标注的环节训练集、验证集、测试集已经按同一类图片分目录放好预处理也做完了直接就能喂给分类网络。适合谁刚入门图像分类想跑通第一个多类别实验的人以及需要快速验证 backbone 或数据增强策略的熟手。下面从目录结构、加载方式、训练配置到踩坑一步步拆开讲。2. 目录结构与数据加载先看清 json 和三个 split 怎么对应拿到一个数据集我习惯先不写模型先把目录和标注文件摸清楚。这份资源的组织方式对分类任务很友好但如果不先确认类别索引和文件夹名的映射关系后面训练出来的 label 很可能整体错位这种翻车在分类项目里太常见了。2.1 目录布局与 json 类别映射典型的结构是这样根目录下分 train、val、test 三个文件夹每个文件夹里再按类别名建子目录图片直接放在对应类别目录下。json 文件里存的是类别列表顺序就是类别索引 0 到 35。常见做法是用os.listdir拿到子目录名后一定要和 json 里的顺序对齐而不是想当然地认为字母序就是索引序。import os import json data_root fruit_veg_dataset with open(os.path.join(data_root, classes.json), r, encodingutf-8) as f: class_list json.load(f) # 形如 [banana, apple, ...]顺序即标签索引 for split in [train, val, test]: split_dir os.path.join(data_root, split) folders sorted(os.listdir(split_dir)) print(split, len(folders), folders[:5]) # 关键确认 folders 的顺序与 class_list 是否一致 assert set(folders) set(class_list), 文件夹名与 json 类别不匹配这段代码先读 json 拿到权威类别顺序再遍历三个 split 的文件夹做集合比对。assert那行是后悔药一旦文件夹名和 json 对不上会立刻报错而不是等到训练完发现准确率异常才回头查。参数上encodingutf-8不能省类别名里如果有中文或特殊字符默认编码会读乱。2.2 用 ImageFolder 还是自定义 Dataset如果目录结构就是标准的「split/类别名/图片」PyTorch 的ImageFolder能直接用配合transforms做预处理。但这份数据已经预处理过尺寸大概率统一所以增强策略要克制别一上来就上重度裁剪。from torchvision import datasets, transforms train_tf transforms.Compose([ transforms.Resize((224, 224)), transforms.RandomHorizontalFlip(p0.5), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ]) train_set datasets.ImageFolder( rootos.path.join(data_root, train), transformtrain_tf ) print(train_set.class_to_idx) # 确认索引映射Resize到 224 是给 ResNet、EfficientNet 这类 backbone 用的如果你换别的输入尺寸这里要同步改。Normalize用的是 ImageNet 统计量这是迁移学习的常规操作。class_to_idx打印出来务必和 json 对一遍ImageFolder默认按文件夹名字母序排索引和 json 顺序不一定相同这是最容易埋雷的地方。2.3 可视化脚本 show 的用法资源里带了 show 脚本用来快速看一批图长什么样。跑之前先确认它依赖的库装了没有常见是 matplotlib 和 PIL。可视化不是为了好看是为了在训练前发现脏图、错标、重复图。我一般会随机抽每个类别若干张拼成网格重点看有没有把胡萝卜标成辣椒这种低级错误。如果 show 脚本读的是固定路径记得把路径参数改成你解压后的实际目录否则会报文件找不到。3. 训练配置与迁移学习36 类分类的 backbone 和超参怎么定数据摸清楚了接下来是把它跑起来。36 类、4200 张平均每类一百多张属于小样本多分类直接从头训容易过拟合迁移学习是更稳的选择。3.1 backbone 选型与冻结策略小数据集上ResNet18 或 ResNet50 预训练权重是性价比很高的起点。做法是先冻结主干只训最后的全连接层几个 epoch让分类头先适应新类别再解冻整体微调。这样收敛快也不容易把预训练学到的特征一开始就冲垮。import torch import torch.nn as nn from torchvision import models model models.resnet18(weightsmodels.ResNet18_Weights.IMAGENET1K_V1) for param in model.parameters(): param.requires_grad False # 先冻结主干 model.fc nn.Linear(model.fc.in_features, 36) # 替换为 36 类 criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.fc.parameters(), lr1e-3)requires_grad False冻结主干model.fc换成 36 维输出。第一阶段学习率可以给 1e-3因为只训分类头。第二阶段解冻后学习率要降到 1e-4 甚至更低否则预训练权重会被大步长破坏。这个两段式策略是我在多个小数据集上验证过的稳妥打法。3.2 数据增强与类别不均衡处理4200 张分 36 类类别之间数量大概率不完全均衡。先统计每类样本数差距大的类别要在采样或损失上做补偿。增强方面水平翻转、轻微颜色抖动够用了别上随机裁剪加旋转的组合拳预处理过的图经不起折腾。from collections import Counter targets [s[1] for s in train_set.samples] counts Counter(targets) print(counts) # 看每类样本数 # 若明显不均衡用带权重的采样器 from torch.utils.data import WeightedRandomSampler weights [1.0 / counts[t] for t in targets] sampler WeightedRandomSampler(weights, num_sampleslen(weights), replacementTrue)Counter统计每类数量WeightedRandomSampler让少样本类别被抽到的概率更高。replacementTrue表示有放回采样这是处理不均衡的标准做法。如果类别还算均衡这一步可以跳过别为了用而用。3.3 训练循环与验证指标训练循环里每个 epoch 结束在验证集上算准确率保存验证集表现最好的权重而不是最后一个 epoch 的。测试集只在最后评估一次中途反复看测试集等于变相泄露。best_acc 0.0 for epoch in range(20): model.train() for imgs, labels in train_loader: optimizer.zero_grad() loss criterion(model(imgs), labels) loss.backward() optimizer.step() model.eval() correct total 0 with torch.no_grad(): for imgs, labels in val_loader: preds model(imgs).argmax(1) correct (preds labels).sum().item() total labels.size(0) acc correct / total if acc best_acc: best_acc acc torch.save(model.state_dict(), best.pth)model.eval()和torch.no_grad()在验证阶段必须加前者关掉 dropout 和 BN 的训练行为后者省显存。保存best.pth而不是覆盖式保存是为了防止后期过拟合把好权重冲掉。20 个 epoch 是起步值实际看验证曲线早停。4. 避坑与排查分类数据集落地最常见的五个问题这一章是我踩过的坑集中营每一条都按现象、原因、解决来写照着排查能省不少时间。4.1 训练准确率一直上不去现象loss 不降准确率卡在 1/36 附近等于随机猜。原因标签索引和模型输出对不上或者 json 类别顺序和文件夹顺序错位。解决回到 2.1 的assert那步打印class_to_idx和 json 逐项比对确认索引一致再训。4.2 验证集准确率远高于测试集现象验证集 95%测试集只有 70%。原因验证集和测试集分布不一致或者验证集被反复用来调参导致过拟合。解决检查三个 split 是不是同一批数据随机划分的确认没有图片重复出现在不同 split调参只看验证集测试集留到最后。4.3 显存爆了或者训练极慢现象batch size 稍微调大就 OOM。原因图片分辨率没统一个别大图拖垮整个 batch或者 num_workers 设太大导致 IO 争抢。解决在 Dataset 里强制 Resize 到固定尺寸num_workers从 4 起步按机器核数调别一上来就设 16。4.4 某些类别几乎全错现象整体准确率还行但某几类混淆严重。原因这几类视觉上太像比如不同品种的辣椒或者样本量太少。解决看混淆矩阵定位具体是哪几类针对性加样本或做类内增强必要时用 focal loss 压制易分样本。4.5 可视化脚本报路径错误现象跑 show 脚本提示文件不存在。原因脚本里写死了作者本地的绝对路径。解决把路径参数改成相对路径或命令行传入解压后先cd到数据根目录再跑。5. 进阶技巧用混淆矩阵和 t-SNE 验证这份数据到底学没学到东西训练完一个模型准确率只是一个数字真正能说明问题的是它错在哪、特征学得怎么样。我习惯在测试集上跑一遍混淆矩阵再用 t-SNE 把倒数第二层的特征降维画出来看同类是否聚拢、异类是否分开。这一步能暴露很多准确率掩盖的问题。混淆矩阵用 sklearn 几行就能出from sklearn.metrics import confusion_matrix import seaborn as sns import matplotlib.pyplot as plt model.eval() all_preds, all_labels [], [] with torch.no_grad(): for imgs, labels in test_loader: preds model(imgs).argmax(1) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.numpy()) cm confusion_matrix(all_labels, all_preds) sns.heatmap(cm, annotFalse, cmapBlues) plt.savefig(confusion.png, dpi150)对角线越亮越好非对角线的亮点就是混淆对。如果发现苹果和梨互相错说明模型对形状和颜色相近的类别区分力不够可以考虑换更强的 backbone 或加注意力模块。t-SNE 则更直观from sklearn.manifold import TSNE feats [] with torch.no_grad(): for imgs, _ in test_loader: f model.avgpool(model.layer4(model.layer3(model.layer2(model.layer1( model.conv1(imgs)))))) feats.append(f.flatten(1)) feats torch.cat(feats).numpy() emb TSNE(n_components2, perplexity30).fit_transform(feats) plt.scatter(emb[:, 0], emb[:, 1], call_labels, cmaptab20, s5) plt.savefig(tsne.png, dpi150)perplexity30是常用起点样本少可以调小。图上同类点聚成一团、不同类分开说明特征有判别力如果混成一锅粥那准确率再高也要怀疑。这两个图我每次训完分类模型都会跑一遍比盯着 loss 曲线有用得多。从那以后我每次拿到新数据集都强制先跑可视化再开训省得训到一半才发现数据本身有问题。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

tick-stock-panel前端工程拆解:React 18 + TanStack Query + Lightweight Charts实时图表完整指南 2026/9/29 1:44:03

tick-stock-panel前端工程拆解:React 18 + TanStack Query + Lightweight Charts实时图表完整指南

tick-stock-panel前端工程拆解:React 18 TanStack Query Lightweight Charts实时图表完整指南 【免费下载链接】tick-stock-panel TSP自托管、零运维的 A 股「选股 监控 回测」量化工作台 | LLM能力驱使策略定制个股分析复盘 | 自由接入第三方数据源与个性化扩展…

阅读更多 →
若依项目部署后白屏转圈?从请求链路到Nginx配置的排查指南 2026/9/29 1:43:57

若依项目部署后白屏转圈?从请求链路到Nginx配置的排查指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
SSD入门必读:从NAND颗粒到主控、SLC Cache与寿命计算 2026/9/29 1:43:57

SSD入门必读:从NAND颗粒到主控、SLC Cache与寿命计算

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
从Gandalf通关到大模型安全:提示注入攻击与防御实战解析 2026/9/29 1:43:57

从Gandalf通关到大模型安全:提示注入攻击与防御实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
微信小程序连续扫码:camera组件 mode=scan 与去重优化 2026/9/29 1:43:57

微信小程序连续扫码:camera组件 mode=scan 与去重优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
SSM+MySQL 校园网上订餐平台:封闭场景下的宿舍楼栋配送与课表错峰设计(含小程序端) 2026/9/29 1:43:57

SSM+MySQL 校园网上订餐平台:封闭场景下的宿舍楼栋配送与课表错峰设计(含小程序端)

SSMMySQL 校园网上订餐平台:封闭场景下的宿舍楼栋配送与课表错峰设计(含小程序端) 演示环境均为本地启动后的真实截图,数据为内置演示库中的种子数据,非空态摆拍。 一、前言 高校食堂的供需矛盾有很强的时段性&#x…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉