尧图精选

智能零售柜商品检测数据集:三格式标签与YOLO11跨平台训练全攻略

🕒 发布时间:2026/11/4 11:40:44 📁 来源:尧图网络
简介面向智能零售柜商品检测项目这份PDF指南整理了5000张真实监控场景商品图片数据集的完整接入方式。数据集覆盖罐装饮料、袋装零食等常见零售柜商品共标注113个类别并配套VOC、COCO、YOLO三种标签格式可直接用于目标检测模型训练适合新零售场景的算法工程师、科研人员及竞赛选手使用。指南还介绍了随资源附赠的YOLO11一键训练脚本支持GPU、CPU及Mac M芯片多平台训练并给出博主训练结果日志作为效果参考。整份资料仅1个PDF文件体积5.77MB内容包括数据集缩略图、标注说明、适用场景说明与百度网盘获取方式。目前已有413人学习浏览对需要快速获取智能零售柜商品训练数据并搭建检测方案的开发者而言能显著节省数据检索和格式转换成本。1. 智能零售柜商品检测数据集为什么这 5000 张图和三格式标签值得你先看做智能零售柜的都知道柜子里那点东西比开放货架难搞得多。饮料瓶反光、包装袋褶皱、小包零食堆叠加上柜内补光灯角度刁钻商品边缘经常跟背景糊在一起。很多团队拿着通用目标检测模型直接上结果在测试集上 mAP 挺好看一放进真实柜子就漏检。我接触过不少做新零售设备方案的朋友大家最后都卡在同一个环节没有一套贴合柜内场景、标注格式齐全、能直接喂给训练脚本的数据资产。所以看到这个「智能零售柜商品检测数据集」标题时我先关注的是三件事图数是否够用、三种标签是否对齐、以及训练脚本是否真的能在不同硬件上跑起来。这套方案把 5000 张图配齐 VOC、COCO、YOLO 三种格式标签同时给出支持 GPU、CPU、Mac 三平台的 YOLO11 一键训练脚本正好命中零售柜识别项目从数据准备到模型训练的全链路缺口。适合谁用比如你正在做智能货柜视觉方案选型或是算法岗需要快速验证柜内商品检测可行性又或者你手里的标注数据只有一种格式想统一成 YOLO 管线这套组合能帮你省掉好几周的数据整理时间。接下来我按实际落地顺序把数据场景、格式转换、平台适配和主要坑位都拆开讲一遍。2. 零售柜场景为什么让通用检测模型翻车先搞懂数据背后的三个难点2.1 小目标占比高货架纵深与相机距离之间的矛盾零售柜内部通常只有 30 到 60 厘米深但摄像头要覆盖 4 到 7 层货架单件商品在画面里经常只有 30×30 像素甚至更小。YOLO 系列默认的输入尺寸是 640×640在这个分辨率下小目标特征会在下采样过程中快速衰减。你可以自己做个试验找一张柜内实拍图把一件 250ml 饮料的标注框输出出来跟整张图的宽高比一下大概率宽度占比不到 5%。这就解释了为什么很多团队用通用预训练权重直接推理时小瓶装商品频繁漏检。处理这类数据的首要原则是别急着改模型结构先把标签质量抓起来。我在处理零售柜数据时会先统计所有标注框的宽高分布把那些宽或高小于 20 像素的框单独拎出来检查一遍看是标错了还是真实存在极小目标。这个环节最花时间但效果立竿见影。2.2 类间相似度高同品牌不同口味只有一个标签差异智能柜里最常见的情况是三瓶不同口味的同系列饮料摆在一起包装主色一致差异集中在标签上一小块图案。如果标注人员在框选时不够细致模型很容易把特征学成「这个位置有一瓶饮料」而不是「这是草莓味还是原味」。这也是零售柜数据集比通用目标检测数据集更讲究标注一致性的原因——你用 COCO 的 80 类逻辑去理解它是不对的这里常常一个 SKU 就是一个类别。拿这个 5000 张图的规模来说如果类目数控制在 30 到 60 个 SKU 之间平均每个类有 80 到 160 个实例基本够训练出一个能用但不算饱满的模型。我的经验是如果单类实例少于 50就该考虑数据增强或者采集更多样张否则这个类别大概率会过拟合到柜内固定位置和固定光照上。2.3 光照和反光标签噪声之外的隐性干扰柜内商品表面有塑封膜、玻璃瓶、易拉罐补光灯一打每张图都带着高光区域。高光会让边框附近的纹理失真特别是瓶身弧面边缘人眼都可能看走眼。很多数据集标注时没考虑这一点导致训练出的模型对亮度极其敏感同一商品换个摆放角度就检测不出来。所以我拿到任何零售柜数据集后第一件事不是急着配训练脚本而是随机挑 200 张图做一次标签抽检看框的贴合度和类别一致性。5000 张图做全量抽检不现实但 4% 的样本量已经能发现系统性标注错误比如某个类别整体偏移了几个像素、某个 SKU 的标签串到了另一类上。如果抽检不合格后续训练投入再多时间也是在脏数据上过拟合。3. 把 VOC/COCO/YOLO 三种格式盘成一份配置脚本转换与对齐细节3.1 先认识三种格式在零售柜场景里的角色标注格式的本质是「用什么结构描述图片里有什么、在哪、属于哪类」。VOC 用的是 XML 文件一个标注框是一组bndbox结点坐标直接是人可读的像素值适合人工检查COCO 用的是单个大 JSON所有图片和标注通过 id 关联适合做统一数据管理和跨项目复用YOLO 则是每个图片对应一个同名 txt一行写一个class_id center_x center_y width height坐标已经归一化到 0 到 1 之间读取效率最高。实际项目里我一般把 VOC 当中间格式用标注工具导出来后先转成 YOLO 直接开训需要做统计分析时再转 COCO。但如果你手里的数据集只提供一种格式而你的脚本依赖另一种就必须自己完成转换。转换本身不复杂复杂的是保持三类信息一致类别列表的顺序、坐标系的定义、以及图片和标注文件的名字对应关系。3.2 用 Python 完成 VOC 转 YOLO代码与三个必须核对的点假设你拿到的数据包含Annotations目录下的一堆 XML 文件和JPEGImages目录下的原图现在要转成 YOLO 格式。直接按下面这个脚本操作import os import xml.etree.ElementTree as ET from pathlib import Path # 类别列表是整个转换的核心顺序必须与后续训练配置完全一致 class_names [coke_330ml, sprite_330ml, water_500ml, snack_chips] # 按需替换 def convert_voc_to_yolo(xml_path, out_path, img_width, img_height): tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: continue # 跳过不在列表内的类别避免污染训练标签 class_id class_names.index(name) box obj.find(bndbox) x_min float(box.find(xmin).text) y_min float(box.find(ymin).text) x_max float(box.find(xmax).text) y_max float(box.find(ymax).text) # 坐标归一化YOLO 要求中心点和宽高都除以图片宽高 x_center (x_min x_max) / 2 / img_width y_center (y_min y_max) / 2 / img_height width (x_max - x_min) / img_width height (y_max - y_min) / img_height # 边界裁剪防止标注越界导致的归一化数值异常 x_center min(max(x_center, 0.0), 1.0) y_center min(max(y_center, 0.0), 1.0) width min(max(width, 0.0), 1.0) height min(max(height, 0.0), 1.0) lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) with open(out_path, w) as f: f.write(\n.join(lines)) # 遍历目录示例 annotations_dir Path(./Annotations) images_dir Path(./JPEGImages) labels_dir Path(./YOLOLabels) labels_dir.mkdir(exist_okTrue) for xml_file in sorted(annotations_dir.glob(*.xml)): img_name xml_file.stem .jpg img_path images_dir / img_name # 实际项目中从图像文件头读取尺寸不要假设固定值 from PIL import Image with Image.open(img_path) as img: w, h img.size convert_voc_to_yolo(xml_file, labels_dir / (xml_file.stem .txt), w, h)这段代码里最关键的是class_names列表它的顺序直接决定了 txt 文件里的class_id。如果你转换时类别顺序是 A、B、C但训练配置里顺序变成了 C、B、A那模型学到的所有类别都是错位的。另外要注意代码里我加了归一化后的边界裁剪因为实际标注中偶尔会出现框的某条边超出图片边界的情况不处理的话训练时会报坐标越界错误。转换完成后我会做一次抽查随机选 10 张训练图用 OpenCV 把标签画回原图检查贴合度。这一步能发现 xml 和 jpg 文件名不对齐、坐标单位不统一有的标注工具用整数有的用浮点这类隐蔽问题。3.3 COCO 与 VOC 之间互转注意 id 连续性和 area 字段COCO 格式转 VOC 时最常见的坑是 category id 不连续。COCO 官方数据集里类别 id 从 1 开始且连续但自定义数据集经常出现 id 跳号的情况。如果你不重映射转换出的 XML 里类别标签就会错乱。我的做法是先构建一份id_to_name字典按 id 升序排序后重新从 1 开始编号再做映射。从 VOC 转 COCO 时area字段必须保证非零否则 COCO 的评估脚本会直接忽略该框。你只需要计算(x_max - x_min) * (y_max - y_min)即可但要注意如果原始标注里出现了退化框宽或高为 0要提前过滤掉。另外 COCO 的图片id和标注id必须全局唯一不能用文件名替代我会显式用自增数生成。3.4 一个文件清单搞定数据集自检训练前必跑的三条命令在正式跑训练脚本之前先对数据集做一轮机器自检能省掉大量排查时间。我把需要检查的内容列成一张对照表检查项命令或方法通过标准图片与标签一一对应对比JPEGImages和labels目录下的文件名集合两边文件名的.stem完全一致标签内容可解析用python -c import cv2; ...逐行读取 txt 并拆分浮点数每行恰好 5 个数值且 class_id 在合法范围内归一化坐标合法检查所有数值是否在[0, 1]区间内不允许出现负数或大于 1 的值类目均匀度统计每个 class_id 的实例数量单类数量不少于 50且没有明显断档这三条命令对应的操作都不难第一条用comm命令对比文件名第二条写个 10 行的 Python 脚本逐文件读取第三条直接grep -E正则扫一遍。做完这套自检数据才有资格进入训练环节。4. 让 YOLO11 一键训练脚本同时吃下 GPU/CPU/Mac设备适配是门手艺4.1 三平台训练的本质差异不是改个布尔值那么简单YOLO11 基于 Ultralytics 框架底层支持 PyTorch。PyTorch 在不同平台上的计算后端不同Windows 和 Linux 上用 CUDA 调 NVIDIA 显卡Mac 上用 MPS 调 Apple Silicon 的 Metal 加速都没有这些硬件就退回 CPU 计算。显卡硬件版本非常老旧时代码里的 GPU 检测机制可能会有对较新架构特性的依赖导致执行到一半报设备能力不够的错误这类问题我一般在脚本开头就先做一次设备能力校验不满足就直接报警提示而不是等训练跑起来才让用户面对一堆晦涩错误。一键训练脚本的真正难点在于它要自动判断当前机器有什么设备选择对应的后端同时处理好不同后端对内存和批大小的约束。比如同样一张 640×640 的图在 12GB 显存的显卡上可以跑 batch size 16在 Mac 的 16GB 统一内存上可能只能跑 8在纯 CPU 机器上 4 都勉强。脚本如果不做这些参数的自适应用户跑起来就是各种 OOM 报错。4.2 写一个能自动选设备的 Python 启动器我给零售柜项目写训练脚本时习惯于先用一个detect_device()函数做设备探测再根据设备类型动态调整训练参数。参考下面的结构import torch from ultralytics import YOLO def detect_device(): 按优先级返回可用设备CUDA MPS CPU 同时返回设备名称供后续参数调整使用 if torch.cuda.is_available(): device cuda gpu_name torch.cuda.get_device_name(0) total_mem torch.cuda.get_device_properties(0).total_memory / 1024**3 print(f[设备] CUDA 可用{gpu_name}显存 {total_mem:.1f} GB) return device, gpu_name elif torch.backends.mps.is_available(): device mps print([设备] Apple MPS 后端可用使用 GPU 加速) return device, MPS else: device cpu print([设备] 未检测到 GPU回退 CPU 训练速度会慢很多) return device, CPU def adjust_batch_by_device(device, gpu_name, default_batch16): 根据设备类型动态调整 batch size避免 OOM if device cuda: # 显存小于 8GB 时降低 batch防止显存溢出 if 8GB in gpu_name or any(k in gpu_name for k in [1660, 2060, 3050]): return 8 return default_batch elif device mps: return 8 # MPS 后端显存与内存共享保守一点 else: return 4 # CPU 训练 batch 太大没有意义反而拖慢 if __name__ __main__: device, name detect_device() batch adjust_batch_by_device(device, name) # 加载自己数据集的 yaml 配置注意 class 顺序必须与转换脚本一致 model YOLO(yolo11n.pt) model.train( dataretail_cabinet.yaml, epochs100, imgsz640, batchbatch, devicedevice, workers4 if device ! cpu else 2, ampFalse if device mps else True, # MPS 的混合精度支持还不完善 projectruns/retail_cabinet, nameexp, patience20, )这段代码把最容易出问题的几个点都兜住了。detect_device函数按优先级返回设备避免用户手动改参数adjust_batch_by_device根据设备类型和显存大小动态调整批大小防止 OOMampFalse if device mps else True是因为 PyTorch 的 MPS 后端在做自动混合精度时偶发数值异常我在 Mac 上训练时遇到过 loss 变成 nan关了之后一切正常。4.3 零售柜数据集的 YAML 配置类别表是唯一真理训练脚本依赖一个数据配置文件指向图片目录、标签目录和类别名称。这个文件写错一处前面所有格式转换的努力就白费了。零售柜场景下我的retail_cabinet.yaml长这样path: ./datasets/retail_cabinet train: images/train val: images/val nc: 4 names: 0: coke_330ml 1: sprite_330ml 2: water_500ml 3: snack_chipsnames的顺序必须与 VOC 转 YOLO 脚本里的class_names列表逐一对应差一个位置都不行。这其实是整个数据链路里最容易翻车的地方——标注格式转换脚本里的类别顺序是自己定义的训练配置里的类别顺序又是在 YAML 里写的两边一旦没有同步模型训练出来的预测结果就全乱了。我一般会在detect_device()之后加一段调试代码把 YAML 里的 names 和数据集标签中实际出现的类别 id 做一个交集检查不匹配就立刻停止训练算是给代码上最后一道保险。4.4 CPU 和 Mac 上的训练预期管理说实话CPU 训练 YOLO11 在 5000 张图上跑 100 个 epoch按照常见配置大概要 20 到 30 个小时基本只能用来验证代码能不能跑通。如果你只有 CPU我的建议是把epochs降到 10imgsz降到 416先走通流程再找一台 GPU 机器做正式训练。Mac 的情况好一些M1 及以上芯片的 MPS 加速差不多是入门级 NVIDIA 显卡的 60% 到 70% 性能但要注意 PyTorch 版本不能太旧MPS 支持在 1.12 之后才逐渐稳定。另外 Mac 训练时不要插着电看温度MPS 跑满 30 分钟后风扇会开始啸叫机身材质传递热量明显属于正常现象不用太担心。5. 智能零售柜训练避坑五条血泪经验让你少走一个月弯路5.1 数据划分不当导致类别分布失衡现象训练集 mAP 接近 0.95验证集 mAP 只有 0.6差距悬殊。原因零售柜数据通常来自同一个柜子的不同时段拍摄如果按文件名顺序直接划分 train/val可能出现某个 SKU 只在训练集出现、验证集完全没有的情况或者某类商品在训练集只有 20 张验证集却有 80 张。这种随机划分在类别数量多、单类样本量少的数据集上特别容易翻车。解决按类别做分层采样保证每个类别在训练集和验证集里的比例接近整体比例。具体来说先统计每个类的实例数量然后按比例把图片分配到两个集合同类图片尽量均匀分布。如果某类实例太少就把它全部放进训练集验证集不包含该类避免模型评估时被极小样本量干扰。5.2 Mac 上训练 loss 变成 nan现象训练第 2 个 epoch 开始 loss 输出显示 nan模型权重失效。原因MPS 后端的自动混合精度实现存在一些算子兼容问题PyTorch 的torch.backends.mps在 float16 计算时偶发异常值。很多 Mac 用户第一次跑训练脚本时中招还以为是代码问题。解决直接在训练参数里关闭 AMPampFalse。代价是训练时间增加约 20%但换来的是稳定收敛。如果你的 PyTorch 版本大于 2.0还可以试试torch.set_float32_matmul_precision(medium)有些场景能缓解数值波动。5.3 边框全偏移导致漏检标签坐标系被默认参数带偏现象新模型在部分货道位置检测框整体向右下偏移尤其在图像边缘区域严重。原因标注工具导出 VOC 时有些会带pose、truncated这类附加信息但坐标本身是正常的。问题出在读取 XML 的脚本里用了硬编码的img_width1920、img_height1080而实际图片尺寸是 1280×960。归一化时除错了分母所有框的坐标都被压缩或拉伸。解决转换代码里严格从图片头部读取尺寸不要相信任何预设值。我在convert_voc_to_yolo函数里用 PIL 读图取了真实的img.size这就是最可靠的做法。另外归一化之后不要立刻覆盖原标签先输出一份 heatmap 可视化图确认框的位置和物体对齐后再替换旧文件。5.4 小目标漏检率居高不下现象瓶装饮料检测正常但类似口香糖、小包巧克力这类小于 30×30 像素的商品频繁漏检。原因YOLO11 默认解耦头对小目标的特征融合做了一些优化但在输入分辨率 640 的情况下小目标的特征图尺寸非常有限。如果数据集中小目标占比不高模型会倾向于忽略小的候选框。解决先把输入分辨率调整到 832 或 1024但要注意这会显著增加训练和推理耗时。更有效的做法是检查数据集里小目标的比例如果超过 30%可以考虑用 SAHI 这类切片推理方案在推理阶段把小图放大。零售柜场景比较取巧的办法是直接按货道切图把单层货架区域裁出来再检测小目标比例瞬间下降。5.5 训练中途显存溢出 OOM现象GPU 训练第 38 个 epoch 时突然报CUDA out of memory前面全部白跑。原因除 batch size 过大外workers数量过高也会让数据加载器占满共享内存尤其当你的机器同时跑着可视化界面时。另外 Ultralytics 默认开启 cache 功能如果评估缓存也占用显存叠加起来就溢出了。解决在model.train()参数里显式设置cacheFalse同时降低workers到 2。如果显存小于 8GB把batch设成 4 到 8 之间开启梯度累积accumulate4来补偿小 batch 带来的 BN 统计波动。6. 验证零售柜模型能不能用自定义评估逻辑比 mAP 数字更要紧模型训练完输出 mAP0.5 到 0.95 的数字只能说明模型在这个数据集上的表现但不等于在实际柜子里能用。零售柜场景里我最看重三个额外指标单次推理耗时、边缘货道漏检率、以及补光灯亮度切换后的稳定性。具体怎么验证呢我会写一个评估脚本模拟柜机运行时的推理逻辑——相机拍到一张图检测模型输出所有商品框然后按货道区域做归类和数量统计最后与真实库存做差。这一步跑通了模型才真正达到交付状态。实际调优中我习惯做一个轻量的在线增强验证把同一张测试图随机调整亮度、对比度和饱和度各生成 5 个版本然后看模型输出的检测框是否稳定。零售柜内补光灯有时会从暖光切成冷光商品颜色偏移比较大如果模型在这个测试下掉点超过 10%就需要补充更多光照变化的样本而不是继续调网络结构。最后想提一个我自己的习惯每次训练都会把 yaml 配置文件、类别列表、转换脚本的版本一起归档训练完把数据集划分的随机种子固定住。这样模型效果下滑时能准确定位是数据变了还是代码变了而不是靠玄学调参。零售柜项目迭代快这种可复现的训练环境能帮你省下大量返工时间。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →