火焰数据集YOLOv5实战:从标注格式到训练部署全解析

发布时间:2026/11/6 7:57:07
火焰数据集YOLOv5实战:从标注格式到训练部署全解析

简介:这份火焰数据集面向从事目标检测的开发者与研究者,尤其适合用YOLOv5做火焰识别、火灾预警等场景的模型训练与验证。压缩包共5260个文件,以1853张jpg图像为主体,配套1854个txt标注文件与1553个xml标注文件,分别对应YOLO格式训练标签和VOC格式位置信息,整体约194.03MB,解压后可直接组织成训练集与验证集。数据集已标注火焰的位置、形状与大小,作者给出的训练结果显示mAP@.5达0.953、mAP@.5:.95为0.679,可作为复现与调参的基准参考。目前已有4912人学习下载,适合希望跳过繁琐标注、快速进入模型训练与效果对比环节的读者,也便于在此基础上尝试数据增强、超参数调整与部署验证。

1. 火焰数据集:一份能直接喂给 YOLOv5 的标注数据到底长什么样

上周有个做园区消防巡检的朋友找我,说他模型训练 loss 一直卡在 0.8 下不去,mAP 死活上不了 0.5。我让他把数据打包发过来一看,问题根本不在模型——他手里那批火焰图片,标注框画得跟闹着玩似的,有的框把整片天空都圈进去了,有的同一张图里三处火只标了一处。这其实是做火焰检测项目最常见的翻车点:大家把精力全砸在调 YOLOv5 的 anchor 和超参上,却忽略了数据集本身的质量才是天花板。

这份火焰数据集(含标注好的标签)解决的正是这个前置问题。它面向的是想快速跑通火焰/明火检测 demo、或者给自有场景做迁移学习的开发者,标签格式对齐 YOLOv5 的 txt 标注规范,拿到手不用再自己从零画框、转格式、清洗。下面我按「这数据怎么用起来 → 目录和标签怎么读 → 训练脚本怎么接 → 踩过哪些坑 → 怎么改成自己的场景」这条线拆一遍,新手能照着跑,熟手能直接看标签结构和改造点。

2. 数据集结构与 YOLOv5 标签格式:先搞懂每张图旁边那个 txt 在说什么

2.1 目录组织与文件对应关系

拿到压缩包解压后,常见的组织方式是按 images 和 labels 分开放,训练集、验证集再各切一刀。我一般会先tree一下看层级,确认图片和标签是不是同名同路径,这是后面能不能直接喂给 YOLOv5 的前提。

# 解压后先看目录层级,确认 images 与 labels 是否平行对应 tree -L 3 fire_dataset/ # 典型输出结构(不同批次可能略有差异,以实际为准) fire_dataset/ ├── images/ │ ├── train/ # 训练图片,jpg/png 混排 │ └── val/ # 验证图片 ├── labels/ │ ├── train/ # 与 images/train 同名的 .txt │ └── val/ └── data.yaml # 数据集描述文件,指向上面两个路径

这里的关键是「同名同相对路径」:images/train/abc.jpg必须对应labels/train/abc.txt。YOLOv5 的 dataloader 是按这个规则去拼路径的,少一个 txt 它不会报错,只会把那张图当负样本处理——这就是很多人训练时明明标了火、模型却学不会的原因之一。我习惯在训练前跑一遍配对检查,把孤儿图片和孤儿标签都揪出来。

import os from pathlib import Path root = Path("fire_dataset") for split in ["train", "val"]: imgs = {p.stem for p in (root / "images" / split).glob("*.*")} labs = {p.stem for p in (root / "labels" / split).glob("*.txt")} # 图片有、标签没有 → 会被当负样本;标签有、图片没有 → 直接报错 print(split, "缺标签:", len(imgs - labs), "缺图片:", len(labs - imgs))

这段脚本干的事很朴素:按文件名主干(stem)做集合差。imgs - labs是那些有图没标签的,训练时会被当成纯背景;labs - imgs是标签找不到图,dataloader 读的时候会抛异常。跑完如果两个数都是 0,说明配对干净,可以往下走。

2.2 YOLO txt 标签的五个数字怎么读

每个 txt 里一行一个目标,格式是class x_center y_center width height,后四个都是归一化到 0~1 的相对值。火焰数据集通常只有一类,class 就是 0。很多人第一次看这种标签会懵:为什么不是像素坐标?因为归一化之后图片 resize 到 640 也不用重算标签,这是 YOLO 系列能随便改输入尺寸的底气。

# labels/train/0001.txt 示例:一行一个火焰目标 0 0.512 0.634 0.087 0.152 0 0.221 0.480 0.045 0.093

第一行意思是:类别 0(火焰),框中心在图片宽 51.2%、高 63.4% 的位置,框宽占图宽 8.7%,高占图高 15.2%。想还原成像素坐标就乘回原图宽高。我排查标注质量时经常写个小脚本把框画回图上,肉眼扫一遍有没有框歪、框大、漏标——这一步比看 loss 曲线有用得多。

import cv2 def draw_yolo_box(img_path, label_path, out_path): img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path) as f: for line in f: c, xc, yc, bw, bh = map(float, line.split()) # 归一化中心点+宽高 → 左上右下像素坐标 x1 = int((xc - bw / 2) * w); y1 = int((yc - bh / 2) * h) x2 = int((xc + bw / 2) * w); y2 = int((yc + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(out_path, img)

参数说明:xc/yc是框中心相对坐标,bw/bh是框宽高相对值,减半加半就得到左上右下。画出来如果发现框普遍偏大或偏小,多半是标注工具导出时坐标系搞错了(有的工具用左上角而非中心点),这种数据得整批返工,别指望模型自己纠偏。

2.3 data.yaml 里三个必须改对的字段

YOLOv5 训练靠一个 yaml 描述数据从哪来、有几类、类名叫什么。这份数据集一般自带一个,但路径往往是作者机器上的绝对路径,直接跑必挂。

# data.yaml:路径改成你解压后的实际位置 train: ./fire_dataset/images/train val: ./fire_dataset/images/val nc: 1 # 类别数,火焰数据集通常就是 1 names: ['fire'] # 类别名,顺序要和标签里的 class id 对上

train/val支持相对路径(相对训练启动目录)也支持绝对路径,我一般用相对路径配--project参数,换机器不用改文件。nc和names长度必须一致,且names的下标就是标签里的 class 值——如果哪天你往数据里加了「烟雾」类,标签写成 1,这里就得补成['fire', 'smoke'],否则烟雾会被当成背景学。这是迁移改造时最容易漏的一步。

3. 用 YOLOv5 跑通训练与推理:从 clone 到看到框的完整链路

3.1 环境准备与依赖版本

YOLOv5 对 PyTorch 版本比较敏感,我一般锁一个能跑的组合,别上来就装最新版,玄学问题多半出在这。下面这套是这几年反复验证过的稳妥搭配。

# 建独立环境,避免和系统里的 torch 打架 conda create -n fire python=3.8 -y conda activate fire # 装 PyTorch(按你的 CUDA 版本选,这里以 cu118 为例) pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 拉 YOLOv5 代码并装依赖 git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt

python=3.8是保守选择,3.9/3.10 大多也能跑;torch 和 torchvision 版本要配套,装完用python -c "import torch; print(torch.cuda.is_available())"确认 GPU 认到了。requirements 里会装 opencv、matplotlib、pyyaml 这些,如果公司内网 pip 慢,配个镜像源就行。这一步翻车的典型表现是torch.cuda.is_available()返回 False,八成是 CUDA 版本和 torch 对不上,重装对应 wheel 即可。

3.2 训练命令与关键参数怎么调

数据配好、环境通了,训练就一行命令的事。但参数怎么给,直接决定你能不能在一晚上看到收敛。

# 从预训练权重起步,小数据集也能较快收敛 python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data ./fire_dataset/data.yaml \ --weights yolov5s.pt \ --project runs/train \ --name fire_exp1

逐项说:--img 640是输入分辨率,火焰目标通常不大,640 够用,显存紧张可以降到 512;--batch 16按显存调,8G 显存跑 yolov5s 大概能到 16,爆显存就减半;--epochs 100是上限,配合默认的早停(patience 100 轮无提升才停,小数据集可手动调小);--weights yolov5s.pt用 COCO 预训练权重做迁移,比从零训快得多,这是小数据集能出效果的关键;--project/--name决定结果落盘位置,方便多次实验对比。训练日志里重点盯mAP@0.5和box_loss,前者涨、后者降才算正常。

3.3 推理验证:拿几张图先看框对不对

训练完别急着上业务,先拿验证集或自己拍的图跑推理,肉眼确认框的位置和置信度。这一步能提前暴露标签问题和过拟合。

# 用训练出的 best.pt 对单张图/整个目录推理 python detect.py \ --weights runs/train/fire_exp1/weights/best.pt \ --source ./fire_dataset/images/val \ --conf-thres 0.4 \ --save-txt

--source可以是单图、目录、视频甚至摄像头编号;--conf-thres 0.4是置信度阈值,火焰场景我一般先给 0.4 看召回,业务上怕漏报就再降到 0.25;--save-txt会把预测框按 YOLO 格式存下来,方便和真值对比算指标。结果默认在runs/detect/exp*/下。如果发现框位置对但类别置信度普遍偏低,多半是训练轮次不够或学习率没退到位;如果框乱飞,回去查标签。

4. 避坑与排查:火焰数据集训练里最容易翻车的五件事

4.1 现象:loss 正常降但 mAP 一直 0,原因:标签路径没对上

训练日志里 box_loss 从 2 降到 0.5,看着挺美,但验证集 mAP 始终是 0。这种情况九成是 dataloader 根本没读到标签——要么data.yaml里train路径写错,要么 labels 目录名拼错(比如写成label)。YOLOv5 找不到标签时不会中断,而是把图当负样本,模型学到的全是「没有火」。解决办法:训练启动时看它打印的Scanning ... images, ... backgrounds,backgrounds 数量如果等于图片总数,就是标签没读到,回头核对路径和文件名配对。

4.2 现象:显存爆掉 OOM,原因:batch 和 img 一起给大了

CUDA out of memory是新手第一课。火焰数据集图片尺寸不一,YOLOv5 会统一 letterbox 到--img指定尺寸,但 batch 一大显存就顶不住。解决顺序:先把--batch减半,还不行再降--img到 512 或 416;另外--workers开太大也会吃内存,Windows 上建议设 0 或 2。别一上来就上多卡,单卡调通了再说。

4.3 现象:验证集效果好、实拍图全漏,原因:数据分布太单一

验证集 mAP 0.9,拿手机拍段视频一跑,几乎不出框。这是火焰数据集最隐蔽的坑:训练图可能全是白天、近距离、清晰火焰,而实际场景是夜间、远距离、烟雾遮挡。数据集的 val 集和 train 同分布,指标好看但不代表泛化。解决办法是往训练集里补夜间图、远景图、带烟的图,或者用 mosaic、HSV 增强把亮度对比度拉开。我一般会留一批完全没参与训练的实拍图做「脏测试」,指标只信这个。

4.4 现象:同一团火出好几个框,原因:NMS 阈值和标注重叠

推理时一团火被框了三四次,或者相邻两个目标被合并成一个。前者是 NMS 的--iou-thres给太高(默认 0.45),重叠框没被抑制;后者是给太低,把挨得近的真目标误删。火焰形状不规则、标注框容易重叠,这个阈值得按场景微调。另外如果标注时同一团火被不同人重复标了多个框,训练出来也会重复检测,这种得在数据清洗阶段按 IoU 去重。

4.5 现象:训练几轮就过拟合,原因:数据量小且没做增强

小批量火焰图(几百张)训到二三十轮,训练 loss 继续降但验证 mAP 掉头向下,典型过拟合。YOLOv5 默认开了 mosaic、mixup、HSV 增强,但数据太少时还是不够。我的做法是:把--epochs压到 50 以内配合早停,--weights一定用预训练,再手动把hyp.yaml里的mosaic概率调高、degrees稍微开一点旋转。数据量实在少,优先补数据而不是调模型,这是血泪经验。

5. 二次开发与迁移改造:把这份火焰数据变成你自己场景的检测器

拿到一份现成标注数据,真正的价值不在跑通 demo,而在把它当成起点改造成自己场景能用的模型。我一般分三步走,每步都有验证手段,避免改完不知道哪步出的问题。

第一步是扩类与改标签。如果你除了火焰还要检测烟雾,最省事的做法不是重标全部数据,而是保留火焰标签、只对含烟图片补标 class 1,然后同步改data.yaml的nc: 2和names: ['fire', 'smoke']。改完先跑2.1那个配对检查脚本,再抽 20 张画框目检,确认新类标签没串位。这里有个容易忽略的点:新增类的样本量要和火焰类大致平衡,否则模型会偏向多数类,烟雾召回上不去。

第二步是换 backbone 或改输入尺寸。火焰目标在监控画面里往往很小,640 输入下可能只剩十几个像素。我试过把--img提到 1280 配合 yolov5m,小目标召回明显改善,代价是显存和推理耗时翻倍。如果部署在边缘设备上,反而要往小了改,用 yolov5n + 416 输入,牺牲一点精度换帧率。改完的验证方法很直接:固定同一批测试图,对比改前改后的 mAP@0.5 和单帧耗时,两个指标一起看,别只看精度。

第三步是导出与部署验证。训练满意后导出 ONNX 或 TensorRT,这一步经常出「Python 里好好的,部署端结果对不上」的问题。常见原因是预处理没对齐——YOLOv5 推理时做了 letterbox 填充,部署端如果直接 resize 会拉伸变形,框就偏了。导出后务必用同一张图分别跑 PyTorch 和部署端,比对输出框坐标,误差在几个像素内才算过。

改造方向关键改动验证手段
扩类data.yaml 的 nc/names + 补标配对检查 + 抽图目检
小目标提高 img 尺寸或换更大模型固定测试集比 mAP 与耗时
边缘部署换 yolov5n、降输入尺寸帧率 + 漏检率实测
导出部署letterbox 预处理对齐PyTorch 与部署端框坐标比对

有个细节值得单独说:迁移到自有场景时,别把这份数据集的 val 集直接当最终评估集。它的分布和你现场不一样,指标会虚高。正确做法是从自己场景里单独留一批图做测试集,哪怕只有几十张,也比在公开分布上刷到 0.95 有意义。我吃过这个亏——模型在数据集验证集上漂亮得不行,装到现场摄像头第一天就漏了两处明火,回头查就是夜间逆光场景训练集里一张都没有。

从那以后我每次拿到任何标注数据集,都强制先跑一遍配对检查和画框目检,再留一批「脏数据」不进训练只做验收,这套习惯帮我省了太多返工。这份火焰数据集的价值就在于它把最耗时的标注环节替你做了,你省下的时间应该花在场景适配上,而不是从零画框。希望帮到你。

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