YOLO烟盒检测实战:1134张带标签数据集训练与调优指南
发布时间:2026/9/28 9:22:00来源:尧图网络
简介这是一份面向YOLO系列算法目标检测训练与验证的烟盒数据集适合正在做目标识别项目、准备课程设计或算法对比实验的开发者与学习者使用。数据集已按训练与验证需求划分完毕并附带data.yaml配置文件可直接接入yolov5、yolov7、yolov8、yolov9、yolov10及yolo11等主流框架省去自行标注与划分的繁琐流程。压缩包共约109.43MB内含2000个文件其中1018个xml文件对应VOC格式标注982个txt文件对应YOLO格式标注两种标签体系分别存放便于按需选用YOLO格式采用类别索引与归一化中心点、宽高坐标符合标准训练输入规范。目前已有130人学习关注说明该数据集在烟盒检测这一细分场景中具备一定参考价值。读者拿到后可直接用于模型训练、精度验证与算法横向对比也能借助双格式标签快速完成数据格式转换与增强实验适合作为目标检测入门到进阶的实战素材。1. 烟盒数据集与 YOLO 检测1134 张图像带标签到底能跑出什么手上拿到一个yolo算法-烟盒数据集-1134张图像带标签.zip第一反应通常不是兴奋而是先掂量1134 张够不够、标签是什么格式、能不能直接喂给 YOLOv8 训练、训完能不能落地到产线或零售场景。烟盒检测这个题目看着小众实际是典型的「小目标 密集堆叠 类间差异小」组合零售盘点、烟草专卖稽核、自动结算台都用得上属于那种数据集不大但业务价值明确的活儿。这个数据集的核心价值在于「带标签」三个字——省掉了最耗人力的标注环节。1134 张图像在 YOLO 体系里属于小规模数据集但烟盒目标通常尺寸大、轮廓规整、背景相对可控所以只要划分合理、增强到位mAP 跑到 0.85 以上并不玄学。它适合三类人想练手 YOLO 完整流程的新手、需要快速验证烟盒识别可行性的产品同学、以及手里有类似小数据集想找复现路径的工程师。需要先泼一盆冷水1134 张不是让你直接开训就完事划分、格式转换、类别平衡、增强策略每一步都会决定最终能不能用。下面按「先立住原理、再动手复现、最后避坑」的顺序拆开讲读完你应该能自己把这个 zip 跑成一份可用的检测模型。2. 拆开 zip 先看什么目录结构、标签格式与类别分布拿到压缩包别急着解压完就train先花十分钟把数据摸清楚这一步省下来的时间后面会加倍还给你。2.1 解压后先确认三件事图像、标签、类别名常见做法是解压到一个干净目录然后跑一段脚本统计文件数量、后缀、标签行数和类别 id 分布。烟盒数据集一般有两种组织方式一种是images/和labels/平行目录另一种是图像和同名.txt放一起。先确认属于哪种不然后面路径全错。# 解压并查看顶层结构 unzip yolo算法-烟盒数据集-1134张图像带标签.zip -d smoke_dataset cd smoke_dataset find . -maxdepth 2 -type d | sort # 统计图像数量与后缀分布 find . -type f \( -iname *.jpg -o -iname *.png -o -iname *.jpeg \) | wc -l find . -type f -iname *.txt | wc -l这段命令先看目录层级再数图像和标签文件数量。如果图像 1134 张、标签也是 1134 个说明一一对应如果标签数量对不上多半有图像没标或标签命名不匹配必须先修。后缀分布决定后面img_formats要不要改YOLO 默认吃 jpg/png遇到 bmp、webp 要提前转。2.2 标签是 YOLO txt 还是 VOC xml决定要不要转换YOLO 训练只认归一化的 txt 格式每行class_id x_center y_center width height坐标都是 0~1 的相对值。如果解压出来是Annotations/*.xml那就是 VOC 格式得先转。判断方法很简单随便打开一个标签文件看第一行。import os, glob label_dir smoke_dataset/labels txt_files glob.glob(os.path.join(label_dir, *.txt)) print(标签文件数:, len(txt_files)) # 抽查前 3 个文件看格式和类别 id for f in txt_files[:3]: with open(f) as fp: lines fp.read().strip().splitlines() print(os.path.basename(f), 行数:, len(lines)) for line in lines[:2]: parts line.split() print( , parts, 字段数:, len(parts))正常 YOLO 标签每行 5 个字段第一个是整数类别 id后四个是 0~1 浮点。如果字段数是 5 但坐标出现大于 1 的值说明是绝对坐标没归一化得除以图像宽高。如果字段数不是 5可能是分割标签多边形或带置信度的旧格式要单独处理。这一步不查清楚训练时 loss 会直接 NaN 或者 mAP 恒为 0属于典型翻车点。2.3 类别分布统计烟盒数据集最容易踩的坑烟盒数据集常见问题是类别不平衡——某个品牌几百个框某个品牌只有十几个。类别 id 和名称的映射一般在classes.txt或data.yaml里先读出来再统计每个类别的框数量。from collections import Counter import glob, os counter Counter() for f in glob.glob(smoke_dataset/labels/*.txt): with open(f) as fp: for line in fp: line line.strip() if line: counter[int(line.split()[0])] 1 total sum(counter.values()) print(总框数:, total) for cid, cnt in sorted(counter.items()): print(f类别 {cid}: {cnt} 框, 占比 {cnt/total:.2%})统计结果直接决定后面增强策略和是否要重采样。如果最小类别占比低于 2%训练时几乎必然被大类别压制要么做过采样要么在 loss 里加类别权重。烟盒这种场景还常见「一图多框」平均每图框数也要算一下低于 1.5 说明图像里目标稀疏增强时要注意别把仅有的目标裁掉。3. 从 zip 到可训练划分、转换与 data.yaml 配置数据摸清楚之后进入真正动手环节。这一章的目标是产出一份 YOLO 能直接吃的目录结构和配置文件。3.1 按 8:1:1 划分并保持类别均衡小数据集划分最怕随机切完验证集里某个类别一个样本都没有。稳妥做法是按类别分层抽样保证 train/val/test 里每个类别都有代表。下面脚本按图像维度划分同时打印每个集合的类别分布做校验。import os, glob, random, shutil from collections import defaultdict random.seed(42) img_dir smoke_dataset/images lbl_dir smoke_dataset/labels out_root dataset_yolo # 收集图像并按主类别分组取该图第一个框的类别作为分层依据 img2cls {} for img in glob.glob(os.path.join(img_dir, *)): stem os.path.splitext(os.path.basename(img))[0] lbl os.path.join(lbl_dir, stem .txt) if not os.path.exists(lbl): continue with open(lbl) as fp: first fp.readline().strip() if first: img2cls[img] int(first.split()[0]) groups defaultdict(list) for img, c in img2cls.items(): groups[c].append(img) splits {train: 0.8, val: 0.1, test: 0.1} for c, imgs in groups.items(): random.shuffle(imgs) n len(imgs) n_train int(n * 0.8) n_val int(n * 0.1) assign ([train] * n_train [val] * n_val [test] * (n - n_train - n_val)) for img, sp in zip(imgs, assign): stem os.path.splitext(os.path.basename(img))[0] for sub in [images, labels]: os.makedirs(os.path.join(out_root, sp, sub), exist_okTrue) shutil.copy(img, os.path.join(out_root, sp, images, os.path.basename(img))) shutil.copy(os.path.join(lbl_dir, stem .txt), os.path.join(out_root, sp, labels, stem .txt)) print(划分完成)关键参数是random.seed(42)固定种子保证可复现分层依据取「第一个框的类别」对单类别烟盒数据集足够多类别且一图多类时建议改成主类别或做多标签分层。划分完一定要再跑一遍 2.3 的统计脚本分别看 train/val/test 的类别分布发现某个集合缺类就调整比例或重新抽样。3.2 写对 data.yaml路径、类别数与名称YOLOv8 训练靠data.yaml找数据路径写错是最常见的「训练启动即报错」。文件里path是根目录train/val是相对路径nc是类别数names是类别名列表顺序必须和标签里的 id 对应。path: /abs/path/to/dataset_yolo train: train/images val: val/images test: test/images nc: 1 names: 0: cigarette_pack如果烟盒数据集区分品牌nc就要改成实际类别数names按 id 顺序列全。注意path建议写绝对路径相对路径在不同工作目录下启动训练时行为不一致属于血泪经验。改完 yaml 用一行命令验证路径可达python -c import yaml; dyaml.safe_load(open(data.yaml)); import os; print(os.path.exists(os.path.join(d[path], d[train])))输出True才继续False就回去检查路径拼接。3.3 用 YOLOv8 跑通第一次训练最小命令与参数含义第一次训练不要调花哨参数先用默认配置跑通确认 loss 能降、mAP 能涨再谈优化。下面是最小可跑命令。yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ projectruns/smoke \ namebaseline \ seed42modelyolov8n.pt用 nano 版本1134 张图用大模型容易过拟合n 或 s 足够。imgsz640是默认输入尺寸烟盒目标如果普遍偏小可以提到 800但显存和速度要权衡。batch16在 8G 显存上比较稳爆显存就降到 8。epochs100对小数据集通常够配合早停。seed42保证可复现。训练启动后重点看三个信号box_loss 是否稳定下降、mAP50 是否在 30 epoch 后明显抬头、val 的 cls_loss 是否远高于 train过拟合信号。4. 训练参数怎么调小数据集上的增强、学习率与早停跑通 baseline 只是起点1134 张的规模决定了增强和正则化是提分主力这一章讲清楚每个参数为什么这么设。4.1 增强参数小数据集的分数主要靠这里YOLOv8 内置增强通过命令行或 yaml 传参。烟盒场景目标规整、方向固定增强要克制过度几何变换反而伤性能。参数建议值作用与理由mosaic1.0四图拼接小数据集提分明显但烟盒堆叠场景后期可降到 0.5close_mosaic20最后 20 epoch 关闭 mosaic让模型适应真实分布hsv_h0.015色调抖动烟盒颜色是重要特征别调大hsv_s0.7饱和度抖动模拟不同光照hsv_v0.4明度抖动应对曝光差异degrees0.0烟盒基本水平摆放旋转增强收益低translate0.1平移模拟目标位置变化scale0.5缩放应对不同拍摄距离fliplr0.5水平翻转烟盒左右对称安全flipud0.0垂直翻转不符合真实场景关掉命令行追加方式yolo detect train datadata.yaml modelyolov8n.pt epochs150 imgsz640 batch16 \ mosaic1.0 close_mosaic20 hsv_h0.015 hsv_s0.7 hsv_v0.4 \ degrees0.0 translate0.1 scale0.5 fliplr0.5 flipud0.0 \ projectruns/smoke nameaug seed42close_mosaic20容易被忽略但它是小数据集从「增强态」平滑过渡到「真实态」的关键不设的话验证指标会虚高。degrees0和flipud0是烟盒场景的针对性选择通用数据集教程里常开这里关掉更合理。4.2 学习率与优化器别用默认值硬跑YOLOv8 默认lr00.01、lrf0.01、优化器 auto。小数据集上lr0偏大容易震荡建议降到 0.005 左右配合余弦退火。yolo detect train datadata.yaml modelyolov8n.pt epochs150 imgsz640 batch16 \ lr00.005 lrf0.01 optimizerSGD momentum0.937 weight_decay0.0005 \ warmup_epochs3 warmup_momentum0.8 cos_lrTrue \ projectruns/smoke namelr_tuned seed42warmup_epochs3让前 3 个 epoch 学习率从低爬升避免一开始就大步长破坏预训练权重。cos_lrTrue开启余弦退火后期学习率平滑下降收敛更稳。weight_decay0.0005是轻量正则小数据集上别加大否则欠拟合。如果训练曲线前期就剧烈震荡先把lr0再砍半。4.3 早停与模型选择patience 和 save_period 怎么设小数据集训练最怕过拟合早停是后悔药。YOLOv8 用patience控制连续多少 epoch 验证指标不涨就停。yolo detect train datadata.yaml modelyolov8n.pt epochs300 imgsz640 batch16 \ patience30 save_period10 \ projectruns/smoke nameearly_stop seed42patience30表示 30 个 epoch 内 mAP 没提升就停配合epochs300上限实际通常 120~180 就停。save_period10每 10 epoch 存一次权重方便回看中间状态也防止训练中断全丢。训练结束后runs/smoke/early_stop/weights/下会有best.pt和last.pt部署用best.pt续训用last.pt。判断是否过拟合看results.csv里 train 和 val 的 loss 曲线是否分叉分叉明显就是过拟合回去加大增强或减模型容量。5. 避坑与排查烟盒数据集训练中最容易翻车的 5 个点这一章全是踩过的坑按「现象 → 原因 → 解决」写遇到对应症状直接对号入座。5.1 训练启动报「No labels found」现象命令跑起来几秒就退出日志提示找不到标签或nc不匹配。原因通常是data.yaml里path写的是相对路径而训练时工作目录变了或者标签目录名不是labelsYOLO 按约定找不到。解决把path改成绝对路径确认train/images和train/labels同级且文件名 stem 一致。跑一遍 3.2 的路径校验命令True再训。5.2 mAP 一直是 0 或极低现象训练 loss 在降但 mAP50 长期低于 0.05。原因多半是标签坐标没归一化或者类别 id 从 1 开始而names从 0 开始错位了。解决抽查标签文件确认坐标都在 0~1确认classes.txt里 id 是 0 起。如果是 VOC 转来的检查转换脚本有没有除以宽高。这个坑最隐蔽因为 loss 看起来正常但模型学的是错误目标。5.3 验证集指标虚高实际推理一塌糊涂现象val mAP 0.9拿真实照片一测全是漏检。原因是 mosaic 增强全程开启验证时也带增强指标虚高或者 train/val 划分时同一张图的增强版本泄漏到了验证集。解决设close_mosaic20确保验证用原始图像划分时按图像而非按框划分同一图的所有框只能进一个集合。推理时用yolo detect predict跑几张真实图目测别只看数字。5.4 显存爆了或训练速度异常慢现象CUDA out of memory或者一个 epoch 跑十几分钟。原因是batch或imgsz太大或者 dataloader 的workers设太高导致 CPU 瓶颈。解决batch从 16 降到 8 或 4imgsz从 640 降到 512workers设成 CPU 核数的 0.7 倍左右Windows 上设 0 或 2 避免多进程问题。用nvidia-smi看显存占用留 10% 余量。5.5 小类别几乎检不出现象大品牌烟盒检得准稀有品牌全漏。原因是类别不平衡小类别框数太少被压制。解决先按 2.3 统计确认不平衡程度轻度不平衡靠增强和cls损失权重缓解重度不平衡要做过采样——把含小类别的图像复制多份进 train或训练时用fraction配合自定义采样器。YOLOv8 没有直接的类别权重参数过采样是最实用的手段。6. 训完之后验证、导出与一个提点的小技巧训练结束不是终点验证和导出决定模型能不能真正用起来。先在验证集上跑一次标准评估拿到 mAP50、mAP50-95、precision、recall 四个数。yolo detect val modelruns/smoke/early_stop/weights/best.pt datadata.yaml imgsz640重点看混淆矩阵和 PR 曲线混淆矩阵能告诉你哪些类别互相误判PR 曲线能看出 recall 高时 precision 掉得多不多。烟盒场景如果 precision 高 recall 低说明漏检多回去降置信度阈值或加数据recall 高 precision 低说明误检多提高阈值或清理标签噪声。导出部署格式按目标平台选# ONNX通用部署 yolo export modelruns/smoke/early_stop/weights/best.pt formatonnx imgsz640 # TensorRTNVIDIA 边缘设备 yolo export modelruns/smoke/early_stop/weights/best.pt formatengine halfTrue imgsz640halfTrue用 FP16 推理速度提升明显精度损失通常可接受但要在验证集上复测确认掉点不超过 1%。ONNX 适合跨平台TensorRT 适合 Jetson 这类边缘盒子。最后分享一个提点的小技巧用训练好的模型对训练集做一次推理把高置信度但漏检的图挑出来人工补标再微调一轮。1134 张的规模补标几十张就能让 mAP 再涨 2~3 个点比调参划算得多。具体做法是yolo detect predict跑 train 集导出每张图的检测结果和原标签比对找出「有标签但模型没检出」的图优先补这些。这个习惯我每做一个新数据集都会跑一遍属于投入产出比最高的操作。我自己做烟盒这类小数据集最大的教训是别一上来就换大模型、调复杂参数先把数据摸清楚、划分做对、增强设合理baseline 往往就已经能用了。1134 张不多但用对了足够撑起一个可落地的检测方案。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网