简介:这份资源面向从事目标检测算法学习与工业质检应用开发的读者,提供一套按YOLOv5目录格式整理的香烟破损检测数据集,可直接投入训练,省去格式转换与标注清洗环节。数据聚焦香烟表面缺陷识别,共划分6个类别,涵盖头部破损、滤嘴破损等典型瑕疵,适合作为缺陷检测练手项目或算法对比实验的基准数据。压缩包共803个文件,以401个txt标注文件、401张jpeg图像和1个可视化py脚本为主,整体约388MB;其中训练集含320张图片及对应标签,验证集含80张图片及对应标签,图像为3024×4032大尺度RGB实拍图,细节丰富。配套脚本随机传入一张图片即可绘制边界框并保存到当前目录,无需修改即可运行,便于快速核验标注质量。目前已有139人学习下载,适合需要现成香烟破损检测数据、希望快速验证模型效果的目标检测学习者与工程人员。
1. 香烟破损检测数据集:6 类缺陷、YOLOV5 目录格式,拿到手怎么用
香烟包装表面的破损检测,在产线质检里是个很典型的细粒度目标检测问题。烟盒在高速传送带上跑,表面可能出现拉线断裂、盒角压溃、烫金磨损、透明膜褶皱、条码污损、内衬纸外露这几类缺陷,每一类的尺度、对比度、纹理都不一样。你如果打算用 YOLOV5 训练自己的数据集做这件事,第一个卡点往往不是模型结构,而是数据:标注格式对不对、类别定义清不清楚、训练集和验证集怎么切、目录结构能不能直接被train.py吃进去。
这个数据集标题里给的信息很明确——YOLOV5 目录格式、6 类别、包含训练集和验证集。它解决的是「从零标注一批香烟破损图片」这个最耗时的环节,让你把精力放在超参调优和部署上。适合两类人:一是做工业质检落地、需要快速验证 YOLOV5 在自己场景可行性的工程师;二是刚接触目标检测、想拿一个真实缺陷数据集跑通完整训练流程的人。下面我按「目录长什么样 → 怎么接进训练 → 参数怎么设 → 哪里会翻车」的顺序讲清楚。
2. YOLOV5 目录格式拆解:6 类香烟缺陷的标注文件到底长什么样
2.1 目录树与 images/labels 的对应关系
YOLOV5 官方推荐的目录结构是images和labels平行放置,训练集和验证集各自成对。香烟破损检测数据集如果按标准组织,展开后大致是这样:
cigarette_defect/ ├── images/ │ ├── train/ # 训练集图片,jpg/png │ │ ├── 0001.jpg │ │ └── ... │ └── val/ # 验证集图片 │ ├── 1001.jpg │ └── ... ├── labels/ │ ├── train/ # 与 train 图片同名的 txt │ │ ├── 0001.txt │ │ └── ... │ └── val/ │ ├── 1001.txt │ └── ... └── data.yaml # 数据集配置文件关键约束只有一条:labels/train/0001.txt必须和images/train/0001.jpg同名,只换扩展名。YOLOV5 的dataset.py在加载时会用图片路径反推标签路径,名字对不上就直接跳过这张图,而且默认不报错——这是新手最容易踩的静默失败。我一般拿到数据集先跑一遍文件名比对,确认没有孤儿图片或孤儿标签。
2.2 标注行格式:class x_center y_center width height
每个 txt 文件里,一行代表一个目标框,6 类别对应 class id 0 到 5。格式是归一化后的中心点坐标和宽高:
2 0.512 0.437 0.186 0.224 5 0.301 0.688 0.092 0.115第一列是类别索引,后四列全部除以图片的宽和高,落在 0 到 1 之间。这里有两个高频错误:一是有人直接写像素坐标,训练时 loss 会异常大甚至 NaN;二是 x_center 和 y_center 写反,模型学出来的框会整体偏移。香烟破损这类缺陷框通常偏小,宽高归一化后常在 0.05 到 0.3 之间,如果发现某类框普遍大于 0.5,基本可以判定标注时框选范围出了问题。
2.3 data.yaml 的六个类别名与路径配置
data.yaml是训练入口的配置核心,内容大致如下:
# 香烟破损检测数据集配置 path: ./cigarette_defect # 数据集根目录 train: images/train # 相对 path 的训练图片目录 val: images/val # 相对 path 的验证图片目录 nc: 6 # 类别数量,必须与 names 长度一致 names: 0: tear # 拉线断裂 1: corner_crush # 盒角压溃 2: gold_wear # 烫金磨损 3: film_wrinkle # 透明膜褶皱 4: barcode_stain # 条码污损 5: liner_expose # 内衬纸外露nc和names长度不一致时,YOLOV5 会在构建检测头时报维度错误。类别名建议用英文小写下划线,避免中文和空格,否则在部分版本的日志输出和可视化里会乱码。类别顺序一旦确定就不要改,因为标注文件里的 class id 是按这个顺序写的,改了顺序等于把所有标签打乱。
2.4 用脚本校验数据集完整性
拿到数据集后,我习惯先跑一段校验脚本,把类别分布、框尺寸分布、文件名匹配情况一次性看清楚:
import os from pathlib import Path from collections import Counter root = Path("./cigarette_defect") for split in ["train", "val"]: img_dir = root / "images" / split lbl_dir = root / "labels" / split imgs = {p.stem for p in img_dir.glob("*") if p.suffix.lower() in (".jpg", ".png")} lbls = {p.stem for p in lbl_dir.glob("*.txt")} # 找出有图无标签、有标签无图的情况 print(f"[{split}] 图片 {len(imgs)} 张, 标签 {len(lbls)} 个") print(f" 缺标签的图片: {len(imgs - lbls)}") print(f" 缺图片的标签: {len(lbls - imgs)}") cls_counter = Counter() box_areas = [] for lbl in lbl_dir.glob("*.txt"): for line in lbl.read_text().strip().splitlines(): parts = line.split() if len(parts) != 5: print(f" 格式异常: {lbl.name} -> {line}") continue c, x, y, w, h = int(parts[0]), *map(float, parts[1:]) cls_counter[c] += 1 box_areas.append(w * h) print(f" 类别分布: {dict(sorted(cls_counter.items()))}") if box_areas: print(f" 框面积 min/mean/max: {min(box_areas):.4f}/" f"{sum(box_areas)/len(box_areas):.4f}/{max(box_areas):.4f}")这段脚本做三件事:比对图片和标签的文件名集合,暴露孤儿文件;统计每个类别的框数量,判断是否存在严重类别不平衡;统计归一化框面积,判断标注尺度是否合理。参数上,root指向数据集根目录,split列表按实际存在的划分调整。如果某个类别在训练集里只有个位数样本,训练时几乎学不到,需要补样本或做增强。
3. 把数据集接进 YOLOV5 训练:从环境到首轮跑通的完整命令
3.1 环境配置与依赖版本选择
YOLOV5 对 PyTorch 和 CUDA 版本比较敏感,我一般用 conda 建独立环境,避免和系统里的其他项目打架:
conda create -n yolo5 python=3.9 -y conda activate yolo5 # 按本机 CUDA 版本装 PyTorch,这里以 CUDA 11.8 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 克隆 YOLOV5 仓库后安装依赖 git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txtPython 选 3.9 是因为它在 YOLOV5 各版本上兼容性最稳。PyTorch 版本要和显卡驱动匹配,装完用python -c "import torch; print(torch.cuda.is_available())"验证,返回 True 才算通。requirements 里的依赖不要随意升级,尤其是 numpy 和 opencv,版本跳太多容易在数据加载阶段报奇怪的错。
3.2 用 train.py 跑通第一轮训练
数据集和代码就位后,第一轮训练不要急着调参,先用小 epoch 确认整条链路能跑通:
python train.py \ --data ./cigarette_defect/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0 \ --project runs/train \ --name cigarette_v1--data指向刚才的 yaml;--weights用官方预训练权重做迁移学习,香烟缺陷样本通常几千张以内,从头训收敛慢且容易过拟合;--img 640是输入分辨率,缺陷框偏小时可以提到 960 或 1280,但显存占用会明显上升;--batch 16在 8G 显存上跑 640 分辨率比较稳,显存不够就降到 8 并配合--accumulate做梯度累积。第一轮建议--epochs 10先看 loss 曲线和验证指标是否正常下降,确认没问题再拉长。
3.3 训练日志里该盯哪几个指标
训练启动后,控制台和runs/train/cigarette_v1/下会输出大量信息,重点看四个:
| 指标 | 含义 | 异常信号 |
|---|---|---|
| box_loss | 边界框回归损失 | 持续不降,检查标注坐标是否归一化 |
| cls_loss | 分类损失 | 震荡剧烈,可能学习率偏高或类别不平衡 |
| mAP@0.5 | IoU 0.5 下的平均精度 | 长期低于 0.3,数据或标注有问题 |
| precision/recall | 查准率/查全率 | recall 极低,模型漏检严重 |
香烟破损检测里,烫金磨损和透明膜褶皱这两类对比度低、边界模糊,mAP 通常比其他类低一截,这是数据本身的难度,不一定是训练出问题。如果所有类别 mAP 都上不去,优先回头查标注,而不是加 epoch。
3.4 验证集评估与推理可视化
训练结束后用val.py做一次完整评估,再用detect.py看实际效果:
# 在验证集上评估,输出每类 AP python val.py --data ./cigarette_defect/data.yaml \ --weights runs/train/cigarette_v1/weights/best.pt \ --img 640 --task val # 对单张图或整个目录做推理,保存可视化结果 python detect.py --weights runs/train/cigarette_v1/weights/best.pt \ --source ./cigarette_defect/images/val \ --img 640 --conf 0.25 --save-txt--conf 0.25是置信度阈值,产线场景如果漏检代价高,可以降到 0.15 换更高 recall,代价是误检增多。--save-txt会把预测框按 YOLO 格式存下来,方便和真值做对比分析。我一般会挑几张误检和漏检的图单独看,判断是标注问题还是模型能力问题。
4. 香烟破损检测的调参与增强:6 类小目标怎么提 mAP
4.1 针对小缺陷框的输入分辨率与 anchor 调整
香烟破损的缺陷框普遍偏小,640 分辨率下有些框只有十几个像素,特征图到 P3 层已经很难保留细节。两个方向:一是把--img提到 960 或 1280,让缺陷占据更多像素;二是检查 anchor 是否匹配。YOLOV5 默认 anchor 是基于 COCO 聚类的,对香烟这种小框未必最优,可以用train.py里的--noautoanchor关闭自动锚框,再手动跑 k-means 聚类:
# 用数据集真值框重新聚类 anchor,输出 9 组建议值 python utils/autoanchor.py --data ./cigarette_defect/data.yaml --img 960聚类结果里偏小的那几组 anchor 如果和默认值差距大,就手动写进模型配置。分辨率提升后 batch 要相应减小,否则显存直接爆。
4.2 数据增强参数的取舍:mosaic 与 mixup 的边界
YOLOV5 默认开启 mosaic 增强,把四张图拼成一张,对小目标检测帮助明显。但香烟破损场景有个坑:mosaic 拼接后,不同烟盒的缺陷可能被拼到同一张图里,模型会学到一些不真实的上下文关系。如果验证集 mAP 波动大,可以调低 mosaic 概率:
# 在 hyp 配置文件里调整增强强度 mosaic: 0.5 # 默认 1.0,降到 0.5 减少拼接 mixup: 0.0 # 香烟缺陷不建议开 mixup,容易产生不合理叠加 copy_paste: 0.1 # 小目标复制粘贴增强,适度开启 degrees: 5.0 # 旋转角度,产线烟盒方向固定可调小 hsv_h: 0.015 # 色调扰动,烫金类缺陷对颜色敏感,别调太大hsv_h对烫金磨损这类靠颜色区分的缺陷影响很大,调太大会让模型把正常烫金误判成磨损。我一般把色调扰动控制在 0.015 以内,饱和度和亮度扰动可以稍大。
4.3 类别不平衡时的损失权重与采样策略
6 类缺陷在真实数据里分布往往不均,拉线断裂可能几百个框,内衬纸外露只有几十个。直接训练会让模型偏向多数类。处理方式有三种:一是对少数类做离线过采样,复制图片并配合增强;二是在hyp里调cls损失权重;三是用--balance类的采样策略(部分 YOLOV5 分支支持)。最稳妥的还是补数据,过采样容易让少数类过拟合。判断是否不平衡,看第 2 章校验脚本输出的类别分布,如果最多和最少差 10 倍以上,就得处理。
4.4 学习率与 warmup 的设置经验
YOLOV5 默认用余弦退火加 warmup,--lr0是初始学习率,--lrf是最终学习率比例。香烟破损数据集规模通常不大,lr0设 0.01 容易震荡,我一般降到 0.005 到 0.008。warmup 的 epoch 数保持默认 3 即可,太少会让前期 loss 爆掉。如果训练曲线前期剧烈抖动,先降lr0,再考虑加--warmup_epochs。
5. 避坑与排查:香烟破损数据集训练中最容易翻车的 5 个点
5.1 现象:训练启动即报「No labels found」
原因:data.yaml里的train/val路径写错,或者 labels 目录名不是labels。YOLOV5 会按images替换成labels去找,路径里带多余层级就找不到。
解决:用绝对路径先排除相对路径歧义,确认images/train同级存在labels/train,且 txt 文件名和图片名完全一致(包括大小写)。
5.2 现象:loss 正常下降但 mAP 始终接近 0
原因:标注坐标没归一化,或者 x_center/y_center 写反。loss 能降是因为模型在拟合错误的坐标分布,但预测框和真值框 IoU 极低。
解决:抽查几个 txt,确认后四列都在 0 到 1 之间;用第 2 章的校验脚本看框面积分布,如果普遍大于 1 就是没归一化。
5.3 现象:某一类缺陷完全检测不到
原因:该类样本太少,或者该类标注的 class id 和data.yaml里的 names 顺序对不上。
解决:先看类别分布统计,确认该类框数量;再核对标注文件里该类的 id 是否和 yaml 一致。顺序错位是高频问题,尤其是多人协作标注时。
5.4 现象:验证集 mAP 高但实际推理漏检严重
原因:训练集和验证集图片来自同一批次、同一光照条件,验证集不能代表真实分布。或者验证集里缺陷样本和训练集高度相似,存在数据泄漏。
解决:按时间、批次或光照条件划分训练验证集,确保验证集覆盖真实场景的多样性。如果数据集本身划分固定,至少人工检查验证集图片是否和训练集有明显重复。
5.5 现象:显存溢出(CUDA out of memory)
原因:--img或--batch设太大,或者 mosaic 增强在内存里拼图时占用翻倍。
解决:优先降 batch,再考虑降 img;也可以用--accumulate用小 batch 模拟大 batch。如果只是偶尔溢出,检查是否有其他进程占用显存。
6. 从能跑到好用:香烟破损检测的推理阈值与部署前验证技巧
训练出 best.pt 只是第一步,真正上线前还有几件事要做。第一是确定推理阈值。产线质检对漏检和误检的容忍度不同,如果漏检一个破损烟盒的代价远高于误检,就把--conf降到 0.15 甚至 0.1,同时用--iou控制 NMS 的合并强度,避免同一缺陷出多个框。我一般会在验证集上画一条 precision-recall 曲线,找到 recall 0.95 对应的 conf 值作为上线阈值,而不是拍脑袋定 0.25。
第二是验证模型对输入尺寸的鲁棒性。训练用 640,推理如果也用 640 最稳,但产线相机分辨率可能更高。直接放大输入会让小缺陷变大、可能提 recall,但也可能因为尺度不匹配掉点。稳妥做法是训练和推理用同一 img 尺寸,或者用--img多尺度测试,看哪个尺寸在验证集上综合指标最好。
第三是导出和速度验证。YOLOV5 支持导出 ONNX、TensorRT 等格式,导出后用val.py再跑一遍,确认精度没有明显掉点。香烟产线节拍快,推理延迟要卡在预算内,TensorRT FP16 通常能比 PyTorch 快 2 到 3 倍,但要注意 FP16 对烫金磨损这类低对比度缺陷可能有精度损失,导出后必须重新评估。
# 导出 ONNX 并做一次精度复核 python export.py --weights runs/train/cigarette_v1/weights/best.pt \ --include onnx --img 640 --dynamic # 用导出的模型在验证集上复核 mAP python val.py --data ./cigarette_defect/data.yaml \ --weights runs/train/cigarette_v1/weights/best.onnx \ --img 640 --task val最后说个我自己的习惯:每次换数据集版本或改标注,都重新跑一遍第 2 章的校验脚本,把类别分布和框尺寸分布存成快照。香烟破损检测这类项目,模型结构基本不用动,真正决定效果的是数据质量和标注一致性。我踩过最深的坑就是改了一批标注后没重新校验,训练了两天才发现某类 id 整体错位,白跑。希望帮到你。
本文还有配套的精品资源,点击获取