
简介一套完整的火灾与烟雾检测训练与部署资源面向需要快速搭建烟火识别系统的算法工程师、科研人员及计算机视觉学习者。数据集包含2059张真实场景图像覆盖大火、小火建筑、草原、森林、车辆起火以及白天/黑夜、室内/室外等多种情况均以Pascal VOC格式标注可直接配合YOLO系列模型使用。资源包同时提供YOLOv5权重文件和详细使用说明并附VOC转YOLO格式的转换脚本可显著降低数据预处理到模型推理的落地门槛。资源共332个文件、约200.15MB主要包含c/cpp/cu等源码、py脚本、yaml配置、pt/weights模型权重、jpg样例图与mp4演示视频以及md/txt使用文档目录结构清晰。目前已有833人学习下载适合作为烟火检测项目的起步数据集与参考实现。 很多人拿到一份带标签的数据集第一反应就是赶紧丢进模型里跑训练结果要么 loss 掉不下去要么训练集表现优秀、一到实拍场景就露馅。灭火检测和烟雾检测的项目尤其容易踩这个坑因为烟火场景的样本形态差异极大从室内垃圾桶起火到山林大面积烟雾视觉特征完全不是一回事。我去年用一份约 2000 张图像的火灾烟火烟雾检测数据集做了完整的 yolov5 训练与部署过程中踩了不少坑也沉淀了一些比较实用的经验。这篇就围绕这份数据集和 yolov5 模型把从数据检查、训练配置到推理调优的整个流程捋一遍给准备做烟火识别项目的朋友一个可以直接参考的路径。1. 这份火灾检测数据集的构成拆解2059张图像能做什么先说数据集本身。市面上的火灾烟火烟雾检测数据集数量不少但多数存在两个问题一是图像来源单一模型泛化能力差二是标签质量参差不齐类别定义混乱。这份 2059 张图像的数据集在规模上不算大但好处是已经完成了标签标注并且按 yolov5 的目录格式做了组织省去了我们自己标注和格式转换的大量时间成本。1.1 标签体系与类别定义拿到数据集后第一步不是直接开训而是先检查标签文件的类别定义。以常见的火灾检测数据集来说标签体系通常有两种设定方式第一种是单一类别也就是把所有烟火区域统一标记为 fire这类数据集的模型只负责回答“有没有火”第二种是多类别常见做法是分为 fire 和 smoke 两类或者细分为 flame、smoke、fire_source 等。我个人更推荐 fire 和 smoke 两类的设定。原因很简单火灾的早期阶段往往先出现烟雾而非明火如果只检测火焰等到模型告警时火势可能已经很难控制。而 smoke 单独成一类能让模型在浓烟初起时就给出反馈。我拿到的这份数据集采用的正是这种两分类体系从实际训练效果看类别划分的合理性对最终模型的影响甚至比数据量还大——如果强行把烟和火合并成一类模型在烟雾场景下的召回率会明显下降。1.2 目录组织与训练集划分解开数据集压缩包后内部目录通常是这样的结构dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── dataset.yamlimages 和 labels 互为对应train 与 val 的划分基本遵循 8:2 或 9:1。要注意的是有些数据集会把 val 和 test 合并这种情况下建议自己从 train 里再切出一部分作为验证集不要全部拿去训练。另外还要检查一个很容易被忽略的细节标签文件的格式是不是 yolov5 所需的 YOLO 格式。YOLO 格式的标签是纯文本文件每一行代表一个目标框格式为class_id x_center y_center width height所有坐标值都是归一化后的 0 到 1 之间的小数。如果你的数据集提供的是 VOC 格式的 XML 或 COCO 格式的 JSON需要先写脚本做转换。比较简单的做法是直接用 labelimg 重新导出或者用现成的格式转换脚本批量处理。这一步没做好的话后面训练时模型会直接报错或者出现 loss 为 NaN 的情况。1.3 数据质量检查的三个关键动作在开始训练之前我强烈建议做一次系统的数据质量检查这个环节很多人会跳过但它能避免你后期花大量时间排查“模型怎么不收敛”的问题。第一个动作是可视化标注结果。用 OpenCV 或 matplotlib 把标签框画到原图上逐个看是否有错标、漏标、框过大或过小的情况。烟火检测数据集里最常见的标注问题是烟雾的边缘比较模糊标注框很容易把大片背景框进去或者只框住烟雾浓密的核心区域这些不一致会让模型学得混乱。第二个动作是检查图像尺寸分布。如果数据集里的图像既有 1920x1080 的高清图又有 416x416 的小图建议统一缩放到训练尺寸再喂入网络。yolov5 本身有自适应缩放机制但差异太大的输入会拖慢训练速度也会影响小目标检测的精度。第三个动作是检查类别的样本均衡度。用一行代码统计每个类别的目标框数量import os from collections import Counter counts Counter() label_dirs [dataset/labels/train, dataset/labels/val] for d in label_dirs: for f in os.listdir(d): if not f.endswith(.txt): continue with open(os.path.join(d, f)) as fp: for line in fp: cls_id int(line.strip().split()[0]) counts[cls_id] 1 print(counts)如果 fire 类别有一万多框而 smoke 只有几百框那就属于严重不均衡这种情况下模型会倾向于把所有目标都预测为 fire。解决手段通常是给少数类提高 loss 权重或者对少数类做简单的复制增强。不少现成数据集在这方面的处理并不严谨所以拿到手之后自己动手检查校验是非常必要的。2. yolov5模型选型与训练环境准备不是所有版本都适合烟火检测模型选型需要结合数据规模和部署目标来判断。yolov5 官方提供了 n、s、m、l、x 五个不同规模的版本从最轻量的 n 到最重的 x参数量和精度依次递增。到底选哪个取决于两件事你手里的计算资源有多强以及你最终要在什么设备上跑推理。2.1 选型逻辑小模型不一定差大模型不一定稳以这份 2059 张图像的数据集来说我建议优先考虑 yolov5s 或 yolov5m而不是直接上 l 或 x。原因很直接数据量刚过 2000 张属于典型的小数据集场景大模型的拟合能力虽然强但也意味着更容易过拟合。yolov5x 在这种数据规模下可能跑到第 50 个 epoch 时已经在训练集上拿到 99% 的 mAP但在验证集上早就开始掉点了。yolov5s 是精度与速度之间比较平衡的选择单张 GPU 上训练时间可控部署到边缘设备也相对轻松如果你的场景是远距离山林监控火焰在图像中占的像素比例很小建议用 yolov5m它的特征提取层更厚对小目标的响应更好。至于 yn 和 ys 的对比yn 虽然推理极快但在小目标烟火检测上漏检率偏高不太建议。2.2 环境配置的几个版本细节yolov5 的环境配置相对成熟但版本兼容问题还是很容易让人卡住。在配置环境时先明确自己的 PyTorch 版本和 CUDA 版本再拉取匹配的 yolov5 分支。官方仓库的 release 版本相对比较稳直接 clone master 分支有时候会因为依赖更新太频繁而出现兼容性问题。Python 环境建议使用 3.8 或 3.9PyTorch 用 1.12 之后的版本。这些信息在 requirements.txt 里面都有写安装时可以通过 pip 自动解决。对于 NVIDIA 显卡用户CUDA 的安装要注意不是装得越新越好而要看 PyTorch 的编译版本是否匹配。最简单的方式是直接在 PyTorch 官网用 pip 安装对应的 wheel 包这样 CUDA 相关的依赖会一并处理好。我实际踩过的坑是一开始用 PyTorch 2.0 跑旧版的 yolov5出现了输出 shape 不一致的报错。排查后发现是 torch 版本与仓库代码中的部分算子不兼容。退回到 PyTorch 1.13 后问题解决。因此我建议在虚拟环境里固定好版本把 requirements.txt 锁住不要随手升级。2.3 预训练权重的重要性在烟火检测这个小样本场景下迁移学习的收益非常明显。使用 COCO 预训练权重作为初始值而不是从零开始训练收敛速度快且效果更好。这是因为 COCO 数据集中包含大量通用物体的特征模型在前几层已经学到了通用的边缘、纹理、颜色等低级特征我们只需要在高层特征上做微调。具体操作是下载官方提供的 yolov5s.pt 或 yolov5m.pt然后在训练时通过 --weights 参数指定。如果你的设备无法访问外网下载这些权重也可以找一些镜像源做离线下载。3. 从数据集到权重文件完整训练流程复盘训练流程是把数据集转化为可用模型的必经之路。这个环节的很多配置参数网上资料说法不一我在多次实验后沉淀了一套相对稳妥的参数组合基本适用于 2000 张级别的小样本烟火数据集。3.1 修改数据集配置文件yolov5 的训练入口是 train.py在开始训练前要先写好 dataset.yaml这个文件告诉模型“在哪里读数据、有几类、类别叫什么”。假设我们的数据放在 dataset 目录下yaml 内容大致如下train: dataset/images/train val: dataset/images/val nc: 2 names: [fire, smoke]这里有个容易出错的细节train 和 val 的路径建议写相对路径或者绝对路径但要确保运行 train.py 时的工作目录和 yaml 中写的路径能对得上。如果直接从仓库的根目录启动训练通常没问题如果是通过 IDE 的调试模式运行工作目录可能会跑到其他位置导致数据集读取失败。3.2 训练参数配置与解释训练命令的基本形式是python train.py \ --weights yolov5s.pt \ --data dataset.yaml \ --img 640 \ --batch 16 \ --epochs 100 \ --device 0重点解释几个参数--img 是输入图像的训练尺寸。对烟火检测来说640 是一个比较稳妥的起点。火焰和烟雾在画面中的占比通常不大如果资源允许可以考虑 768 或 832对提升小目标检测精度有帮助。但随之而来的是显存占用增大和训练时间变长。--batch 的大小要根据显存来定。对于 8GB 显存的卡yolov5s 配合 640 输入batch 一般设置在 8 到 16 之间。如果 batch 太小比如只有 4BN 层的统计量会很不稳定影响收敛效果。--epochs 在 2000 张的小数据集上不建议设太大。100 到 150 个 epoch 是比较合理的范围配合 early stopping 机制yolov5 自带当验证集指标连续多轮不提升时自动停止既省时间又防止过拟合。3.3 数据增强策略与过拟合防控小数据集的头号敌人就是过拟合。yolov5 内置了很多数据增强策略在训练时默认开启包括马赛克增强、随机仿射变换、HSV 色域变换、水平翻转等。对于烟火检测这些增强有两点值得注意。马赛克增强Mosaic会随机组合 4 张图拼接成一张这对小样本场景非常友好可以显著增加背景多样性。但同时烟火目标在拼接后可能被裁掉一部分导致标注框信息错乱。yolov5 官方参数里 mosiac 默认在最后 10 个 epoch 会自动关闭这是为了避免模型在训练后期被不自然的拼接图干扰属于合理设计不建议手动干预。HSV 色域增强对火焰检测有特殊价值。火焰的颜色从亮黄到暗红跨度非常大色域增强可以模拟不同光照和燃烧状态下的颜色变化让模型对“火到底长什么样”有更鲁棒的理解。我试过把 HSV 增强的强度从默认值调大一些在验证集上的效果确实有提升尤其在夜间火灾场景的检测上表现更稳定。3.4 训练过程监控与评估指标训练开始后日志会实时输出每个 epoch 的 loss 和 mAP 指标。建议重点关注 mAP0.5 和 mAP0.5:0.95 这两个指标的变化趋势。mAP0.5 是 IOU 阈值取 0.5 时的平均精度它反映的是模型“大致框准”的能力mAP0.5:0.95 是多个 IOU 阈值下的平均精度要求更严格能体现目标框定位的精细程度。对于烟火检测mAP0.5 能到 0.9 以上基本就够用了因为烟火告警类应用对框的精细度要求没那么高更看重的是“有没有框住”和“框得及时”。但如果你的场景需要联动消防喷淋或摄像头云台跟踪那么 mAP0.5:0.95 至少要保持在 0.65 以上否则定位偏差会导致联动设备误操作。训练结束后在 runs/train/exp 目录下会生成混淆矩阵、PR 曲线、F1 曲线等可视化结果。其中混淆矩阵值得多看几眼如果 smoke 类别大量被预测成 fire说明训练数据中 smoke 的样本质量或者数量存在短板需要回去补数据而不是盲目调参。4. 推理实测阈值调优与误报控制的工程细节训练的终点是模型的交付使用。很多人训练完拿到权重文件就直接部署上线结果发现在真实场景中误报率完全不可接受。对比训练时的评估指标和实际部署效果差距往往比想象中大。烟火检测对误报的容忍度非常低一个风吹草动的光影变化就触发告警的话用户很快就会把系统关掉。因此推理阶段的调优本质上是在灵敏度和误报率之间做平衡。4.1 置信度阈值和IOU阈值的选择yolov5 推理时有两个关键参数conf_thres 和 iou_thres。前者控制一个框只有当置信度超过该值时才会被输出后者控制 NMS 阶段两个重叠框是否被合并。默认值分别是 0.25 和 0.45但实际部署中我建议把 conf_thres 调高到 0.35 到 0.5 这个区间。火焰和烟雾在视觉上的特征相对明确不像行人检测那样有大量姿态和遮挡变化所以模型输出的置信度通常比较可信。如果某个目标框的置信度只有 0.2大概率是误检比如橙色的窗户反光、黄昏时的霞光甚至穿橙色衣服的人。把阈值调高能有效过滤掉这类干扰。IOU 阈值 0.45 是默认值一般在烟火检测中不需要大幅调整。如果你发现同一堆火焰出现了好几个重叠框可以适当提高 iou_thres 到 0.6 左右让 NMS 更激进地合并重叠框反过来如果两个紧挨着的火焰目标被错误合并成一个框就需要降低 iou_thres。4.2 视频流检测中的抽帧策略与告警逻辑烟火检测在多数场景下是视频流接入的而不是跑单张图片。视频流推理的性能优化上抽帧策略比较关键。这里先给出一份参数参考摄像头实时预览场景每 100 到 300 毫秒抽一帧做检测兼顾实时性和 CPU/GPU 负载火情重点监控区域每隔 500 毫秒到 1 秒抽一帧降低误报对告警系统的干扰夜间红外摄像头抽帧频率不变但需要额外对图像做对比度增强因为红外图像的特征分布与训练集中的可见光图像差异非常大更重要的一个细节是连续帧确认机制。我之前在做一个厂区监控项目时最初仅单帧出现烟火目标就触发告警结果是每十分钟就响一次全是误报。后来改成连续 3 帧都检测到目标才触发告警误报数量直线下降但真正的火情又不会因此错过——因为烟火是持续出现的视觉特征不会只闪一帧就消失这个机制实现起来成本也低强烈推荐加进告警逻辑中。4.3 边界情况的缺失与补强真实部署时最常见的翻车场景是夜间和恶劣天气。很多训练数据集中白天的样本占了 90% 以上夜间火灾场景的样本少得可怜。模型在白天场景下表现优秀但到了晚上尤其是路灯和车灯干扰的情况下误报率会急剧上升。解决思路有两个一是通过图像预处理把夜间的红外或低照度图像做增强比如直方图均衡或伽马校正再喂入模型二是补充夜间火灾样本重新做微调训练。前者的优势是改动成本低后者效果更稳定。在样本缺乏的前提下先把前者用起来同时逐步积累夜间样本这是比较实际的策略。4.4 边缘设备部署的量化取舍如果你最终要把模型部署到 Jetson Nano、树莓派或者国产边缘计算盒子那么模型量化基本是躲不开的环节。yolov5 提供了导出脚本可以把训练好的权重导出为 TensorRT、ONNX、OpenVINO 等格式。TensorRT 量化后推理速度提升明显尤其是 FP16 模式下对烟火检测这类对精度要求不算极端的任务来说几乎没有损失。但要注意量化后最好用一批真实场景的图片做一次回归测试确认所有测试用例的检测结果和量化前保持一致。我曾经遇到过量化后的模型把深色衣服的人误判为火焰的情况原因是量化误差放大了模型对颜色特征的敏感度。5. 给后来者的几条实操建议最后聊几个这次实践中感悟比较深、也最能直接影响项目成败的点。第一个建议是不要压缩数据质量检查的时间。2000 张图像的标注检查听起来很费劲实际上抽 10% 的图可视化看一下就能发现大部分问题。我曾经在一份公开数据集中发现 val 集里混入了不少与 train 集重复的图像这会导致 mAP 虚高部署后实际效果比预期差一大截。数据是模型的上限这个道理在样本量越小的场景下越明显。第二个建议是训练前把超参数锁死不要频繁调整。烟火检测的模型训练周期不长但很多人喜欢在训练途中看到 loss 下降慢就立刻改学习率或换优化器这是训练的大忌。我的做法是先用默认的超参数完整跑一轮 100 个 epoch记录基线指标再针对性地调整需要改进的部分。比如发现小目标检测不行优先改数据增强而不是调学习率发现过拟合了优先加 dropout 或减少训练轮数。第三个建议是保留训练过程中的所有中间产物。yolov5 在 runs 目录下会自动记录每次训练的超参数、评价指标、预测样例图这些在你后续写技术报告或者复现问题时非常有用。我在做项目交付的时候经常需要回头对比不同参数组合下的结果如果当时没有保存好日志和权重很多结论就说不清了。第四个建议和实际场景非常相关如果你的模型要在户外环境长期运行一定要考虑季节变化。夏天树叶茂密阳光透过树叶在地面形成的光斑很容易被模型识别成火焰冬天枯草的颜色和烟雾在特定角度下也容易混淆。训练集中如果只有单一季节的图像建议在部署前专门采集当前季节的样本做测试必要时做增量训练。这套从数据检查到训练调优再到推理部署的流程是我在烟火检测项目中反复验证过的路径。它的核心逻辑并不复杂小样本数据集的每一个环节都要以“控制过拟合、保证泛化能力”为第一目标。数据集只有 2059 张这意味着模型的上限由数据决定但最终效果的下限完全取决于你处理数据的细心程度。希望能给正在做类似项目的朋友一些参考也欢迎有实际部署经验的人在评论区交流自己遇到过的特殊场景和解决方案。本文还有配套的精品资源点击获取