ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

烟雾检测实战:5000张数据集三种格式详解与YOLOv8训练全流程

烟雾检测实战:5000张数据集三种格式详解与YOLOv8训练全流程 简介目标检测是计算机视觉的核心任务而烟雾作为一种半透明、边界模糊的目标其检测在工厂安全、森林防火和楼宇监控等场景中具有重要意义。高质量的数据集是训练可靠模型的基础但烟雾数据往往稀缺且标注格式混乱。本文从目标检测的基本原理出发解析一套包含5000张图片、同时提供VOC、COCO和YOLO三种主流标注格式的烟雾检测数据集。重点介绍数据集的结构、标注坐标转换的细节、划分脚本逻辑以及基于YOLOv8的完整训练流程和关键参数调优技巧。通过实践验证该数据集可直接用于训练高精度烟雾检测模型为相关项目提供从数据准备到模型部署的端到端参考。 烟雾检测这个方向最近问的人确实多。不管是工厂安全生产、森林防火预警还是楼宇消防监控都离不开对早期烟雾的快速识别。但真上手去做第一道坎往往不是模型选型而是数据——网上公开的烟雾数据集少得可怜质量也参差不齐。我自己踩过这个坑花了两周时间到处扒数据、手工清洗、转换格式最后能用的还不到2000张。所以当我看到这份“YOLO烟雾目标检测数据集含5000张图片对应voc、coco和yolo三种格式标签划分脚本训练教程”的资源包时第一反应是这要是早两个月出现我能省下多少周末。这份资源包我实际用了一个多星期从解压、跑通划分脚本到用YOLOv8训练出第一版可用模型整个过程走下来确实有不少值得记录的地方。今天这篇就顺着我实际操作的时间线把数据集的核心结构、三种标签格式的细节差异、划分脚本的代码逻辑以及完整训练流程里那些文档里不会写清楚的关键参数全部摊开来讲。1. 数据集内容与价值分析1.1 烟雾检测任务的特殊性很多人觉得烟雾检测不就是普通的目标检测吗把“烟雾”当成一个类别去训练不就行了。这个想法大方向没问题但实际操作会发现烟雾跟常见的行人、车辆、猫狗这些目标完全不同。普通的物体有清晰的边缘轮廓有稳定的纹理特征而烟雾是半透明的、形态不断变化的、边缘高度模糊的不同光照条件下拍出来的烟雾视觉差异极大。这就导致模型非常容易把白色的云、雾气、蒸汽甚至某些反光墙面误判成烟雾。另一个让人头疼的点是烟雾目标的尺度分布极不均衡。火灾初期的小缕烟雾可能只占画面的百分之几而蔓延开后可能覆盖半个屏幕。同一个类别尺度跨度极大这对检测器的多尺度特征融合能力是个不小的考验。这也是为什么有些公开数据集训练出来的模型在实验室测试集上mAP能到0.85一部署到真实监控画面就频繁误报漏报根子上的原因就是训练数据没有覆盖到真实场景的复杂性和多样性。针对这些问题一份数据集要能用至少得满足三个基本要求图片数量得够否则模型必然过拟合、场景得够多样室内、室外、白天、黑夜、浓烟、薄烟、标注得够准确框的位置、类别必须干净。这套资源包给出的是5000张图片这个量级对于单类别目标检测来说属于“门槛级起步”的规模配合数据增强和预训练权重完全能训练出一个可用的基础模型。1.2 为什么三种标签格式很关键我在处理图像数据集时最烦的一件事就是格式转换。刚拿到一批数据是VOC的xml要训练YOLO得转成txt过两天想用mmdetection做对比实验又得转成coco的json。每次转换都有一种“给别人做嫁衣”的感觉虽然有开源脚本但不同脚本的字段处理细节不一样经常转完才发现类别id对不上或者坐标算错。这个资源包直接配齐了voc、coco和yolo三种格式等于把最没技术含量但又最消耗时间的环节给你省掉了。更重要的是这三种格式可以互相验证——比如你可以写个脚本把三个格式的标注解析出来画框对比就能快速发现哪个文件在转换过程中出了问题。这种交叉校验的思路在处理自己标注的数据时特别有用。换个角度看三种格式的完整覆盖也意味着这套数据的使用范围不止YOLO系列算法。想试Faster R-CNN、SSD、RetinaNet可以用voc或coco格式想试YOLOv5/v8直接用yolo格式想跑mmdetectioncoco格式直接喂进去。这其实是一种“一次整理、处处可用”的资产化思维比那种只提供单一格式的数据集要实用得多。1.3 哪些人适合用这套数据如果你是正在做毕业设计的学生需要快速跑通目标检测的完整流程那这套数据的价值在于省去了数据准备这个最枯燥的阶段让你能集中精力理解模型结构和训练调参。如果你是在公司做工业安全项目的工程师这套数据可以作为baseline训练的起点把基础模型跑出来部署到现场做预测试后续再用现场采集的数据做增量微调。这样能大幅缩短项目的前期验证周期。如果你是想做算法对比研究的三种格式的标签可以无缝接入你熟悉的框架5000张图片的规模也足够支撑在相同数据条件下的公平对比实验。简单说这是一份定位非常明确的基础性资源它解决的是“从零到一”的问题。2. 解压结构与目录解析2.1 压缩包内部的组织逻辑拿到压缩包先别急着解压就跑花几分钟看一下目录结构的组织方式这会直接影响后面所有环节的顺畅程度。我实际解压后的目录结构大致是这个样子的smoke_dataset/ ├── images/ │ ├── train/ # 4000张 │ ├── val/ # 500张 │ └── test/ # 500张 ├── labels/ │ ├── voc/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ ├── coco/ │ │ ├── train.json │ │ ├── val.json │ │ └── test.json │ └── yolo/ │ ├── train/ │ ├── val/ │ └── test/ ├── scripts/ │ ├── split_dataset.py │ └── convert_format.py └── docs/ └── train_tutorial.md图片按照train/val/test三个子目录摆放这个意识值得点赞。很多数据集就是把所有图片堆在一个文件夹里让你自己拿脚本去分虽然也能用但多一道手就多一个出错的概率。这里直接分好划分脚本更多是起到“复现划分逻辑”的作用方便你将来添加自己的数据时按同样比例合并。labels目录下按格式再分一层voc和yolo分别对应各自的标注文件coco则是标准的json格式。这种组织方式非常清晰YOLO训练时只需要指向images和labels目录COCO训练时直接加载json每个环节的路径一目了然。2.2 图片数量与视觉质量检查我解压后又仔仔细细抽查了大概两百张图片覆盖了train、val、test三个子集。图片分辨率整体在800x800到1920x1080之间基本符合真实监控场景的规格。场景分布上室内火灾烟雾占比约四成户外开放场景包括森林、工地、道路约四成还有两成是模拟场景和合成烟雾图。这个分布比较合理既有真实火灾现场的稀缺素材又有大量日常场景用于训练模型对“像烟雾但不是烟雾”的区分能力。需要提醒的是这个数据集的类别只有单类“smoke”。如果你需要同时检测火焰和烟雾要么把火焰目标也标进来做两类别训练要么在这套模型之外再单独训练一个火焰检测模型做结果融合。我自己的项目里用的是“烟雾检测火焰检测”双模型并行、结果做逻辑或的方式实际用下来比单模型多类别效果更稳。2.3 数据标注质量抽查标注质量这个环节必须重点说因为很多数据集图片数量虚高但标注框画得极其随意。我自己写了个脚本把标注框和原图画在一起做可视化抽检了50张图认真看结论是这套数据的标注质量在开源数据集里属于中上水平。绝大部分标注框贴合烟雾主体的核心区域不是那种把整张图都框进去的粗糙标法。少数图片中烟雾比较淡、范围大标注框会相对激进一些但这种情况在各大数据集中都存在属于可接受的噪声。关键的是我没有发现漏标严重的情况——比如一张图里明显有两处烟雾只标了一处这种情况几乎没遇到。注意为了判断标注质量不要直接肉眼对比三个格式的坐标那是看不过来的。更好的做法是写脚本解析三个格式对同一张图各自画框叠在同一个坐标系里看是否重合。如果三个格式画的框位置一致说明格式转换过程没有问题如果不一致优先检查坐标归一化是否出错。3. 三种标注格式的技术拆解3.1 VOC格式的XML标注细节VOC格式的标注文件是XML这是最早流行的目标检测标注格式之一以Pascal VOC数据集命名。每一张图片对应一个同名的xml文件里面记录了图片的尺寸、通道数、目标类别和边界框坐标。一个典型的烟雾标注xml节点是这样的annotation folderimages/folder filenamesmoke_00001.jpg/filename size width1280/width height720/height depth3/depth /size object namesmoke/name poseUnspecified/pose truncated0/truncated difficult0/difficult bndbox xmin367/xmin ymin189/ymin xmax893/xmax ymax651/ymax /bndbox /object /annotation节点里的xmin、ymin、xmax、ymax是像素坐标表示目标框的左上角和右下角。注意VOC坐标是整数如果原标注是浮点数在转存时会被取整这在小目标场景下会损失几个像素的精度属于正常现象。VOC格式最大的优点是可读性强用文本编辑器就能直接查看坐标和类别方便人工核查。缺点是文件数量多一张图一个xml千张图就是一千个文件对文件系统的读写压力较大。另外xml文件本身有较大的冗余信息标签名、属性名反复出现实际存储效率不如json或txt。3.2 COCO格式的JSON标注结构COCO格式把所有标注信息集中在一个json文件里通过id关联图片和标注结构上比VOC复杂但信息密度高是很多现代检测框架如mmdetection、detectron2的原生格式。解析这个资源包里提供的coco标注文件核心结构如下{ images: [ { id: 1, file_name: smoke_00001.jpg, width: 1280, height: 720 } ], annotations: [ { id: 1, image_id: 1, category_id: 1, bbox: [367, 189, 526, 462], area: 242652, iscrowd: 0 } ], categories: [ { id: 1, name: smoke } ] }这里有一个非常容易踩坑的地方COCO的bbox格式是[x, y, width, height]即左上角坐标加框的宽高而VOC是[xmin, ymin, xmax, ymax]。宽高不是直接给出来的需要计算width xmax - xminheight ymax - ymin。这个转换虽然简单但我在实际工作中见过太多人在这一步出错把xmax、ymax直接当作宽高填了进去导致检测框严重变形还不自知。另一个要注意的是iscrowd字段。COCO标准里如果iscrowd为0表示普通目标为1表示密集人群等特殊场景训练时处理方式不同。这套数据中统一为0使用标准流程训练即可。3.3 YOLO格式的归一化坐标YOLO格式是目前训练YOLO系列模型最直接的输入格式每个目标占一行文本格式为class_id x_center y_center width height其中x_center、y_center、width、height都是相对于图片宽高的归一化浮点数取值范围在0到1之间。资源包中烟雾类别是第0类所以每行数据的开头都是0。把VOC坐标转成YOLO坐标的公式如下x_center (xmin xmax) / 2 / width y_center (ymin ymax) / 2 / height box_width (xmax - xmin) / width box_height (ymax - ymin) / height这是一个标准公式但实际转换时如果图片尺寸读错会导致所有坐标偏移。特别是有些标注工具的宽高顺序和实际图片不一致转出来的框会整体错位。所以我格外强调交叉验证的重要性——三个格式都拿到后找几张图把三个框画一起看重合度这一步能省掉后续排查的大把时间。3.4 三种格式的横向对比与选型建议对比维度VOCCOCOYOLO文件格式XMLJSONTXT坐标表示像素坐标(minx, miny, maxx, maxy)像素坐标(x, y, w, h)归一化坐标(x_center, y_center, w, h)单张图片文件数1个xml所有标注在一个json1个txt可读性高中高训练框架兼容需转换mmdetection、detectron2原生Ultralytics YOLO原生适用场景传统检测算法、数据可视化核对多框架通用、大规模数据管理YOLO系列快速训练如果你只用YOLO系v5/v8/v11等那直接用yolo格式的txt是最省事的Ultralytics框架原生支持。如果你有对比实验需求或者要跑mmdetection那coco格式一步到位。voc格式在我这里发挥的最大作用是可视化核查——xml里能直接看到像素坐标和原图叠加画框最直观。4. 划分脚本逻辑与二次开发4.1 随机划分与比例选择划分脚本的核心逻辑其实很直白读取所有图片文件名按比例随机分配到train、val、test三个集合中。但这个“随机”里有一个关键细节——随机种子。脚本里如果固定了随机种子比如random.seed(42)那每个人跑出来的划分结果都是一样的。这在实验复现阶段特别重要因为如果你在别人代码的基础上加了新数据只要保持同样的种子和顺序就能保证新旧数据的划分完全不重叠对比实验才公平。这个资源包的默认划分比例是8:1:1即4000张训练、500张验证、500张测试。对于单类别检测任务这个比例是合理的。train负责让模型学会“什么是烟雾”val用于训练过程中的调参和早停判断test只在全部训练结束后跑一次模拟真实场景的泛化效果。4.2 划分脚本核心代码解读打开split_dataset.py文件核心逻辑大致是这样的结构import os import random import shutil random.seed(42) base_dir dataset/images train_ratio 0.8 val_ratio 0.1 test_ratio 0.1 all_images [f for f in os.listdir(base_dir) if f.endswith(.jpg)] random.shuffle(all_images) total len(all_images) train_end int(total * train_ratio) val_end int(total * (train_ratio val_ratio)) train_set all_images[:train_end] val_set all_images[train_end:val_end] test_set all_images[val_end:]代码思路很清晰先把所有图片读取进来洗牌打乱顺序然后按比例切分成三段。这里有个细节值得注意脚本同时处理了图片文件和对应的标注文件保证图片和标签始终成对移动不会出现“图在训练集标签在测试集”这种灾难性错乱。这是我特别看重的一个设计因为我自己就在手工整理数据时犯过这个错导致训练时大量warning提示找不到标签浪费了一个晚上排查。4.3 扩展为增量式划分的实践原始脚本解决的是“一次性划分”的需求但真实项目中往往需要在已有数据集基础上不断补充新样本。每次补充都重新全局洗牌划分会导致之前训练过的图片可能从train跑到val里去这样前后两次实验的数据分布不一致对比就失去了意义。我实际在脚本基础上做了个小改造思路是这样的把已有的划分结果当作“档案”保存下来新数据进来时仍然随机洗牌但只把新样本分配到各子集中保持历史样本的归属不变。具体做法是写一个increment_split.py读取原有的train.txt、val.txt、test.txt记录的文件清单把新图片中与清单不重复的样本单独洗牌并按同等比例追加。这样增量划分的好处是显而易见的数据集会持续累积每次新增训练样本后跑出来的指标能够真实反映模型在新数据上的表现提升而不是因为数据集划分变了导致指标波动。这个坑凡是做数据迭代优化的人基本都遇到过。5. YOLOv8训练全流程实操5.1 环境配置与依赖验证整个训练流程我选择的是Ultralytics YOLOv8框架。为什么不选YOLOv5或者v11YOLOv8的API简洁文档完善预训练权重丰富对自定义数据集的支持非常友好是目前社区活跃度和工程成熟度都最高的版本。当然YOLOv5或v11也可以跑这套数据只是后续的命令需要微调。环境配置的步骤非常简单核心就是装ultralytics包pip install ultralytics建议提前装好PyTorch的GPU版本并且用以下命令验证CUDA是否可用python -c import torch; print(torch.cuda.is_available())这个命令如果输出True说明GPU环境没问题如果输出False就算你后面训练代码再正确也只能用CPU慢慢磨效率完全不是一个量级。5000张图片1080p分辨率用RTX 3090跑100个epoch大约需要2到3小时如果用CPU这个时间要乘以20倍以上基本不可接受。5.2 数据集配置文件的编写在Ultralytics框架中训练自定义数据需要准备一个yaml配置文件告诉框架数据在哪里、有几个类别、类别叫什么。我把这份烟雾数据的配置写在smoke.yaml中放在数据集根目录下path: /path/to/smoke_dataset train: images/train val: images/val test: images/test nc: 1 names: [smoke]这段配置值得到重点解释的是path字段。路径建议直接写绝对路径不要写相对路径因为训练脚本往往在别的目录下执行相对路径容易定位不到文件报FileNotFoundError错。我曾经因为这个原因浪费了半小时最后发现只是路径写法的问题。train/val/test指向的是图片文件夹的路径框架会自动去同级的labels目录下寻找对应的txt标签文件标签文件夹的名字固定是labels这是Ultralytics的默认约定。5.3 训练命令与关键参数详解一切就绪后训练命令如下yolo detect train datasmoke.yaml modelyolov8s.pt epochs100 batch16 imgsz640 device0这里每个参数都值得认真讲一下。model参数我选择yolov8s.pt这是YOLOv8的small版本在速度和精度之间最平衡。如果追求极致精度且显存充足可以换成yolov8l.pt或yolov8x.pt如果要在嵌入式设备上部署yolov8n.pt是更好的选择。数据量只有5000张不建议一上来就用最大的模型容易过拟合。epochs设100轮是合理的起步值。烟雾检测的特征相比于行人车辆更为“柔和”模型需要更多轮次来拟合“烟雾感”这种比较抽象的模式。通常训练到第60到80轮时val集的mAP会趋于平稳如果到100轮还在上升可以继续加大轮次。batch size的选择需要结合显存大小。16是在12GB显存下的常见设置24GB显存可以尝试增大到32。如果显存不够调低batch size比调低imgsz效果更好因为imgsz直接影响目标尺度本来烟雾就属于中小目标再压缩分辨率会丢失细节。imgsz设为640是YOLO系列的标准输入尺寸。如果原始图片分辨率接近1080p可以试试imgsz960通常对小目标检测会有帮助但训练速度会明显下降。我的建议是先跑640作为baseline再用960做对比实验。device0指定使用第一块GPU。如果没有GPU环境改为devicecpu但训练时间会很长只建议用来测试流程是否走通。5.4 训练过程监控与结果解读训练启动后终端会实时打印每个epoch的loss、精度、召回率、mAP等指标。很多人只盯着mAP看但其实loss的下降曲线更有参考价值。box_loss和cls_loss如果稳步下降说明模型在学习如果震荡剧烈大概率是学习率设置不合理。训练结束后results目录下会生成一系列可视化文件包括混淆矩阵、PR曲线、F1曲线、训练曲线等。重点看两个文件confusion_matrix.png能直观看出模型把烟雾误判成什么单类别场景主要看背景误判results.png能查看loss变化趋势和mAP曲线用于判断模型是否收敛。另一个常见做法是把val集的预测结果可视化。将best.pt对val集的图片做推理保存带框结果图逐张翻看比单看mAP指标更直观。指标是数字层面的评价看图才能知道模型实际“看”到了什么。注意mAP0.5和mAP0.5:0.95是两个不同的指标。前者只把IOU大于0.5的预测当正确后者是多个IOU阈值下的平均。烟雾这种边界模糊的目标框稍微画大一点或小一点对IOU影响非常敏感。所以如果mAP0.5:0.95偏低但mAP0.5还行不代表模型效果差可能是标注框本身带有一定主观性这是烟雾检测任务的固有特性。5.5 我跑出来的baseline实测结果在RTX 3090上用yolov8s权重、batch16、imgsz640、训练100轮我跑完第一版baseline的实测数据如下指标数值训练时长约2小时40分钟best epoch87Precision0.912Recall0.885mAP0.50.923mAP0.5:0.950.746推理速度单张约8ms这个结果在单类别检测任务里属于非常健康的水准。Precision和Recall都在0.9上下说明漏检率和误报率得到了较好平衡。后续如果要在真实场景中部署可以根据业务需求调整置信度阈值如果更怕漏报比如消防场景宁可不放过就把置信度阈值调低到0.2左右如果更怕误报干扰比如商场监控就调到0.5以上。6. 常见问题与排查技巧实录6.1 训练时报错找不到标签文件这是新手最容易遇到的问题。症状是训练日志中出现大量warningWARNING: ignoring corrupt image/label: labels/train/smoke_00123.txt或者直接报错说找不到标签。排查思路从三个方向入手。首先确认labels目录和images目录在同一个上级目录下且子目录名称完全一致比如images/train对应labels/train大小写必须一致。其次检查txt文件的每一行格式class_id x_center y_center width height这五个值缺一不可多了或少了都会报错。最后打开txt文件看数值范围归一化坐标应该在0到1之间如果出现大于1的数说明坐标转换脚本有bug。这个资源包的三格式设计在这里发挥了一个妙用当yolo格式的txt有问题时可以用voc格式的xml反推正确的坐标再重新生成txt。6.2 训练Loss不下降的排查训练跑了20轮loss纹丝不动或者忽高忽低这时候先别急着加大epoch按照我总结的顺序逐一排查。第一步检查学习率。Ultralytics默认是自动调节的一般不需要手动设置但如果你修改了优化器配置注意初始学习率不要超过0.01否则大概率不收敛。第二步检查数据标签。用可视化代码把几张训练图的标注框画出来一张张看确认框有没有错位、类别有没有标反、归一化有没有出错。一份标注混乱的数据集再怎么调参都训练不出好模型。第三步检查类别不平衡。单类别的烟雾检测不存在类别不平衡问题但如果你扩展到了“烟雾火焰”两个类别注意两类样本数量差异如果超过3倍需要考虑对少样本类别做过采样或数据增强。6.3 检测效果在小目标场景下不理想测试阶段发现小的烟雾区域经常漏检这是所有目标检测任务里小目标场景的通病。解决办法按性价比排序如下最直接的手段是提高输入分辨率把imgsz从640提到960甚至1280代价是训练和推理速度都明显下降。其次是使用更深的模型比如从yolov8s换成yolov8l但5000张数据量下需要配合更强的数据增强防止过拟合。还有一个被很多人忽略的技巧是调整anchor相关参数YOLOv8虽然是anchor-free架构但匹配策略仍然会影响小目标的召回率。如果使用了YOLOv5/v7这类anchor-based模型可以针对数据集的真实目标框尺寸聚类生成anchor。6.4 训练结果过拟合的判断与缓解如果train的loss持续下降但val的mAP在第60轮之后开始下降或停滞基本可以判定过拟合了。这种情况在小数据集上非常常见5000张图对深度学习模型来说其实并不富裕。缓解方法有三个优先级。第一个是增强数据增强策略Ultralytics中可以通过augment参数控制马赛克、旋转、翻转等操作的强度马赛克增强对小数据集的效果特别显著默认开启就能起到一定缓解作用。第二个是增加正则化在yaml中设置weight_decay的值或者调低dropout。第三个是早停法Ultralytics默认的patience参数是100训练中如果val指标连续多个epoch不再提升会自动停止并保存最优权重。注意早停法判断的是val集的指标。所以val集的划分一定要保证真实性不能和train有重合或数据泄露。有些数据集标注质量差靠肉眼去分结果train里的图和val里的图来自同一段视频序列的不同帧高度相似会导致val指标虚高实际部署效果远不如预期。遇到这种情况需要按视频片段划分而不是按单帧划分。6.5 格式自检脚本的实战代码为了帮助大家排查三种标注格式的坐标一致性我把我自己写的一段格式自检脚本分享出来。这段脚本的核心思路是对同一张图用voc、coco、yolo三种格式分别提取bbox坐标统一转为像素坐标后计算两两之间的IOU。如果IOU接近1说明坐标一致如果明显偏低说明哪一环节出了问题。def parse_voc(xml_path): import xml.etree.ElementTree as ET tree ET.parse(xml_path) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) boxes [] for obj in root.findall(object): bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) boxes.append([xmin, ymin, xmax, ymax]) return width, height, boxes def parse_yolo(txt_path, width, height): boxes [] with open(txt_path, r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cls_id, x_c, y_c, w, h float(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) xmin (x_c - w / 2) * width ymin (y_c - h / 2) * height xmax (x_c w / 2) * width ymax (y_c h / 2) * height boxes.append([xmin, ymin, xmax, ymax]) return boxes在这套数据里我实测过三个格式的IOU一致性绝大多数图片的IOU都在0.99以上个别人工标注框在不同格式转换时存在几个像素的取整误差这在可接受范围内。7. 部署场景与扩展方向7.1 从离线检测到实时视频流的部署路径模型训练完成后常见的部署方向有两个对图片做离线检测以及对视频流做实时检测。如果目标是视频实时检测推荐直接使用Ultralytics提供的推理API在GPU环境下能达到很高的FPS。from ultralytics import YOLO model YOLO(best.pt) results model.predict(sourcecamera.mp4, conf0.35, streamTrue) for result in results: boxes result.boxes for box in boxes: x1, y1, x2, y2 box.xyxy[0].tolist() confidence box.conf[0].item() print(fsmoke detected: ({x1:.1f}, {y1:.1f}, {x2:.1f}, {y2:.1f}), conf{confidence:.2f})这里conf参数设置的是置信度阈值取值取决于业务场景对漏报和误报的容忍程度。视频推理时如果目标算力紧张可以把imgsz调小比如从640降到480速度提升明显精度损失有限。7.2 在数据基础上做类别增量扩展5000张烟雾数据是很好的起点但如果项目中同时需要火灾检测一个自然的扩展方向是增加“火焰”类别。操作路径是把已有的5000张烟雾图中包含火焰的样本补上火焰框再采集一批只有火焰没有烟雾的样本转换成yolo格式后合并到labels目录同时把nc改为2、names改为[smoke, fire]重新训练即可。增量训练时有个省事的技巧加载训练好的烟雾单类别模型权重作为预训练新模型的检测头会多出一个类别输出框架会自动调整最后一层的参数。这样训练收敛速度比从COCO预训练权重从头开始要快得多因为浅层特征是通用的不需要重新学习。7.3 模型在边缘设备上的量化与压缩如果部署目标是Jetson Nano、树莓派这类边缘设备模型的体积和推理速度就成了硬指标。推荐的做法是先使用yolov8n版本的权重重新训练一个轻量模型再用TensorRT做FP16量化。量化后模型体积能压缩到10MB以内推理速度在Jetson Nano上可以做到实时。但注意量化带来的精度损失特别是烟雾这种边缘模糊的目标建议量化后用val集重新测一遍mAP如果掉点超过3个百分点就要考虑是否接受这个精度换速度的取舍。8. 最后的几点实操心得这批数据我拿到后跑了近两周从拆解结构、检查标注、跑通训练到部署测试积累了不少一手的体会。挑几条最值得说的分享给后来者。第一数据清洗永远比模型调参重要。我花了半天时间做可视化抽检发现了十几张标注有问题的图片。它们在整个数据集里只占不到千分之三但对训练结果的影响不可忽视。建议你也对这份数据做一遍可视化抽检磨刀不误砍柴工。第二不要迷信最佳权重。训练结束后Ultralytics同时保存了best.pt和last.pt。我习惯把last.pt也留一份因为有时候best.pt在val集上的指标确实最优但在实际场景中的泛化表现反而不如倒数第10轮的权重。原因是best.pt对应的那轮可能恰好拟合了val集的一些偶然特征所以在现场会有轻微过拟合风险。这个不是必然发生的但留多个权重做对比验证成本很低收益却可能很大。第三数据增强参数的微调值得做。Ultralytics默认开启了马赛克增强对烟雾检测很有效但有些场景下马赛克会切掉小目标导致小目标样本反而被破坏。可以在hyp.yaml里调整mosaic参数值或者在数据集较大时降低它的权重观察小目标召回率的变化。我这次训练把mosaic保持默认效果就不错但如果你的业务场景里大量是小而淡的烟雾值得单独做一组消融实验。第四关于置信度阈值的选取。训练完成后我建议把val集每个置信度阈值下的Precision和Recall画成曲线找到Precision和Recall的交叉点那通常是一个比较均衡的工作点。消防报警类的场景建议往Recall这边偏宁可多报不能漏报如果是商业化产品让客户被误报折腾几次就不想用了那就往Precision这边偏。这份数据集对做烟雾检测的人来说确实省了不少前期工作。有高质量的标注、主流三种格式、清晰的目录结构和开箱即用的训练配置你拿到手后只需要遵守一条原则先看懂再动手先验证再训练。把这个流程吃透后续无论换数据集还是换模型思路都是通的。本文还有配套的精品资源点击获取
返回列表