YOLOv5吸烟检测实战:从环境配置到模型训练全流程解析
2026/9/13 2:05:39 网站建设 项目流程

简介:基于YOLOv5的吸烟检测源码与配套数据,是一份得分为97分的期末大作业,面向计算机相关专业学生,适用于课程设计、期末项目答辩、目标检测实战练习等场景,主要解决监控场景下的吸烟行为识别问题。压缩包内共收录100个文件,核心类型包括41个Python脚本文件、31个YAML模型配置、2个预训练权重、2个Notebook教学文档,以及容器部署文件、Shell脚本和Markdown说明,整体约25.76MB,目录结构清晰,兼顾数据组织、模型训练、推理验证与部署应用。目前已有117人学习下载,是同类课设题目中可参考的完整案例。项目已经过严格调试,解压后即可直接运行;读者不仅能获得可直接使用的模型与代码,还能从中理解数据集标注与划分、训练参数调整、模型评估和推理部署的完整流程,节省自行搜集数据和反复排错的时间,适合作为毕业设计、课程报告或简历项目的备选素材。

1. 拿到YOLOv5吸烟检测源码包后,先解决“能跑”再谈“高分”

很多期末大作业的源码压缩包里,YOLOv5训练脚本、吸烟数据集和预训练权重往往混在一起,看起来文件齐全,实际解压后直接运行train.py大概率会报“Dataset not found”或者类别数对不上。原因很简单:YOLOv5的代码框架和数据集目录结构是强耦合的,zip包里的数据多半没有按照YOLO格式组织好,而源码版本又五花八门,这导致“高分期末大作业”的成品质量,主要取决于你能不能把数据路径、标签格式、模型参数三者对齐。本文将基于“YOLOv5吸烟检测”这个固定场景,把从环境搭建、数据检查到训练调参、最终验证的完整链路写清楚,适合正在赶课程设计、毕业设计或想快速落地一个目标检测demo的开发者。

2. YOLOv5网络结构与吸烟样本数据集的对应关系

2.1 为什么期末作业选YOLOv5s而不是YOLOv5x或YOLOv8

目标检测项目里最常问的一个问题就是“用哪个模型”。YOLOv5s是YOLOv5系列中深度最浅、计算量最小的变体,COCO预训练权重体积约14MB,推理时在普通笔记本GPU上能跑到60 FPS以上。对于吸烟检测这种类别少、目标尺度相对固定的任务,YOLOv5s的精度完全够用,而且对显存要求低,6GB显存即可训练。YOLOv5x虽然mAP更高,但训练时间长,显存占用动辄超过10GB,毕设机器跑不起来反而拖慢进度。

YOLOv5网络结构本身是单阶段检测器,核心由Backbone(CSPDarknet)、Neck(PANet)和Head(Detect层)组成。Backbone负责提取特征,Neck通过自上而下和自下而上的路径融合多尺度特征,Head输出三个尺度的预测框。吸烟检测这个任务里,烟头属于极小目标,往往只有十几个像素,因此需要留意小尺度特征层,这也是训练时把输入分辨率设定为640而不是320的原因之一。

提示:如果压缩包里的数据图片分辨率普遍较低,优先采用YOLOv5s配合640分辨率训练,而不是换更大的模型。

2.2 吸烟检测数据集的YOLO标注格式与目录结构

YOLOv5要求标签与图片同名,图片放在images目录,标签放在labels目录,标签文件是txt格式,每行表示一个目标。一行内容为:类别ID 归一化中心x 归一化中心y 归一化宽度 归一化高度。吸烟检测数据集的类别通常有两类:person(人)和cigarette(香烟),但很多数据集只标注了smoking或cigarette单个类别,这取决于任务定义。

dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ └── ... │ └── val/ │ ├── 000101.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 000001.txt │ │ └── ... │ └── val/ │ ├── 000101.txt │ └── ... └── smoking.yaml

检查标签时,最常出现的三个问题:一是txt文件为空,表示这张图没有被标注,训练时会自动跳过;二是类别ID超出yaml中nc声明数,导致索引越界;三是坐标值有小于0或大于1的异常值,通常是标注工具导出时换算错误。写一个快速校验脚本会节省大量排错时间。

import os label_dir = "dataset/labels/val" nc = 1 # 假设只有吸烟一个类别 for f in os.listdir(label_dir): if not f.endswith(".txt"): continue lines = open(os.path.join(label_dir, f)).read().strip().splitlines() for line in lines: parts = line.split() cls = int(parts[0]) x, y, w, h = map(float, parts[1:]) assert cls < nc, f"{f} 类别ID {cls} 超出范围" assert 0 <= x <= 1 and 0 <= y <= 1, f"{f} 中心点坐标异常" assert w > 0 and h > 0, f"{f} 宽高异常" print("标签检查通过")

该脚本读取所有标签文件,逐行解析类别ID和坐标,任意一项不合法就报错。重点看类别ID是否小于nc,以及中心点坐标是否落在0到1区间,这两个条件不满足时训练必然出问题。

2.3 smoking.yaml中的路径、nc与names三者的连带关系

YOLOv5训练时用指定的数据配置文件作为唯一入口,比较典型的写法如下:

path: ../dataset train: images/train val: images/val nc: 1 names: ["smoking"]

path字段是数据集根目录,train和val是相对路径。很多源码包里的images和labels不在同一级目录,或者train和val的目录名不叫这个名字,导致YOLOv5启动时直接报错。nc必须与标签txt中的最大类别ID加1相等;names列表的顺序则对应txt中类别ID的索引,顺序一旦写错,推理时标注的名字就会错乱。最后检查路径:源码目录、数据集目录和权重目录三者是否在同一个盘符下,Windows系统对中文路径和空格路径的支持不好,建议统一改成英文小写目录名。

3. 用YOLOv5跑通吸烟检测:环境配置与最小推理命令

3.1 创建conda环境并安装依赖的完整步骤

YOLOv5对Python版本要求不高,3.8到3.11均可运行。先创建虚拟环境,然后安装依赖。核心依赖包括torch、torchvision、opencv-python、matplotlib、pyyaml等几十个包,使用requirements.txt安装即可完成绝大多数配置。

conda create -n yolov5 python=3.9 -y conda activate yolov5 cd yolov5-master pip install -r requirements.txt

requirements.txt中会列出torch的安装命令,但默认安装的可能是CPU版本,如果需要GPU加速需要单独安装CUDA版本的torch。例如CUDA 11.8对应pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118。安装完成后可以用以下命令确认CUDA是否可用:

import torch print(torch.__version__) print(torch.cuda.is_available())

torch.cuda.is_available()输出True才说明GPU环境正常,否则训练和推理都会退回到CPU,速度慢几十倍。

3.2 用detect.py测试一张吸烟图片的最短命令

环境就绪后,先不要急着训练,而是用现成权重跑一次推理。源码包通常会带一个训练好的best.pt,将它放到yolov5-master根目录下,然后执行:

python detect.py --weights best.pt --source data/images/test01.jpg --conf-thres 0.25 --iou-thres 0.45 --save-txt

--weights指定模型权重文件,--source指定输入图片,--conf-thres是置信度阈值,低于该值的预测框会被过滤,--iou-thres用于NMS去重。执行完成后结果保存在runs/detect/exp目录下,包括带预测框的图片和对应的txt标签文件。查看图片时,重点看一下预测框是否正确框住了烟头而不是整只手,如果大量误检,需要调整置信度阈值或者重新训练。

3.3 命令行参数表中与吸烟检测推理关系最大的5个参数

参数名默认值吸烟检测建议值作用说明
--conf-thres0.250.15~0.3滤除低置信度框,烟头目标小,阈值太高会漏检
--iou-thres0.450.4~0.5NMS重叠阈值,多个烟头靠得近时不宜过低
--imgsz640640推理时缩放尺寸,太小影响小目标检测
--max-det1000300每张图片最大检测数量,防止密集场景过载
--devicecpu0指定GPU编号,时序场景建议用0

烟头在监控画面中往往只有几个像素,conf-thres设成0.25可能什么都检不出来,这是推理结果为空的主要原因。常见做法是先降到0.1看输出效果,再逐步调大,找到一个“误检少且漏检少”的平衡点。overlap较高的连续帧可以用--iou-thres 0.5,检测密集场景反而要降低到0.3以下,避免两个相邻烟头被合并成一个框。

3.4 从zip解压到中文路径引发的报错排查

源码压缩包解压后,第一件事是检查整个目录是否有中文或空格。YOLOv5的工程在路径解析时依赖相对路径和符号链接,中文路径经常导致“Dataset not found”或者权重文件读取失败。另一个高频问题是解压工具把深层目录的权限或符号链接弄丢,使用Windows自带解压功能比第三方压缩软件更稳妥。

解压后依次检查根目录下是否存在detect.py、train.py、requirements.txt、data目录和weights目录。如果只有源代码没有权重,训练和推理都需要先用预训练权重初始化。yolov5s.pt可以单独下载后放到项目根目录,官方权重文件名称固定,避免使用来源不明的覆盖版。解压后建议执行一次python models/yolo.py验证模型结构是否能完整加载,这一步能测出权重文件与代码版本不匹配的问题。

4. 用自己的数据集训练YOLOv5吸烟检测模型

4.1 train.py最小训练命令与超参数选择逻辑

数据无误后执行训练命令。以单GPU、batch size 16、训练100轮为例:

python train.py --data smoking.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --name smoking_exp

该命令使用预训练权重yolov5s.pt初始化模型,数据集配置指向smoking.yaml,训练结果保存在runs/train/smoking_exp目录下。epochs设100轮对于小数据集足够,当模型在验证集上的mAP连续多轮不再提升时,YOLOv5会自动提前停止训练。

4.2 与训练效果直接相关的超参数表

参数默认值含义吸烟数据场景呈现的差异
--img 640640训练输入边长烟头是小目标,小于640会漏检
--batch 1616每批次图片数量显存不足时降到8或4
--epochs 300300遍历全量数据的次数数据集越大轮次可适当减少
--patience 100100验证指标连续多少轮不涨就停止监控真实场景建议保持默认
--workers 88数据加载线程数Windows下设为0避免内存错误
--hypdata/hyps/hyp.scratch-low.yaml数据增强策略含Mosaic、HSV扰动等

Mosaic增强是YOLOv5提升小目标检测的关键,hyp配置文件中的mosaic参数默认是1.0,即每张训练图都由4张图拼接而成。烟头属于小目标,mosaic带来的尺度变化对小目标学习非常有利。但如果训练集本身不过几百张,过强的增强会让模型学不到真实分布,这时可以把mosaic从1.0降到0.5,同时把hsv_h(色调扰动)从0.015调低到0.005,避免颜色偏移太厉害。

4.3 训练集只有几百张时应对过拟合的4个具体操作

很多期末作业手里只有几百张标注图,训练时最典型的症状是训练损失持续下降,验证集mAP却震荡不涨。这说明模型过度拟合训练集的背景和光照条件。常见做法按优先级排序:

  1. 使用预训练权重,而非随机初始化。yolov5s.pt在COCO上预训练过,已经具备通用特征提取能力,小数据微调时收敛快且泛化好。
  2. 调低epochs到60~80,并将patience降为30,观察验证集指标一旦连续不涨就立即停止,避免在训练集上继续过拟合。
  3. 在hyp配置中降低mosaic和mixup的强度,数据太少时过度增强会导致模型记不住真实目标的形态。
  4. 训练阶段做一次类别统计,如果smoking类只有300个标注框,而person类有3000个,建议只保留person中嘴巴附近区域的框,或者将smoking类单独作为唯一类别训练。多数毕设把“是否吸烟”作为二分类问题处理,直接标注cigarette目标框。

4.4 数据集切分与常见标注格式转换的错误

YOLOv5期望的目录结构是images/train和images/val,标签目录同理。许多数据集原始格式是VOC的xml,存放在Annotations目录中,需要转换为YOLO的txt格式。转换脚本的基本逻辑是读取xml中bndbox的xmin、ymin、xmax、ymax,再除以图片宽高得到归一化坐标。转换时的两个易错点:VOC坐标是整型像素值,而YOLO需要相对图片宽高的比例;图片宽高必须以原图实际尺寸为准,不能用统一默认值替代。

import xml.etree.ElementTree as ET tree = ET.parse("Annotations/000001.xml") root = tree.getroot() size = root.find("size") w = int(size.find("width").text) h = int(size.find("height").text) with open("labels/000001.txt", "w") as f: for obj in root.iter("object"): cls = obj.find("name").text if cls != "cigarette": continue box = obj.find("bndbox") xmin = int(box.find("xmin").text) ymin = int(box.find("ymin").text) xmax = int(box.find("xmax").text) ymax = int(box.find("ymax").text) x_c = (xmin + xmax) / 2 / w y_c = (ymin + ymax) / 2 / h bw = (xmax - xmin) / w bh = (ymax - ymin) / h f.write(f"0 {x_c} {y_c} {bw} {bh}\n")

这个脚本只转换类别名为cigarette的目标,且跳过其他类别。实际使用中需要根据数据集的类别名做调整:有的数据把标注目标称为smoke,有的称为smoking,统一在脚本里做映射,否则训练时会出现大量空标签文件。转换完成后用上一节的校验脚本检查一遍坐标范围是数字0到1之间,而不是像素值。

训练启动后的前10轮观察终端输出的P、R、mAP50三个指标。P是精确率,R是召回率,mAP50是IoU阈值为0.5时的平均精度。R过低说明漏检严重,P过低说明误检严重。小目标数据集上,mAP50实战参考值在0.7以上就可以输出结果,不必追求论文里的0.9。

5. 用验证集评测吸烟模型并生成答辩展示材料

5.1 从训练输出文件读取mAP与混淆矩阵

训练完成后runs/train/smoking_exp目录下会生成results.png、confusion_matrix.png和weights/best.pt三个关键文件。results.png是损失和指标随训练轮次变化的曲线,能直观展示模型收敛情况,答辩时放这一张图就可以说明训练过程正常。confusion_matrix.png显示每个真实类别被预测成其他类别的比例,如果cigarette这一类有大量样本被预测为background,说明漏检主要集中在远距离小目标上。

用best.pt对验证集重新评测一次,得到正式的指标输出。

python val.py --weights runs/train/smoking_exp/weights/best.pt --data smoking.yaml --img 640 --conf-thres 0.001 --iou-thres 0.6

5.2 自动生成带检测框的演示视频

答辩演示环节,需要一段能展示检测效果的视频。YOLOv5支持用--source指定视频文件,并配合--save-vid自动保存结果视频:

python detect.py --weights runs/train/smoking_exp/weights/best.pt --source demo.mp4 --conf-thres 0.3 --save-vid --save-txt --project runs/detect --name demo_result

输出视频默认保存为runs/detect/demo_result/demo.mp4。值得注意的是,视频检测的每一帧都会标注框,帧与帧之间的抖动会很明显,如果想要更平滑的视觉效果,可以引入简单的帧间过滤,即连续至少两帧检测到香烟才在画面上绘制框,逻辑代码循环处理检测结果即可。

5.3 期末验收前最后一个小时必做的3项检查

第一,把数据集和源码打包前删掉runs/train下的中间权重,只用best.pt,避免文件过大。第二,确认detect.py与val.py可以离线运行,即权重、数据集、图片都在本地,不依赖任何网络路径。第三,将一张测试图片、一段3秒短视频和对应的检测输出图放在同一个目录,三者名字一一对应,截图上传到文档中作为实验效果证据。三项检查全部通过,项目才算真正交付。

提示:对于监控摄像头场景,抽帧间隔建议保持在3到5帧,模型每帧检测一次会在远处的烟头上产生闪烁识别框,反而影响演示效果。

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

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

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

立即咨询