首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
YOLOv5 6.0吸烟检测实战:从数据集配置到边缘部署全流程
📅 2026/10/7 15:58:25
✍️ 爱科研究院
👁 阅读 3,247
简介本资源面向计算机视觉学习者与行为识别方向开发者提供基于YOLOv5-6.0框架训练完成的吸烟检测模型可用于公共场所、校园、工地等场景下的吸烟行为自动识别。包内包含YOLOv5m与YOLOv5s两个已训练权重目标类别为smoke在数千张吸烟数据上训练准确率超过90%并附有PR曲线、loss曲线等训练过程记录便于评估模型表现与复现实验。压缩包共373个文件约128.03MB涵盖pt权重、py源码、yaml配置、jpg样本图、png曲线图、csv训练日志及Dockerfile等部署文件结构完整兼顾训练、验证与推理需求。目前已有2392人学习下载适合希望快速上手吸烟检测、进行二次训练或对比不同模型精度的读者参考使用。1. 从一张吸烟检测数据集说起yolov5-6.0-smoking_detect.zip 到底能跑出什么吸烟检测这个需求最早找上来的往往不是算法团队而是工地安全、加油站、化工厂、写字楼物业这些场景的负责人。他们要的东西很朴素摄像头已经装好了能不能自动认出画面里有人正在抽烟然后给个告警。真正动手做才发现公开数据集里吸烟这个类别的标注质量参差不齐烟头小、遮挡多、手部动作和点烟动作容易混模型训出来要么漏检要么误报。yolov5-6.0-smoking_detect.zip这个包名透露的信息很明确基于 YOLOv5 6.0 版本、面向吸烟检测任务的一套工程文件。它解决的不是从零发明一个检测器而是把 YOLOv5 这套成熟框架落到吸烟这个具体类别上——数据怎么组织、配置怎么改、训练怎么起、推理怎么接。适合两类人一类是手里有吸烟场景数据、想快速跑通 baseline 的算法工程师另一类是需要在边缘设备上部署吸烟识别的嵌入式开发者。下面按先立住原理、再动手复现、最后讲坑的顺序拆开讲。2. YOLOv5 6.0 做吸烟检测为什么选它、数据怎么摆2.1 吸烟检测为什么落在 YOLOv5 而不是别的检测器吸烟检测本质是一个小目标 特定姿态的单类或多类检测问题。烟头在 1080P 画面里可能只有十几个像素人手夹烟的动作又和拿笔、拿手机高度相似。选检测框架时核心看三点小目标召回、推理速度、工程成熟度。YOLOv5 6.0 这个版本在工程上是个分水岭。它把模型结构、训练脚本、导出工具、推理接口都收进了一个仓库models/下按yolov5s/m/l/x给出不同规模的配置data/下用 YAML 描述数据集路径和类别train.py、detect.py、export.py各司其职。对吸烟检测这种需要反复调数据、调 anchor、调输入分辨率的任务这种改一个 YAML 就能重训的结构省掉了大量胶水代码。和两阶段检测器比YOLOv5 的单阶段结构在边缘设备上更友好。吸烟检测往往要跑在 Jetson、RK3568、树莓派这类算力有限的板子上两阶段检测器的候选框生成会吃掉不少时间。YOLOv5s 在 640 输入下主流边缘设备上做到实时并不难这是它被大量吸烟检测项目选中的现实原因。另一个容易被忽略的点是后处理。YOLOv5 的输出是三个尺度的特征图经过 NMS 之后给出框。吸烟检测里烟头小如果 NMS 的 IoU 阈值设得太激进相邻的烟头和手指框会被误合并。YOLOv5 的后处理参数在detect.py里是显式暴露的改起来直观这对调吸烟这种密集小目标很关键。2.2 数据集目录结构与 YAML 配置怎么写拿到yolov5-6.0-smoking_detect.zip这类包第一件事不是急着train.py而是把数据目录和 YAML 对齐。YOLOv5 6.0 要求的数据组织方式是固定的smoking_dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/images/train放训练图labels/train放同名.txt标注。标注格式是 YOLO 格式每行class_id x_center y_center width height后四个都是相对整图宽高的归一化值范围 0 到 1。吸烟检测常见两类标法只标smoking一类或者标smokingcigarette两类。类别数直接决定后面模型头部的输出通道改错了训练能跑但结果全乱。对应的数据配置文件通常放在data/smoking.yaml# 吸烟检测数据集配置 path: ../smoking_dataset # 数据集根目录 train: images/train # 训练集相对路径 val: images/val # 验证集相对路径 nc: 1 # 类别数只检测吸烟行为时为 1 names: [smoking] # 类别名顺序必须和标注里的 class_id 对应这里path用相对路径时是相对于 YOLOv5 仓库根目录解析的不是相对于这个 YAML 文件。很多人第一次配错就是栽在这——把path写成相对 YAML 的路径训练时报找不到图片。稳妥做法是直接写绝对路径或者确认相对的是仓库根。nc和names必须和标注文件里的 class_id 严格对应。如果标注里出现了class_id1但nc1训练时不会立刻报错而是在计算 loss 时索引越界或者静默丢弃表现为 loss 不下降、mAP 一直是 0。这是吸烟检测数据集里最常见的翻车点之一。2.3 模型配置选型yolov5s 还是 yolov5mYOLOv5 6.0 在models/下给了几个预设yolov5s.yaml、yolov5m.yaml、yolov5l.yaml、yolov5x.yaml深度和宽度依次递增。吸烟检测选哪个取决于你的部署目标和数据量。配置参数量级别适用场景吸烟检测建议yolov5s最小边缘设备、实时数据量 5000 张以上首选yolov5m中等服务器推理小目标多、漏检严重时换yolov5l/x大离线高精度吸烟检测一般用不上吸烟检测里烟头是小目标直觉上会想用大模型。但实际经验是数据量不够时大模型过拟合更快验证集 mAP 反而低于 yolov5s。我一般先用 yolov5s 跑通全流程看验证集漏检集中在哪再决定要不要换 yolov5m。换模型只需要改--cfg参数不用动数据。如果标注里烟头占比特别小可以在模型配置里调整 anchor。YOLOv5 6.0 的 anchor 是写在 YAML 里的默认三组九個。吸烟检测的小目标如果普遍小于 16 像素默认 anchor 匹配度低可以重新用 k-means 在自家标注上聚类一遍把小的那组 anchor 调小。这一步不是必须但漏检严重时值得试。3. 从零跑通训练命令、参数与验证3.1 环境准备与最小训练命令YOLOv5 6.0 对环境的依赖写在requirements.txt里核心是 PyTorch、torchvision、numpy、opencv-python。Python 版本建议 3.8 到 3.10太新的版本有时会在某些 CUDA 组合上出问题。装依赖# 建议在虚拟环境里操作避免污染系统 Python python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install -r requirements.txt装完之后先验证 PyTorch 能不能看到 GPUpython -c import torch; print(torch.cuda.is_available(), torch.cuda.device_count())输出True 1之类才说明 CUDA 可用。如果输出False训练会退到 CPU吸烟检测这种数据量下 CPU 训练基本没法等。最小训练命令长这样# 用 yolov5s 在吸烟数据集上训练 python train.py \ --data data/smoking.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --batch-size 16 \ --epochs 100 \ --img 640 \ --device 0--weights yolov5s.pt是加载 COCO 预训练权重做迁移学习。吸烟检测数据量通常不大从预训练权重起步比从零训收敛快得多也更稳。如果拿不到预训练权重--weights 从零训但需要更多 epoch 和更谨慎的学习率。--img 640是输入分辨率。吸烟检测里烟头小有人会想上 1280。分辨率翻倍显存占用大约翻四倍batch-size 要相应降。我的建议是先用 640 跑通看验证集里小目标漏检比例再决定要不要上 960 或 1280。3.2 关键超参数怎么设学习率、batch、epochYOLOv5 6.0 的超参数分两层命令行参数和data/hyp.scratch.yaml里的超参文件。命令行参数覆盖训练流程hyp 文件管数据增强和损失权重。吸烟检测调参重点看这几个。学习率。YOLOv5 默认用余弦退火 warmup初始学习率在 hyp 文件里是lr0: 0.01。迁移学习时这个值偏大容易把预训练权重冲掉。我一般把lr0降到 0.001 到 0.003lrf最终学习率比例保持 0.01 到 0.1。如果训练前几个 epoch loss 剧烈震荡先降lr0。batch-size。受显存限制能大则大。batch 太小BN 层统计不稳loss 抖动明显。吸烟检测 640 输入下单卡 8G 显存大概能跑 batch 16 的 yolov5s。显存不够就用--batch-size -1让 YOLOv5 自动选或者开梯度累积。epoch。100 到 300 是常见区间。判断该不该停看runs/train/exp/results.csv里的metrics/mAP_0.5。如果连续二三十个 epoch 不涨基本可以停。吸烟检测数据量小的时候100 epoch 往往就收敛了再多是浪费。数据增强。hyp 文件里的mosaic、mixup、hsv_h/s/v对吸烟检测影响很大。mosaic 把四张图拼一张能显著增加小目标的上下文多样性建议保持开启。但如果你的吸烟场景背景高度固定比如固定工位摄像头mosaic 可能引入不相关背景反而干扰可以适当降低mosaic概率。3.3 训练过程怎么看loss 曲线与验证指标训练起来之后runs/train/exp/下会生成一堆文件。重点看三个results.csv记录每个 epoch 的 loss 和指标。train/box_loss、train/obj_loss、train/cls_loss是训练损失val/box_loss等是验证损失。正常情况训练损失和验证损失同步下降。如果训练损失降、验证损失涨是过拟合加数据或加增强。results.png是上面 CSV 的可视化一眼能看出趋势。confusion_matrix.png是混淆矩阵吸烟检测里能直接看出吸烟被误判成背景和背景被误判成吸烟各有多少。误判成背景多说明漏检考虑提高输入分辨率或调小 anchor背景误判成吸烟多说明误报考虑提高置信度阈值或补负样本。weights/下会存best.pt和last.pt。best.pt是验证集 mAP 最高的那个 epoch部署用这个。last.pt是最后一个 epoch用来断点续训。验证命令# 在验证集上评估 best.pt python val.py \ --data data/smoking.yaml \ --weights runs/train/exp/weights/best.pt \ --img 640 \ --task val输出里mAP_0.5和mAP_0.5:0.95是两个核心指标。吸烟检测这种单类任务mAP_0.5到 0.85 以上算可用0.9 以上算不错。如果mAP_0.5高但mAP_0.5:0.95低说明框的位置不够准可能是标注框画得太松。4. 推理、导出与边缘部署从 detect.py 到 RK35684.1 用 detect.py 做图片和视频推理训练完拿到best.pt先用detect.py验证效果# 对单张图片推理 python detect.py \ --weights runs/train/exp/weights/best.pt \ --source test.jpg \ --img 640 \ --conf-thres 0.4 \ --iou-thres 0.45--conf-thres是置信度阈值低于它的框直接丢。吸烟检测里这个值很关键设高了漏检设低了误报。0.4 是个常见起点实际按场景调。--iou-thres是 NMS 的 IoU 阈值控制重叠框合并。吸烟检测里如果一个人手部有多个疑似烟头框iou-thres设太低会合并掉设太高会留一堆重复框。0.45 到 0.5 之间比较稳。视频推理把--source换成视频路径或0摄像头。--view-img可以实时显示结果调试时有用部署时去掉。推理结果默认存到runs/detect/exp/。如果要做告警可以在detect.py里加逻辑检测到smoking类且置信度超过阈值就触发一次告警。注意加去重同一目标连续多帧命中不要重复告警。4.2 导出 ONNX 与 RK3568 量化部署要点边缘部署绕不开模型导出。YOLOv5 6.0 的export.py支持导出 ONNX、TorchScript、TensorRT 等格式。RK3568 这类 NPU 平台常见路径是先导出 ONNX再用厂商工具转成 RKNN。# 导出 ONNX指定 opset 和输入尺寸 python export.py \ --weights runs/train/exp/weights/best.pt \ --include onnx \ --img 640 \ --opset 12 \ --batch-size 1--opset 12是常见选择太低有些算子不支持太高部分转换工具跟不上。--batch-size 1是因为边缘部署通常单帧推理batch 固定为 1 能让后续量化更顺。导出 ONNX 后用 RKNN 工具链转换时要注意几点。第一输入尺寸要和训练时一致训练用 640 就转 640转成别的尺寸精度会掉。第二量化需要校准集从验证集里抽一两百张有代表性的图覆盖不同光照和场景校准集太单一会导致量化后精度崩。第三YOLOv5 的输出后处理解码 NMS在 RKNN 上通常放在 CPU 做NPU 只跑主干和检测头这样兼容性最好。树莓派 4B/5 上部署 YOLOv5走的是另一条路要么用 ONNX Runtime要么用 NCNN。树莓派没有专用 NPU纯 CPU 推理 yolov5s 640 输入大概几帧到十几帧取决于是否开多线程和输入分辨率。如果帧率不够降输入到 416 或换 yolov5n 是常见做法。量化到 INT8 在树莓派上收益有限因为 CPU 对 INT8 的支持不如 NPU 平台。4.3 后处理参数对吸烟检测结果的影响后处理是吸烟检测里最容易被低估的一环。YOLOv5 的输出是三个尺度的特征图每个格子预测若干框经过置信度过滤和 NMS 才得到最终结果。参数没调好前面训练再准也白搭。置信度阈值conf-thres。吸烟检测的误报大多来自这个值设太低。画面里的手指、笔、耳机线在低阈值下都可能被当成烟。但设太高远处的小烟头又检不到。实操里我会在验证集上画一条 conf 从 0.1 到 0.9 的 precision-recall 曲线选 F1 最高的点作为起点再按场景微调。NMS 的iou-thres。吸烟检测里一个人可能同时有手、烟、脸多个框如果烟头和手指框重叠度高iou-thres设太低会把烟头框 NMS 掉。0.45 是默认值小目标密集时可以提到 0.5 到 0.6。多尺度推理--augment。开启后会对图像做翻转、缩放等多尺度推理再合并能提升小目标召回但推理时间翻几倍。离线分析可以用实时部署一般不开。类别置信度和框置信度的乘积是最终分数。YOLOv5 里--conf-thres过滤的是这个乘积。如果发现某些框分数卡在阈值边缘反复出现说明模型对这个目标本身就不确定与其调阈值不如回去补这类样本。5. 吸烟检测避坑清单五条血泪经验5.1 标注类别和 nc 不一致导致 mAP 恒为 0现象训练能正常启动loss 也在动但验证集mAP_0.5一直是 0混淆矩阵全空。原因标注文件里的class_id超出了nc的范围。比如nc: 1但标注里出现了class_id1从 1 开始编号而不是从 0。YOLOv5 在计算 loss 时对越界类别做了静默处理不报错但也不学。解决写个脚本扫一遍所有 label 文件统计class_id的取值分布确认最大值小于nc。YOLO 格式的类别从 0 开始编号只有一个类别时全部应该是 0。5.2 图片和标签文件名不匹配导致部分样本被跳过现象训练日志里显示的图片数量和实际数据集数量对不上少了一部分。原因YOLOv5 按文件名匹配图片和标签。images/train/001.jpg对应labels/train/001.txt。如果标签文件名带了多余后缀或者图片是.jpeg而标签按.jpg命名匹配不上就被跳过。解决统一图片扩展名标签文件名严格等于图片文件名去掉扩展名。写个脚本检查两边文件名集合是否一致差集就是被跳过的样本。5.3 输入分辨率改了但 anchor 没跟着调现象把--img从 640 提到 1280 后小目标召回没提升反而框的位置偏移。原因YOLOv5 的 anchor 是按训练分辨率设计的。改了输入尺寸但 anchor 还是默认值anchor 和实际目标尺寸的匹配度下降尤其是小目标那组 anchor。解决改输入分辨率后用utils/autoanchor.py里的逻辑在自家数据集上重新聚类 anchor或者至少确认默认 anchor 在新分辨率下仍能覆盖目标尺寸分布。5.4 量化后精度断崖式下跌现象FP32 模型 mAP 0.88转成 INT8 量化后掉到 0.6 甚至更低。原因校准集不具代表性。量化需要校准集统计激活值分布如果校准集全是白天清晰图模型没见过夜间或逆光场景的分布量化参数就偏了。解决校准集从验证集里分层抽样覆盖不同光照、不同场景、不同目标大小。数量一两百张够用关键是分布要全。如果还是掉考虑混合量化对敏感层保留 FP16。5.5 边缘设备上帧率不达标现象模型在服务器上跑得好好的部署到 RK3568 或树莓派上帧率只有个位数。原因后处理放在 CPU 做或者输入分辨率没降或者模型没量化。YOLOv5 的解码和 NMS 在 CPU 上是纯 Python 循环时很慢。解决后处理用 C 重写或换成 numpy 向量化实现输入分辨率按实际需求降监控场景 416 往往够用NPU 平台务必走 INT8 量化。树莓派上可以试 NCNN它对 ARM 的优化比 ONNX Runtime 好。6. 把吸烟检测做稳的一个习惯先看混淆矩阵再调参调吸烟检测调到最后我发现最省时间的做法不是盲目试参数而是每次训练完先看confusion_matrix.png。这张图把吸烟被判成背景和背景被判成吸烟两个方向的错误分开摆着指向的调参方向完全不同。漏检多吸烟被判成背景优先动三处输入分辨率往上提、小目标 anchor 调小、conf-thres往下降。误报多背景被判成吸烟优先补负样本、提高conf-thres、检查标注里有没有把非吸烟的手部动作错标成吸烟。下面这个小脚本我常用来快速统计验证集上的错误分布比翻日志直观import numpy as np from pathlib import Path # 读取 YOLOv5 val.py 输出的混淆矩阵简化示意 # 实际可从 runs/val/exp/confusion_matrix.png 对应的数据读取 def summarize_errors(cm): cm: 混淆矩阵行是预测列是真实最后一行为背景 返回漏检率和误报率 cm np.array(cm) # 吸烟类索引为 0背景为最后一行/列 fn cm[-1, 0] # 真实是吸烟预测成背景 - 漏检 fp cm[0, -1] # 真实是背景预测成吸烟 - 误报 tp cm[0, 0] fnr fn / (tp fn 1e-6) # 漏检率 fpr fp / (tp fp 1e-6) # 误报率 print(f漏检率: {fnr:.3f}, 误报率: {fpr:.3f}) return fnr, fpr # 示例矩阵实际替换为真实统计值 summarize_errors([[800, 50], [120, 30]])这段代码的逻辑很简单从混淆矩阵里取出漏检和误报的计数分别除以对应的真实样本数得到两个比率。参数上cm的行列顺序要和 YOLOv5 输出一致背景类在最后。跑完看哪个比率高就按上面说的方向调。漏检率高于 0.15 基本不能接受误报率高于 0.1 在告警场景里会烦人。我自己的习惯是每换一次数据增强策略或 anchor都重新跑一遍这个统计把漏检率和误报率记在一张表里。调参调到最后往往不是某个参数一改就灵而是几个参数配合着把两个错误率压到可接受范围。吸烟检测这种场景漏检和误报的代价不对称——漏检可能意味着安全隐患误报多了运维会直接关掉告警。先想清楚你的场景更怕哪个再决定往哪边偏。希望帮到你。本文还有配套的精品资源点击获取
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/7 15:58:25
ADE Explorer实战指南:从Spectre仿真配置到Monte Carlo与收敛排查
2026/10/7 15:58:25
控制即推理:从贝叶斯推断看强化学习中的最大熵与SAC
2026/10/7 15:58:25
ponytail skill 插件使用指南:从零搭建自动化工作流
2026/10/7 18:38:45
用Visual C++与ID3DXSprite实现DSP数据实时可视化指南
2026/10/7 18:38:45
JavaWeb增删改查源码包怎么跑通?从技术栈到部署避坑全解析
2026/10/7 18:38:45
Java在线考试管理系统源码解析:组卷判分与交卷幂等实战
2026/10/7 18:38:45
Cadence AC/STB仿真与PLL死区调试:从仿真到流片的实战方法论
2026/10/7 18:38:45
飞船内景模块化搭建:物理可信的太空场景制作方法论
2026/10/7 18:33:45
传递熵与widelymfx:时间序列因果推断的方向性分析工具
2026/10/7 0:01:56
基于sEMG与IMU的手语手势识别:从数据采集到实时部署避坑指南
2026/10/7 0:01:56
装配车间MES落地指南:SimpleMES工单流转、BOM与齐套检查实战
2026/10/7 0:01:56
AI获客怎样减少重复线索?意客AI的原文复用与版本筛选
2026/10/6 15:41:36
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/7 9:55:49
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/7 14:02:03
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/6 21:51:29
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/6 22:05:33
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/6 22:06:19
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)