1. 项目概述为什么我们需要一个专门的吸烟检测数据集在计算机视觉的落地应用里行为识别一直是个硬骨头而吸烟检测又是其中兼具社会价值和挑战性的一个细分领域。你可能在不少公共场所见过“禁止吸烟”的标识旁配着一个不起眼的摄像头背后很可能就运行着一套基于深度学习的检测系统。但要让这套系统真正“聪明”起来能准确区分一个人是在抽烟、喝水还是仅仅用手托着下巴核心中的核心就是一个高质量、标注精准的数据集。我接触过不少刚入行的朋友想用YOLOv5、YOLOv8甚至最新的RT-DETR来做吸烟检测第一步就卡在了数据上。网上搜到的图片要么质量参差不齐要么场景单一基本都是室内正面照训练出来的模型一到复杂的真实环境——比如光线昏暗的楼梯间、人员密集的餐厅角落或者只是行人侧身的一个动作——就频频误报或漏报。这就像让一个只见过教科书例题的学生去参加综合考试结果可想而知。所以这个项目聚焦于“吸烟检测数据集”本身。它不只是一个简单的图片打包而是构建一个可靠检测系统的基石。我们将深入拆解一个合格的数据集应该包含哪些要素从哪里获取以及如何正确地使用它涵盖从数据准备到模型训练以PyTorch为例乃至考虑移动端Android部署的完整链条。无论你是算法工程师、在校学生还是对AI应用感兴趣的开发者理解数据集的内涵都能让你在后续的模型调优和工程化中事半功倍。2. 吸烟检测数据集的核心要素与构建逻辑一个直接可用的、标注好的数据集无疑是宝贵的资源。但在急切地寻找下载链接之前我们必须先搞清楚什么样的数据集才算是一个“好”的数据集。这决定了你未来模型的性能上限。2.1 数据多样性与场景覆盖吸烟行为并非发生在真空中。一个鲁棒的检测模型必须能应对各种复杂情况。视角多样性这是最容易被忽视的一点。监控摄像头可能是俯视安装在屋顶、平视安装在墙壁或斜视。数据集必须包含这多种视角下的吸烟样本。例如俯视视角下香烟和手的相对位置与平视视角截然不同。光照条件涵盖白天、夜晚、室内灯光、逆光、阴影交错等不同光照环境。模型需要学会不依赖于特定的亮度或对比度来识别特征。场景复杂性吸烟可能发生在办公室、工厂车间、餐厅、楼梯间、户外公园、车内等。背景的复杂程度干扰极大。一个只在干净背景下训练的数据集在杂乱背景中几乎无法工作。行为状态包括点烟、持烟、吸烟、弹烟灰、熄灭烟头等完整动作序列的不同瞬间。特别是“持烟”静止状态容易与手持笔、手机、牙刷等物品混淆。人群与遮挡吸烟者可能是不同年龄、性别、穿着且香烟可能被手部分遮挡或者人在人群中只露出局部。注意很多开源数据集往往在“室内办公室白墙前”这种简单场景下表现良好但一到实战就“掉链子”。评估一个数据集时务必检查其场景是否单一。2.2 标注质量与规范标注是给数据“注入灵魂”的过程。对于吸烟检测通常采用目标检测的标注格式如PASCAL VOC的XML或COCO的JSON。标注粒度香烟级别仅标注香烟本身。优点是目标小标注快但模型容易混淆比如筷子、笔。手部-香烟联合体标注包含手和香烟的整个区域。这更符合人类认知“正在吸烟的手”能提供更多上下文信息模型更鲁棒但标注成本高。人-香烟级别先检测人再判断人手中是否有烟。这适合需要先进行行人检测的复杂场景。数据集可能需要人体和香烟的两级标注。实操建议对于通用性要求高的场景推荐使用“手部-香烟联合体”的标注方式。它平衡了精度和鲁棒性。标注精确性边界框Bounding Box必须紧密贴合目标物体既不能过大引入背景噪声也不能过小裁切目标。对于细长的香烟框的宽高比会非常极端需要标注员格外仔细。难点样本标注对于模糊、遮挡严重、尺寸极小的吸烟样本不应直接舍弃而应尽可能准确地标注。这些“困难样本”对提升模型在边缘情况下的性能至关重要。2.3 数据格式与划分一个准备完善的数据集通常包含以下结构Smoking_Dataset/ ├── images/ # 存放所有图像文件 │ ├── train/ # 训练集图片 │ ├── val/ # 验证集图片 │ └── test/ # 测试集图片可选有时用val代替 ├── annotations/ # 存放所有标注文件 │ ├── train/ # 训练集标注如 .xml 文件 │ ├── val/ # 验证集标注 │ └── test/ # 测试集标注 └── labels/ # 另一种常见格式存放YOLO格式的.txt标注文件 ├── train/ ├── val/ └── test/关键点训练集Training Set、验证集Validation Set和测试集Test Set必须严格分离确保图像无重复。通常按照7:2:1或类似比例随机划分。验证集用于训练过程中调整超参数、监控过拟合测试集仅在最终评估时使用一次以反映模型的真实泛化能力。3. 吸烟检测数据集的获取与处理实战了解了标准接下来就是如何获取和处理数据。这里有开源、自制和合规使用三个方向。3.1 开源数据集检索与评估完全从零开始制作数据集成本高昂。首先应积极寻找开源资源。主流学术数据集平台Kaggle Datasets搜索关键词“smoking detection”、“cigarette”。Kaggle上的数据集通常附带讨论和基线模型适合入门。但需注意数据量和质量可能参差不齐。Google Dataset Search这是一个专门搜索数据集的引擎用英文关键词搜索效果更好如“smoking cigarette image dataset”。Roboflow Universe一个非常实用的计算机视觉数据集平台。它提供大量预处理已标注、已划分、已增强的数据集并且支持一键导出为YOLO、COCO、TensorFlow等多种格式。在这里搜索“Smoking”很可能有惊喜发现。评估开源数据集下载前或下载后务必进行快速评估查看数据统计图片数量、标注实例数量、类别分布是否只有“smoking”一类还是有“non-smoking”作为负样本。可视化检查随机打开几十张图片用标注工具如LabelImg加载对应的标注文件直观感受标注质量、场景多样性和难点样本比例。检查许可协议明确数据集的使用许可License特别是用于商业项目时需遵守CC BY-SA、MIT等开源协议的要求。3.2 从零构建数据采集与标注流程如果开源数据集无法满足需求就需要自己动手。这是一个系统性的工程。数据采集渠道合规的网络爬取从遵守Robots协议且允许图片用于研究的网站如某些公开的监控场景数据集网站采集。必须严格遵守法律法规和版权要求禁止爬取个人隐私、商业机密或明确禁止爬取的内容。可使用Scrapy或Selenium框架但需设置合理的请求间隔避免对目标服务器造成压力。模拟场景拍摄在确保安全、合规且不侵犯他人权益的前提下可以自行组织拍摄。使用不同型号的手机、摄像头在多种光照和背景下拍摄模拟吸烟动作可使用道具代替真烟避免健康风险并符合规定。这种方式获取的数据最贴合自身需求。公开视频帧提取从公开的影视剧、纪录片需注意版权或某些行为分析公开视频中截取帧。可以使用OpenCV的VideoCapture模块轻松实现。数据标注工具与实操工具选型LabelImg经典支持PASCAL VOC格式、CVAT功能强大支持在线协作和视频标注、Roboflow Annotate在线工具体验流畅。对于新手LabelImg足矣。标注实操步骤 a.统一规范在开始前团队内必须统一标注规范是标“香烟”还是“手拿香烟”模糊样本标不标遮挡超过多少比例则舍弃 b.启动LabelImg打开工具设置图片目录和预保存的标注文件目录。 c.创建标签在标签栏输入“smoking”或其他你定义的类别名。 d.绘制边界框对于每一个吸烟实例用鼠标框选出目标区域。尽量紧贴目标。 e.保存格式选择保存为PASCAL VOC格式.xml或YOLO格式.txt。YOLO格式是归一化后的中心点坐标和宽高更常用。 f.质量控制标注一部分后应由另一人进行复核纠正错误标注和不一致的地方。数据清洗与增强清洗删除完全无效的图片如全黑、全模糊检查并修正错误的标注文件。数据增强Data Augmentation这是在小数据集上提升模型泛化能力的关键。应在训练时在线on-the-fly进行而不是预先增强存储。常用增强包括几何变换随机水平翻转、小角度旋转如±15度、缩放、裁剪。颜色变换随机调整亮度、对比度、饱和度添加高斯噪声。高级增强albumentations或torchvision.transforms库支持更复杂的增强如CutMix、MosaicYOLO系列常用能极大提升模型性能。实操心得对于吸烟检测随机水平翻转非常有效且安全因为吸烟行为通常没有固定的左右手倾向。但大角度旋转要谨慎因为倒立吸烟的样本在现实中几乎不存在可能引入噪声。3.3 数据格式转换与准备不同的训练框架需要不同的数据格式。最常见的是YOLO格式和COCO格式。YOLO格式详解每个图像对应一个.txt文件每行代表一个目标。class_id x_center y_center width heightclass_id类别索引从0开始。如果只有吸烟一类就是0。x_center, y_center边界框中心点的x、y坐标已归一化除以图片宽度和高度范围0~1。width, height边界框的宽度和高度已归一化。示例图片尺寸为640x480一个目标框的左上角为(100, 120)右下角为(200, 300)。则中心点 x (100 200)/2 / 640 0.234375中心点 y (120 300)/2 / 480 0.4375宽度 w (200 - 100) / 640 0.15625高度 h (300 - 120) / 480 0.375txt文件内容为0 0.234375 0.4375 0.15625 0.375格式转换脚本如果你拿到的是VOC格式.xml需要转换为YOLO格式。下面是一个简单的Python脚本示例import xml.etree.ElementTree as ET import os def convert_voc_to_yolo(xml_file, img_w, img_h, classes): tree ET.parse(xml_file) root tree.getroot() yolo_lines [] for obj in root.findall(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) xmlbox obj.find(bndbox) x1 float(xmlbox.find(xmin).text) y1 float(xmlbox.find(ymin).text) x2 float(xmlbox.find(xmax).text) y2 float(xmlbox.find(ymax).text) # 计算归一化后的中心点和宽高 x_center (x1 x2) / 2.0 / img_w y_center (y1 y2) / 2.0 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h yolo_lines.append(f{cls_id} {x_center} {y_center} {w} {h}) return yolo_lines # 假设 classes [smoking] # 遍历所有xml文件调用函数并写入对应的txt文件使用这个脚本你可以批量完成格式转换。4. 基于PyTorch与YOLO的训练环境搭建与配置有了高质量的数据集下一步就是选择模型和搭建训练环境。PyTorch因其灵活性和活跃的社区成为当前深度学习研究和应用的首选。4.1 PyTorch与CUDA环境精准配置这是让训练跑起来的第一步也是最容易踩坑的一步。版本匹配矩阵PyTorch、CUDA、cuDNN、显卡驱动之间必须版本兼容。以目前主流的RTX 40系显卡如5060和CUDA 12.x为例显卡驱动去NVIDIA官网下载最新版驱动通常新版驱动向下兼容多个CUDA版本。CUDA Toolkit决定你的PyTorch能调用哪些GPU功能。CUDA 12.1/12.4是当前稳定选择。PyTorch访问PyTorch官网https://pytorch.org/get-started/locally/使用其提供的配置命令。例如对于CUDA 12.1# 使用conda安装推荐便于环境隔离 conda create -n smoking_det python3.9 conda activate smoking_det conda install pytorch torchvision torchaudio pytorch-cuda12.1 -c pytorch -c nvidia # 或者使用pip安装 pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121验证安装在Python中运行以下代码import torch print(torch.__version__) # 输出PyTorch版本 print(torch.cuda.is_available()) # 应输出 True print(torch.cuda.get_device_name(0)) # 输出你的GPU型号Anaconda环境管理强烈建议使用Anaconda或Miniconda为每个项目创建独立的虚拟环境。避免不同项目间的包版本冲突。上述安装命令就是在虚拟环境中执行的。踩坑记录我曾遇到CUDA error: no kernel image is available for execution的错误根本原因是PyTorch版本与CUDA版本不匹配。例如用pip默认安装的可能是仅支持CUDA 11.8的PyTorch而我的环境是CUDA 12.4。务必使用官网命令明确指定CUDA版本。4.2 YOLOv8训练框架快速部署Ultralytics YOLOv8因其极简的API和出色的性能已成为目标检测的新标杆。用它来训练我们的吸烟检测模型非常高效。安装YOLOv8在配置好的PyTorch环境中安装非常简单。pip install ultralytics这个命令会安装YOLOv8所需的所有依赖。准备数据集配置文件YOLOv8需要一个描述数据集的.yaml文件。这是连接你的数据和模型的桥梁。 创建一个名为smoking_dataset.yaml的文件内容如下# 数据集路径建议使用绝对路径避免相对路径引发的错误 path: /home/user/Smoking_Dataset # 数据集的根目录 train: images/train # 训练集图片路径相对于 path val: images/val # 验证集图片路径相对于 path # test: images/test # 测试集路径可选 # 类别数量 nc: 1 # 类别名称列表 names: [smoking] # 可选下载地址/说明 # download: ...关键点确保path目录下的结构严格符合前文所述images/train和labels/train等文件夹名称必须对应。模型选择与训练启动YOLOv8提供了不同尺寸的模型n, s, m, l, x在精度和速度之间权衡。from ultralytics import YOLO # 加载一个预训练模型推荐即迁移学习 model YOLO(yolov8s.pt) # 使用小模型yolov8s训练快适合初步尝试 # 开始训练 results model.train( datasmoking_dataset.yaml, # 数据集配置文件路径 epochs100, # 训练轮数根据数据集大小调整 imgsz640, # 输入图像尺寸 batch16, # 批次大小根据GPU内存调整 device0, # 使用GPU 0如果是CPU则设为cpu workers4, # 数据加载线程数 namesmoking_det_v1, # 本次训练的实验名称 pretrainedTrue, # 使用预训练权重 optimizerAdamW, # 优化器 lr00.01, # 初始学习率 ... )训练过程会自动在runs/detect/smoking_det_v1目录下生成所有结果包括模型权重、训练曲线、验证结果等。4.3 训练过程监控与调优核心参数启动训练后并非一劳永逸。你需要像教练一样观察模型的“学习状态”。关键监控指标损失曲线losstrain/box_loss,train/cls_loss,val/box_loss,val/cls_loss。关注训练损失是否平稳下降验证损失是否同步下降且未明显上升防止过拟合。性能指标metrics/mAP50-95(mAP0.5:0.95) 是核心指标综合衡量模型在不同IoU阈值下的精度。metrics/precision,metrics/recall分别关注查准率和查全率。可视化工具YOLOv8训练时会启动一个本地Web服务默认http://localhost:6006使用TensorBoard展示所有曲线非常直观。核心调优参数解析imgsz输入图像尺寸。增大尺寸如从640到1280通常会提升检测小目标如远处香烟的能力但会显著增加显存消耗和训练时间。需要根据你的GPU资源和目标大小权衡。batch批次大小。在GPU显存允许范围内尽可能设大。大的batch size能使梯度更新更稳定。如果出现“CUDA out of memory”错误首先尝试减小batch或imgsz。lr0初始学习率。这是最重要的超参数之一。太大可能导致训练震荡甚至发散太小则收敛缓慢。YOLOv8内置了学习率调度器通常从lr0开始会先经过一个热身warmup阶段再根据策略下降。对于小数据集可以从更小的学习率如0.001开始尝试。patience早停Early Stopping耐心值。如果验证集指标在连续patience个epochs内没有提升训练将自动停止以防止过拟合。默认是50对于小数据集可以设小一些如20。实操心得数据决定上限调参决定逼近上限的速度。如果模型性能始终上不去首先应该回头检查数据质量标注是否准确、难点样本是否足够、数据增强是否有效而不是盲目调整超参数。增加数据多样性往往比调参带来的提升更显著。5. 模型评估、优化与Android端部署考量训练完成后得到一个.pt权重文件但这只是开始。我们需要评估其真实能力并考虑如何让它“跑”起来。5.1 模型性能评估与错误分析使用训练时预留的测试集或验证集进行最终评估。使用YOLOv8进行验证# 在命令行中使用最佳权重进行验证 yolo taskdetect modeval modelruns/detect/smoking_det_v1/weights/best.pt datasmoking_dataset.yaml这会输出详细的评估表格包括mAP、精确率、召回率等。可视化预测结果from ultralytics import YOLO model YOLO(runs/detect/smoking_det_v1/weights/best.pt) results model(path/to/test_image.jpg, saveTrue, conf0.25) # conf为置信度阈值将预测结果边界框和标签画在图片上保存。这是错误分析Error Analysis的关键步骤。错误分析实战仔细查看模型在测试集上的错误预测。误报False Positive把不是吸烟的行为如喝水、打电话识别为吸烟。这说明模型学到的特征不够鲁棒可能需要对负样本非吸烟图片进行增强或在数据集中加入更多容易混淆的负样本。漏报False Negative漏掉了真实的吸烟行为。重点关注这些漏报的样本是香烟太小遮挡太严重光照太暗还是视角太奇特针对性地补充这类困难样本到数据集中重新训练。定位不准框的位置偏差大。检查标注是否准确或者尝试调整损失函数中定位损失的权重在YOLO中通常是box_loss_gain参数。5.2 模型优化与压缩策略为了在资源受限的端侧如Android手机部署模型通常需要优化。模型剪枝Pruning移除网络中不重要的连接或通道减少参数量和计算量。YOLOv8本身提供了model.prune()方法进行尝试性剪枝但更精细的剪枝需要借助其他工具如Torch Pruning。知识蒸馏Knowledge Distillation用一个庞大复杂的“教师模型”来指导一个轻量级“学生模型”的训练让学生模型在保持较小体积的同时获得接近教师模型的性能。这对于从YOLOv8l到YOLOv8n的压缩是一个研究方向。量化Quantization将模型权重和激活从高精度如FP32转换为低精度如INT8。这能大幅减少模型大小和推理延迟是移动端部署的标配技术。训练后量化Post-Training Quantization, PTQ对已训练好的模型进行量化简单快捷但可能有精度损失。量化感知训练Quantization-Aware Training, QAT在训练过程中模拟量化效应让模型适应低精度计算通常能获得更好的精度保持。5.3 向Android端部署的转换路径将PyTorch模型部署到Android主流路径是转换为适用于移动端的推理框架格式。中间格式ONNXONNX是一个开放的模型表示格式。首先将PyTorch模型导出为ONNX。from ultralytics import YOLO model YOLO(best.pt) success model.export(formatonnx, dynamicFalse, simplifyTrue, opset12)dynamicFalse表示固定输入输出尺寸有利于部署优化。simplifyTrue会应用ONNX Simplifier简化计算图。移动端推理引擎选择TensorFlow Lite (TFLite)Google主推Android原生支持良好工具链成熟。需要将ONNX模型进一步转换为TFLite格式可使用onnx-tf和TFLite Converter工具链。PyTorch MobilePyTorch官方移动端解决方案保持了PyTorch API风格但社区生态和性能优化目前略逊于TFLite。NCNN腾讯开源的为手机端极致优化的神经网络前向计算框架。特别针对ARM架构做了大量优化在不少移动设备上性能优于TFLite。通常需要先将模型转到ONNX再用NCNN的工具链转换。MNN阿里巴巴开源的轻量级深度学习引擎同样性能优异支持多种模型格式。Android集成核心步骤 a.模型转换根据选择的引擎将ONNX模型转换为对应的格式如.tflite,.ncnn.bin/param。 b.引入引擎库在Android项目的build.gradle中添加对应引擎的依赖。 c.编写推理代码在Java或Kotlin中加载模型预处理输入图像缩放、归一化、转换为ByteBuffer等运行推理解析输出边界框、置信度、类别。 d.后处理将模型输出的归一化坐标转换为屏幕坐标应用非极大值抑制NMS去除重叠框绘制结果。 e.性能优化利用多线程、GPU委托如果引擎支持如TFLite GPU Delegate来提升推理速度。部署心得在Android真机上测试前务必在PC上用相同的引擎和模型进行推理验证确保转换过程没有引入错误。预处理和后处理必须与训练时完全一致任何细微差别如图像归一化方式、颜色通道顺序都可能导致结果异常。对于吸烟检测这种实时性要求较高的应用需要重点关注每帧的处理耗时确保能达到流畅的检测帧率如15-30 FPS。