简介面向住宅、工业园区、森林、加油站等场景的火焰与烟雾检测需求这份基于YOLOv5的深度学习资源提供了完整源码与配套数据集适合具备一定PyTorch基础的目标检测学习者、安全监控开发人员以及相关课程设计团队使用。包内包含约2000个文件其中1900多张JPG图像与对应txt标注文件构成可直接投入训练的数据集图像覆盖多种室内外环境与光照条件另有yaml训练配置、Python脚本、pyc缓存、预训练pt权重、Shell辅助脚本等可支撑从数据准备、模型训练到推理部署的完整流程。压缩包还附带Dockerfile、Jupyter Notebook示例、安装说明docx文档和演示视频能够显著降低环境配置门槛方便用户对照说明快速复现火焰烟雾识别效果。数据集内样本覆盖白天、夜间等不同时段有助于增强模型鲁棒性已有12849人学习下载。整体结构清晰、组件齐全可作为智慧安防、园区监测等项目的实验基础或二次开发蓝本工程实用价值较高。 如果你做的是安防、消防或者园区巡检这类视觉项目大概率会碰到一个尴尬的局面网上搜“火焰检测”看到的论文一套一套的但真正能下载下来直接跑的工程少之又少。我前阵子把一套实际部署过的方案重新整理了一遍留下了yolov5火焰和烟雾源码和数据集.zip这个压缩包里面YOLOv5的完整源码、训练脚本、已经标注好的火焰烟雾数据集都在解压后既能直接训练也能对摄像头视频流做实时推理。这篇文章就围绕这套东西展开把火焰烟雾为什么难检测、数据集该怎么看、训练时怎么调参、部署后怎么处理误报从头到尾讲清楚。1. 火焰和烟雾检测的特殊性为什么通用目标检测模型做不好这件事1.1 火焰和烟雾在视觉上“反常规”的原因先解释一个很多人会忽略的问题火焰和烟雾不是普通目标。普通目标检测里行人、车辆、水杯、桌子它们都有相对稳定的轮廓、固定的纹理和可预测的尺度范围。火焰正好反过来它时刻在跳动边缘是抖动的内部颜色从红到黄到白一直渐变同一个火焰在不同曝光条件下拍出来的样子差别非常大。烟雾更麻烦它是半透明的背景会透过烟雾显示出来边缘几乎不存在你让标注员去画一个烟雾的框框太大会把背景包进去框太小又会切断烟雾主体。这种目标特性决定了直接用通用检测模型不做针对性调整训练起来会异常吃力。还有尺度问题。火灾早期火焰和烟雾往往只占据画面的很小一部分尤其是森林防火、园区高点监控这种场景一个烟点在1080P画面里可能只有十几个像素可一旦火势蔓延整个画面又都是目标。这种极端尺度跨度和COCO数据集里猫啊狗啊那种“目标占比相对稳定”的分布完全不同。所以很多人在自己数据集上跑出来的模型检测普通目标时挺准一到火焰烟雾上就出现大量漏检核心原因就在这里模型对“目标长什么样”的先验认知和火焰烟雾的实际情况不匹配。另一个维度是时间信息。单看一张静态图一个红色灯光和一小团火焰很难区分但放到视频里火焰会闪烁烟雾会缓慢扩散这些动态特征才是判断关键。YOLOv5本身是单帧检测器不擅长利用时序信息所以单靠模型本身很难消除所有误报必须通过后处理逻辑去弥补。这一点在后面的部署环节我会详细展开。1.2 这个项目的数据与标注设定这个压缩包里的数据集通常包含两部分图片文件images和对应的标签文件labels并且已经划分好了训练集、验证集和测试集。类目一般就两个火焰fire和烟雾smoke。YOLO格式的标签长这样每一行代表一个目标框格式是类别id 中心点x 中心点y 框宽 框高坐标值都做了归一化范围在0到1之间。datasets/fire_smoke/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yamldata.yaml里指定了类别名称和图片路径训练前一定要确认里面的路径和你本地的实际目录一致不然会报文件找不到。关于标注标准我要特别提醒一点火焰的框尽量框住“可见火焰区域”不要为了把火苗根部一起包进去就把框向下拉得很大那样会让模型学到一堆无效背景烟雾的框则要框住“肉眼可辨的浓烟主体”边缘那层很淡的气体不要硬框否则标注噪声会直接传导给模型。拿到压缩包后我强烈建议你写个小脚本把标注画回图片上看一看检查框是否贴合。如果发现标注框明显偏移宁可先剔除这些样本也不要让模型去学脏数据。我自己的习惯是跑训练前至少抽5%的图片做人工目检尤其是验证集。验证集标注质量直接决定了mAP能不能正确反映模型好坏这一步值得花时间。2. 拿到压缩包后的第一件事数据检查和环境准备2.1 先看数据分布再动手训练很多拿到源码和数据集的人第一反应是直接运行python train.py。我的建议是别急先花十几分钟看数据。用脚本统计一下类别分布、每张图的平均目标数、边界框的尺寸分布。火焰烟雾数据集最常见的两个问题一是类别不均衡火多烟少或者反过来二是某些图片是网上随手扒下来的低分辨率图训练前没有清洗。如果类别分布差异很大后续训练时可以通过调整采样权重或者针对性增广来缓解但你得先知道问题存在。另一个值得做的检查是标签重合度和空标签。数据集中可能会混入个别没有标注文件的图片YOLOv5支持把它们作为背景参与训练但数量上要控制否则会让模型过度偏向“什么都不检测”。如果你发现背景图占比超过一半建议先剔除一部分。清洗完之后再确认数据目录和data.yaml中的路径一致把路径改成绝对路径或者项目内相对路径都可以但别留着别人电脑上的旧路径。这一步看似琐碎实际能帮你省掉大量排查时间。2.2 环境配置Python版本、依赖和CUDA问题环境配置是初学者劝退重灾区。这套源码建议用 Python 3.8 到 3.10 之间的版本太新的Python版本容易遇到某些依赖库还没有兼容轮子。用conda建一个独立环境最省心conda create -n fire python3.9 conda activate fire cd yolov5-fire-smoke pip install -r requirements.txtGPU环境下的头号问题是torch和CUDA版本不匹配。装完依赖后先用python -c import torch; print(torch.cuda.is_available())确认一下。如果输出False说明torch的CUDA版本不对或者显卡驱动版本太低需要根据你的CUDA版本重新安装对应的torch。CPU环境也不是不能跑训练速度会慢得离谱建议直接把输入分辨率降到512甚至416模型换成yolov5n或yolov5s。还有一个小坑依赖安装时opencv-python如果和系统自带的libGL冲突import时就会报libGL.so.1找不到。解决办法是apt-get install -y libgl1Linux环境或者直接装opencv-python-headless。这些都是常见的环境问题遇到了不用慌搜一下报错信息基本都有现成答案。3. 训练全流程拆解从预训练权重到收敛判断3.1 超参数怎么定才不浪费算力先给一套最稳妥的起步配置模型选yolov5s输入分辨率--img 640批大小根据显存来8G显存就--batch 1612G以上可以到32。训练轮数先跑150轮数据量小就加到300轮。下面的命令可以直接用python train.py --data datasets/fire_smoke/data.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 150 \ --cache--cache的作用是把图片一次性加载到内存里省去每轮训练反复读盘的耗时前提是你的内存够用。默认权重yolov5s.pt是官方在COCO上预训练的加载它做迁移学习网络底层的边缘、颜色、纹理特征对火焰烟雾依然有效比自己从头训练收敛快得多。学习率通常不用刻意调0.01的默认值对自定义数据集基本适用。但如果训练刚开始loss就爆掉或者验证集指标乱跳把hyp.scratch-low.yaml里的lr0改成0.005再试。另外建议加上--cos-lr让学习率按余弦曲线衰减我实测对小数据集更稳定。显存不够时优先减小batch而不是减小输入分辨率。火焰烟雾的小目标多分辨率降太多会直接牺牲召回率。如果想让训练更稳可以先冻结前10层微调50轮再全量训练这种两阶段方式在数据量不足时效果比较明显。3.2 看训练曲线而不是只看mAP训练结束后去runs/train/expN目录重点看results.png。这张图会画出box_loss、obj_loss、cls_loss三类loss的下降曲线以及验证集上的精确率、召回率、mAP。模型是否收敛标准是loss降到平台期、不再明显波动同时mAP0.5还在缓慢上升。有一个判断技巧如果训练loss一直降但验证loss在某个点后开始回升说明过拟合了这时模型在训练集上学到了太多无关细节对现场新场景的泛化会变差。解决办法是提前停止训练或者增加增广、减小模型复杂度。火焰烟雾任务的mAP0.5通常能跑到0.85以上但mAP0.5:0.95会明显偏低这是烟雾边界模糊导致的正常现象不用太焦虑。这个指标对边框的贴合程度极其敏感而烟雾本身就很难做到精确框定。判断模型好坏最终还是要靠视频实测。3.3 针对火焰烟雾的小目标改进如果小目标漏检严重有几个提升手段。首先是输入分辨率--img 960甚至--img 1280对小目标召回帮助显著代价是推理速度变慢、显存占用上升。其次是--multi-scale多尺度训练让模型在不同分辨率下都能适应目标尺寸的变化。训练日志里如果出现autoanchor分析锚框的环节可以多看两眼。火焰和烟雾的长宽比和COCO里的目标差异很大重新计算锚框有时能带来几个点的提升。YOLOv5训练时默认会自动分析锚框不需要手动干预。数据增广方面YOLOv5默认开启的Mosaic、HSV扰动对火焰烟雾非常有用。火焰在不同光照条件下色差极大HSV色相饱和度扰动可以模拟这种变化增强模型鲁棒性。旋转增广要少加火苗和烟雾基本是向上的旋转角度过大会制造出不真实的训练样本。4. 推理实测中的误报与漏报原因分析和完整排查链路4.1 先跑通视频/摄像头识别闭环训练完拿到best.pt第一步是把视频推理跑通python detect.py --weights runs/train/exp/best.pt \ --source 0 \ --conf 0.35--source 0表示读取本机摄像头也可以换成视频文件路径。--conf是置信度阈值低于这个值的结果会被过滤掉。如果你要在自己的业务代码里集成一般逻辑是用cv2.VideoCapture读取视频帧把帧交给模型推理再把检测结果画到帧上。YOLOv5的接口封装得很干净调用model(frame)后返回的results.xyxy[0]就是检测框坐标、置信度和类别ID。视频流处理的性能问题上一个常用优化是“跳帧”每处理一帧间隔两三帧再做一次检测中间那些帧直接沿用上一次的检测结果。火焰烟雾不像行人那样在画面中突然消失跳帧对检测实时性影响很小但可以把处理帧率提升好几倍。如果还是卡就用多线程把视频解码和模型推理拆开解码线程持续往队列里塞帧推理线程从队列取帧处理避免解码时间阻塞推理。4.2 误报漏报的主要原因部署到真实场景后最折磨人的不是模型跑不起来而是报警满天飞。我做过的项目里误报和漏报的核心原因大致可以归成几类现象常见原因解决方向夕阳、红色灯箱、车尾灯被识别成火焰火焰的颜色特征太明显模型学到的是“红色发光物”加入时序闪烁判断或检查区域颜色分布和运动特征白色水蒸气、雾被识别成烟雾纹理半透明和烟雾视觉相似利用浓度变化和运动方向过滤远处小火苗、早期烟点漏掉目标像素太少特征不明显提高输入分辨率增加小目标样本大火浓烟下目标互相遮挡目标大量重叠框重叠严重多尺度训练增加高密度场景数据其中误报的杀伤力最大。一个现场日误报几十次值班人员很快就会麻痹等真火情出现时反而没人理。所以降低误报优先级高于提高召回率。4.3 一次真实的排查过程夜间灯光误报我做一个园区高点监控项目时系统上线第一天晚上就频繁报警。把报警截图导出来一看全是红颜色的灯箱和车尾灯。当时的第一反应是调高置信度阈值从0.3提到0.5效果确实有但漏报率也跟着上来一些远处的小烟点被过滤掉了。这说明单靠阈值解决不了问题。第二步增加时序逻辑。火焰在视频中会闪烁真实火焰的信号不会静态不变。我在推理层加了一个滑动窗口同一位置连续5帧里至少3帧检测到火焰才触发报警。实现起来不难# 简化的时序确认逻辑 history deque(maxlen5) def should_alarm(current_boxes): history.append(current_boxes) fire_frames 0 for boxes in history: if any(box[5] 0 for box in boxes): # 类别0对应火焰 fire_frames 1 return fire_frames 3叠加这个逻辑后夜晚灯光误报明显减少因为灯箱和车尾灯虽然颜色像火焰但它们在画面里是静态的。这一条经验对于所有火焰检测项目都有参考价值。第三步把误报截图收集起来作为背景图放回训练集做增量训练。具体做法是新建一批不带标注文件的图片加入数据集的images/train目录中。图片里没有目标对应labels/train目录也不需要标签文件YOLOv5会把这些图当作负样本参与训练。通过这种方式模型会逐渐把“红色灯箱”视为背景。重新训练后误报从一天二三十次降到了每周一两次效果立竿见影。负样本的数量需要控制我一般控制在正样本总数的20%到40%。加太多会让模型偏保守导致真实火情的召回率下降。5. 从Demo到落地模型轻量化与工程化部署思路5.1 导出ONNX再用TensorRT加速训练好的best.pt只能跑在YOLOv5的Python环境里想要部署到生产环境或者边端设备一般要先导出成ONNX格式python export.py --weights runs/train/exp/best.pt --img 640 --include onnx得到.onnx文件后可以转成TensorRT引擎在NVIDIA显卡上获得大幅推理加速。实测下来yolov5s用TensorRT的FP16精度推理比PyTorch原生推理快2到4倍在Jetson Orin这类边缘设备上可以跑出实时帧率。如果部署在无GPU的机器上可以考虑ONNX Runtime配合INT8量化但烟雾这类半透明目标对量化比较敏感INT8精度下降会比较明显建议先跑一遍本地验证集确认效果。5.2 边缘设备和多路视频监控的注意点部署到边缘设备时模型选择要克制。树莓派这类CPU设备能跑到每秒几帧就不错了所以要么用最小的yolov5n并把输入分辨率降到416要么干脆放弃低端板子选用带GPU的Jetson系列或者x86工控机加独立显卡。监控场景需要同时处理多路视频流时我通常的做法是一个推理进程管理一个GPU上下文内部用线程池轮转处理多路摄像头而不是为每路摄像头都单独加载一个模型显存占用会小很多。工程上还有几个容易被忽略的点。报警联动不要逐帧保存图片否则一张火警卡几十秒就能把硬盘塞满。更好的设计是检测到目标后只保存触发报警前几秒到后几秒的视频片段同时推送一条带截图的消息到值班平台。这需要在推理主循环外面维护一个环形缓冲队列。模型版本管理同样重要。现场部署后每过一段时间就会收集到新场景的误报和漏报样本。我习惯按照轮次建立独立数据集目录比如datasets/fire_smoke_round2/每轮训练都在上一次的数据基础之上增加新样本训练完成后生成新best.pt并保留上一个版本方便回滚。不要在原数据集上覆盖式更新这一点很关键因为现场回传的样本质量参差直接混进去可能把模型带偏。最后分享一个我踩过多次坑之后的体会做火焰烟雾检测最大的精力投入不应该在调模型结构上而是建负样本库。漏检可以通过加分辨率、加正样本逐步改善误报却往往因为模型没见够现场的真实干扰物。每次落地新场景我都让现场把至少一周的报警截图导出来人工筛选后放进下一轮训练集当作背景图。这样迭代两三轮误报基本就压下来了。这个思路比反复调置信度阈值有用得多。本文还有配套的精品资源点击获取
