首页 / 资讯中心 / 文章详情

吸烟数据集实战:991张图片与YOLOv8训练全流程

吸烟数据集实战:991张图片与YOLOv8训练全流程 ★ FEATURED ARTICLE
简介这份吸烟行为检测数据集面向计算机视觉方向的目标检测学习者与算法开发者可用于训练和验证吸烟、抽烟场景下的识别模型适合课程设计、毕业项目或算法对比实验等用途。资源包共收录1983个文件其中991张jpg原始图片与991个txt标注文件一一对应标注采用yolov8格式另附1个yaml配置文件用于定义数据集路径与类别信息压缩包整体约44.7MB结构规整、开箱即用。据描述基于该数据集训练的平均识别率可达88.3%可作为吸烟检测任务的基线参考。目前已有110人学习下载。图片覆盖多种吸烟姿态与场景标注文件可直接接入YOLO系列训练流程省去自行采集与标注的成本帮助读者快速搭建数据管线、复现检测效果并在此基础上做模型调优与精度对比。1. 吸烟数据集落地991 张原始图片与 88.3% 识别率的真实边界手上这个吸烟数据集第一次看到「991 张原始图片、平均识别率 88.3%、yolov8 格式标注」这三个数字摆在一起时我的第一反应不是兴奋而是先算了一笔账。991 张图如果按 8:1:1 切分验证集不到 100 张单类目标检测任务里这个量级属于「能跑通、能出活但别指望它扛住复杂场景」的档位。它适合谁适合做吸烟行为识别原型验证的算法同学、需要快速搭一个抽烟检测 demo 的工程团队以及拿它当 yolov8 训练自己数据集练手素材的新手。不适合谁不适合直接拿去上生产做高精度合规检测也不适合指望它覆盖多角度、多光照、多遮挡的开放场景。这份资源的核心价值在于标注格式已经是 yolov8 可直接吃的 txt 结构省掉了从 VOC、COCO 转格式那一步最容易翻车的环节991 张图的体量也刚好够在一张消费级显卡上把完整训练流程走一遍。下面我按「先搞懂它是什么 → 再动手复现 → 最后说清楚坑在哪」的顺序拆开讲。2. 数据集结构与 yolov8 标注格式先看清 991 张图到底给了什么2.1 目录组织与文件命名规律从项目正文给出的文件名看图片命名有两类一类是纯数字加_jpg.rf.加一串哈希比如1277_jpg.rf.9c8828412f0497d36739ffc3e4553b84.jpg另一类是带连字符的编号比如1000-10-_jpg.rf.c26c21d03f55d5e9ded35bb9d1955f12.jpg。这个rf.加 32 位十六进制哈希的命名风格是 Roboflow 导出数据集时的典型特征说明这份数据大概率是从标注平台直接导出的成品包而不是手工整理的原始文件夹。这种命名对训练本身没影响但对排查问题有影响哈希名不可读你没法从文件名判断这张图是室内还是室外、是近景还是远景。所以拿到手第一件事不是急着训练而是先把图片和标签配对检查一遍。常见做法是写个脚本统计图片数和标签数是否一致再抽查几张可视化看看框的位置对不对。import os from pathlib import Path img_dir Path(datasets/smoking/images/train) lbl_dir Path(datasets/smoking/labels/train) imgs {p.stem for p in img_dir.glob(*.jpg)} lbls {p.stem for p in lbl_dir.glob(*.txt)} # 图片有但标签缺失或标签有但图片缺失都会让训练报错或静默丢样本 missing_lbl imgs - lbls missing_img lbls - imgs print(f图片总数: {len(imgs)}, 标签总数: {len(lbls)}) print(f缺标签的图片: {len(missing_lbl)}) print(f缺图片的标签: {len(missing_img)})这段脚本的逻辑很直接用stem去掉扩展名的文件名做集合运算。参数上唯一要注意的是img_dir和lbl_dir的路径要按你实际解压后的结构改。如果missing_lbl不为零训练时 yolov8 默认会跳过这些图你不会收到明显报错但实际参与训练的样本数就少了这是很多人训完发现 mAP 对不上预期的隐藏原因。2.2 yolov8 标签格式逐字段拆解yolov8 的检测标签是每张图对应一个同名.txt每行一个目标格式是class_id x_center y_center width height五个字段全部归一化到 0~1 之间。这里有两个新手最容易搞错的点第一x_center和y_center是框中心点坐标不是左上角第二width和height是框的宽高不是右下角坐标。如果你从 VOC 的xmin ymin xmax ymax直接搬过来必须做转换否则框会整体偏移甚至跑到图外。字段含义取值范围常见错误class_id类别索引从 0 开始整数写成类别名而非数字x_center框中心 x / 图宽0~1误填左上角 xy_center框中心 y / 图高0~1误填左上角 ywidth框宽 / 图宽0~1误填右下角 xheight框高 / 图高0~1误填右下角 y吸烟检测通常是单类任务也就是class_id恒为 0。如果你后续想区分「手持烟」「嘴叼烟」「烟雾」等子类就得重新标注并调整nc参数不能指望这份单类标注直接扩展。2.3 用可视化脚本验证标注质量在正式训练前我一般会抽 20 张图把框画出来看一眼。这一步花不了几分钟但能提前发现框偏移、漏标、类别错乱等问题比训到一半才发现强得多。import cv2 import random from pathlib import Path img_dir Path(datasets/smoking/images/train) lbl_dir Path(datasets/smoking/labels/train) for img_path in random.sample(list(img_dir.glob(*.jpg)), 20): img cv2.imread(str(img_path)) h, w img.shape[:2] lbl_path lbl_dir / f{img_path.stem}.txt if not lbl_path.exists(): continue with open(lbl_path) as f: for line in f: cid, xc, yc, bw, bh map(float, line.split()) # 反归一化回像素坐标 x1 int((xc - bw / 2) * w) y1 int((yc - bh / 2) * h) x2 int((xc bw / 2) * w) y2 int((yc bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(fvis_{img_path.name}, img)关键在反归一化那四行先减半个宽高得到左上角再加整个宽高得到右下角最后乘回图像尺寸。跑完打开vis_开头的图如果框都稳稳套在烟或抽烟动作上说明标注可用如果框整体偏一个方向多半是归一化时用错了图宽图高或者标注时用的尺寸和实际图片尺寸不一致。3. 从零跑通 yolov8 训练环境、配置与 88.3% 识别率的复现路径3.1 环境配置与依赖版本选择yolov8 现在统一走ultralytics这个包不再像 yolov5 那样克隆仓库改代码。环境配置本身不复杂但版本组合有讲究。我一般会固定 Python 3.9 或 3.10PyTorch 选和 CUDA 匹配的版本ultralytics用较新的稳定版即可。conda create -n smoke python3.10 -y conda activate smoke # 根据你的 CUDA 版本去 PyTorch 官网选对应命令这里以 CUDA 11.8 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics opencv-python参数说明python3.10是兼容性比较稳的选择PyTorch 的 index-url 一定要和你机器上的 CUDA 对齐装错了会退化成 CPU 训练速度差几十倍。装完用python -c import torch; print(torch.cuda.is_available())验证输出True才算过关。这一步翻车的人不少血泪经验是别用pip install torch裸装它默认可能给你 CPU 版。3.2 data.yaml 配置与路径陷阱yolov8 训练靠一个data.yaml描述数据位置和类别。这份吸烟数据集是单类配置很简洁path: /abs/path/to/datasets/smoking train: images/train val: images/val nc: 1 names: [smoking]这里最大的坑是path必须写绝对路径train和val写相对path的子路径。很多人写成相对当前工作目录的路径结果训练启动时报「找不到图片」。另外names的顺序就是class_id的映射单类时只有smoking对应 0别多加空格或中文yaml 对缩进和引号敏感。如果你的验证集是单独切出来的确保images/val和labels/val成对存在。3.3 训练命令与关键超参设置配置好之后一条命令就能起训yolo detect train \ datadatasets/smoking/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/smoke \ nameexp1逐个说参数modelyolov8n.pt用 nano 版991 张图这个量级用大模型容易过拟合n 版性价比最高epochs100配合patience20意思是 20 轮验证指标不涨就早停避免无效训练imgsz640是默认输入尺寸如果你的图里烟的目标很小可以提到 960 但显存占用会上升batch16在 8G 显存上比较稳显存不够就降到 8。lr00.01是初始学习率小数据集不建议调太大否则 loss 震荡。训练过程中重点看两个东西一是mAP50和mAP50-95的曲线二是train/box_loss和val/box_loss的分离程度。如果训练 loss 一直降但验证 loss 早早抬头就是过拟合信号这时候要么加数据增强要么减模型容量。88.3% 这个识别率大概率指的是mAP50或某种场景下的准确率具体口径要以你复现时的验证结果为准别默认它等于mAP50-95。3.4 推理验证与结果解读训完在验证集上跑一遍yolo detect val \ modelruns/smoke/exp1/weights/best.pt \ datadatasets/smoking/data.yaml \ imgsz640输出会给出每类的 precision、recall、mAP50、mAP50-95。单类任务重点看 recall因为漏检一个抽烟行为往往比误检代价高。如果 recall 明显低于 precision说明模型偏保守可以适当降低推理时的conf阈值。想直观看点检效果用yolo detect predict指定一张图或一个文件夹输出图会画好框。这里提醒一句验证集指标好看不代表真实场景好用991 张图的验证集本身就有随机性多跑几次不同切分才能看出稳定性。4. 避坑与排查这份吸烟数据集最容易翻车的五个地方4.1 训练报「No labels found」现象启动训练后日志里出现No labels found或者WARNING: corrupt image/label训练照跑但 mAP 一直是 0。原因九成是路径问题。data.yaml里的path没写绝对路径或者train指向的目录下只有图片没有同名 txt又或者图片和标签被放在了同一层但 yolov8 期望的是images/和labels/平行结构。解决先用第 2.1 节的配对脚本确认图片和标签数量一致再检查目录结构是不是images/train配labels/train。yolov8 找标签的规则是把路径里的images替换成labels所以目录名不能随便改。4.2 显存溢出导致训练中断现象训练跑了几十轮突然CUDA out of memory或者一开始就报错起不来。原因batch或imgsz设太大或者没开混合精度。991 张图虽然不大但 640 分辨率下 batch16 在 6G 显存卡上就可能吃紧。解决优先降batch到 8 或 4其次考虑imgsz512。也可以在训练命令里加ampTrue开自动混合精度显存占用能降一截。别一上来就换大显存卡先把参数调合理。4.3 识别率远低于 88.3%现象自己训完 mAP50 只有 70% 出头和标称的 88.3% 差一大截。原因数据切分方式不同、随机种子不同、模型规模不同都会造成差异。另外如果验证集里混入了训练集图片数据泄漏指标会虚高反过来如果验证集切得太难指标会偏低。解决固定随机种子用相同的切分比例多跑几次取平均。确认验证集和训练集没有重叠。如果还是低检查标注质量用 2.3 节的可视化脚本抽查看有没有大量漏标或框偏移。88.3% 是一个参考值不是保证值。4.4 推理时框位置整体偏移现象预测出来的框系统性偏左上或偏右下或者框比实际目标大一圈。原因训练时的imgsz和推理时的imgsz不一致或者图片在预处理时被拉伸而非等比例缩放导致归一化坐标还原时出错。解决训练和推理保持相同的imgsz。yolov8 默认会做 letterbox 等比例填充一般不用手动改但如果你自己写了预处理代码要确保和训练时一致。用 2.3 节的反归一化逻辑对照检查一遍。4.5 单类数据集误加多类配置现象data.yaml里nc写了大于 1 的值或者names里列了多个类别训练不报错但结果混乱。原因直接套用了其他多类数据集的配置文件忘了这份吸烟数据是单类。解决确认nc: 1names: [smoking]。如果标签文件里出现了大于 0 的class_id说明标注有问题需要回去检查标注源文件。单类任务里任何非 0 的类别索引都会被当成无效或错误类别处理。5. 进阶技巧把 991 张图的价值榨干数据量不大时提升效果的关键不在换模型而在把现有数据用足。我一般会从三个方向下手。第一是数据增强yolov8 内置了 mosaic、mixup、HSV 抖动等增强默认开启一部分但你可以针对吸烟场景调参抽烟动作常出现在室内弱光环境适当加大hsv_v的扰动范围能提升暗光鲁棒性烟的目标偏小mosaic对小目标友好保持默认 1.0 即可。第二是交叉验证991 张图做 5 折每折验证集约 200 张把 5 折的 mAP 平均后比单次切分可信得多也能顺便看出模型对数据分布的敏感度。# 5 折交叉验证的切分思路先按 8:2 切出固定测试集剩余做 5 折 # 每折训练命令只需改 data.yaml 里的 train/val 指向 yolo detect train datadatasets/smoking/fold1.yaml modelyolov8n.pt epochs100 imgsz640 batch16第三是难例挖掘。训完第一版后用best.pt在验证集上跑推理把漏检和误检的图挑出来单独看。如果发现某类场景比如侧脸抽烟、远距离小目标系统性失败要么补标这类数据要么在增强里针对性模拟。这一步是 991 张图能不能逼近甚至超过 88.3% 的关键因为小数据集的瓶颈往往不是模型不够强而是数据覆盖不够全。还有一个容易被忽略的点导出模型时的格式选择。如果你后续要部署到边缘设备yolo export modelbest.pt formatonnx导出 ONNX 是常见做法但要注意 opset 版本和推理引擎的兼容性。导出后务必用同一张图对比 PyTorch 和 ONNX 的输出确认框坐标一致再上线否则会出现「训练时好好的部署后框全乱」这种黑匣子问题。从那以后我每次拿到新数据集都强制先跑一遍图片标签配对检查和 20 张可视化抽查再动训练命令。这个习惯帮我省下的返工时间远比多训几个 epoch 值。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站