ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv11实战:罐装饮料识别数据集训练与调参全流程

YOLOv11实战:罐装饮料识别数据集训练与调参全流程 简介罐装饮料识别数据集面向YOLOv11目标检测训练场景包含一千多张实拍图片覆盖薯片、可乐、雪碧、红牛、东鹏特饮、芬达、养乐多、王老吉、AD钙奶、金典、特仑苏、蒙牛、伊利、旺仔牛奶等常见商品适合计算机视觉初学者、算法工程师以及有自定义检测模型需求的项目团队使用。资源共2000个文件其中1678个txt为YOLO格式标注文件321个jpg为对应原图另有1个yaml类别配置文件整体大小45.95MB结构清晰可直接接入YOLOv11训练流程。已有929人学习浏览数据经过基础整理标注格式统一省去自行采集、清洗和标注的繁琐步骤。借助该数据集使用者能快速完成罐装饮料识别模型的训练与验证并在此基础上调整类别或扩充数据用于零售场景的货架识别、智能贩卖机等方向。1. 罐装饮料识别一千多张已标注图片直接把 YOLOv11 训练跑起来货架巡检、自动贩卖机视觉、无人零售柜这些场景里最烦的不是模型结构而是标注数据。一张图动辄要标几十个框标完还要转格式、检查坐标、分训练集验证集等把这些干完热情基本耗光了。这篇要拆的资源是一份现成的罐装饮料识别数据集一千多张真实场景图片已经按 YOLOv11 能直接吃的标注格式整理好能识别薯片、东鹏特饮、红牛、芬达、养乐多、可乐、雪碧这 7 类常见货架商品。适合刚跑通 YOLO 系列但缺实战数据的人也适合做零售视觉但不想从标框开始耗时间的人。拿到手之后你要做的就是把目录结构放对、写个数据配置 yaml然后训练命令一敲剩下的交给显存。2. 先看懂 YOLO 标注文件夹结构与 txt 里的 7 个类别2.1 图片与标注文件如何一一对应YOLO 系列的标注体系非常简单每一张图片对应一个同名 txt 文件图片是sprite_001.jpg标注就是sprite_001.txt。这个 zip 解压后的核心结构是images/和labels/两大部分图片按 train/val 拆好labels 目录里按同样的目录结构放 txt。标注文件里每一行代表一个目标框行内从左到右依次是类别 ID、归一化中心点 x、归一化中心点 y、归一化框宽 w、归一化框高 h。# 解压后建议先跑一遍目录树确认结构是不是符合 ultralytics 的预期 tree . -L 2 # 期望看到的目录结构 . ├── images │ ├── train │ │ ├── sprite_001.jpg │ │ └── ... │ └── val │ ├── sprite_127.jpg │ └── ... └── labels ├── train │ ├── sprite_001.txt │ └── ... └── val ├── sprite_127.txt └── ...这里有一个关键点图片名和 txt 文件名必须严格一致包括后缀前的所有字符。我见过有人用 Windows 批量重命名后把jpg后缀变成了jpg.txtultralytics 训练时找不到对应标注会直接跳过这张图最后训练日志里显示图片数量变少还以为自己数据丢了。解压之后第一件事就是写个脚本校验文件名匹配率这个动作一次能做后面省掉不少排查时间。import os from pathlib import Path img_dir Path(images/train) label_dir Path(labels/train) img_names {p.stem for p in img_dir.glob(*.jpg)} label_names {p.stem for p in label_dir.glob(*.txt)} no_label img_names - label_names no_image label_names - img_names print(f缺标注的图片数量: {len(no_label)}) print(f缺图片的标注数量: {len(no_image)}) # 正常输出两个数量都是 0只要有一个不是 0先处理命名问题再开工这段做的是集合减法图片 stem 集合减去标注 stem 集合差集就是缺标注的图反过来是缺图片的标注。常见做法是把projects/SPRITE_001.JPG这种大写后缀统一换成小写否则 stem 对不上也会误报。2.2 7 类目标的类别 ID 与分布预判这份数据集的类别覆盖了货架视觉里很有代表性的三波目标塑料瓶装/罐装饮料可乐、雪碧、芬达、东鹏特饮、红牛、乳饮品养乐多、零食薯片。其中最容易被混淆的是可乐、雪碧、芬达这三类它们的包装主色调分别是红、绿、橙在货架灯光下如果训练样本里出现了滤镜偏色模型很容易把雪碧认成芬达。类别 ID 从 0 开始计数最终在 yaml 里会挂上对应的 names 列表。标注是同名的 txt7 类目标对应 7 个 ID常见标注顺序是0 代表薯片chips、1 代表东鹏特饮、2 代表红牛、3 代表芬达、4 代表养乐多、5 代表可乐、6 代表雪碧。这份正常表现出来的类别内差异比较明显颜色区分度够唯一要注意的是东鹏特饮和红牛都是金色罐身靠瓶身文字区分如果标注框画得太大把背景包进去训练时模型就容易盯着金色背景学习而不是文字特征。我拿到这类数据会先随机挑 30 个标注框可视化看框是不是紧贴物体边缘再做下一步。标注框质量检查是一个几分钟就能完成但很多人跳过的步骤画框工具随便用 OpenCV 或 PIL 都行。import cv2 from pathlib import Path classes [chips, dongpeng, redbull, fanta, yakult, coke, sprite] def draw_labels(img_path, label_path, save_path): img cv2.imread(str(img_path)) h, w img.shape[:2] with open(label_path, r, encodingutf-8) as f: for line in f: cid, cx, cy, bw, bh map(float, line.split()) x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, classes[int(cid)], (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) cv2.imwrite(str(save_path), img) train_dir Path(images/train) for img_path in list(train_dir.glob(*.jpg))[:30]: label_path Path(labels/train) / (img_path.stem .txt) draw_labels(img_path, label_path, fcheck_{img_path.stem}.jpg)坐标换算就是把归一化的中心点乘回图片宽高拿到像素级的左上角和右下角再画矩形框。这里有个细节标注文件里偶尔会出现坐标略超出 [0,1] 区间的情况比如框边缘贴到图片边界归一化后写成 1.002YOLO 训练时会做边界裁剪但不建议靠它兜底批量检查时遇到超界值的先手工修掉。2.3 一千多张样本对训练量意味着什么纯数量上看一千多张图在 YOLOv11 的目标检测里算小规模数据集。平均下来每个类别大概一两百个实例这个量级直接训练不是不行但 M AP 可能卡在一个尴尬的位置常见类别如可乐、雪碧可能到了 0.8/0.9而东鹏特饮或养乐多这种出现频次低的类别会掉到 0.6 以下因为你喂给正负样本的比例不均衡。这种场景的对策有几条加数据增强翻转、HSV 扰动、马赛克把训练轮数从默认的 100 提到 200 并配合早停以及用迁移学习。YOLOv11 的预训练权重包含 COCO 80 类其中没有东鹏特饮这种本土商品但检测器的 low-level 特征边缘、颜色分块已经训得很扎实把 backbone 权重迁移过来依旧有效这一点也是选 YOLOv11 而不是从零搭 Faster R-CNN 的核心原因。3. 环境与目录准备让 YOLOv11 在本地跑起来3.1 conda 环境与依赖安装清单这一节是给新手的完整路径也是给熟手的一份检查清单。YOLOv11 的训练代码目前集成在 ultralytics 库里pip 装这一个包就能拉起训练、验证、导出、推理全流程。Python 版本建议 3.9 或以上PyTorch 需要带 CUDA 的版本纯 CPU 训练一千多张图不是不能跑但一个 epoch 可能要拖到十几分钟我劝你直接装 CUDA 版哪怕用云端 GPU 也别拿笔记本硬扛。conda create -n yolo11 python3.10 -y conda activate yolo11 pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118装完跑一句python -c import torch; print(torch.cuda.is_available())输出 True 说明 GPU 版可用False 就得回去检查是驱动没装还是 CUDA 版本和 PyTorch 不匹配。常见做法是先用nvidia-smi看本机驱动支持的 CUDA 版本再选择对应 index-url这一条写进踩坑笔记里也不冤。3.2 数据配置 yaml 的写法与路径易错点ultralytics 的训练入口接收一个 yaml 文件路径里面定义数据集的根目录、训练图片路径、验证图片路径、类别数量和类别名。路径写绝对路径最稳但要注意 Windows 下路径分隔符和转义的问题yaml 里直接写D:\datasets\drink\images\train会被解析成\d转义推荐全部改成正斜杠D:/datasets/drink/images/trainYOLO 家族对正斜杠兼容得很好。# drinks.yaml path: D:/datasets/drink train: images/train val: images/val nc: 7 names: 0: chips 1: dongpeng 2: redbull 3: fanta 4: yakult 5: coke 6: spritepath字段是根目录train和val相对它定位。这里最容易犯的错有两个一是把train: images/train写成train: D:/datasets/drink/images/train再配上path就变成了路径拼接错误二是nc数量对不上 names 列表长度ultralytics 会直接报索引越界压根进不了训练。写完 yaml 后可以用from ultralytics import YOLO; YOLO(yolo11s.pt).val(datadrinks.yaml)做一次数据体检但更快捷的是直接看训练日志开头打印的train和val图片数量确认数量跟自己的数据集对得上。3.3 目录细节图片格式与文件名规范化YOLO 训练对图片格式没有严苛要求jpg、png、bmp 都能处理但我建议统一成 jpg一是体积小读取快二是避免 png 带透明通道时某些增强操作出异常。文件名也不要带空格和中文ultralytics 对中文路径的支持从 8.x 开始已经比较友好但图像增强里有些操作要临时写缓存文件中文路径在部分 Windows 环境下仍会踩编码坑。把图片统一改成drink_001.jpg这种纯英文数字命名排查问题时省心不少。# 批量把 png 转成 jpg 并统一命名的示例 for f in *.png; do base${f%.png} convert $f -quality 95 ${base}.jpg rm $f done这段用了 ImageMagick 的 convert 命令如果没装就换成 Python 的 Pillow 来转目的是一边转格式一边清理原文件。注意这里的rm是删原图批量操作前务必先跑一遍不带rm的 dry-run我见过有人把整个数据集的原图删光只留了转换后的半批然后哭着从回收站恢复。4. 训练与参数调优yaml 配置和三组核心超参4.1 用官方预训练权重起步而不是随机初始化YOLOv11 提供了 n/s/m/l/x 几个档位的模型尺寸对应参数量和推理速度的权衡。这份数据集只有一千多张图s 或者 n 就够m 到后面边际收益很有限。用 s 起步是这种做法下的稳妥选择预训练权重yolo11s.pt是从 COCO 上训出来的拿来微调比随机初始化在收敛速度和精度上都有明显优势。yolo train modelyolo11s.pt datadrinks.yaml epochs150 imgsz640 batch16 patience20 projectdrink_yolo11 nameexp_s逐项拆开解释model指定预训练权重或模型结构文件data指向刚才写的 yamlepochs是最大训练轮数imgsz是训练输入尺寸也是推理尺寸batch是每批图片数受显存限制。patience20的含义是验证集 mAP 连续 20 轮不上升就提前结束这对小数据集很友好省时间。完整训练下来大概一到一个半小时取决于显卡型号。4.2 三个最常见的调参动作batch、imgsz、数据增强显存不够的时候先降 batch8 不够就 4再不行就换更小的模型档位。imgsz从 640 提到 768 或 896 能改善小目标检测但训练时间和显存占用陡增对这个数据集的罐装饮料来说640 是性价比最高的起点。数据增强方面ultralytics 默认开了马赛克增强在小数据集上帮助明显但马赛克在训练后期偶尔会引入无意义的拼接框所以常见做法是前 50 轮开启后 50 轮通过mosaic0.0关闭。# 一个偏保守的增强配置适合类别差异大、样本量中等的情况 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 0.0 translate: 0.1 scale: 0.5 fliplr: 0.5 mosaic: 1.0这里的hsv_h/s/v是色调、饱和度、明度的随机扰动范围数值越大颜色变化越猛translate和scale控制平移和缩放fliplr是水平翻转概率。罐装饮料检测对颜色敏感所以 hsv 不要给太大0.7 的饱和度扰动已经能让模型不容易过拟合到特定灯光。degrees0.0表示不旋转因为货架场景里商品基本都是竖直摆放旋转增强反而会让模型学习到不真实的角度。4.3 用验证集指标而不是训练 loss 判断训练效果训练过程中看tbox_loss下降没意义模型过拟合时训练 loss 照样降得很好看。以验证集 mAP50 和 mAP50-95 为准这两个指标打印在每轮结束的日志里。还有个容易忽略的点epochs设太大配合patience早停最终保存的权重是验证集表现最好的那个 epoch而不是最后一个 epoch这个逻辑必须在收官前搞明白否则你会拿着一份过拟合权重去推理。训练结束后输出目录里通常有best.pt和last.pt前者是验证集最优后者是最后一个 epoch 的模型。推理部署一律用best.pt这一点我在实际项目里反复提醒过到最后很多人还是用错了。5. 训练与数据避坑五个真实翻车点5.1 图片和标注对不上总量没问题但部分文件缺失现象训练日志显示训练图片数量比实际图片少几十张或者验证时 mAP 突然偏低。原因标注 txt 文件名与图片名没完全对应常见来源是 zip 解压时系统把*.txt隐藏了或者在 Windows 上编辑过 txt 后扩展名被改动。解决解压后第一步就做文件名匹配检查上面给过的集合差集脚本直接跑缺失的用同名空标注补齐或直接删掉这组图片。我一般会把校验脚本放在数据集目录里每次复用前跑一遍。5.2 中文路径导致数据加载中断现象Windows 下训练中途报NotADirectoryError或FileNotFoundError位置随机重启又偶尔能跑。原因ultralytics 在处理缓存文件时用了临时目录拼接中文字符在部分编码环境下被破坏。解决数据集根目录不要带中文整个项目所有路径统一用英文如果已经解压到中文路径了最省事的处理是重新解压到D:/datasets/drink而不是带着罐装饮料识别之类的中文目录名训练。5.3 小目标漏检易拉罐在画面里只占一小块现象训练完测试货架远端的小罐装目标完全没框出来近距离目标一切正常。原因数据集里大量图片是近景拍摄小尺寸目标样本少加上 imgsz640 对小目标不友好。解决训练时把imgsz提到 896 试试另一个更直接的办法是检查标注框面积分布如果大量目标框在原图中占比小于 1%优先考虑不从这端解决而是在推理端用imgsz1280跑 TTA。这种场景我一般会先看box大小直方图再有针对性地决定要不要切分图片推理。5.4 使用 Notes 或 Excel 打开并保存 txt 后标注直接作废现象训练开始后报坐标解析错误或者所有类别 ID 变成了 -1。原因系统默认用带格式的编辑器打开 txt保存后文件加上了 UTF-8 BOMultralytics 解析时首行类别 ID 读到\ufeff0这种带隐藏字符的值。解决标注文件只用纯文本编辑器改已经坏了的大批量文件用脚本把 BOM 去除from pathlib import Path for p in Path(labels/train).glob(*.txt): raw p.read_bytes() if raw.startswith(b\xef\xbb\xbf): p.write_bytes(raw[3:]) print(ffixed: {p.name})这段代码检测文件前三个字节是否是 UTF-8 BOM是就去掉重写。写完之后记得重新做一遍标注可视化确认坐标没有因为编码问题被破坏。5.5 训练中断后从头再来现象训练到一半显存溢出或断电重新执行一模一样命令又开始从 epoch 0 跑。原因没有指定 resume 参数ultralytics 不会自动续训。解决只要原始命令里有project和name训练中断后执行yolo train resumedrink_yolo11/exp_s/weights/last.ptresume参数直接接收last.pt的路径它会读取训练状态包括当前 epoch、优化器参数和数据增强配置从断点继续。我通常在训练脚本里封装一层检测到last.pt存在就直接走 resume相当于给训练上了后悔药。6. 推理验证与精度救急从 best.pt 到漏检修复模型训练结束后验证手段和推理习惯决定你在别人眼里是不是真的掌握了这份资源。先跑批量预测把结果可视化再针对漏检目标做定向优化。YOLOv11 的推理接口非常简洁from ultralytics import YOLO model YOLO(drink_yolo11/exp_s/weights/best.pt) results model.predict( sourcetest_images, imgsz640, conf0.25, saveTrue, nameinference_output )conf0.25是置信度阈值低于它的框会被过滤掉saveTrue会把绘制好框的图片存到runs/detect/inference_output下。我在一轮推理后习惯跑一次混淆矩阵看看芬达和雪碧之间有没有系统性错认如果确有混淆就针对这两类做两件事一是把验证集里这类图片单独挑出来检查标注框是否真的贴合罐体二是适当提高hsv_h扰动让模型学会看瓶身文字而不只是依赖主色调。除了图片推理YOLOv11 也支持对视频流直接跑yolo predict modeldrink_yolo11/exp_s/weights/best.pt sourcetest_video.mp4 saveTrue视频推理时同样的conf参数有效货架巡检类场景往往在运动模糊处掉框对这种工况可以稍微调低置信度到 0.2再开启iou0.45控制 NMS 的合并尺度避免同一罐饮料被框成两截。从那以后我每次拿到新数据集都会强制走一遍完整流程先验证文件名匹配再可视化 30 张标注框然后才允许进入训练这套习惯让我踩过的坑基本没再犯过第二次希望帮到你。本文还有配套的精品资源点击获取
返回列表