【实战指南】从零构建冰箱食材识别数据集:数据采集、标注与YOLO模型训练全流程

张开发
2026/6/1 16:36:01 15 分钟阅读
【实战指南】从零构建冰箱食材识别数据集:数据采集、标注与YOLO模型训练全流程
1. 数据采集构建高质量食材图像库的三种方法第一次做食材识别项目时我在数据采集阶段踩过不少坑。最惨痛的经历是用手机随手拍了200张照片就开始训练结果模型连苹果和西红柿都分不清。后来才发现构建高质量数据集需要系统性方法。下面分享三种经过验证的数据采集方式帮你避开我踩过的那些坑。网络爬虫方案最适合快速获取基础数据。我用Python的requestsBeautifulSoup组合写过一套爬虫脚本核心思路是import requests from bs4 import BeautifulSoup import os def download_images(keyword, save_dir, max_count100): search_url fhttps://www.example.com/search?q{keyword} response requests.get(search_url) soup BeautifulSoup(response.text, html.parser) img_urls [img[src] for img in soup.find_all(img)][:max_count] for i, url in enumerate(img_urls): try: img_data requests.get(url).content with open(f{save_dir}/{keyword}_{i}.jpg, wb) as f: f.write(img_data) except Exception as e: print(f下载失败: {url}, 错误: {e})实际使用时要注意三个细节1) 设置合理的下载间隔避免被封 2) 添加User-Agent模拟浏览器行为 3) 对图片进行初步过滤尺寸过小、明显水印等。我通常会先用爬虫获取各类食材200-300张基础图片。开源数据集整合能大幅节省时间。Kaggle上的Food-101、UECFoodPix等数据集包含数万张标注好的食材图片。但直接使用会有两个问题1) 西方食材居多 2) 拍摄角度单一。我的经验是先用torchvision.datasets加载这些数据from torchvision import datasets food101 datasets.Food101(root./data, downloadTrue) print(f数据集包含 {len(food101)} 张图片)然后筛选出需要的类别再与自定义数据混合。这样既保证数据量又能覆盖本地特色食材。自定义拍摄最关键也最耗时。我建议准备一个简易摄影棚环形补光灯纯色背景板白/灰最佳用手机支架固定拍摄角度。要特别注意每种食材拍摄10-15个样本包含不同成熟度/切割状态如整颗苹果和切块苹果变换摆放位置和背景杂物记录不同光照条件自然光/暖光/冷光实测发现在冰箱内直接拍摄效果最好。我用树莓派摄像头搭建了自动拍摄装置每隔1小时拍摄一次冰箱内部累计收集了800张真实场景图。这种数据虽然获取麻烦但对模型泛化能力提升显著。2. 数据清洗与标注打造精准训练集的秘诀拿到原始图片只是第一步我早期项目失败80%是因为数据质量不过关。最近一个项目中经过严格清洗后模型准确率直接提升了23%。下面分享我的数据优化流程。清洗阶段要像侦探一样挑剔。我开发了一套自动化过滤脚本from PIL import Image import cv2 import numpy as np def is_low_quality(img_path): try: img cv2.imread(img_path) if img is None: return True # 检查分辨率 if min(img.shape[:2]) 256: return True # 检查模糊度 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) fm cv2.Laplacian(gray, cv2.CV_64F).var() if fm 100: return True # 检查主要颜色占比过滤纯色图 _, counts np.unique(img.reshape(-1,3), axis0, return_countsTrue) if max(counts)/sum(counts) 0.3: return True return False except: return True这个脚本帮我过滤掉了15%的无效图片。但自动化工具不能解决所有问题我还会人工检查每张图片重点关注目标食材是否清晰可见是否有严重遮挡如包装袋遮挡一半的蔬菜是否存在多个同类物体如一堆苹果应按单个目标标注标注工具选择直接影响效率。我对比过LabelImg、CVAT和Roboflow新手推荐LabelImg安装简单pip install labelImg支持VOC和YOLO格式团队协作选CVAT支持在线协作有高级审核功能大规模项目用Roboflow内置智能标注和版本管理这是我的标注检查清单边界框要紧贴物体边缘但不必完全贴合遮挡超过30%的物体不标注小目标小于图像面积1%建议舍弃同类重叠物体分开标注为每个类别保留10%的困难样本非常规角度/光照标注格式转换是容易出错的环节。YOLO格式要求坐标归一化我常用这个转换函数def voc_to_yolo(xmin, ymin, xmax, ymax, img_w, img_h): x_center ((xmin xmax)/2) / img_w y_center ((ymin ymax)/2) / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h return [x_center, y_center, width, height]记得验证转换后的标签是否准确。我遇到过因为整数除法导致的坐标偏移bug导致训练时损失值震荡。3. 数据增强让小数据集发挥大威力刚开始玩深度学习时我以为数据越多越好直到看到这篇论文《Learning from Small Data》。现在我的原则是质量大于数量好的增强策略能让500张图发挥5000张的效果。基础增强每个人都应该掌握。我用Albumentations库配置增强管道import albumentations as A train_transform A.Compose([ A.RandomResizedCrop(512, 512, scale(0.8, 1.0)), A.HorizontalFlip(p0.5), A.VerticalFlip(p0.5), A.RandomBrightnessContrast(p0.2), A.RGBShift(r_shift_limit20, g_shift_limit20, b_shift_limit20, p0.3), A.GaussNoise(var_limit(10.0, 50.0), p0.2), ], bbox_paramsA.BboxParams(formatyolo))这个配置实现了随机裁剪缩放模拟不同距离拍摄水平/垂直翻转改变物体朝向亮度对比度调整应对不同光照颜色偏移补偿白平衡差异高斯噪声模拟低光噪点高级增强能解决特定场景问题。比如冰箱内食材常出现的冷凝水干扰用模拟水滴的局部模糊玻璃反光添加随机高光区域部分遮挡随机擦除部分区域advanced_transform A.Compose([ A.RandomRain(drop_length20, blur_value3, p0.1), A.RandomSunFlare(flare_roi(0,0,1,1), angle_lower0.3, p0.1), A.Cutout(num_holes8, max_h_size32, max_w_size32, p0.5) ])智能增强是最新趋势。我最近在用YOLOv5自带的mosaic增强效果惊艳# yolov5/data/hyps/hyp.scratch-low.yaml mosaic: 1.0 # 启用mosaic增强 mixup: 0.1 # 启用mixup增强这种增强方式将4张训练图像拼接成1张让模型学习在不同上下文中识别物体。实测使用后小目标检测精度提升了17%。注意验证集不要做任何增强我犯过这个错误导致验证指标虚高实际部署时效果很差。4. YOLOv5模型训练实战技巧第一次训练YOLO模型时我直接跑了默认参数结果GPU烧了12小时得到的模型连香蕉和黄瓜都分不清。后来通过系统学习现在用1/10的时间就能训练出好得多的模型。下面是我的实战心得。环境配置是第一个坎。我的推荐配置CUDA 11.3 PyTorch 1.12.1版本要严格匹配创建干净的conda环境conda create -n yolo python3.8 conda install pytorch1.12.1 torchvision0.13.1 cudatoolkit11.3 -c pytorch数据准备要特别注意路径结构。YOLOv5要求如下目录dataset/ ├── images/ │ ├── train/ │ ├── val/ ├── labels/ │ ├── train/ │ ├── val/我写了个自动校验脚本检查图片和标签文件是否一一对应标签文件是否为空图片是否能正常打开模型选择取决于硬件条件YOLOv5n (1.9M参数)树莓派级设备YOLOv5s (7.2M参数)入门级显卡YOLOv5m (21.2M参数)主流训练配置YOLOv5l (46.5M参数)高端显卡推荐我的调参经验# data/custom.yaml train: ../dataset/images/train val: ../dataset/images/val nc: 20 # 类别数 names: [apple, banana, ...] # 按字母顺序排列 # hyp.scratch-low.yaml lr0: 0.01 # 初始学习率 lrf: 0.1 # 最终学习率 lr0 * lrf momentum: 0.937 weight_decay: 0.0005训练命令的关键参数python train.py \ --img 640 \ --batch 16 \ # 根据GPU内存调整 --epochs 100 \ --data custom.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --cache ram # 加速训练几个实用技巧先用小图--img 320训练50轮快速验证流程添加--evolve参数进行超参数进化使用--resume中断后继续训练监控GPU使用情况nvidia-smi -l 1常见问题排查损失不下降检查数据标注是否正确我遇到过标签文件错位的坑显存不足减小batch_size或图像尺寸mAP低尝试更复杂的模型或增加数据增强过拟合添加更多真实场景数据训练完成后用这个命令测试模型python detect.py \ --weights runs/train/exp/weights/best.pt \ --source test_images/ \ --conf 0.25 \ --iou 0.45记得保存完整训练日志方便后续分析。我的项目文件夹通常长这样runs/ ├── train/ │ ├── exp1/ │ │ ├── weights/ │ │ ├── results.png │ │ ├── opt.yaml │ ├── exp2/ ├── detect/ │ ├── exp1/ │ │ ├── apple.jpg │ │ ├── banana.jpg

更多文章