从零开始使用chinesefoodnet数据集:数据预处理与模型训练实战指南

1次阅读
没有评论

共计 2789 个字符,预计需要花费 7 分钟才能阅读完成。

image.webp

数据集背景介绍

chinesefoodnet 是一个专门针对中国菜品的图像分类数据集,包含超过 10 万张高质量食物图片,涵盖 200 多种常见中式菜品。数据集结构通常如下:

从零开始使用 chinesefoodnet 数据集:数据预处理与模型训练实战指南

chinesefoodnet/
├── train/
│   ├── 宫保鸡丁 /
│   │   ├── 001.jpg
│   │   └── ...
│   └── ... 其他菜品
└── test/
    ├── 鱼香肉丝 /
    │   ├── 001.jpg
    │   └── ...
    └── ... 其他菜品 
  • 每张图片尺寸不一,常见为 500×500 到 2000×2000 像素
  • 标注信息存储在 JSON 文件中,包含菜品名称和边界框信息
  • 典型应用包括:智能点餐系统、营养分析、美食推荐等

数据预处理实战

  1. 安装依赖库
pip install torch torchvision pillow pandas
  1. 基础数据加载
from torchvision import datasets, transforms

# 定义基础转换
transform = transforms.Compose([transforms.Resize(256),  # 统一尺寸
    transforms.CenterCrop(224),  # 中心裁剪
    transforms.ToTensor(),  # 转为 Tensor
    transforms.Normalize(mean=[0.485, 0.456, 0.406],  # ImageNet 均值
                         std=[0.229, 0.224, 0.225])  # ImageNet 标准差
])

# 加载数据集
dataset = datasets.ImageFolder('chinesefoodnet/train', transform=transform)
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=True)
  1. 数据增强(训练时使用)
train_transform = transforms.Compose([transforms.RandomResizedCrop(224),
    transforms.RandomHorizontalFlip(),
    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

模型训练示例

  1. 简单 CNN 模型实现
import torch.nn as nn
import torch.nn.functional as F

class SimpleFoodCNN(nn.Module):
    def __init__(self, num_classes=200):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.fc1 = nn.Linear(64 * 56 * 56, 512)  # 输入尺寸需要根据实际情况调整
        self.fc2 = nn.Linear(512, num_classes)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x
  1. 完整训练循环
model = SimpleFoodCNN().cuda()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

for epoch in range(10):
    running_loss = 0.0
    for i, (inputs, labels) in enumerate(dataloader):
        inputs, labels = inputs.cuda(), labels.cuda()

        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if i % 100 == 99:
            print(f'Epoch {epoch+1}, Batch {i+1}: loss {running_loss/100:.3f}')
            running_loss = 0.0

性能优化技巧

  1. 批量大小选择
  2. 显存充足时(如 16GB+):尝试 128-256 的 batch size
  3. 普通显卡(如 8GB):32-64 更安全
  4. 可配合梯度累积技术模拟更大 batch

  5. 学习率调整策略

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)
# 每个 epoch 后调用 scheduler.step()
  1. 混合精度训练(需支持 FP16 的 GPU)
scaler = torch.cuda.amp.GradScaler()

with torch.cuda.amp.autocast():
    outputs = model(inputs)
    loss = criterion(outputs, labels)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()

避坑指南

  1. 内存溢出问题
  2. 症状:训练时突然崩溃
  3. 解法:减小 batch size 或图像尺寸

  4. 类别不平衡

  5. 症状:某些菜品准确率极低
  6. 解法:使用加权采样或 focal loss

  7. 过拟合

  8. 症状:训练准确高但测试差
  9. 解法:增加 Dropout 层或数据增强

  10. 学习率不当

  11. 症状:loss 不下降或剧烈波动
  12. 解法:尝试 1e- 3 到 1e- 5 范围

  13. 预处理不一致

  14. 症状:部署时性能下降
  15. 解法:确保训练和推理使用相同 transform

延伸学习建议

  1. 尝试更复杂模型:ResNet、EfficientNet 等预训练模型
  2. 探索多标签分类:一道菜可能属于多个类别
  3. 加入目标检测:使用边界框信息实现菜品定位
  4. 迁移学习:用 Food-101 等大型食物数据集预训练
  5. 部署优化:转换为 ONNX 或 TensorRT 格式加速推理

结语

通过本教程,你应该已经掌握了 chinesefoodnet 数据集的基本使用方法。实际应用中可能会遇到更多挑战,但核心处理流程是相通的。建议先从简单模型开始,逐步迭代优化,同时注意记录每次实验的参数和结果,这对理解模型行为非常有帮助。

正文完
 0
评论(没有评论)