ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

火灾烟火烟雾检测数据集与YOLOv5模型实战:2059张图训练与调优

2026/9/29 15:17:03 拓冰建站 浏览量
火灾烟火烟雾检测数据集与YOLOv5模型实战:2059张图训练与调优 简介本资源面向计算机视觉与深度学习方向的开发者、学生及安防算法研究者提供一套完整的火灾烟火烟雾检测数据集与YOLOv5训练模型可用于目标检测模型训练、算法验证及课程设计。数据集覆盖大火小火、建筑起火、草原与森林起火、车辆起火以及白天黑夜、室内外等多种场景烟雾场景与火焰保持一致标注格式为Pascal VOC含2059张图像及对应XML标签标签类别为fire。压缩包共332个文件约200.15MB包含C/C源码、Python脚本、YAML配置、CUDA内核、Shell脚本及权重文件等并附带使用说明与VOC转YOLO格式的转换脚本方便直接投入训练。目前已有838人学习下载适合希望快速搭建烟火检测基线、复现训练流程或进行二次开发的读者参考使用。1. 火灾烟火烟雾检测数据集与 YOLOv5 模型2059 张图能跑出什么结果如果你正在做园区消防预警、森林防火监控或者工业厂区的烟火识别大概率绕不开一个现实问题公开的火灾烟雾数据集要么太小要么标注质量参差要么只有图没有配套训练代码。这份资源把 2059 张带标签的火灾烟火烟雾图像和一套 YOLOv5 检测模型打包在一起还附了使用说明省掉了自己从零标注和搭训练框架的时间。它适合三类人一是刚接触目标检测、想拿一个完整数据集跑通 YOLOv5 全流程的新手二是需要快速验证烟火检测方案可行性、不想在数据准备上耗太久的算法工程师三是做安防产品原型、需要一份可复现基线模型的开发者。数据集覆盖火焰和烟雾两类目标标注格式适配 YOLO 系列模型基于 YOLOv5 训练推理和微调都能直接上手。下面从数据组织、环境配置、训练调参到推理部署把这条链路拆开讲清楚。2. 数据集结构与 YOLOv5 训练链路从目录到权重2.1 2059 张图像的目录组织与标签格式拿到一份目标检测数据集第一件事不是急着跑训练而是先确认目录结构和标签格式对不对。YOLOv5 对数据组织有固定约定图像和标签分开放标签用.txt文件每行格式为class_id x_center y_center width height坐标全部归一化到 0~1 之间。这份 2059 张的数据集通常按以下结构组织fire_smoke_dataset/ ├── images/ │ ├── train/ # 训练集图像 │ └── val/ # 验证集图像 ├── labels/ │ ├── train/ # 训练集标签 │ └── val/ # 验证集标签 └── data.yaml # 数据集配置文件常见做法是按 8:2 或 7:3 划分训练集和验证集。2059 张的规模训练集大约 1600~1700 张验证集 350~450 张。如果拿到的是 VOC 格式的 XML 标注需要先转成 YOLO 格式转换脚本如下import xml.etree.ElementTree as ET import os # 类别映射根据实际标注类别调整 classes [fire, smoke] def convert_bbox(size, box): 将 VOC 的 xmin/ymin/xmax/ymax 转为 YOLO 的归一化中心坐标 dw 1.0 / size[0] dh 1.0 / size[1] x (box[0] box[1]) / 2.0 y (box[2] box[3]) / 2.0 w box[1] - box[0] h box[3] - box[2] return (x * dw, y * dh, w * dw, h * dh) def convert_annotation(xml_path, output_dir): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) # 用图像文件名生成对应的 txt 文件名 txt_name os.path.splitext(os.path.basename(xml_path))[0] .txt with open(os.path.join(output_dir, txt_name), w) as f: for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) xmlbox obj.find(bndbox) b (float(xmlbox.find(xmin).text), float(xmlbox.find(xmax).text), float(xmlbox.find(ymin).text), float(xmlbox.find(ymax).text)) bb convert_bbox((w, h), b) f.write(f{cls_id} .join([f{x:.6f} for x in bb]) \n)这段脚本的核心逻辑是读取每张图对应的 XML 文件提取边界框的四个角点坐标再按图像宽高做归一化最终输出 YOLO 需要的中心点加宽高格式。classes列表的顺序决定了class_id必须和data.yaml里的names保持一致否则训练时类别会错位。转换完成后建议随机抽 5~10 张图用可视化脚本画框检查一遍确认坐标没有偏移。2.2 data.yaml 配置与类别定义YOLOv5 训练依赖一个 YAML 配置文件来指定数据路径和类别信息。这份资源的使用说明里一般会附带但路径需要改成你本地的实际路径# data.yaml train: ./fire_smoke_dataset/images/train val: ./fire_smoke_dataset/images/val nc: 2 # 类别数火焰 烟雾 names: [fire, smoke] # 类别名称顺序必须与标签中的 class_id 对应nc和names是最容易出错的两个参数。如果标签里只有火焰一类nc写 2 会导致训练时找不到 smoke 类样本模型学不到有效特征反过来如果实际有两类但nc写成 1第二类的标签会被忽略。训练前用一行命令统计各类别样本数# 统计训练集标签中每个类别的框数量 cat labels/train/*.txt | awk {print $1} | sort | uniq -c输出会告诉你每个class_id出现了多少次。如果某一类数量极少比如不到总数的 5%需要考虑过采样或数据增强来缓解类别不平衡。2.3 YOLOv5 环境配置与依赖安装YOLOv5 的环境不算复杂但版本兼容性有几个坑。推荐用 Python 3.8~3.10PyTorch 1.8 以上。以下是经过验证的安装流程# 克隆 YOLOv5 仓库使用官方仓库 git clone https://github.com/ultralytics/yolov5.git cd yolov5 # 安装依赖建议先建虚拟环境 pip install -r requirements.txt # 验证 PyTorch 和 CUDA 是否可用 python -c import torch; print(torch.__version__, torch.cuda.is_available())如果输出True说明 GPU 可用训练会快很多。2059 张图在单卡 8GB 显存下用 YOLOv5s 模型大约 2~3 小时能跑完 100 个 epoch。如果只有 CPU建议把batch-size降到 4 或 8epoch 也要相应减少否则一轮就要跑很久。注意requirements.txt里的torch版本可能和你的 CUDA 驱动不匹配。如果安装后torch.cuda.is_available()返回False去 PyTorch 官网按你的 CUDA 版本重新安装对应的 torch 包不要直接改 requirements 里的版本号硬装。3. 训练参数怎么设YOLOv5 超参与数据增强策略3.1 模型选型YOLOv5s vs YOLOv5m 的取舍YOLOv5 提供 s/m/l/x 四个规格参数量和精度递增。对于 2059 张的烟火数据集我的建议是先用 YOLOv5s 跑基线确认流程通了再考虑换大模型。原因很直接数据量不算大YOLOv5m 以上的模型容易过拟合而且训练时间翻倍。模型参数量适合场景2059 张图的建议YOLOv5s~7M快速验证、边缘部署首选先跑通YOLOv5m~21M精度要求较高数据增强充分时可尝试YOLOv5l~46M大规模数据不推荐容易过拟合YOLOv5x~87M服务器级训练不推荐选型逻辑是数据量在 2000 张左右时模型容量不是瓶颈数据质量和增强策略才是。与其换大模型不如把增强参数调好。3.2 训练命令与关键参数解读以下是一条完整的训练命令基于 YOLOv5s 预训练权重做迁移学习python train.py \ --weights yolov5s.pt \ # 预训练权重迁移学习起点 --data data.yaml \ # 数据集配置文件路径 --epochs 100 \ # 训练轮数 --batch-size 16 \ # 批大小显存不够就降 --imgsz 640 \ # 输入图像尺寸 --img-size 640 \ --device 0 \ # 使用第 0 号 GPUCPU 则写 cpu --workers 4 \ # 数据加载线程数 --optimizer SGD \ # 优化器SGD 或 Adam --lr0 0.01 \ # 初始学习率 --lrf 0.01 \ # 最终学习率因子 --patience 20 \ # 早停耐心值20 轮无提升则停止 --project runs/train \ # 输出目录 --name fire_smoke_v1 # 实验名称几个参数值得展开说。--weights yolov5s.pt是迁移学习的关键用 COCO 预训练权重初始化比从零训练收敛快得多尤其在小数据集上。--imgsz 640是 YOLOv5 的默认输入尺寸如果你的图像分辨率远大于 640可以调到 1280但显存占用会翻倍。--patience 20是早停机制验证集 mAP 连续 20 轮不提升就自动停止避免浪费时间。--lr0 0.01配合 SGD 是 YOLOv5 的经典组合。如果你用 Adam 优化器学习率要降到 0.001 左右否则容易震荡。--lrf 0.01控制学习率衰减的最终值余弦退火策略下学习率从lr0逐渐降到lr0 * lrf。3.3 数据增强参数烟火检测场景的特殊考量YOLOv5 默认开启了多种数据增强但烟火检测场景有几个需要特别注意的地方。火焰和烟雾的颜色、纹理是重要特征过度增强可能破坏这些特征。# 在 data.yaml 同级目录或 hyp 配置中调整 hsv_h: 0.015 # 色调增强默认 0.015烟火场景建议保持或降低 hsv_s: 0.7 # 饱和度增强默认 0.7可降到 0.5 hsv_v: 0.4 # 亮度增强默认 0.4烟雾检测建议保持 degrees: 0.0 # 旋转角度默认 0.0不建议大幅旋转 translate: 0.1 # 平移默认 0.1 scale: 0.5 # 缩放默认 0.5 mosaic: 1.0 # Mosaic 增强默认 1.0小数据集建议保持 flipud: 0.0 # 上下翻转默认 0.0火焰有方向性不建议开 fliplr: 0.5 # 左右翻转默认 0.5可以保持Mosaic 增强把四张图拼成一张对小数据集非常有效能显著提升模型泛化能力。但要注意如果烟雾目标在拼接后被截断得太厉害反而会引入噪声。训练几个 epoch 后去runs/train/fire_smoke_v1/下看train_batch*.jpg这些是实际送入网络的增强后图像能直观判断增强是否合理。提示flipud上下翻转在烟火场景建议关闭。火焰的形态有方向性上下翻转后的火焰在现实中几乎不会出现开了反而干扰学习。4. 训练过程排查与推理验证避坑与效果确认4.1 训练日志怎么看loss 曲线与 mAP 指标训练启动后控制台会输出每轮的 loss 和 mAP。重点看三个指标box_loss边界框回归损失、obj_loss目标置信度损失、mAP0.5IoU 阈值 0.5 下的平均精度。正常情况下三个 loss 应该稳步下降mAP 稳步上升。如果box_loss下降但mAP不涨大概率是标注框有问题——要么坐标偏移要么类别标错。如果obj_loss震荡剧烈检查batch-size是否太小或者学习率是否过高。训练结束后runs/train/fire_smoke_v1/下会生成results.csv和results.png用图表看趋势比盯控制台更直观。4.2 推理测试用验证集图片跑一遍训练完成后用detect.py对验证集或单张图片做推理确认模型实际效果python detect.py \ --weights runs/train/fire_smoke_v1/weights/best.pt \ --source fire_smoke_dataset/images/val \ --img-size 640 \ --conf-thres 0.25 \ # 置信度阈值低于此值的框不输出 --iou-thres 0.45 \ # NMS 的 IoU 阈值控制重叠框合并 --save-txt \ # 保存检测结果为 txt --project runs/detect \ --name val_result--conf-thres 0.25是默认值烟火检测场景可以适当调低到 0.2宁可多报不可漏报。--iou-thres 0.45控制非极大值抑制的力度如果发现同一个火焰被画了多个框把这个值调低如果相邻的两个火焰被合并成一个框调高。推理结果保存在runs/detect/val_result/下图像上会画出检测框和类别标签。建议随机抽 20~30 张人工核对统计漏检和误检的情况。如果烟雾漏检严重回头检查训练集中烟雾样本的数量和标注质量。4.3 避坑记录烟火检测训练中最容易翻车的五个点现象一训练 loss 正常下降但推理时什么都检测不到。原因data.yaml里的names顺序和标签中的class_id不一致模型学到的类别映射错了。解决用cat labels/train/*.txt | awk {print $1} | sort | uniq -c确认实际类别 ID再对照data.yaml修正。现象二mAP 一直在 0.3 以下上不去。原因标注框质量差比如框太大把背景也包进去了或者框太小只覆盖了火焰的一部分。解决用可视化脚本把标签框画到原图上逐张检查重点看烟雾这种边界模糊的目标是否标注合理。现象三训练到一半 loss 突然变成 NaN。原因学习率过高或者某张图的标签坐标超出了 0~1 范围。解决先把--lr0降到 0.001 重跑同时写个脚本扫描所有标签文件检查是否有坐标值大于 1 或小于 0 的异常行。现象四GPU 显存溢出CUDA out of memory。原因batch-size或imgsz设得太大。解决把--batch-size降到 8 或 4或者把--imgsz从 640 降到 416。也可以在训练命令里加--accumulate做梯度累积用时间换显存。现象五验证集 mAP 很高但实际场景误检严重。原因训练集和验证集来自同一批数据分布模型没有见过真实场景的多样性。解决如果条件允许额外收集一批不同场景的图片做测试集不要只看验证集指标。数据增强里的mosaic和scale能一定程度上缓解这个问题但不能完全替代真实数据。5. 从 baseline 到可用模型微调技巧与部署前验证5.1 用自己数据微调冻结层与学习率策略拿到这份资源后更常见的需求是在自己采集的烟火数据上微调。假设你手头有几百张特定场景的图片直接混合训练可能被原数据集的分布带偏。我的做法是分两步先冻结骨干网络只训练检测头再解冻全部层做小学习率微调。# 第一步冻结骨干只训练检测头学习率稍大 python train.py \ --weights runs/train/fire_smoke_v1/weights/best.pt \ --data custom_data.yaml \ --epochs 30 \ --batch-size 8 \ --freeze 10 \ # 冻结前 10 层骨干网络 --lr0 0.01 # 第二步解冻全部层小学习率微调 python train.py \ --weights runs/train/custom_v1/weights/best.pt \ --data custom_data.yaml \ --epochs 50 \ --batch-size 8 \ --lr0 0.001 \ # 学习率降一个数量级 --patience 15--freeze 10冻结前 10 层这些层负责提取通用特征边缘、纹理不需要重新学。检测头负责烟火特有的分类和定位需要适配新数据。第二步解冻后用更小的学习率避免破坏已经学到的特征。5.2 模型导出与推理速度测试训练完成后如果要在边缘设备部署需要把 PyTorch 权重导出为 ONNX 或 TensorRT# 导出 ONNX python export.py \ --weights runs/train/fire_smoke_v1/weights/best.pt \ --include onnx \ --img-size 640 \ --batch-size 1 # 导出 TensorRT需要 GPU 和 TensorRT 环境 python export.py \ --weights runs/train/fire_smoke_v1/weights/best.pt \ --include engine \ --img-size 640 \ --batch-size 1 \ --device 0导出后务必做一次速度测试确认在目标设备上的推理帧率。YOLOv5s 在 RTX 3060 上大约 5~8ms 一帧在 Jetson Nano 上大约 80~120ms。如果帧率不够考虑用--half做 FP16 量化或者换更小的输入尺寸。5.3 一个验证模型是否可用的笨办法指标好看不代表模型能用。我自己的习惯是训练完先不急着部署而是找 10 张「刁钻」的图——远景小火、浓烟遮挡、夜间光照、火焰和灯光混淆的场景——跑一遍推理逐张看结果。如果这 10 张里漏检超过 3 张说明模型还没到可用状态回去补数据或调增强。从那以后我每次训练完烟火检测模型都强制走一遍这个「10 张刁钻图」的验证流程比看 mAP 数字靠谱得多。希望这份数据集和模型能帮你少走一段从零标注到跑通训练的弯路。本文还有配套的精品资源点击获取