简介本资源为面向目标检测初学者与算法工程师的YOLO火灾火焰检测数据集聚焦真实场景下的火焰目标识别任务可用于安防监控、消防预警等方向的模型训练与课程实践。压缩包共2000个文件约103.66MB包含1000张高质量标注图片以及voc格式xml、yolo格式txt等标签文件并附yaml配置文件与Python划分脚本方便按需生成训练集、验证集和测试集。资源同时提供YOLO环境搭建与训练教程覆盖Windows与Linux两种平台帮助读者快速跑通训练流程并迁移到自有数据。目前已有1378人学习下载适合需要完整数据与配套脚本、希望减少数据准备成本的目标检测学习者参考使用。1. 火灾火焰检测数据集到底解决了什么工程问题做消防通道占用识别、烟火预警、林火早期发现这类项目最卡脖子的从来不是模型结构而是数据。你搜 YOLO 火灾火焰目标检测数据集大概率是手里已经有一个 YOLO 训练流程缺的是能直接喂进去的火焰标注数据。这个标题里最值钱的部分不是那 1000 张图片而是「voc、coco、yolo 三种格式标签 划分脚本 训练教程」这套组合拳——它把数据准备阶段最容易翻车的格式转换和数据集划分两件事提前做完了。火焰检测和常规目标检测有个本质区别火焰没有固定形状边界模糊同一张图里可能同时存在明火、烟雾、反光、夕阳、暖色灯光这些强干扰源。这意味着数据集的质量直接决定模型是学到「火焰」还是学到「亮橙色区域」。1000 张图片属于小规模数据集适合做迁移学习微调不适合从零训练。如果你打算用 YOLOv8 或 YOLOv5 在 V100 上跑这批数据配合预训练权重大概几小时就能出一个能用的基线模型。这篇文章面向三类人刚接触 YOLO 训练、想拿一份现成数据跑通全流程的新手手里有数据但被 VOC 转 YOLO 坐标对不上折磨过的熟手以及需要评估「这个方向值不值得投入」的技术负责人。下面从数据格式拆解讲到训练参数再到我踩过的坑尽量让你少走弯路。2. 三种标签格式的差异与转换逻辑2.1 VOC、COCO、YOLO 各自存了什么很多人拿到数据集直接开训结果 loss 不降回头查才发现标签格式和模型要求对不上。先把三种格式的存储结构说清楚。VOC 格式的核心是每张图片对应一个 XML 文件里面用bndbox记录xmin、ymin、xmax、ymax这四个值是像素绝对坐标。它的优点是可读性强用文本编辑器打开就能看懂缺点是文件多、解析慢而且不同标注工具导出的 XML 字段名可能不一致。COCO 格式把所有标注塞进一个 JSON 文件用images、annotations、categories三个数组组织。bbox字段是[x, y, width, height]注意这里是左上角坐标加宽高不是右下角坐标。COCO 的 JSON 结构嵌套深手写容易出错但适合多任务检测、分割、关键点统一管理。YOLO 格式最简每张图片对应一个.txt文件每行是class_id x_center y_center width height后四个值全部是相对于图片宽高的归一化值范围 0 到 1。它没有坐标原点歧义但一旦归一化算错模型看到的框就全偏了。格式坐标类型存储方式典型用途VOC绝对像素 xmin/ymin/xmax/ymax每图一个 XML传统检测框架、标注工具交换COCO绝对像素 x/y/w/h单个 JSON多任务、学术评测YOLO归一化中心点宽高每图一个 txtYOLO 系列直接训练2.2 用脚本把 VOC 转成 YOLO坐标归一化的四个边界转换的核心就一个公式但边界条件能坑死人。下面是我常用的转换脚本处理了图片尺寸读取、坐标裁剪和类别映射。import os import xml.etree.ElementTree as ET from PIL import Image # 类别映射根据你的数据集实际类别修改 CLASS_MAP {fire: 0, smoke: 1} def voc_to_yolo(xml_path, img_path, out_dir): tree ET.parse(xml_path) root tree.getroot() # 读取图片真实尺寸不要用 XML 里写的 size有些标注工具会写错 with Image.open(img_path) as im: img_w, img_h im.size lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in CLASS_MAP: continue bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 边界裁剪防止标注超出图片范围导致归一化后为负或大于1 xmin max(0, min(xmin, img_w)) xmax max(0, min(xmax, img_w)) ymin max(0, min(ymin, img_h)) ymax max(0, min(ymax, img_h)) if xmax xmin or ymax ymin: continue # 跳过无效框 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{CLASS_MAP[cls_name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) if lines: name os.path.splitext(os.path.basename(xml_path))[0] with open(os.path.join(out_dir, name .txt), w) as f: f.write(\n.join(lines))逻辑说明先读图片真实尺寸而不是 XML 里的size因为部分标注工具在图片被裁剪后不会更新 size 字段。边界裁剪那四行是血泪经验火焰标注经常有人把框拉到图片边缘外不裁剪的话归一化值会小于 0 或大于 1YOLO 训练时虽然不报错但模型学到的位置是错的。if xmax xmin这行跳过退化框避免出现宽高为 0 的无效标注。参数说明CLASS_MAP必须和你的data.yaml里names顺序一致否则类别索引错位模型会把火焰预测成烟雾。归一化保留 6 位小数足够YOLO 内部会再处理。2.3 划分脚本训练集验证集比例与随机种子1000 张图片我一般按 8:1:1 划分训练、验证、测试。火焰场景有个特殊点如果数据里有连续视频抽帧的图片相邻帧高度相似随机划分会导致验证集泄漏训练集信息指标虚高。所以划分前最好先按来源分组。import os import random import shutil random.seed(42) # 固定种子保证每次划分结果一致方便复现 IMG_DIR images LBL_DIR labels OUT_DIR dataset RATIO (0.8, 0.1, 0.1) imgs [f for f in os.listdir(IMG_DIR) if f.lower().endswith((.jpg, .png, .jpeg))] random.shuffle(imgs) n len(imgs) n_train int(n * RATIO[0]) n_val int(n * RATIO[1]) splits { train: imgs[:n_train], val: imgs[n_train:n_train n_val], test: imgs[n_train n_val:] } for split, files in splits.items(): for sub in (images, labels): os.makedirs(os.path.join(OUT_DIR, split, sub), exist_okTrue) for f in files: shutil.copy(os.path.join(IMG_DIR, f), os.path.join(OUT_DIR, split, images, f)) lbl os.path.splitext(f)[0] .txt src_lbl os.path.join(LBL_DIR, lbl) if os.path.exists(src_lbl): shutil.copy(src_lbl, os.path.join(OUT_DIR, split, labels, lbl))逻辑说明random.seed(42)是后悔药没有它每次划分结果不同你没法判断指标变化是模型改动带来的还是数据划分带来的。按 8:1:1 切完后训练集约 800 张对于微调够用但如果你的火焰场景特别复杂比如同时有森林火、建筑火、车辆火800 张可能覆盖不全需要考虑数据增强。参数说明RATIO可以调数据量小于 500 时建议 7:2:1验证集大一点更能反映泛化能力。random.seed换成其他整数也行但一旦定了就别改。3. 用 YOLOv8 跑通火灾火焰检测训练3.1 环境配置与 data.yaml 写法YOLOv8 的环境用 pip 装就行不需要编译。V100 上跑CUDA 11.8 配 PyTorch 2.x 是稳的。pip install ultralytics # 验证环境和 GPU 是否可用 yolo checksdata.yaml是训练入口路径和类别名写错是最常见的翻车点。path: /data/fire_dataset # 数据集根目录绝对路径最稳 train: train/images val: val/images test: test/images nc: 2 names: 0: fire 1: smoke逻辑说明path用绝对路径相对路径在不同工作目录下启动训练时容易找不到。train、val是相对于path的子路径。nc是类别数必须和names长度一致也和前面转换脚本的CLASS_MAP一致。参数说明如果你的数据集只有火焰一个类nc: 1names只留0: fire。多一个类就多一组输出通道类别数写错模型结构会对不上。3.2 训练命令与关键参数怎么设yolo detect train \ data/data/fire_dataset/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ device0 \ projectruns/fire \ nameexp1逻辑说明modelyolov8s.pt用预训练权重小数据集从零训练基本没戏。epochs100配合patience2020 轮验证指标不提升就早停省时间。imgsz640是 YOLOv8 默认火焰目标如果偏小可以提到 1280但显存占用翻倍V100 16G 跑 batch16 的 640 没问题1280 要降到 batch4 左右。参数说明lr00.01是初始学习率微调场景可以降到 0.001 更稳。batch16根据显存调OOM 就减半。device0指定第一块 GPU多卡用device0,1。训练过程中重点看三个指标box_loss应该持续下降如果震荡剧烈说明学习率偏大mAP50是主指标火焰检测一般能到 0.85 以上算可用cls_loss如果居高不下检查类别映射是否错位。3.3 推理验证与混淆矩阵怎么看训练完先别急着部署用验证集跑一遍推理肉眼确认框的位置。yolo detect predict \ modelruns/fire/exp1/weights/best.pt \ source/data/fire_dataset/test/images \ conf0.25 \ saveTrue逻辑说明conf0.25是置信度阈值火焰检测建议先设低一点看召回漏报比误报在消防场景更致命。saveTrue把带框图片存下来抽查 20 张看有没有系统性偏移。混淆矩阵在runs/fire/exp1/目录下。火焰检测的混淆矩阵常见问题是 fire 和 smoke 互相混淆因为烟雾边缘和火焰过渡区域标注本身就模糊。如果混淆严重考虑把两类合并成一类「烟火」或者增加过渡区域的标注样本。4. 火焰检测训练避坑与排查记录4.1 现象loss 从第一轮就不降mAP 始终接近 0原因九成是标签格式问题。要么data.yaml里names顺序和 txt 里的 class_id 对不上要么 VOC 转 YOLO 时归一化用了 XML 里的错误尺寸。还有一种隐蔽情况图片和标签文件名不一致YOLO 找不到标签就当成背景图训练模型学到的全是「没有目标」。解决先跑一遍标签校验确认每张图都有对应 txt且 txt 里每行五个值、后四个在 0 到 1 之间。用yolo detect train启动后看日志里train: Scanning那行如果显示0 backgrounds说明标签都找到了如果backgrounds数量接近图片总数就是文件名或路径问题。4.2 现象训练到一半 loss 突然变成 nan原因学习率太大或者 batch 里有脏数据。火焰数据集如果混入了标注框宽高为 0 的样本归一化后出现 0 值反向传播时梯度爆炸。另外 V100 上跑 fp16 混合精度时某些极端宽高比的框也会触发 nan。解决先把lr0降到 0.001 试一轮。如果还 nan用脚本扫一遍所有标签把宽或高小于 0.001 的行删掉。还不行就关掉混合精度加ampFalse。我遇到过最玄学的一次是某张图片本身损坏PIL 读出来尺寸是 0换掉那张图就好了。4.3 现象验证集 mAP 很高但实际图片推理漏检严重原因数据泄漏。如果数据集里有视频抽帧相邻帧被随机分到了训练集和验证集验证集指标虚高。另外如果验证集图片和训练集来自同一场景、同一光照模型只是记住了场景而不是学到了火焰特征。解决划分前按视频来源或拍摄批次分组同一组的图片只进一个 split。验证集尽量选不同场景的图片比如训练集是白天建筑火验证集里放几张夜间林火。如果指标掉得厉害说明模型泛化不行需要补充多样化的数据或做更强的数据增强。4.4 现象模型把夕阳、暖色灯光误检成火焰原因火焰的颜色特征和这些干扰源高度重叠1000 张图片里如果负样本没有火焰但有色温干扰的图太少模型没学会区分。解决在训练集里加入 10% 到 20% 的纯负样本图片即没有火焰但包含夕阳、路灯、橙色衣服的图对应的标签文件为空。YOLO 会把它们当背景学习。另外可以开启颜色抖动增强让模型不过度依赖颜色。4.5 现象训练速度极慢GPU 利用率只有 20%原因数据加载是瓶颈。1000 张图片如果放在机械硬盘上每个 epoch 的 IO 时间可能超过计算时间。另外workers参数默认是 8但在某些容器环境里多进程 DataLoader 会卡住。解决把数据集拷到 SSD。workers根据 CPU 核数调一般设成 CPU 核数的一半。如果容器里多进程有问题设workers0用主进程加载速度反而稳定。V100 上正常情况一个 epoch 应该在 1 分钟以内。5. 小数据集涨点技巧从 1000 张里榨出更多信息1000 张图片做火焰检测基线模型大概能到 mAP50 0.85 左右想再往上走靠的不是换更大的模型而是把数据用透。我一般会做三件事。第一是离线增强扩充训练集。火焰检测对翻转、缩放、亮度变化不敏感但对马赛克增强和混合增强很吃。用 YOLOv8 内置的mosaic1.0和mixup0.1就能在训练时动态增强。如果想更激进可以离线用 Albumentations 把训练集扩到 3 倍加入随机遮挡和运动模糊模拟烟雾遮挡和相机抖动。第二是难例挖掘。先用基线模型跑一遍训练集把漏检和误检的图片挑出来人工检查标注是否有误然后把这些图复制多份加入训练。火焰检测里最难的是小火焰和远距离火焰可以专门裁出小目标区域放大后作为独立样本训练。第三是调整锚框。YOLOv8 是无锚框的但如果你用 YOLOv5火焰的宽高比分布和 COCO 通用锚框差异很大用kmeans重新聚类锚框能明显提升召回。YOLOv8 虽然不需要锚框但可以调整imgsz来匹配火焰尺度小火焰多就把输入尺寸提到 960 或 1280。验证技巧方面别只看 mAP。消防场景更关心漏报率我习惯在验证集上单独统计recall如果 recall 低于 0.9即使 mAP 好看也不能上线。另外可以画一张F1-confidence曲线找到 F1 最高点对应的置信度阈值部署时用那个值而不是默认的 0.25。最后说个我自己的习惯每次训练完把best.pt和data.yaml、训练命令一起存进一个带日期和参数的文件夹比如20250115_yolov8s_640_lr001。火焰检测项目经常要迭代过两周你根本记不住哪个权重是哪个参数跑出来的。这个习惯帮我省过好几次重新训练的时间。希望帮到你。本文还有配套的精品资源点击获取