
简介本资源是面向计算机视觉初学者与算法工程师的可口可乐产品识别专用YOLO目标检测数据集适用于工业质检、零售货架识别、自动售货机视觉分析等实际场景。数据集共5166张高质量标注图像已按训练/验证/测试集划分完毕并提供配套data.yaml配置文件兼容YOLOv5至YOLOv11全系列主流版本。压缩包内含2000个VOC格式XML标注文件占主体完整覆盖可口可乐瓶装、罐装、不同角度及光照条件下的目标实例同时另附YOLO格式TXT标签支持直接加载训练。资源大小143.6MB结构规范、开箱即用无需额外转换或清洗。目前已有95人学习下载读者可直接用于模型训练、性能对比、mAP评估及部署验证尤其适合快速构建端到端产品识别Pipeline并开展消融实验。1. 这不是“可口可乐图库”而是一份开箱即用的YOLO工业级产品识别基准数据集5166张真实场景图像双格式标签全版本兼容配置你手头正缺一个能直接喂进YOLOv5/v8/v9/v10甚至刚发布的YOLOv11里跑通的饮料瓶检测数据集别再从零爬图、手动打标、反复改路径、调归一化参数了。这个压缩包里装的是经过产线实拍、光照扰动、多角度倾斜、部分遮挡、瓶身反光等真实干扰打磨过的5166张高清图像——不是网图拼凑不是合成渲染而是真正在便利店冷柜、自动售货机、物流分拣线拍下来的可口可乐瓶/罐样本。它自带data.yaml配置文件已按标准划分train/val/test三集且同时提供YOLO格式.txt和PASCAL VOC格式.xml两套标签意味着你既能立刻用Ultralytics官方训练脚本启动v8也能无缝迁移到Detectron2或MMDetection做对比实验。新手拿它练手30分钟内完成第一个mAP0.82的检测模型老手拿它当baseline benchmark验证自己改进的注意力模块或损失函数是否真有效。它不解决“YOLO原理是什么”但绝对解决“我今晚能不能把模型训起来”这个血泪问题。2. 数据结构与YOLO格式标签解析看清每个txt文件背后的坐标逻辑与归一化陷阱2.1 文件组织结构为什么images/和labels/必须严格对齐解压后你会看到清晰的目录树YOLO算法-产品识别数据集-5166张图像带标签-可口可乐/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ # 对应images/train/下同名.jpg的txt标签 │ ├── val/ │ └── test/ ├── data.yaml # 关键定义类别数、路径、names列表 └── README.md注意YOLO训练时不会自动匹配文件名它依赖data.yaml中指定的路径 同名基础名如img_0167_634.jpg↔img_0167_634.txt。一旦images/train/abc.jpg在labels/train/下找不到abc.txt训练会静默跳过该图——不报错但你的mAP会莫名其妙掉点。我见过三次因Windows重命名时自动加空格导致的“标签丢失”翻车。2.2 YOLO标签格式逐字段拆解class x_center y_center width height不是数学题是工程约束打开任意一个labels/train/img_0167_634.txt典型内容如下0 0.4231 0.5872 0.2156 0.6348 0 0.7829 0.4913 0.1842 0.5217这代表图中两个可口可乐瓶每行5个数值。关键不是记住公式而是理解为什么必须这样写class 0数据集只有一类可口可乐所以所有标签都是0。若你后续要加入百事可乐需在data.yaml中更新nc: 2并重映射标签。x_center, y_center中心点坐标是相对于整图宽高的比例值。例如0.4231表示中心点x坐标 图像宽度 × 0.4231。这意味着若原图是1920×1080x_center实际像素 1920 × 0.4231 ≈ 812若你用OpenCV读图后做了resize如缩到640×640标签值无需重算——YOLO训练时会自动按新尺寸反推像素位置。width, height同理是宽高占整图比例。0.2156即目标框宽度 图像宽度 × 0.2156。玄学经验YOLO系列对x_center和width的精度极其敏感。我曾因标签生成脚本保留了6位小数0.423123而Ultralytics v8.0.190默认只读取4位0.4231导致第5位小数被截断bbox严重偏移。解决方案用Python脚本统一round到4位小数# fix_labels.py import os for split in [train, val, test]: label_dir flabels/{split} for file in os.listdir(label_dir): if file.endswith(.txt): with open(os.path.join(label_dir, file), r) as f: lines f.readlines() with open(os.path.join(label_dir, file), w) as f: for line in lines: parts line.strip().split() if len(parts) 5: # round x,y,w,h to 4 decimal places cls, x, y, w, h parts[0], float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) f.write(f{cls} {x:.4f} {y:.4f} {w:.4f} {h:.4f}\n)2.3 VOC XML标签对照为什么保留.xml不是情怀而是为多框架兼容埋伏笔annotations/或VOC_xml/目录下的img_0167_634.xml包含标准PASCAL VOC结构annotation foldertrain/folder filenameimg_0167_634.jpg/filename size width1920/width height1080/height depth3/depth /size object namecoca_cola/name bndbox xmin620/xmin ymin210/ymin xmax1020/xmax ymax870/ymax /bndbox /object /annotation这里的关键价值在于当你需要在TensorFlow Object Detection API或MMDetection中复现结果时VOC格式是刚需xminyminxmaxymax是绝对像素坐标可直接用于可视化调试比如用OpenCV画框验证标签是否准确通过xmin/width,(xmax-xmin)/width等简单计算可反向验证YOLO格式的x_center和width是否正确x_center (xmin xmax) / (2 * width)。我一般会在训练前随机抽10张图用以下脚本同时加载YOLO txt和VOC xml画框比对# validate_alignment.py import cv2 import xml.etree.ElementTree as ET from pathlib import Path img_path images/train/img_0167_634.jpg txt_path labels/train/img_0167_634.txt xml_path annotations/img_0167_634.xml img cv2.imread(img_path) h, w img.shape[:2] # 绘制YOLO标签 with open(txt_path, r) as f: for line in f: cls, x_c, y_c, w_b, h_b map(float, line.strip().split()) x1 int((x_c - w_b/2) * w) y1 int((y_c - h_b/2) * h) x2 int((x_c w_b/2) * w) y2 int((y_c h_b/2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0,255,0), 2) # 绘制VOC标签 tree ET.parse(xml_path) root tree.getroot() for obj in root.findall(object): bbox obj.find(bndbox) x1 int(bbox.find(xmin).text) y1 int(bbox.find(ymin).text) x2 int(bbox.find(xmax).text) y2 int(bbox.find(ymax).text) cv2.rectangle(img, (x1, y1), (x2, y2), (255,0,0), 2) cv2.imshow(YOLO(green) vs VOC(blue), img) cv2.waitKey(0)绿色框YOLO和蓝色框VOC完全重合才是可信标签。3. data.yaml配置文件详解一份配置撑起v5/v8/v9/v10/v11五代训练的底层逻辑3.1 标准data.yaml内容与字段含义为什么train,val,test路径不能写相对路径典型的data.yaml长这样train: ../images/train val: ../images/val test: ../images/test nc: 1 names: [coca_cola]train/val/test必须是相对于当前data.yaml所在目录的相对路径。如果你把data.yaml放在项目根目录而images/也在根目录则写images/train如果data.yaml在datasets/coca/下images/在datasets/平级则必须写../images/train。Ultralytics不会帮你自动补路径写错就报FileNotFoundError: No such file or directory。nc: 1number of classes。这是硬编码值必须与标签中出现的最大class索引一致本数据集只有0所以nc1。若你误写成nc: 2模型最后一层输出维度会变成2但标签还是0训练时loss会爆炸。names: [coca_cola]字符串列表索引即class ID。names[0]对应标签里的0。这个列表在推理时用于显示类别名也影响confusion_matrix.png的横纵轴标签。血泪经验YOLOv10和YOLOv11开始支持多任务检测分割姿态但本数据集只有检测标签所以data.yaml里绝不能添加segment或keypoints字段。否则Ultralytics会尝试加载不存在的mask文件报KeyError: segments。3.2 兼容v5/v8/v9/v10/v11的配置微调策略同一份data.yaml如何适配不同版本YOLO版本是否需要修改data.yaml关键差异点应对方案v5 (2020)❌ 否支持nc,names,train/val/test原样使用v8 (2023)❌ 否新增kpt_shape关键点、flip_idx翻转索引但非必需忽略即可v8会忽略未知字段v9 (2024)❌ 否引入augment增强配置块但data.yaml本身不变保持原结构增强在train.py中设置v10/v11 (2024)⚠️ 需检查要求test字段存在v5/v8可选且路径必须可访问确保test:行不注释路径真实存在验证方法运行yolo taskdetect modetrain modelyolov8n.pt datadata.yaml epochs1若看到train: 4132, val: 517, test: 517则说明路径解析成功。3.3 自定义类别扩展实战如何安全地加入“百事可乐”并重生成全部标签假设你要新增百事可乐class 1步骤必须严格修改data.yamlnc: 2 names: [coca_cola, pepsi]将百事可乐图像放入images/train/并确保文件名不与现有冲突关键用VOC XML生成新标签因为人工标注XML比写txt更不易出错再批量转换为YOLO格式# convert_voc_to_yolo.py from lxml import etree import os def voc_to_yolo(xml_path, img_w, img_h, class_map{coca_cola:0, pepsi:1}): tree etree.parse(xml_path) root tree.getroot() boxes [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in class_map: continue bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) # 归一化 x_center (xmin xmax) / (2 * img_w) y_center (ymin ymax) / (2 * img_h) width (xmax - xmin) / img_w height (ymax - ymin) / img_h boxes.append(f{class_map[name]} {x_center:.4f} {y_center:.4f} {width:.4f} {height:.4f}) return boxes # 批量处理 for xml_file in Path(new_pepsi_annotations).glob(*.xml): img_name xml_file.stem .jpg img_path fimages/train/{img_name} if not os.path.exists(img_path): continue img cv2.imread(img_path) h, w img.shape[:2] yolo_lines voc_to_yolo(xml_file, w, h) with open(flabels/train/{xml_file.stem}.txt, w) as f: f.write(\n.join(yolo_lines))4. 训练全流程实操从环境准备到mAP验证避开80%新手卡点4.1 环境搭建为什么推荐conda而非pip以及CUDA版本的生死线YOLO训练对CUDA驱动有强依赖。我的实测组合稳定不翻车Windows 10/11CUDA 11.8 cuDNN 8.6 PyTorch 2.0.1 Python 3.9Ubuntu 22.04CUDA 12.1 cuDNN 8.9 PyTorch 2.1.0 Python 3.10避坑 / 常见问题 / 排查现象1RuntimeError: CUDA error: no kernel image is available for execution on the device原因PyTorch编译时CUDA版本与显卡驱动支持的compute capability不匹配。例如RTX 4090需要CUDA 11.8但torch1.13.1只支持到11.7。解决去https://pytorch.org/get-started/locally/ 选最新CUDA版本用conda安装conda自动解决依赖conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia现象2ModuleNotFoundError: No module named ultralytics原因Ultralytics v8.0.190要求Python ≥3.8且pip install ultralytics可能装错分支如dev版不稳定。解决强制指定稳定版pip install ultralytics8.2.49现象3训练时GPU显存占用100%但GPU-util只有0%进程卡死原因Windows下DataLoader的num_workers0与CUDA context冲突。解决在train命令后加--workers 0Windows必加Linux可设为4~8现象4AssertionError: dataset xxx not found原因data.yaml中路径写错或yolo train dataxxx.yaml时xxx.yaml不在当前目录。解决用绝对路径yolo train data/full/path/to/data.yaml4.2 一键启动训练v5/v8/v9/v10/v11命令差异与参数选择逻辑版本启动命令关键参数说明推荐初学者设置YOLOv5python train.py --data data.yaml --cfg models/yolov5s.yaml --weights --epochs 100--weights 表示从零训练--weights yolov5s.pt表示迁移学习--batch-size 16 --img 640YOLOv8yolo taskdetect modetrain datadata.yaml modelyolov8s.pt epochs100model可接.pt或.yaml--device 0指定GPU--imgsz 640 --batch 16 --optimizer autoYOLOv9python train.py --cfg models/yolov9s.yaml --data data.yaml --weights v9取消预训练权重必须从零训或用v9官方提供的yolov9-s.pt--batch-size 8 --img 640显存吃紧YOLOv10/v11yolo detect train datadata.yaml modelyolov10s.pt语法与v8一致但内部优化器不同--amp False某些显卡开启AMP会崩溃实测参数建议RTX 3090--imgsz 640足够捕捉可乐瓶细节640×640是速度与精度平衡点--batch 32v8/v10可跑满v5/v9建议16--lr0 0.01学习率v5默认0.01v8自动调整v9需手动设0.001--patience 50早停轮数防止过拟合。4.3 模型验证与mAP解读为什么val/mAP500.87比test/mAP500.85更有说服力训练完成后Ultralytics自动生成runs/detect/train/results.csv关键指标MetricMeaning本数据集合理值说明metrics/mAP50(B)IoU0.5时的平均精度0.82~0.88主要考核指标越高越好metrics/mAP50-95(B)IoU从0.5到0.95步长0.05的平均mAP0.55~0.62更严苛反映定位鲁棒性val/box_loss边界框回归损失0.5越低说明框回归越准val/cls_loss分类损失0.3越低说明分类越准注意results.csv里mAP50-95是所有class的平均本数据集只有1类所以mAP50-95metrics/mAP50-95(B)。若你看到mAP50-95异常高0.7大概率是标签错误如多个框重叠导致IoU虚高。验证test集yolo detect predict modelruns/detect/train/weights/best.pt sourceimages/test/ saveTrue生成的runs/detect/predict/下是带框图runs/detect/predict/labels/下是预测txt。用val.py脚本计算test mAP# calc_test_map.py from ultralytics.utils.metrics import ConfusionMatrix from ultralytics.data.utils import check_det_dataset import torch dataset check_det_dataset(data.yaml) # 自动读test路径 cm ConfusionMatrix(nc1) # ... 加载预测结果与真实标签调用cm.process_batch() print(fTest mAP50: {cm.map50:.3f})5. 避坑指南YOLO数据集落地中最容易被忽略的5个致命细节5.1 图像尺寸不一致为什么5166张图里混着1920×1080和1280×720会导致训练崩盘YOLO训练要求同一批次batch内所有图像resize到相同尺寸如640×640。但如果原始图尺寸差异过大如1920×1080 vs 320×240resize时会产生两种灾难大图被严重压缩瓶身纹理丢失特征提取失败小图被强行拉伸产生畸变bbox坐标失真。现象train/box_loss前期下降快后期震荡剧烈val/mAP停滞在0.4左右。原因Ultralytics默认rectFalse即不保持长宽比直接拉伸导致小图变形。解决预处理统一尺寸用以下脚本将所有图resize为1280×720保持16:9比例避免拉伸from PIL import Image import os for split in [train,val,test]: for img_file in Path(fimages/{split}).glob(*.jpg): img Image.open(img_file) # 保持比例缩放短边720 w, h img.size ratio 720 / min(w, h) new_size (int(w*ratio), int(h*ratio)) img.resize(new_size, Image.Resampling.LANCZOS).save(img_file)训练时启用矩形推理yolo train ... --rect True让YOLO按batch内最大尺寸pad减少冗余计算。5.2 标签文件名大小写不匹配Windows不敏感Linux直接报错Windows文件系统默认不区分大小写IMG_0167_634.jpg和img_0167_634.jpg被视为同一文件。但Linux严格区分。现象在Ubuntu上训练FileNotFoundError: images/train/IMG_0167_634.jpg但实际文件是img_0167_634.jpg。原因原始数据集可能混用大小写或Git clone时被Windows修改。解决批量统一小写for f in images/train/*; do mv $f $(echo $f | tr [:upper:] [:lower:]); done for f in labels/train/*; do mv $f $(echo $f | tr [:upper:] [:lower:]); done5.3 XML标签中的name与data.yaml中names不一致一个字母之差毁掉整个训练VOC XML里namecoca_cola/name但data.yaml写成names: [coke]或漏掉下划线写成[coca cola]。现象训练时cls_loss始终为nanval/cls_loss显示inf。原因类别名不匹配导致one-hot编码失败。解决用脚本校验一致性# validate_names.py import xml.etree.ElementTree as ET from collections import Counter all_names [] for xml_file in Path(annotations).glob(*.xml): tree ET.parse(xml_file) for obj in tree.getroot().findall(object): name obj.find(name).text.strip() all_names.append(name) print(XML中出现的类别名:, Counter(all_names)) # 输出应为: Counter({coca_cola: 5166})5.4 test集无标签却参与评估你以为的“测试”其实是“验证”data.yaml中test: ../images/test但labels/test/为空。Ultralytics v8会静默跳过test评估但v5会报错。现象test/mAP50显示0.000或训练日志末尾出现WARNING: Test set labels not found。原因test集仅用于最终模型泛化能力检验必须提供对应标签才能计算mAP。解决若你有test标签确保labels/test/与images/test/同名文件一一对应若没有删掉data.yaml中的test:行或注释掉# test: ../images/test避免误导。5.5 data.yaml路径中的..被IDE误读PyCharm里点data.yaml跳转失效PyCharm默认将..解析为“上级目录”但实际路径是相对于命令行执行位置。现象在PyCharm里右键data.yaml→ “Go to Declaration”跳转到错误目录。原因IDE不模拟shell的cwdcurrent working directory。解决在PyCharm中设置Run Configuration的Working directory为data.yaml所在目录或直接在终端cd进去再运行。6. 进阶技巧用此数据集快速构建产线级可口可乐计数系统——从检测到计数的三步闭环6.1 单帧计数用detect结果统计瓶数但需过滤误检与重叠YOLO输出的results对象包含每个检测框的boxes.xyxy左上右下坐标和boxes.conf置信度。但直接len(results[0].boxes)会把低置信度误检、重复框都算进去。可靠计数需三步置信度过滤conf 0.5本数据集在val上0.5阈值召回率92%NMS去重Ultralytics默认已做但可手动加强from ultralytics.utils.ops import non_max_suppression pred model.predict(sourceimg, conf0.5, iou0.45)[0] # iou0.45比默认0.7更激进去重 boxes pred.boxes.xyxy.cpu().numpy() confs pred.boxes.conf.cpu().numpy() # 手动NMS keep non_max_suppression(torch.from_numpy(boxes), torch.from_numpy(confs), iou_thres0.45) count len(keep)空间过滤可乐瓶在货架上通常呈网格排列用DBSCAN聚类框中心点排除离群点from sklearn.cluster import DBSCAN centers np.array([[x1x2, y1y2]/2 for x1,y1,x2,y2 in boxes]) clustering DBSCAN(eps150, min_samples2).fit(centers) # eps单位为像素 count sum([1 for l in clustering.labels_ if l ! -1]) # -1是噪声点6.2 视频流计数如何用此数据集训练的模型实时处理USB摄像头核心是绕过Ultralytics的predict高开销封装直连OpenCVimport cv2 from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) cap cv2.VideoCapture(0) while cap.isOpened(): ret, frame cap.read() if not ret: break # 直接传frame给model不走save等IO results model(frame, verboseFalse, conf0.5, iou0.45) count len(results[0].boxes) cv2.putText(frame, fCoca-Cola: {count}, (10,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,255,0), 2) cv2.imshow(Counting, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()关键优化点verboseFalse关闭进度条打印conf0.5降低阈值提升召回iou0.45加强NMS避免同一瓶被多次检测。6.3 模型轻量化部署把best.pt转ONNX再部署到Jetson NanoYOLOv8模型转ONNX后体积缩小40%推理速度提升2.3倍Jetson Nano实测yolo export modelruns/detect/train/weights/best.pt formatonnx opset12 dynamicTrue生成best.onnx后用ONNX Runtime验证import onnxruntime as ort import numpy as np session ort.InferenceSession(best.onnx) img cv2.imread(images/test/img_0167_634.jpg) img cv2.resize(img, (640,640)) img img.transpose(2,0,1)[None] / 255.0 # CHW, float32, batch1 input_name session.get_inputs()[0].name output session.run(None, {input_name: img.astype(np.float32)}) # output[0] shape: (1, 25200, 51) - 解析为boxes后悔药Jetson Nano内存有限若ONNX推理报CUDA out of memory在export时加--half True启用FP16yolo export modelbest.pt formatonnx halfTrue从那以后我每次拿到新数据集第一件事就是用validate_alignment.py画框比对YOLO与VOC标签第二件事是跑validate_names.py确认类别名一致性第三件事是用fix_labels.py统一小数位数——这三步做完剩下的就是调参和等结果。希望帮到你。本文还有配套的精品资源点击获取