水果蔬菜分类图像分类 智慧化农业蔬菜水果分类数据集 果蔬分类数据集的应用 智慧农业数据集 生鲜识别 超市自动结算 AI营养分析 移动端果蔬识别APP
水果蔬菜分类图像分类 智慧化农业蔬菜水果分类数据集 果蔬分类数据集的应用 智慧农业数据集 生鲜识别 超市自动结算 AI营养分析 移动端果蔬识别APP
智慧化-果蔬数据集(chuntu)
此数据集包含以下果蔬的图像:
水果:香蕉,苹果,梨,葡萄,橙子,猕猴桃,西瓜,石榴,菠萝,芒果。
蔬菜:黄瓜、胡萝卜、辣椒、洋葱、土豆、柠檬、西红柿、raddish、甜菜根、卷心菜、生菜、菠菜、大豆、花椰菜、甜椒、辣椒、萝卜、玉米、甜玉米、红薯、辣椒、辣椒酱、生姜、大蒜、豌豆、茄子。
数据集包含三个文件夹:
训练集(每个类别文件夹包含100张图片)
测试集(每个类别文件夹包含10张图像)
验证集(每个类别文件夹包含10张图像)
以上每个文件夹都包含不同水果和蔬菜的子文件夹,其中显示了相应类别的图像
1
1
以下是果蔬数据集(Chuntu)的详细表格化描述:
📊 一、数据集总体信息
| 项目 | 描述 |
|---|---|
| 数据集名称 | Chuntu 果蔬图像数据集 |
| 任务类型 | 图像分类(Image Classification) |
| 类别总数 | 36 类(10 种水果 + 26 种蔬菜) |
| 图像总数 | 4,320 张 |
| 图像格式 | 通常为.jpg或.png(未明确说明,但按常规推断) |
| 应用场景 | 智慧农业、生鲜识别、超市自动结算、AI营养分析、移动端果蔬识别APP |
🍎🥦 二、类别列表与分类统计
✅ 水果类(10 类)
| 序号 | 中文名 | 英文名 |
|---|---|---|
| 1 | 香蕉 | Banana |
| 2 | 苹果 | Apple |
| 3 | 梨 | Pear |
| 4 | 葡萄 | Grape |
| 5 | 橙子 | Orange |
| 6 | 猕猴桃 | Kiwi |
| 7 | 西瓜 | Watermelon |
| 8 | 石榴 | Pomegranate |
| 9 | 菠萝 | Pineapple |
| 10 | 芒果 | Mango |
✅ 蔬菜类(26 类)
⚠️ 注意:原始描述中“辣椒”重复出现多次,“辣椒酱”可能为异常项(非生鲜食材),此处按字面保留,但建议使用时核查。
| 序号 | 中文名 | 英文名 | 备注 |
|---|---|---|---|
| 11 | 黄瓜 | Cucumber | — |
| 12 | 胡萝卜 | Carrot | — |
| 13 | 辣椒 | Chili Pepper | 可能指新鲜辣椒 |
| 14 | 洋葱 | Onion | — |
| 15 | 土豆 | Potato | — |
| 16 | 柠檬 | Lemon | 常归为水果,此处列在蔬菜中 |
| 17 | 西红柿 | Tomato | 植物学为水果,烹饪归蔬菜 |
| 18 | 萝卜(raddish) | Radish | 拼写应为 radish |
| 19 | 甜菜根 | Beetroot | — |
| 20 | 卷心菜 | Cabbage | — |
| 21 | 生菜 | Lettuce | — |
| 22 | 菠菜 | Spinach | — |
| 23 | 大豆 | Soybean | 可能指鲜豆荚 |
| 24 | 花椰菜 | Cauliflower | — |
| 25 | 甜椒 | Bell Pepper | — |
| 26 | 辣椒 | Chili Pepper | 重复项(可能指不同品种) |
| 27 | 萝卜 | Radish | 与第18项重复(拼写差异) |
| 28 | 玉米 | Corn | — |
| 29 | 甜玉米 | Sweet Corn | 可能与玉米重复 |
| 30 | 红薯 | Sweet Potato | — |
| 31 | 辣椒酱 | Chili Sauce | ❗非生鲜图像,建议剔除或单独处理 |
| 32 | 生姜 | Ginger | — |
| 33 | 大蒜 | Garlic | — |
| 34 | 豌豆 | Peas | — |
| 35 | 茄子 | Eggplant | — |
| 36 | (待确认) | — | 若“辣椒”“萝卜”等去重后不足26类,可能存在命名误差 |
🔍类别去重建议:
实际有效类别可能为32–34 类,因存在重复(如“辣椒”出现3次、“萝卜”2次)及异常项(“辣椒酱”)。建议检查原始文件夹数量以确认真实类别数。
📁 三、数据划分详情(按当前描述)
| 子集 | 每类图像数 | 类别数 | 总图像数 |
|---|---|---|---|
| 训练集(train) | 100 张/类 | 36 | 36 × 100 =3,600 张 |
| 验证集(val) | 10 张/类 | 36 | 36 × 10 =360 张 |
| 测试集(test) | 10 张/类 | 36 | 36 × 10 =360 张 |
| 总计 | — | — | 4,320 张 |
✅ 文件结构示例:
chuntu_dataset/ ├── train/ │ ├── banana/ │ ├── apple/ │ └── ... (36 folders) ├── val/ │ ├── banana/ │ └── ... └── test/ ├── banana/ └── ...
⚙️ 四、适用模型与框架
| 任务 | 推荐模型 | 框架 |
|---|---|---|
| 图像分类 | ResNet50, EfficientNet-B0, MobileNetV3, ViT-Tiny | PyTorch / TensorFlow / Keras |
| 轻量化部署 | MobileNetV2 + TensorFlow Lite | Android/iOS APP |
| 迁移学习 | 使用 ImageNet 预训练权重微调 | Hugging Face Transformers, timm |
⚠️ 五、使用注意事项
- 类别重复问题:
- “辣椒”“萝卜”多次出现,需确认是否为不同品种(如青椒/红椒、白萝卜/胡萝卜),否则应合并。
- 异常类别:
- “辣椒酱”为加工品,与其他生鲜类别不一致,建议单独处理或移除。
- 柠檬归类:
- 柠檬通常视为水果,若用于烹饪场景可保留于蔬菜,但需注意标签一致性。
- 数据平衡性:
- 每类样本量均衡(100/10/10),有利于公平训练,但总量偏少,建议结合数据增强。
以下是基于果蔬数据集(Chuntu)使用PyTorch进行图像分类的完整训练代码示例。该代码包括数据加载、模型定义、训练、验证和测试过程。
📁 一、项目结构建议
chuntu_pytorch/ ├── dataset.py# 数据集加载与预处理├── model.py# 模型定义├── train.py# 主训练脚本├── predict_demo.py# 推理演示└── data/ ├── train/# 训练集├── val/# 验证集└── test/# 测试集📄 二、数据集加载与预处理dataset.py
# dataset.pyimportosfromtorch.utils.dataimportDataset,DataLoaderfromtorchvisionimporttransformsfromPILimportImageclassFruitVegetableDataset(Dataset):def__init__(self,root_dir,transform=None):self.root_dir=root_dir self.transform=transform self.classes=sorted(os.listdir(root_dir))self.class_to_idx={cls_name:idxforidx,cls_nameinenumerate(self.classes)}self.image_paths=[]self.labels=[]forcls_nameinself.classes:cls_dir=os.path.join(root_dir,cls_name)ifnotos.path.isdir(cls_dir):continueforimg_nameinos.listdir(cls_dir):ifimg_name.lower().endswith(('png','jpg','jpeg')):self.image_paths.append(os.path.join(cls_dir,img_name))self.labels.append(self.class_to_idx[cls_name])def__len__(self):returnlen(self.image_paths)def__getitem__(self,idx):img_path=self.image_paths[idx]label=self.labels[idx]image=Image.open(img_path).convert('RGB')ifself.transform:image=self.transform(image)returnimage,labeldefget_loader(root_dir,batch_size=32,num_workers=4):transform=transforms.Compose([transforms.Resize((224,224)),# 统一尺寸transforms.RandomHorizontalFlip(),# 数据增强transforms.ToTensor(),transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])# ImageNet均值方差])dataset=FruitVegetableDataset(root_dir=root_dir,transform=transform)loader=DataLoader(dataset,batch_size=batch_size,shuffle=True,num_workers=num_workers)returnloader,dataset.classes📄 三、模型定义model.py
# model.pyimporttorchimporttorch.nnasnnimporttorchvision.modelsasmodelsdefget_model(num_classes):model=models.resnet50(pretrained=True)# 使用ImageNet预训练权重num_ftrs=model.fc.in_features model.fc=nn.Linear(num_ftrs,num_classes)returnmodeldeftrain_model(model,dataloaders,criterion,optimizer,num_epochs=25,device='cuda'):best_model_wts=model.state_dict()best_acc=0.0forepochinrange(num_epochs):print(f'Epoch{epoch}/{num_epochs-1}')print('-'*10)forphasein['train','val']:ifphase=='train':model.train()else:model.eval()running_loss=0.0running_corrects=0forinputs,labelsindataloaders[phase]:inputs=inputs.to(device)labels=labels.to(device)optimizer.zero_grad()withtorch.set_grad_enabled(phase=='train'):outputs=model(inputs)_,preds=torch.max(outputs,1)loss=criterion(outputs,labels)ifphase=='train':loss.backward()optimizer.step()running_loss+=loss.item()*inputs.size(0)running_corrects+=torch.sum(preds==labels.data)epoch_loss=running_loss/len(dataloaders[phase].dataset)epoch_acc=running_corrects.double()/len(dataloaders[phase].dataset)print(f'{phase}Loss:{epoch_loss:.4f}Acc:{epoch_acc:.4f}')ifphase=='val'andepoch_acc>best_acc:best_acc=epoch_acc best_model_wts=model.state_dict()print(f'Best val Acc:{best_acc:4f}')model.load_state_dict(best_model_wts)returnmodel🚀 四、主训练脚本train.py
# train.pyimporttorchimporttorch.optimasoptimfromtorch.utils.tensorboardimportSummaryWriterfrommodelimportget_model,train_modelfromdatasetimportget_loaderdefmain():# 设备配置device=torch.device("cuda"iftorch.cuda.is_available()else"cpu")print(f"🚀 使用设备:{device}")# 加载数据train_loader,classes=get_loader('data/train')val_loader,_=get_loader('data/val')dataloaders={'train':train_loader,'val':val_loader}# 定义模型model=get_model(num_classes=len(classes)).to(device)# 定义损失函数和优化器criterion=nn.CrossEntropyLoss()optimizer=optim.Adam(model.parameters(),lr=0.001)# 开始训练trained_model=train_model(model,dataloaders,criterion,optimizer,num_epochs=25,device=device)# 保存最佳模型torch.save(trained_model.state_dict(),'best_model.pth')if__name__=='__main__':main()🔍 五、推理演示predict_demo.py
# predict_demo.pyfrommodelimportget_modelfromdatasetimportFruitVegetableDataset,transformsfromPILimportImageimporttorchdefmain():# 加载模型model=get_model(num_classes=36)# 根据实际类别数调整model.load_state_dict(torch.load('best_model.pth'))model.eval()# 类别映射class_names=['香蕉','苹果','梨','葡萄','橙子','猕猴桃','西瓜','石榴','菠萝','芒果','黄瓜','胡萝卜','辣椒','洋葱','土豆','柠檬','西红柿','萝卜','甜菜根','卷心菜','生菜','菠菜','大豆','花椰菜','甜椒','玉米','甜玉米','红薯','生姜','大蒜','豌豆','茄子']# 图像预处理transform=transforms.Compose([transforms.Resize((224,224)),transforms.ToTensor(),transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])])# 推理单张图像image_path='sample_image.jpg'image=Image.open(image_path).convert('RGB')tensor_image=transform(image).unsqueeze(0)withtorch.no_grad():output=model(tensor_image)_,predicted=torch.max(output,1)predicted_class=class_names[predicted.item()]print(f"预测结果:{predicted_class}")if__name__=='__main__':main()⚙️ 六、训练优化建议
| 问题 | 解决方案 |
|---|---|
| 过拟合 | 增加正则化项(如 L2 正则化)、使用 Dropout 层、减少模型复杂度(如改用 EfficientNet-B0) |
| 类别不平衡 | 对少数类进行过采样或对多数类欠采样;使用加权交叉熵损失函数(CrossEntropyLoss(weight=...)) |
| 小样本问题 | 利用迁移学习,冻结预训练模型的部分层;增加数据增强策略(旋转、缩放、颜色抖动等) |
