☰
YOLO吸烟行为检测数据集实战:从数据验证到模型训练与落地
2026/9/28 7:19:39 网站建设 项目流程

简介:这份YOLO吸烟检测数据集面向计算机视觉学习者与目标检测开发者,用于训练和验证吸烟行为识别模型,可应用于公共场所禁烟监控、工地安全管理等场景。数据集已按train、val、test完成划分,并附带data.yaml配置文件,类别涵盖no_smoking、no_smoking_area、smoking三类,yolov5、yolov7、yolov8等主流框架可直接读取训练,省去自行标注与整理目录的繁琐工作。压缩包共412个文件,以204个jpg图像与204个txt标注文件为主,另含4个yaml配置,整体约11.48MB,体积轻便便于快速下载与本地调试。目前已有658人学习下载,配套博文还提供了检测结果参考,方便读者对照验证模型效果。对于想快速跑通吸烟检测流程、研究多类别行为识别或搭建禁烟监控原型的读者,这份资源能直接作为训练起点,减少数据准备成本。

1. 吸烟行为检测数据集:从拿到 smoking-dataset-yolo-1.zip 到跑通第一轮训练

上周有个做智慧工地和校园安防的朋友找我,说甲方要在现有监控里加一路「吸烟行为识别」,问我有没有现成的 YOLO 数据集能直接开训。我第一反应就是翻出这份 smoking-dataset-yolo-1.zip——它属于典型的「拿来就能跑」型目标检测数据集,目录已经按 train/valid/test 切好,data.yaml 也配好了,yolov5、yolov7、yolov8 这些主流版本不用改结构就能直接喂进去。它解决的不是「从零标注」的问题,而是帮你省掉最耗时的数据清洗和划分环节,让你把精力放在模型选型和调参上。适合谁?做安防、工地、校园行为分析的算法工程师,以及想拿一个真实三分类数据集练手 YOLO 训练流程的人。下面我按自己拆包、验证、训练的顺序,把这份资源讲透。

2. 拆开压缩包先看什么:目录结构、类别定义与 data.yaml 逐行解读

拿到一个 YOLO 数据集,我从来不急着敲训练命令,而是先花十分钟把目录和配置文件过一遍。这一步能提前暴露 80% 的低级错误,比如路径写错、类别名对不上、图片和标签数量不匹配。smoking-dataset-yolo-1.zip 解压后是一个标准的 YOLO 格式工程,下面按我实际拆包看到的顺序讲。

2.1 目录树与文件命名规律

解压后顶层目录大致是这样:

smoking-dataset-yolo-1/ ├── data.yaml ├── train/ │ ├── images/ │ └── labels/ ├── valid/ │ ├── images/ │ └── labels/ └── test/ ├── images/ └── labels/

图片文件名是b6_jpg.rf.80e68736669583c0526225e7e294ca4f.jpg这种形式,前缀b6、b7、b3、c7、b2是原始采集批次或场景编号,后面rf.加一长串哈希是导出工具(常见的是 Roboflow)自动加的唯一标识。这种命名看着乱,但好处是不会重名,坏处是你没法从文件名直接判断内容。标签文件是同名的.txt,和图片一一对应,放在同级labels/目录下。

这里有个血泪经验:很多人解压后直接看train/images里图片挺多就以为没问题,结果labels目录是空的或者数量对不上。所以第一步一定是数数。

# 分别统计三个子集的图片数和标签数,两者必须相等 for split in train valid test; do img=$(ls smoking-dataset-yolo-1/$split/images | wc -l) lbl=$(ls smoking-dataset-yolo-1/$split/labels | wc -l) echo "$split: images=$img labels=$lbl" done

逻辑说明:ls | wc -l统计文件数量,循环遍历三个子集。如果某个子集 images 和 labels 数量不一致,说明有图片没标注或者标签文件丢失,训练时 YOLO 会直接跳过无标签图片,导致实际训练样本比你以为的少。参数上没什么可调的,就是核对数量。

2.2 data.yaml 三个类别与路径配置

data.yaml 是 YOLO 训练的入口配置,内容如下:

names: ['no_smoking', 'no_smoking_area', 'smoking'] train: ./train/images val: ./valid/images test: ./test/image

逐行看。names是类别列表,索引从 0 开始,也就是说0=no_smoking、1=no_smoking_area、2=smoking。标签 txt 里每行的第一个数字就是这里的索引,所以类别顺序绝对不能改,改了标签含义就全乱了。train、val、test是三个子集的图片路径,注意这里是相对路径,相对于你启动训练时的工作目录,不是相对于 data.yaml 所在目录——这是新手最容易翻车的地方。

注意:test那行写的是./test/image,少了个s。如果你的 test 目录实际叫images,这行必须改成./test/images,否则做测试集评估时会报路径不存在。我一般会先手动确认目录名再决定改不改。

三个类别的设计其实有讲究:smoking是明确的吸烟行为,no_smoking是不吸烟的正常状态,no_smoking_area是禁烟区域标识。这意味着模型不仅要识别「有没有烟」,还要区分「人在不在禁烟区」,属于行为加场景的联合判断。如果你的业务只关心吸烟动作本身,可以只保留smoking和no_smoking两类重新生成标签,但那就脱离了这份数据集的原设计。

2.3 标签格式与坐标归一化

YOLO 标签每行格式是class_id x_center y_center width height,后四个都是归一化到 0~1 的相对值。随便打开一个标签文件看看:

# 查看某个标签文件内容,确认格式正确 cat smoking-dataset-yolo-1/train/labels/b6_jpg.rf.80e68736669583c0526225e7e294ca4f.txt

正常输出类似2 0.512 0.634 0.087 0.211,表示类别 2(smoking),目标中心在图片宽高 51.2% 和 63.4% 位置,框宽高占整图 8.7% 和 21.1%。如果看到坐标大于 1 或者负数,说明标注工具导出时没归一化,需要自己转换。这份数据集我抽查了几个文件,坐标都在合理范围内,格式是标准的。

3. 用 YOLOv8 跑通第一轮训练:环境、命令与参数怎么设

数据确认没问题,就可以上模型了。这份数据集官方说法是 yolov5、yolov7、yolov8 都能直接训,我选 YOLOv8 演示,因为它的命令行最简洁,报错信息也最友好。下面从环境到训练到看结果,一步步来。

3.1 环境搭建与依赖安装

我一般用 conda 建独立环境,避免和系统里的包打架:

conda create -n yolo_smoke python=3.10 -y conda activate yolo_smoke pip install ultralytics

逻辑说明:ultralytics这个包同时包含 YOLOv8 的训练、验证、推理接口,装它一个就够了。Python 选 3.10 是因为 3.11 以上某些 torch 版本兼容性还在磨合,3.10 最稳。装完可以yolo checks看一下环境,它会列出 torch 版本、CUDA 是否可用。如果你有 GPU,确认CUDA那行是可用状态;没有 GPU 就用 CPU 训,速度慢但能跑通流程。

参数上,ultralytics会自动拉取匹配的 torch 版本。如果你机器上已经有特定版本的 torch,建议先pip install torch指定版本再装 ultralytics,避免它给你升级或降级。

3.2 训练命令与关键参数含义

假设你已经cd到解压后的smoking-dataset-yolo-1目录,训练命令:

yolo detect train \ data=data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ project=runs/smoke \ name=exp1

逐参数说明。data=data.yaml指向配置文件,路径要对。model=yolov8n.pt是 nano 版本预训练权重,最小最快,适合先跑通流程;如果精度不够再换yolov8s.pt或yolov8m.pt。epochs=100是训练轮数,这份数据集规模不算大,100 轮通常够收敛,但要看后面的 loss 曲线决定加不加。imgsz=640是输入分辨率,YOLO 默认 640,如果你的监控画面里吸烟动作目标很小,可以提到 1280,但显存占用会翻倍。batch=16是批大小,显存不够就降到 8 或 4。project和name决定结果保存路径,跑完在runs/smoke/exp1/下能看到权重、曲线和日志。

提示:第一次跑建议先用epochs=10快速验证流程通不通,确认没问题再改成 100 正式训。这样能省下大量等待时间。

3.3 训练过程看什么指标

训练启动后终端会滚动输出每个 epoch 的 loss 和 mAP。重点盯三个:box_loss、cls_loss、mAP50。box_loss是边界框回归损失,cls_loss是分类损失,两个都应该随 epoch 下降并逐渐平稳。mAP50是 IoU 阈值 0.5 下的平均精度,应该上升。如果cls_loss一直不降,常见原因是类别不平衡——这份数据集里smoking样本可能远少于no_smoking,模型倾向于全预测多数类。

训练结束后在runs/smoke/exp1/下会生成results.png,里面包含所有曲线。我习惯先看confusion_matrix.png,能直观看到三个类别之间有没有互相混淆。如果no_smoking和no_smoking_area混淆严重,说明这两个类在视觉上区分度不够,可能需要更多场景样本或调整标注边界。

4. 训练完怎么验证:推理、指标解读与常见误判排查

模型训完不是看个 mAP 就完事,得实际跑几张图看看效果,再结合指标判断能不能上线。这一章讲验证流程和几个我踩过的坑。

4.1 用训练好的权重做推理

yolo detect predict \ model=runs/smoke/exp1/weights/best.pt \ source=smoking-dataset-yolo-1/test/images \ conf=0.25 \ save=True

逻辑说明:model指向训练产出的最佳权重best.pt,source可以是单张图、目录或视频。conf=0.25是置信度阈值,低于这个值的检测框会被过滤。save=True把带框结果存到runs/detect/predict/下。跑完去翻结果图,重点看漏检和误检:漏检是明明在吸烟没框出来,误检是把正常动作框成吸烟。

参数上,conf调低会召回更多但误检增加,调高则相反。安防场景一般宁可误报不可漏报,可以设 0.2 左右;如果误报太多影响体验,提到 0.4 再观察。

4.2 混淆矩阵与 mAP 指标怎么读

confusion_matrix.png的横轴是预测类别,纵轴是真实类别,对角线是正确预测。如果smoking那一行有大量落到no_smoking列,说明吸烟被误判成不吸烟,这是最危险的漏检。mAP50和mAP50-95两个指标,前者宽松后者严格,一般看mAP50判断整体可用性,看mAP50-95判断框的定位精度。这份数据集如果mAP50能到 0.8 以上,基本可用;低于 0.6 就要考虑加数据或换更大模型。

4.3 三个高频误判场景

第一,手靠近嘴部的动作(打电话、吃东西)容易被误判为吸烟,因为视觉特征相似。第二,远处小目标吸烟动作,640 分辨率下可能只有十几个像素,模型看不清。第三,逆光或夜间红外画面,颜色特征丢失,smoking和no_smoking区分度下降。这三个场景我在实际项目里都遇到过,解决办法分别是:补充负样本、提高输入分辨率、增加红外场景训练数据。

5. 避坑与排查:路径、类别、显存和标签的五个真实翻车记录

这一章是我和身边同事用这类数据集时踩过的坑,每条按现象、原因、解决写,你对照排查能省不少时间。

现象一:训练报No labels found。原因:data.yaml 里的路径是相对启动目录的,你在别的目录下敲命令,YOLO 找不到train/images。解决:要么cd到数据集根目录再启动,要么把 data.yaml 里的路径改成绝对路径。

现象二:训练正常但 mAP 一直是 0。原因:标签里的 class_id 超出了names列表范围,比如标签写了3但只有三个类别(0、1、2)。解决:用脚本扫描所有标签文件,找出最大 class_id,确认不超过len(names)-1。

# 扫描所有标签,输出出现过的最大类别索引 cat smoking-dataset-yolo-1/train/labels/*.txt | awk '{print $1}' | sort -n | uniq

逻辑说明:awk '{print $1}'取每行第一个字段即类别索引,sort -n | uniq排序去重后列出所有出现过的类别。如果看到 3 或更大,说明标签有问题。

现象三:CUDA out of memory。原因:batch或imgsz设太大,显存不够。解决:先把batch降到 8 甚至 4,还不行就把imgsz从 640 降到 416。也可以开混合精度训练,YOLOv8 默认开启 AMP,如果被手动关了记得打开。

现象四:test路径报错找不到目录。原因:data.yaml 里写的是./test/image,实际目录是images。解决:核对实际目录名,改 data.yaml 或重命名目录保持一致。

现象五:验证集指标很好但实际推理很差。原因:train 和 valid 可能来自同一批场景,分布太接近,模型过拟合了。解决:看 test 集指标,如果 test 明显低于 valid,说明泛化不行,需要补充不同场景的数据。这份数据集已经分好了 test,一定要用它做最终评估,别只看 valid。

6. 进阶技巧:类别不平衡处理与从检测到行为判定的落地思路

跑通基础训练后,如果你要把这份数据集用到真实项目里,还有两件事值得做。一是处理类别不平衡,二是把单帧检测升级成时序行为判定。

类别不平衡方面,smoking样本通常少于no_smoking,我一般会在训练时给类别加权。YOLOv8 没有直接的 class weight 参数,但可以通过复制少数类样本或使用focal loss变体来缓解。更简单的做法是数据增强时对smoking类多做几次随机裁剪和亮度扰动,间接提升它的占比。

时序行为判定是落地关键。单帧检测到smoking不等于人在吸烟,可能只是手拿了个类似烟的物体。我的习惯是:对同一路视频流,连续 N 帧中至少有 M 帧检测到smoking,才触发告警。这个 N 和 M 要根据帧率调,25fps 下我一般设 N=50、M=30,也就是 2 秒内超过一半帧命中才报。这样能过滤掉大量瞬时误检。

# 简化的时序判定逻辑,counter 为滑动窗口内 smoking 命中帧数 from collections import deque window = deque(maxlen=50) def judge(is_smoking_frame): window.append(1 if is_smoking_frame else 0) if len(window) == 50 and sum(window) >= 30: return True # 触发吸烟告警 return False

逻辑说明:deque(maxlen=50)维护一个固定长度滑动窗口,每帧追加 0 或 1,窗口满且命中数达到阈值就返回 True。参数maxlen和阈值30按实际帧率和业务容忍度调整。这个逻辑不依赖模型本身,是后处理层,能显著降低误报。

从那以后我每次拿到新的行为检测数据集,都强制先跑一遍 test 集看混淆矩阵,再决定要不要上时序后处理。这份 smoking-dataset-yolo-1.zip 的价值在于它把最繁琐的数据准备做完了,你拿到手就能验证模型和调后处理逻辑,省下的时间够你把告警策略打磨好几轮。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询