1. 项目说明
随着科技的发展,图像识别与目标检测技术在自动驾驶、智能交通等领域得到了广泛应用。然而,在复杂的环境条件下,如雾天,现有的目标检测技术可能会面临识别率下降的问题。为此,我们提出了基于Yolov5的雾天行人车辆目标检测项目,以提高在复杂环境下的检测准确性。YOLOv5是近年来最先进的目标检测算法之一,其结合了高速和准确性,适用于实时场景。这里我们选用的 RTTS 数据集为例,该项目的挑战在于:
-
目标复杂
- 环境复杂,要适应各种能见度条件下的白天、阴天、雾天、霾天等气候环境;
- 场景复杂,城市道路、乡村、高速公路等场景差异性较大;
-
样本不均衡
- 类别多,包含:行人、骑车人、汽车、巴士、摩托车、自行车;
- 每张图像中包含多类目标,以及各种程度的遮挡与截断;
图 1 - RTTS 数据集示例
2. 环境说明
本示例是基于yolov5网络,在 RTTS 数据集进行了训练。
-
PaddlePaddle 2.2
-
OS 64位操作系统
-
深度学习框架:PyTorch 1.7或更高版本,用于搭建和训练Yolov5模型。
-
Python 3(3.6/3.7/3.8/3.9),64位版本
-
pip/pip3(9.0.1+),64位版本
-
CUDA >= 10.1
-
cuDNN >= 7.6
3. 数据准备
3.1 数据介绍
RTTS:雾天行人车辆目标检测_数据集-飞桨AI Studio星河社区
RTTS 数据集源自 RESIDE数据集(RESIDE-雾天数据集是一个公开的数据集,用于雾天图像处理和计算机视觉的相关研究),RTTS数据集包含 4322 张真实雾天图片,作为项目训练集。另外有 100 张真实场景图片作为验证集。图像数量分布如下表所示:
数据集 | train | val |
---|---|---|
图像数量 | 4322 | 100 |
数据预处理:对收集的图像数据进行清理和预处理,包括图像增强(如对比度增强、图像去雾)等;
3.2 数据结构
文件的组织结构如下(参考COCO):
YOLO格式标注数据文件如下:
VOC格式标注数据文件如下:
4. 模型选择
Joseph Redmon等人在2015年提出YOLO(You Only Look Once,YOLO)算法,通常也被称为YOLOv1;2016年,他们对算法进行改进,又提出YOLOv2版本;2018年发展出YOLOv3版本;2020年发布YOLOv5版本,目前v5也是这几个版本中使用最广泛的一版。
-
Yolov5是一种基于深度学习的目标检测算法,相比传统的两阶段目标检测方法,Yolov5采用单阶段的检测流程,速度上有较大优势[2]。在雾天环境下,由于能见度较低,需要处理的图像数量较多,因此使用速度较快的算法可以提高检测效率。
-
Yolov5将输入图像划分为一个固定大小的网格,并在每个网格上预测目标的边界框和类别。这种网格划分的方式使得Yolov5对于小目标的检测效果较好,能够有效地检测到雾天环境下的人和车辆目标。
-
Yolov5可以在多个尺度上进行预测,结合不同尺度的特征信息,提高检测精度。在雾天环境下,由于光线衰减和散射的影响,图像中的目标可能出现模糊或者噪声,使用多尺度的预测可以增强对目标的区分能力。
综上所述,Yolov5作为雾天人车目标检测的算法,具有速度快、对小目标检测效果好、能够利用多尺度信息等优点,能够在雾天环境下有效地检测人和车辆目标。
5. 模型训练
默认 8 卡配置,如在 AI Studio 使用单卡训练则需要修改train.sh文件。具体修改如下:
export CUDA_VISIBLE_DEVICES=0
python -m paddle.distributed.launch --gpus 0 tools/train.py -c configs-hazedet/ppyoloe/ppyoloe_crn_m_100e_hazedet.yml --eval
In [7]
! bash train.sh
6. 模型评估
基于 PaddleDetection 库,我们提供了多种预测方式,可自行选择。
模型位置: output/ppyoloe_crn_m_100e_hazedet
In [4]
! bash eval.sh
7. 模型优化
本小节侧重展示在模型迭代过程中优化精度的思路:
- Baseline:主干网络加载ImageNet预训练的CSPResNetb_m模型参数,训练100epoch后进行评估:
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.260
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.499
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.237
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.180
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.319
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.447
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.208
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.413
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.428
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.318
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.550
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.574
- COCO预训练模型:加载COCO预训练的ppyoloe_crn_m模型模型,并在RTTS数据集进行finetune训练。最终检测mAP获得14.7%的提升。
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.407
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.672
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.416
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.283
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.489
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.716
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.282
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.492
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.510
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.390
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.618
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.769
- 离线数据增强;利用去雾算法对训练集进行离线的数据增广,常见去雾方法如MSBDN、Trident-Dehazing network、FFA-net等模型。
这里我们选择了MSBDN模型,离线对训练集进行了去雾增强,并与原始训练集共同进行训练,目的是通过生成不同雾浓度的图片来丰富训练集,同时通过降低浓雾样本的识别难度,加速模型收敛。最终检测mAP获得0.6%的提升。
11583 Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.413
11584 Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.672
11585 Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.415
11586 Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.277
11587 Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.519
11588 Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.726
11589 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.282
11590 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.499
11591 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.517
11592 Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.387
11593 Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.641
11594 Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.780
8. 推理可视化
参考 infer.sh
,最终输出文件在 output
目录。
In [9]
! python tools/infer.py \
-c configs-hazedet/ppyoloe/ppyoloe_crn_m_100e_hazedet.yml \
--infer_img=dataset/hazedet/val/HR/59.png \
-o weights=output/ppyoloe_crn_m_100e_hazedet/best_model
检测前
检测前
图 2 - 图片检测前后对比(取自 output 目录)
默认执行100次epoch迭代计算,结果详情如下:
LABEL可视化:
F1值曲线:
PR曲线:
batch计算实例:
可视化推理样例如下:
9. 模型导出
导出推理模型
PaddlePaddle框架保存的权重文件分为两种:支持前向推理和反向梯度的训练模型 和 只支持前向推理的推理模型。二者的区别是推理模型针对推理速度和显存做了优化,裁剪了一些只在训练过程中才需要的tensor,降低显存占用,并进行了一些类似层融合,kernel选择的速度优化。因此可执行如下命令导出推理模型。
默认导出到 inference_model
目录。
In [10]
# 模型导出
! bash export_model.sh
10. 模型部署
使用飞桨原生推理库paddle-inference,用于服务端模型部署
总体上分为三步:
- 创建PaddlePredictor,设置所导出的模型路径
- 创建输入用的 PaddleTensor,传入到 PaddlePredictor 中
- 获取输出的 PaddleTensor ,将结果取出
#include "paddle_inference_api.h"
// 创建一个 config,并修改相关设置
paddle::NativeConfig config;
config.model_dir = "xxx";
config.use_gpu = false;
// 创建一个原生的 PaddlePredictor
auto predictor =
paddle::CreatePaddlePredictor<paddle::NativeConfig>(config);
// 创建输入 tensor
int64_t data[4] = {1, 2, 3, 4};
paddle::PaddleTensor tensor;
tensor.shape = std::vector<int>({4, 1});
tensor.data.Reset(data, sizeof(data));
tensor.dtype = paddle::PaddleDType::INT64;
// 创建输出 tensor,输出 tensor 的内存可以复用
std::vector<paddle::PaddleTensor> outputs;
// 执行预测
CHECK(predictor->Run(slots, &outputs));
// 获取 outputs ...
更多内容详见 > C++ 预测 API介绍
我们以Paddle Inference的Python部署为例进行说明:
使用PaddleDetection提供的deploy/python/infer.py脚本可以对图片进行推理预测。项目中我们使用TensorRT FP16进行推理,在单卡V100上推理速度可以达到208fps。
# 推理单张图片
CUDA_VISIBLE_DEVICES=0 python deploy/python/infer.py --model_dir=inference_model/ppyoloe_crn_m_100e_hazedet --image_file=dataset/hazedet/val/HR/0.png --device=gpu --run_mode=trt_fp16
# 推理文件夹下的所有图片
CUDA_VISIBLE_DEVICES=0 python deploy/python/infer.py --model_dir=inference_model/ppyoloe_crn_m_100e_hazedet --image_dir=dataset/hazedet/val/ --device=gpu --run_mode=trt_fp16
In [15]
# 推理单张图片
! python deploy/python/infer.py --model_dir=inference_model/ppyoloe_crn_m_100e_hazedet --image_file=dataset/h