简介:目标检测是计算机视觉的核心任务之一,旨在识别图像中的物体并定位其位置。其原理通常基于深度学习模型,通过卷积神经网络提取特征,并预测边界框和类别。这项技术的价值在于能够自动化、高精度地完成视觉感知,极大地提升了安防、工业质检等领域的效率。在众多应用场景中,火灾预警是一个典型且重要的方向,它要求模型具备实时性和高可靠性。本文聚焦于使用YOLOv5这一流行的目标检测框架,结合一个包含4000多张图片的火焰数据集,详细阐述了从环境搭建、数据标注、模型训练调优到最终部署的完整工程实践路径,为开发者构建类似的实时检测系统提供了可复用的解决方案。
1. 项目概述与核心价值
最近在做一个安防相关的项目,其中有一个核心需求是实时识别监控画面中的火焰。这听起来像是计算机视觉里一个经典的应用场景,但真上手做,你会发现从数据准备到模型部署,每一步都有不少门道。我最终选择了YOLOv5这个目前工业界和学术界都挺火的算法框架,并且自己整理标注了一个包含4000多张图片的火焰数据集。整个过程走下来,感觉收获颇丰,也踩了不少坑,今天就把这个“火焰识别检测”项目的完整实现路径、技术细节和实操心得系统地梳理一下,希望能给想做类似目标检测项目的朋友一些参考。
这个项目本质上是一个特定场景下的目标检测任务。它的核心价值在于,能够自动化、高精度地识别图像或视频流中的火焰区域,并给出其位置(边界框)。这比传统基于温度或烟雾的传感器方案更直观、更前置,尤其适用于大范围、开放空间的早期火灾预警,比如森林防火、仓库监控、厨房安全等。YOLOv5以其在精度和速度上的优秀平衡,以及极其友好的工程化实现,成为了完成这个任务的首选工具。而一个高质量、针对性的数据集,则是模型能否“学好”的关键。我准备的这4000多张火焰图片,涵盖了室内、室外、白天、夜晚、近景、远景、大火苗、小火星等多种场景,就是为了让模型具备强大的泛化能力。
2. 火焰检测项目的整体设计思路
做任何一个AI项目,动手写代码之前,理清整体思路至关重要。火焰检测不是一个新课题,但要想做得好、用得稳,需要综合考虑多个维度。
2.1 为什么选择YOLOv5?
市面上目标检测的算法很多,从两阶段的Faster R-CNN到一阶段的SSD、YOLO系列,各有优劣。我选择YOLOv5,主要基于以下几点考量:
- 速度与精度的平衡:YOLO(You Only Look Once)系列的核心思想就是“单次前向传播”完成检测,速度天生有优势。YOLOv5在YOLOv4的基础上,进一步优化了网络结构和训练策略,在保持高速度的同时,精度(mAP)也有不错的表现。对于火焰检测这种可能需要部署在边缘设备(如NVIDIA Jetson、RK3568等)进行实时分析的应用,推理速度是硬指标。
- 工程化友好程度极高:这是YOLOv5最吸引人的地方。它的代码库(GitHub - ultralytics/yolov5)结构清晰,文档相对完善,提供了从环境安装、数据准备、模型训练、验证到导出的全套脚本。对于大多数开发者来说,几乎可以“开箱即用”,大大降低了入门和部署的难度。
- 模型尺寸灵活:YOLOv5提供了从轻量级到高性能的多个预训练模型(n, s, m, l, x),你可以根据你的硬件算力和精度要求灵活选择。例如,在算力受限的嵌入式平台(如RV1106)上,可以选择YOLOv5n或YOLOv5s;在服务器端追求极致精度,则可以选择YOLOv5l或x。
- 活跃的社区与生态:YOLOv5有非常庞大的用户社区,这意味着你在实践中遇到的大部分问题,很可能已经有人遇到过并给出了解决方案。丰富的教程、博客和衍生工具(如标注工具、部署工具)也构成了强大的生态支持。
2.2 数据集:项目的基石与挑战
“垃圾进,垃圾出”(Garbage in, garbage out)在机器学习领域是铁律。对于目标检测,数据集的质量直接决定了模型性能的上限。
- 数据来源与采集:我的4000多张火焰图像主要来自几个渠道:公开数据集(如Fire Detection Dataset)、网络爬取(需注意版权)、以及部分实地拍摄和模拟实验。关键是要保证多样性:不同环境(森林、街道、房间、厂房)、不同光照条件(强光、逆光、夜晚)、不同火焰形态(明火、烟雾中的火、小火苗、爆燃瞬间)、不同尺度(占画面大部分的特写火焰和远处的小火点)都要尽可能覆盖。
- 数据标注规范:我使用LabelImg、CVAT或Roboflow这类工具进行标注。标注时统一使用
fire作为类别名。边界框(Bounding Box)要尽可能紧密地贴合火焰区域,包括摇曳的火苗尖端。对于被部分遮挡的火焰,也需要根据可见部分进行标注。一个常见的坑是标注不一致,比如有时包含烟雾,有时不包含,这会让模型产生混淆。我们团队内部会先制定详细的标注规范文档,并让所有标注人员统一培训。 - 数据格式:YOLOv5要求特定的数据格式。每张图片对应一个同名的
.txt标注文件。文件内容为多行,每行代表一个目标,格式为:<class_id> <x_center> <y_center> <width> <height>。这里的坐标是归一化后的(即除以图片宽高),取值在0到1之间。例如:0 0.5 0.5 0.2 0.3表示类别0(火焰)的一个目标,其中心点位于图片(50%, 50%)位置,宽度和高度分别为图片宽高的20%和30%。 - 数据集划分:我将4000多张数据按大约8:1:1的比例划分为训练集(train)、验证集(val)和测试集(test)。验证集用于训练过程中监控模型表现、调整超参数和进行早停(Early Stopping);测试集则是在模型训练完成后,用于最终评估其泛化性能,在整个训练过程中绝对不参与。
2.3 技术栈与工具选型
一个顺畅的项目流程离不开合适的工具。以下是本项目核心的技术栈:
- 深度学习框架:PyTorch。YOLOv5基于PyTorch实现,这是目前最主流的框架之一,灵活且生态丰富。
- 算法框架:Ultralytics YOLOv5。我们直接克隆其官方GitHub仓库。
- 开发环境:Python 3.8+, CUDA(如果使用NVIDIA GPU)。建议使用Anaconda或Miniconda创建独立的虚拟环境,避免包依赖冲突。
- 标注工具:LabelImg(本地开源)、Roboflow(在线平台,提供数据增强、格式转换等增值服务)。
- 版本控制:Git。用于管理代码、配置文件和数据集清单。
- 实验管理:可选W&B(Weights & Biases)或TensorBoard。用于可视化训练过程中的损失曲线、精度指标等,对于调参和Debug非常有用。
3. 环境搭建与YOLOv5部署
万事开头难,一个干净、稳定的环境是成功的第一步。这里我详细记录下从零开始的部署过程。
3.1 基础环境配置
我强烈推荐使用Conda来管理环境,它能很好地解决不同项目间Python版本和包版本的冲突问题。
# 1. 创建并激活一个新的conda环境,命名为yolov5,指定Python版本 conda create -n yolov5 python=3.8 conda activate yolov5 # 2. 安装PyTorch。请务必去PyTorch官网(https://pytorch.org/get-started/locally/) # 根据你的CUDA版本(通过 nvidia-smi 查看)选择正确的安装命令。 # 例如,对于CUDA 11.3: pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113 # 如果没有GPU或CUDA,则安装CPU版本 # pip install torch torchvision torchaudio注意:PyTorch版本与CUDA版本的匹配是关键。版本不匹配会导致无法调用GPU,甚至报错。如果安装后运行
python -c “import torch; print(torch.cuda.is_available())”返回False,大概率是版本问题。
3.2 克隆与安装YOLOv5
YOLOv5的官方仓库更新比较活跃,建议克隆后切换到某个稳定发布版本(Release Tag),而不是直接使用主分支(main),以避免潜在的API变动。
# 克隆仓库 git clone https://github.com/ultralytics/yolov5.git cd yolov5 # 查看可用版本标签,建议选择最新的稳定版,例如 v7.0 git tag # git checkout v7.0 # 切换到指定版本 # 安装项目依赖 pip install -r requirements.txtrequirements.txt文件包含了所有必要的依赖,如opencv-python, pandas, seaborn等。安装过程如果遇到某些包版本问题,可以尝试单独安装或稍微调整版本号。
3.3 验证安装
安装完成后,运行一个简单的测试脚本来验证环境是否正常,并快速体验YOLOv5的检测效果。
python detect.py --source data/images/bus.jpg --weights yolov5s.pt --conf 0.25这条命令的含义是:使用预训练的yolov5s.pt权重文件,对data/images/bus.jpg这张示例图片进行推理,只显示置信度大于0.25的检测结果。首次运行会自动下载yolov5s.pt模型文件。运行成功后,会在runs/detect/exp目录下生成带检测框的结果图片。如果能看到巴士被正确检测出来,说明基础环境搭建成功。
4. 数据集准备与预处理
环境好了,接下来就是重头戏——准备我们自己的火焰数据集。这是整个项目中最耗时但也最关键的环节。
4.1 数据集目录结构
YOLOv5对数据集的目录结构有明确要求。我建议按照以下方式组织,清晰且便于管理:
fire_dataset/ ├── images/ │ ├── train/ # 训练集图片,约3200张 │ ├── val/ # 验证集图片,约400张 │ └── test/ # 测试集图片,约400张 └── labels/ ├── train/ # 训练集标注文件,与images/train/一一对应 ├── val/ # 验证集标注文件 └── test/ # 测试集标注文件关键点:images和labels下的子目录名称(train, val, test)必须严格对应,且其中的文件名(不含后缀)要一一匹配。例如,images/train/fire_001.jpg对应的标注文件必须是labels/train/fire_001.txt。
4.2 创建数据集配置文件
我们需要创建一个YAML配置文件(例如fire_data.yaml),告诉YOLOv5我们的数据集在哪里、有多少个类别、类别名是什么。
# fire_data.yaml path: /path/to/your/fire_dataset # 数据集的根目录绝对路径 train: images/train # 训练集路径,相对于path val: images/val # 验证集路径,相对于path test: images/test # 测试集路径,相对于path(可选,用于最终测试) # 类别数量 nc: 1 # 类别名称列表 names: ['fire'] # 可选:下载地址/说明 # download: https://your-dataset-url.com将这个文件放在YOLOv5项目目录下(例如data/文件夹内)。路径中的/path/to/your/fire_dataset一定要替换成你本地的实际绝对路径。
4.3 数据增强策略
YOLOv5在训练时内置了强大的数据增强(Data Augmentation)功能,这能有效提升模型的鲁棒性和泛化能力。我们可以在训练命令中通过参数进行控制,但理解其原理有助于我们调整。
- Mosaic增强:将四张训练图片随机拼接成一张,让模型学习在不同背景、不同尺度下识别目标。这是YOLOv4/v5带来性能提升的关键技术之一。
- 随机仿射变换:包括缩放、平移、旋转、剪切。模拟摄像头视角变化、物体远近变化。
- 色彩空间扰动:调整图像的色调(Hue)、饱和度(Saturation)、明度(Value)。这对于火焰检测特别重要,因为火焰的颜色(红、黄、橙)和亮度在不同场景下差异很大,增强后能让模型不依赖于固定的颜色特征。
- 随机水平翻转:简单的几何翻转,能有效扩充数据。
在data/hyps/hyp.scratch-low.yaml等超参数文件中,可以找到控制这些增强强度的参数,如hsv_h,hsv_s,hsv_v,degrees,translate,scale,shear等。对于火焰检测,我通常会适度增强色彩扰动(hsv_h, hsv_s, hsv_v),因为火焰颜色是核心特征之一,但也要防止扰动过大导致模型学偏。
5. 模型训练与超参数调优
数据就绪,就可以开始“炼丹”(训练模型)了。这个过程是自动的,但我们需要理解每个步骤和关键参数。
5.1 启动训练
最基本的训练命令如下:
python train.py --img 640 --batch 16 --epochs 100 --data data/fire_data.yaml --weights yolov5s.pt --project runs/train --name fire_exp1让我逐一解释这些参数:
--img 640: 输入图片会被自动缩放到640x640像素进行训练。这是YOLOv5的默认尺寸,平衡了速度和精度。你也可以尝试更大的尺寸(如1280)以获得更高精度,但会显著增加显存消耗和训练时间。--batch 16: 批次大小(Batch Size)。一次迭代送入模型的数据量。越大训练越稳定,速度越快,但需要更多显存。如果出现“CUDA out of memory”错误,就需要减小batch值,或减小--img尺寸。--epochs 100: 训练轮数。整个数据集被完整遍历一次称为一个Epoch。100是一个常见的起始值,具体需要根据验证集损失是否收敛来决定。--data data/fire_data.yaml: 指定我们刚才创建的数据集配置文件路径。--weights yolov5s.pt: 指定预训练权重。这里使用在COCO数据集上预训练的yolov5s.pt。这是迁移学习的关键,能极大加速收敛并提升最终性能。从零开始训练(--weights ‘’)通常效果差且慢。--project runs/train --name fire_exp1: 指定训练日志、权重文件、可视化结果等的保存目录。所有输出会保存在runs/train/fire_exp1/下。
5.2 训练过程监控
训练开始后,终端会打印每个epoch的损失(box_loss, obj_loss, cls_loss)和评估指标(precision, recall, mAP@0.5, mAP@0.5:0.95)。更重要的是,YOLOv5会自动在runs/train/fire_exp1/目录下生成一系列有用的文件:
weights/best.pt: 训练过程中在验证集上表现最好的模型权重。weights/last.pt: 最后一个epoch的模型权重。results.png/results.csv: 训练过程中各项指标的变化曲线图和数据表。这是调参的核心依据。confusion_matrix.png: 混淆矩阵,查看模型在各类别上的分类错误情况。val_batchX_labels.jpg/val_batchX_pred.jpg: 验证集批次的实际标签和模型预测结果可视化对比。
实操心得:训练时一定要盯着results.png中的损失曲线。理想的曲线应该是训练损失和验证损失都平稳下降,并最终趋于平缓。如果验证损失在中间开始上升,而训练损失继续下降,这就是过拟合的典型信号,需要采取早停、增加数据增强、使用更简单的模型或添加正则化(如权重衰减)等措施。
5.3 关键超参数解析与调优
YOLOv5的超参数配置文件(位于data/hyps/)包含了大量可调参数。对于新手,我建议先使用默认的hyp.scratch-low.yaml(针对小数据集)或hyp.scratch-med.yaml。在有一定经验后,可以针对火焰检测任务进行微调。几个最值得关注的超参数:
- 学习率(lr0):这是最重要的超参数之一。它控制模型参数更新的步长。太大容易震荡不收敛,太小则收敛慢。YOLOv5使用了带热启动(warmup)和余弦退火(cosine annealing)的学习率调度器,通常默认值(0.01)是个不错的起点。如果训练不稳定(损失值NaN或剧烈波动),尝试将其调小(如0.001)。
- 权重衰减(weight_decay):一种正则化手段,防止模型过拟合。默认值(0.0005)通常适用。如果怀疑过拟合,可以尝试稍微增大(如0.001)。
- 数据增强强度:如前所述,在
hyp文件中调整hsv_h,degrees,scale等参数。对于火焰,我可能会把hsv_h(色调扰动)调低一点,因为火焰的色调范围相对固定(红黄),而过度的色调变化可能生成不真实的“紫色火焰”图片,干扰学习。 - 锚框(Anchors):YOLOv5会针对你的数据集自动计算新的锚框尺寸(在训练开始时输出“AutoAnchor: Done”信息)。这是一个非常实用的功能,意味着你通常不需要手动调整锚框。它会根据你数据集中目标框的宽高分布,聚类生成9组更适合的初始锚框。
调优建议:不要一次性改动多个参数。采用“控制变量法”,每次只调整一个你认为最重要的参数,观察results.png的变化,特别是验证集mAP的提升。使用TensorBoard或W&B可以更方便地进行超参数搜索和实验对比。
6. 模型评估与性能分析
训练完成后,我们不能只看训练日志里的数字,必须对模型进行系统性的评估,了解其真实性能。
6.1 使用验证集进行评估
YOLOv5在训练过程中已经会在验证集上计算指标。训练结束后,我们可以用保存的最佳模型(best.pt)专门在验证集上跑一次评估,生成更全面的可视化结果。
python val.py --weights runs/train/fire_exp1/weights/best.pt --data data/fire_data.yaml --img 640 --task val --save-txt --save-conf--save-txt: 将预测的边界框保存为txt文件(YOLO格式),便于后续分析。--save-conf: 在保存的txt文件中同时保存置信度。
运行后,会在runs/val/exp目录下生成评估结果。重点关注以下几个文件:
confusion_matrix_normalized.png: 归一化混淆矩阵。对于单类别任务,主要看背景被误检为火焰(假阳性)和火焰被漏检(假阴性)的比例。F1_curve.png: F1分数随置信度阈值变化的曲线。F1是精确率(Precision)和召回率(Recall)的调和平均,帮助我们选择一个平衡的置信度阈值。P_curve.png/R_curve.png: 精确率和召回率曲线。PR_curve.png: 精确率-召回率曲线,曲线下的面积就是AP(Average Precision)。mAP@0.5就是IoU阈值为0.5时的AP值,是目标检测的核心指标。
6.2 核心指标解读
对于火焰检测这样的安全应用,我们需要在多个指标间权衡:
- 精确率(Precision):模型预测为“火焰”的框中,有多少真的是火焰。高精确率意味着误报少,不会总是“狼来了”。对于避免不必要的恐慌和资源调动很重要。
- 召回率(Recall):所有真实的火焰框中,有多少被模型找出来了。高召回率意味着漏报少,不会错过真正的火灾隐患。这是安全系统的底线。
- mAP@0.5(mean Average Precision):在IoU(交并比)阈值为0.5时,对所有类别(这里就一类)计算的平均精度。这是综合衡量检测性能的核心指标。我的火焰数据集上,一个训练良好的YOLOv5s模型,mAP@0.5通常能达到85%以上。
- 推理速度(FPS):在特定硬件上,模型每秒能处理多少帧图像。这决定了能否满足实时性要求。可以用
python detect.py --weights best.pt --source 0(调用摄像头)并观察终端输出的FPS来粗略评估。
经验之谈:在实际部署中,我们往往通过调整检测时的--conf-thres(置信度阈值)来在精确率和召回率之间做取舍。如果部署环境对误报容忍度低(如家庭监控),就调高阈值(如0.5);如果对漏报容忍度低(如化工厂高危区域),就调低阈值(如0.25)。这个阈值的选择,需要结合PR曲线和实际业务需求来决定。
6.3 在测试集上进行最终“考试”
验证集参与了训练过程中的模型选择(选best.pt),因此其指标可能过于乐观。我们需要用完全没参与过任何训练环节的测试集来做最终的性能评估,这最能反映模型在真实未知数据上的表现。
python val.py --weights runs/train/fire_exp1/weights/best.pt --data data/fire_data.yaml --img 640 --task test命令和验证时类似,只是将--task参数改为test。YOLOv5会根据fire_data.yaml中的test路径找到测试集。分析测试集的结果,如果与验证集结果差距不大(例如mAP下降不超过3-5个百分点),说明模型泛化能力良好;如果差距很大,则很可能存在过拟合,需要回头检查数据划分、数据增强或模型复杂度。
7. 模型推理与部署应用
模型训练评估完毕,接下来就是让它“干活”的时候了。YOLOv5的detect.py脚本提供了极其方便的推理接口。
7.1 对图片、视频、流进行推理
# 1. 检测单张图片 python detect.py --weights runs/train/fire_exp1/weights/best.pt --source path/to/your/test_image.jpg --conf 0.4 # 2. 检测一个文件夹下的所有图片 python detect.py --weights best.pt --source path/to/image_folder/ --conf 0.4 # 3. 检测视频文件 python detect.py --weights best.pt --source path/to/video.mp4 --conf 0.4 # 4. 调用本地摄像头(实时检测) python detect.py --weights best.pt --source 0 --conf 0.4 # 5. 检测网络流(如RTSP) python detect.py --weights best.pt --source rtsp://username:password@ip:port/stream --conf 0.4--conf 0.4: 设置置信度阈值。高于此值的检测框才会被显示和保存。你可以根据之前评估的结果调整这个值。- 检测结果默认保存在
runs/detect/exp目录下,每次运行会新建一个递增的文件夹(exp, exp2, exp3...)。
7.2 将模型集成到你的应用中
detect.py脚本适合快速测试和演示。在实际项目中,我们通常需要将训练好的模型集成到自己的Python应用程序或服务中。YOLOv5提供了简洁的Python API。
import torch import cv2 from pathlib import Path # 加载自定义训练好的模型 model = torch.hub.load('ultralytics/yolov5', 'custom', path='runs/train/fire_exp1/weights/best.pt', force_reload=True) # 或者直接使用本地仓库中的模型 # model = torch.hub.load('./yolov5', 'custom', path='runs/train/fire_exp1/weights/best.pt', source='local') # 设置模型参数 model.conf = 0.4 # 置信度阈值 model.iou = 0.45 # NMS的IoU阈值 # 准备图像(支持多种输入格式:路径,URL,PIL,OpenCV,numpy等) img = 'path/to/test.jpg' # 或 cv2.imread('path/to/test.jpg')[:,:,::-1] # 进行推理 results = model(img) # 解析结果 predictions = results.pandas().xyxy[0] # 返回一个Pandas DataFrame # DataFrame列包括: xmin, ymin, xmax, ymax, confidence, class, name for index, row in predictions.iterrows(): x1, y1, x2, y2 = int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax']) conf = row['confidence'] label = row['name'] print(f"检测到 {label}, 置信度 {conf:.2f}, 位置 [{x1}, {y1}, {x2}, {y2}]") # 可视化结果(带检测框的图片) results.imgs # 原始图像列表 results.render() # 对图像进行渲染,添加检测框 for img in results.imgs: cv2.imshow('YOLOv5 Detection', img) cv2.waitKey(0) cv2.destroyAllWindows() # 也可以直接保存结果图片 results.save(save_dir='output/')这段代码展示了加载模型、推理和解析结果的基本流程。你可以将其嵌入到Flask/Django Web服务、桌面应用或视频流处理循环中。
7.3 模型导出与优化
为了在不同平台部署,我们可能需要将PyTorch模型(.pt)转换成其他格式。
- 导出为TorchScript:适用于PyTorch生态内的C++部署或移动端。
python export.py --weights best.pt --include torchscript - 导出为ONNX:一种开放的模型交换格式,被TensorRT, OpenVINO, ONNX Runtime等多种推理引擎支持。
python export.py --weights best.pt --include onnx - 导出为TensorRT:如果部署在NVIDIA GPU上,TensorRT能提供极致的推理加速。
python export.py --weights best.pt --include engine --device 0注意:TensorRT导出需要先安装TensorRT,并且过程相对复杂,涉及精度校准(FP16/INT8)等步骤。
部署考量:在资源受限的边缘设备(如树莓派、RK3568、RV1106)上部署时,需要选择最小的模型(如YOLOv5n),并可能需要进行模型量化(将FP32权重转换为INT8)来进一步减小模型体积、提升推理速度。这通常会带来轻微的精度损失,需要在速度和精度之间做权衡。
8. 常见问题、避坑指南与进阶技巧
在完成这个项目的过程中,我遇到了不少典型问题,也总结了一些提升效果的小技巧。
8.1 训练阶段常见问题
CUDA内存不足(Out of Memory)
- 现象:训练开始不久就报错
RuntimeError: CUDA out of memory。 - 原因:批次大小(
--batch)或图像尺寸(--img)设置过大,超出了GPU显存容量。 - 解决:
- 首先减小
--batch(如从16降到8或4)。 - 其次减小
--img(如从640降到416或320)。 - 检查是否有其他程序占用了大量显存。
- 在
train.py中尝试使用--adam优化器替代默认的SGD,因为Adam对批次大小不那么敏感。
- 首先减小
- 现象:训练开始不久就报错
损失值为NaN或无限大
- 现象:训练过程中损失突然变成NaN或inf。
- 原因:学习率(
lr0)设置过高;数据中存在损坏的图片或标注(如坐标超出0-1范围);梯度爆炸。 - 解决:
- 大幅降低学习率(如从0.01降到0.001)。
- 使用
python -c “from utils.general import check_dataset; check_dataset(‘data/fire_data.yaml’)”命令检查数据集格式和图片路径是否正确。 - 在超参数文件中增加梯度裁剪(
grad_clip)的值。
验证集mAP不升反降,过拟合明显
- 现象:训练损失持续下降,但验证集损失在某个epoch后开始上升,验证集mAP停滞甚至下降。
- 原因:模型过于复杂(如用了YOLOv5l/x但数据量只有几千张);训练轮数过多;数据增强不够;数据多样性不足。
- 解决:
- 使用更小的模型(从YOLOv5l切换到YOLOv5s或n)。
- 启用早停(
--patience参数,如设置--patience 50,当验证集损失连续50轮不下降时停止训练)。 - 增强数据多样性,或使用更激进的数据增强(适度增加
hsv_h,scale,flipud等参数)。 - 在超参数中增加权重衰减(
weight_decay)。
8.2 推理阶段常见问题
误检(False Positive)高
- 现象:模型将红色衣物、夕阳、车灯等误认为是火焰。
- 原因:训练数据中缺乏此类“负样本”(看起来像火焰但不是火焰的样本)。
- 解决:在数据集中主动加入一些易混淆的负样本图片,并在标注时不标注任何框(即生成一个空的
.txt文件)。这样模型会学习到这些区域“没有火焰”。这被称为“困难负样本挖掘”,对降低误报率非常有效。
小目标火焰漏检
- 现象:远处的、在画面中占比很小的火焰检测不到。
- 原因:YOLOv5默认的锚框和特征图可能对小目标不敏感;训练数据中小目标样本不足。
- 解决:
- 在数据集中增加更多包含小火焰的图片。
- 尝试使用更大的输入图像尺寸进行训练和推理(如
--img 1280),这会增加特征图分辨率,有利于小目标检测。 - 可以修改模型结构,但门槛较高。一个更简单的方法是使用YOLOv5的P6模型(如
yolov5s6.pt),它专为更高分辨率输入设计。
推理速度慢
- 现象:在目标设备上FPS达不到实时要求(如<10 FPS)。
- 解决:
- 换用更小的模型(YOLOv5n > s > m > l > x)。
- 降低推理图像尺寸(
--img 416)。 - 使用TensorRT、OpenVINO或ONNX Runtime等优化后的推理引擎。
- 对于视频流,可以尝试跳帧处理(每N帧处理一帧)。
8.3 提升模型性能的进阶技巧
模型集成(Ensemble):训练多个不同初始化或不同数据子集的YOLOv5模型,在推理时综合它们的预测结果。这几乎总能提升几个点的mAP,但代价是推理速度成倍下降。适用于对精度要求极高、对速度不敏感的场景。
python detect.py --weights best.pt second_best.pt --source test.jpg --augment测试时增强(Test Time Augmentation, TTA):在推理时对输入图像进行多种变换(如翻转、缩放),将多个预测结果合并。这能提升精度,但也会增加计算量。在
detect.py或val.py中加入--augment参数即可启用。python detect.py --weights best.pt --source test.jpg --augment利用预训练权重进行微调:如果你有更多的数据,或者想从一个更好的起点开始,可以使用在更大数据集(如COCO)上预训练的权重,而不是默认的
yolov5s.pt。有时官方会发布在特定任务上(如车辆检测)预训练的权重,用它们初始化可能收敛更快、效果更好。关注数据质量:永远不要低估数据清洗和标注质量的重要性。定期复查和修正标注错误,剔除模糊、不相关的图片,其带来的性能提升可能比调参更显著。可以考虑使用模型预测结果对未标注数据进行“预标注”,再由人工审核修正,能极大提升数据标注效率。
这个从零到一的火焰识别项目,涵盖了数据准备、模型训练、评估调优和部署应用的完整链路。最关键的两点体会是:第一,数据决定上限,算法逼近上限,在数据上多花一分功夫,效果提升立竿见影;第二,理解原理比跑通代码更重要,明白每个参数、每个步骤背后的“为什么”,才能在遇到问题时快速定位,在调优时有的放矢。希望这份详尽的记录能帮你绕过我踩过的那些坑,更快地构建出属于你自己的、稳定可靠的火焰检测系统。
本文还有配套的精品资源,点击获取