ARTICLE DETAIL

资讯详情

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

烟盒数据集1134张图带标签,YOLO全系直接开训

烟盒数据集1134张图带标签,YOLO全系直接开训 简介这是一份面向YOLO系列算法目标检测任务的烟盒数据集适合正在做目标识别项目、准备训练自定义检测模型的学生与开发者使用。数据集已按训练与验证需求划分完毕并附带data.yaml配置文件可直接接入yolov5、yolov8、yolov9、yolov7、yolov10及yolo11等主流框架省去自行整理与划分数据的繁琐步骤。压缩包共约109.43MB内含2000个文件其中1018个xml文件对应VOC格式标注982个txt文件对应YOLO格式标注两种标签分别存放于独立文件夹便于按需选用YOLO格式采用类别索引与归一化中心点、宽高坐标符合常见训练脚本的读取规范。目前已有130人学习下载可作为烟盒检测赛题或课程实验的现成数据基础帮助读者快速跑通训练与验证流程把精力集中在模型调参与效果优化上。1. 烟盒数据集到手1134 张图带标签YOLO 全系直接开训做零售货架盘点、烟草陈列合规检查或者智能回收箱识别的人多半都卡在同一个地方模型代码跑得通公开数据集却对不上业务场景。COCO 里没有烟盒这个类自己拍图标注又要耗掉几天。这份烟盒数据集就是冲着这个缺口来的——1134 张图像全部带标签已经划分好训练集和验证集附data.yamlYOLOv5 到 YOLO11 都能直接吃。标签同时给了 YOLO 格式的 txt 和 VOC 格式的 xml两套文件夹分开存想换框架不用重新标。如果你正在找一份能立刻跑起来、类别单一、标注干净的检测数据这份资源省掉的是从零采集到格式转换的整条链路。下面按「拿到手怎么验、怎么接进训练、哪里会翻车」的顺序拆一遍。2. 先验数据再开训目录结构、标签格式与划分逻辑2.1 拿到压缩包先看什么解压之后别急着写训练脚本先花两分钟把目录摸清楚。这类数据集常见的组织方式是按images和labels分目录再各自切train/val。你手上这份带data.yaml说明划分已经做完了路径大概率是相对路径。先确认三件事图像总数是不是 1134、txt 标签数量是否和图像一一对应、data.yaml里的nc和names写的是什么。# 统计图像数量常见后缀都覆盖 find . -type f \( -name *.jpg -o -name *.jpeg -o -name *.png \) | wc -l # 统计 YOLO 格式标签数量 find . -type f -name *.txt | wc -l # 看一眼 data.yaml 内容 cat data.yaml第一行命令数图像第二行数标签。两个数字对不上就说明有图没标或者有标没图训练时 YOLO 会直接报No labels found或者静默跳过这种问题不提前查跑完一轮才发现 mAP 是 0纯属浪费卡时。data.yaml里重点看train和val的路径是不是指向你解压后的实际位置很多人直接拿别人的 yaml 用路径没改训练脚本一启动就FileNotFoundError。2.2 YOLO 标签格式逐字段拆解YOLO 的 txt 标签一行一个目标格式是class x_center y_center width height。这五个值里第一个是类别索引从 0 开始后面四个全是归一化到 0 到 1 的比例值不是像素坐标。这一点是新手最容易翻车的地方——拿像素坐标直接写进去训练不报错但框全跑到图像外面loss 降不下去。# 读一个标签文件验证数值范围是否合法 def check_label(path): with open(path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(f字段数异常: {path} - {parts}) continue cls, x, y, w, h parts vals [float(x), float(y), float(w), float(h)] # 归一化坐标必须落在 0~1 if any(v 0 or v 1 for v in vals): print(f坐标越界: {path} - {vals}) if float(w) 0 or float(h) 0: print(f宽高非正: {path} - w{w}, h{h}) check_label(labels/train/img_0891_185.txt)这段脚本做的是合法性校验。x_center和y_center是框中心点相对整图宽高的比例width和height是框宽高相对整图宽高的比例。如果某个值大于 1 或者小于 0说明标注时用了绝对坐标或者算错了归一化分母。宽高出现 0 或负数通常是标注工具导出异常这种样本留着会干扰回归分支。跑一遍全量校验把异常文件列出来比训练中途看 loss 曲线猜问题快得多。2.3 VOC 格式与 YOLO 格式的对应关系数据集里另一套 xml 是 VOC 格式坐标是绝对像素值结构是xmin ymin xmax ymax。两种格式的换算关系不复杂但边界处理有讲究。字段VOC (xml)YOLO (txt)换算方式类别name文本class索引需维护类别映射表中心 x无直接字段x_center(xminxmax)/2/width中心 y无直接字段y_center(yminymax)/2/height宽xmax-xminwidth(xmax-xmin)/width高ymax-yminheight(ymax-ymin)/height换算时width和height指的是图像本身的像素宽高不是框的宽高命名容易混。如果你要用 xml 那套自己转记得先读图像尺寸别拿框的尺寸当分母。这份数据两套格式都给了正常训练直接用 txt 那套就行xml 留着做格式转换练习或者接其他框架时用。3. 接进 YOLOv8 训练data.yaml 配置与首轮跑通3.1 data.yaml 怎么写才不出错data.yaml是 YOLO 系列训练的入口配置路径、类别数、类别名都在这里。拿到手先按自己的实际解压路径改一遍别直接用压缩包里的相对路径。# data.yaml 示例路径按实际解压位置改 path: /home/user/smoke_dataset # 数据集根目录 train: images/train # 训练集图像相对路径 val: images/val # 验证集图像相对路径 nc: 1 # 类别数烟盒通常是 1 类 names: 0: cigarette_box # 类别名索引从 0 开始path是根目录train和val是相对path的子路径。nc必须和names的条目数一致写错了训练时分类头维度对不上报错信息不一定直观。烟盒这种单类别场景nc: 1如果你拿到的数据里其实分了「硬盒」「软盒」两类那nc要改成 2names也要对应加一行。改完 yaml用 Python 快速加载验证一下语法。import yaml with open(data.yaml) as f: cfg yaml.safe_load(f) print(cfg[nc], cfg[names]) assert cfg[nc] len(cfg[names]), nc 与 names 数量不一致yaml.safe_load比yaml.load安全不会执行任意对象构造。断言那行是防止nc和names对不上这种错误在训练启动阶段就会暴露提前拦住省时间。3.2 首轮训练命令与关键参数环境装好 ultralytics 之后一条命令就能起训。首轮别急着调参先用小 epoch 验证整条链路通不通。# 安装 ultralyticsYOLOv8/YOLO11 通用 pip install ultralytics # 首轮冒烟测试3 个 epoch小模型确认数据能读进来 yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs3 \ imgsz640 \ batch16 \ device0 \ projectruns/smoke \ namefirst_trymodelyolov8n.pt用 nano 版下载快、显存占用低适合先跑通。epochs3只为验证数据管道看 loss 有没有正常下降、验证集有没有出 mAP。imgsz640是 YOLO 系列的常规输入尺寸烟盒在货架图里通常不会太小640 够用如果图像里烟盒占比很小可以提到 1280但显存和速度要重新权衡。batch16是保守值显存够可以往上加。device0指定第一块 GPUCPU 训练把这项去掉或者写cpu。首轮跑完看runs/smoke/first_try/下的results.csv重点看train/box_loss和metrics/mAP50。3 个 epoch 的 mAP 不会高但 loss 应该在降。如果 loss 是nan或者一直不降回到第 2 章查标签格式。3.3 从冒烟测试到正式训练的参数调整冒烟通过之后换正式配置。YOLOv8 和 YOLO11 的接口基本一致换模型权重文件即可。# 正式训练100 epoch中等模型 yolo detect train \ datadata.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch32 \ device0 \ patience20 \ projectruns/train \ namesmoke_v8spatience20是早停验证指标 20 轮不提升就停省得白跑。model从n换到s精度通常有提升代价是显存和单轮时间增加。1134 张图属于小数据集s或m量级的模型足够上l或x容易过拟合除非你做大量增强。batch32在 8G 显存上跑 640 尺寸一般没问题爆显存就降到 16。训练过程中盯runs/train/smoke_v8s/下的results.png看 train loss 和 val loss 是否同步下降。train 降 val 不降甚至上升就是过拟合信号这时候加增强或者减模型容量别硬跑完。4. 换 YOLOv5 / YOLOv9 / YOLO11跨版本适配与标签复用4.1 各版本对标签格式的兼容性这份数据的 YOLO txt 标签是通用格式YOLOv5、v7、v8、v9、v10、v11 都认。差异不在标签在训练入口和配置文件命名。YOLOv5 用data.yaml加--data参数YOLOv8 之后统一到yoloCLI 或者 Python API。VOC 那套 xml 在 YOLO 原生训练里用不上但转成 txt 后同样通用。版本训练入口配置文件标签格式YOLOv5train.pydata.yamlYOLO txtYOLOv7train.pydata.yamlYOLO txtYOLOv8yolo detect traindata.yamlYOLO txtYOLOv9train.py/yolodata.yamlYOLO txtYOLO11yolo detect traindata.yamlYOLO txt换版本时data.yaml基本不用动路径和类别对就行。YOLOv5 的data.yaml里多一个download字段可以忽略不影响本地训练。4.2 用 Python API 跑 YOLOv8 与 YOLO11命令行适合快速验证要嵌到自己的流水线里用 Python API 更灵活。from ultralytics import YOLO # 加载预训练权重换成 yolov8s.pt 或 yolo11s.pt 即可切换版本 model YOLO(yolov8s.pt) # 训练 results model.train( datadata.yaml, epochs100, imgsz640, batch32, device0, patience20, projectruns/train, namesmoke_api ) # 训练完直接在验证集上评估 metrics model.val() print(fmAP50: {metrics.box.map50:.4f}) print(fmAP50-95: {metrics.box.map:.4f})model.train()返回的结果对象里带训练指标model.val()单独跑验证。metrics.box.map50是 IoU 阈值 0.5 下的 mAPmetrics.box.map是 0.5 到 0.95 的平均后者更严格。烟盒这种形状规整、类内差异小的目标mAP50 通常能到 0.9 以上mAP50-95 会低一些0.6 到 0.75 算正常。如果 mAP50 高但 mAP50-95 很低说明框的位置不够准检查标注框是否贴合目标边缘。4.3 推理与导出从训练权重到可用模型训练完的权重在runs/train/smoke_api/weights/best.pt拿它做推理或者导出成部署格式。from ultralytics import YOLO model YOLO(runs/train/smoke_api/weights/best.pt) # 单图推理 results model(test.jpg, conf0.25, iou0.45) results[0].save(output.jpg) # 导出 ONNX方便后续部署 model.export(formatonnx, imgsz640, simplifyTrue)conf0.25是置信度阈值低于这个值的框不输出iou0.45是 NMS 的 IoU 阈值控制重叠框合并。烟盒密集摆放的场景iou可以适当调低到 0.4避免相邻烟盒被误合并。导出 ONNX 时simplifyTrue会做图优化部署到 TensorRT 或 OpenVINO 时更顺。5. 避坑与排查标签、路径、显存、过拟合的五个血泪经验5.1 训练启动报 No labels found现象训练脚本一启动就报No labels found in ...或者警告一堆图像被跳过。原因data.yaml里train路径指向的目录下没有labels子目录或者图像和标签的文件名对不上。YOLO 默认按「图像路径替换images为labels、后缀换成.txt」去找标签目录结构不匹配就找不到。解决确认images/train/和labels/train/同级文件名主干一致。用find对比两边文件名差集就是问题文件。5.2 坐标越界导致 loss 不降现象训练能跑但box_loss一直在高位震荡mAP 接近 0。原因标签里混入了绝对像素坐标或者归一化时除错了分母。YOLO 不会对越界坐标报错直接拿去算 loss梯度方向就乱了。解决跑第 2 章那段校验脚本把所有越界文件列出来重新归一化或者剔除。别指望模型自己学回来回归分支对错误标签很敏感。5.3 显存爆了但 batch 已经很小现象batch8还是CUDA out of memory。原因imgsz设太大或者开了ampFalse导致全精度训练。640 尺寸下batch8还爆多半是图像本身分辨率极高预处理阶段就占满显存。解决先把imgsz降到 416 或 320 跑通再逐步往上加。确认ampTrue默认开启混合精度能省不少显存。实在不够就换更小的模型n版比s版省显存。5.4 验证集 mAP 高但实际推理漏检现象val的 mAP50 有 0.9拿新图推理却漏掉很多烟盒。原因训练集和验证集划分时没有打散同一场景的图全进了训练集验证集也是类似场景指标虚高。或者验证集图像和训练集来自同一批拍摄分布太接近。解决检查划分是否按场景分层。如果数据里有多家门店、多种光照确保每个子集都覆盖。1134 张图不算多划分比例 8:2 比较稳别用 9:1 导致验证集太小、指标波动大。5.5 过拟合train loss 降 val loss 升现象训练到 30 轮左右train loss 继续降val loss 开始往上走mAP 停滞。原因数据量小、模型容量大、增强不够。1134 张图训l或x模型过拟合几乎是必然。解决换小模型加增强mosaic、mixup、hsv色调抖动开早停。YOLOv8 默认增强已经比较强如果还过拟合把dropout加上或者减层。别硬跑 300 轮过拟合之后的训练全是负收益。6. 进阶技巧用验证集反查标注质量与类别平衡训练跑通只是第一步这份数据真正的价值在于它能反过来帮你查标注质量。我一般会在正式训练前做一轮「标注体检」用验证集的推理结果和原始标签做比对把 IoU 低于阈值的样本挑出来人工复核。from ultralytics import YOLO import os model YOLO(runs/train/smoke_api/weights/best.pt) # 在验证集上跑推理保存每张图的预测结果 results model.val(datadata.yaml, save_jsonTrue) # 读回预测和真值算每张图的匹配情况 # save_json 会在 runs/val/ 下生成 predictions.json import json with open(runs/val/predictions.json) as f: preds json.load(f) # 统计预测框数量分布异常少或异常多的图重点看 from collections import Counter count_per_img Counter() for p in preds: count_per_img[p[image_id]] 1 # 打印框数最多和最少的图 sorted_imgs count_per_img.most_common() print(框最多:, sorted_imgs[:5]) print(框最少:, sorted_imgs[-5:])save_jsonTrue会把预测结果按 COCO 格式存下来方便和真值做匹配。框数异常多的图可能是把货架上的其他矩形物体误检成烟盒框数异常少的图可能是漏检或者标注本身漏标。把这两类图挑出来人工看一遍比盲目加数据有效。另一个技巧是查类别平衡。单类别数据集不存在类别不平衡但如果你后续要扩展成多类别比如区分品牌就得先看现有标注里各类的分布。用一行命令统计每个类别的框数# 统计所有标签文件里各类别的出现次数 cat labels/train/*.txt | awk {print $1} | sort | uniq -c | sort -rnawk {print $1}取每行第一个字段即类别索引uniq -c计数。如果某个类别只有几十个框扩展训练时就要针对性补数据否则模型对少数类基本没召回。最后说一个我自己的习惯每次拿到新数据集先跑 3 个 epoch 的冒烟测试确认 loss 在降、mAP 不是 0再动正式训练的参数。这个习惯帮我拦下过至少五次标签格式错误和路径配置问题省掉的卡时够跑好几轮完整实验。从那以后我每次接新数据都强制走一遍冒烟流程不跳步。希望帮到你。本文还有配套的精品资源点击获取
返回列表