简介
飞桨目标检测端到端开发套件PaddleDetection正式开源车辆分析工具PP-Vehicle!该工具主要包含:提供车牌识别、车辆属性分析(颜色、车型)、车流量统计以及违章检测四大功能,兼容图片、在线视频流、视频输入,提供完善的二次开发文档教程
PP-vehicle是一款针对车辆分析相关场景的开源工具,产品主要围绕以下几个方面进行设计开发:
-
实用性:针对车辆分析场景共性的底层模型进行优化迭代;针对几个高频场景进行了详细的后处理策略设计,可以满足业务的快速上线需求。同时提供丰富的二次开发教程,方便用户根据自己的业务场景进行私有化开发。
-
泛化性:在公开数据集以及自采数据集上进行充分训练,并且提供预训练模型,覆盖车辆分析中监控视角、驾驶员视角、俯拍视角等常见相机视角。
-
低代码:实现1行代码快速部署,支持 图片、视频、单路/多路rtsp视频流输入,修改配置文件即可快速实现策略修改以及pipeline的组合。
PP-Vehicle整体方案
PP-Vehicle整体分为输入、核心算法、输出三部分:
1.核心算法
主要由预训练模型以及逻辑策略组成。预训练模型主要由4个:车辆检测模型、车辆跟踪模型、车牌识别模型、车辆属性分析模型。各个模型性能见下表。
2.案例展示
2.1配置文件说明
PP-Vehicle相关配置位于deploy/pipeline/config/infer_cfg_ppvehicle.yml
中,存放模型路径,完成不同功能需要设置不同的任务类型
功能及任务类型对应表单如下:
输入类型 | 功能 | 任务类型 | 配置项 |
---|---|---|---|
图片 | 属性识别 | 目标检测 属性识别 | DET ATTR |
单镜头视频 | 属性识别 | 多目标跟踪 属性识别 | MOT ATTR |
单镜头视频 | 车牌识别 | 多目标跟踪 车牌识别 | MOT VEHICLEPLATE |
例如基于视频输入的属性识别,任务类型包含多目标跟踪和属性识别,具体配置如下:
crop_thresh: 0.5 visual: True warmup_frame: 50 MOT: model_dir: https://bj.bcebos.com/v1/paddledet/models/pipeline/mot_ppyoloe_l_36e_ppvehicle.zip tracker_config: deploy/pipeline/config/tracker_config.yml batch_size: 1 enable: True VEHICLE_ATTR: model_dir: https://bj.bcebos.com/v1/paddledet/models/pipeline/vehicle_attribute_model.zip batch_size: 8 color_threshold: 0.5 type_threshold: 0.5 enable: True
注意:
-
如果用户需要实现不同任务,可以在配置文件对应enable选项设置为True。
-
如果用户仅需要修改模型文件路径,可以在命令行中--config后面紧跟着
-o MOT.model_dir=ppyoloe/
进行修改即可,也可以手动修改配置文件中的相应模型路径,详细说明参考下方参数说明文档。
2.2预测部署
1.直接使用默认路径或者examples中配置文件,或者直接在infer_cfg_ppvehicle.yml
中修改配置:
# 例:车辆检测,指定配置文件路径和测试图片 python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_ppvehicle.yml --image_file=test_image.jpg --device=gpu # 例:车辆车牌识别,指定配置文件路径和测试视频 python deploy/pipeline/pipeline.py --config deploy/pipeline/config/examples/infer_cfg_vehicle_plate.yml --video_file=test_video.mp4 --device=gpu
2.使用命令行进行功能开启,或者模型路径修改:
# 例:车辆跟踪,指定配置文件路径和测试视频,命令行中开启MOT模型并修改模型路径,命令行中指定的模型路径优先级高于配置文件 python deploy/pipeline/pipeline.py --config deploy/pipeline/config/infer_cfg_ppvehicle.yml -o MOT.enable=True MOT.model_dir=ppyoloe_infer/ --video_file=test_video.mp4 --device=gpu # 例:车辆违章分析,指定配置文件和测试视频,命令行中指定违停区域设置、违停时间判断。 python deploy/pipeline/pipeline.py --config deploy/pipeline/config/examples/infer_cfg_illegal_parking.yml \ --video_file=../car_test.mov \ --device=gpu \ --draw_center_traj \ --illegal_parking_time=3 \ --region_type=custom \ --region_polygon 600 300 1300 300 1300 800 600 800
3.方案解析
3.1车牌识别方案
-
通过目标检测来获取图片中的车辆检测框,模型方案为pp-YOLOE-l。当输入为视频时,会基于车辆检测框,使用OC-SORT跟踪器来完成车辆多目标跟踪
-
通过车辆检测框的坐标截取对应位置图像;
-
使用车牌检测模型在每张车辆截图中识别车牌所在位置,同理截取车牌区域,模型方案为PP-OCRv3车牌检测模型
-
使用字符识别模型识别车牌中的字符,模型方案为PP-OCRv3车牌识别模型
-
此外还使用了一些优化策略提升速度以及准确率
-
使用跳帧策略,每10帧做一次车牌检测,避免每帧做车牌检测的算力消耗
-
车牌结果稳定策略,避免单帧结果的波动,利用同一个ID的历史所有车牌识别结果进行投票,得到该id最大可能的正确结果
-
车辆检测模型联合BDD-100k和UA-DETRAC数据集训练,车牌检测方案采用CCPD数据集在车牌场景finetune提升检测精度。
-
3.2车辆属性识别方案
-
车辆属性识别模型使用了PaddleClas超轻量图像分类方案(PULC,Practical Ultra Lightweight image Classification)
-
在该模型的基础上,进一步使用了以下优化方案:
-
使用SSLD预训练模型,在不改变推理速度的前提下,精度提升约0.5个百分点
-
融合EDA数据增强策略,精度提升0.52个百分点
-
使用SKL-UGI知识蒸馏,精度提升0.23个百分点
-
3.3违规检测方案
-
通过目标检测来获取车辆检测框,模型方案为PP-YOLOE
-
基于跟踪算法获取每辆车的轨迹,模型方案为OC-SORT。如果车辆中心在违规区域内且在指定时间内未发生移动,则视为违规停车;
-
使用车牌识别模型得到违规停车车牌并可视化
4.车辆属性识别-PaddleClas
基于paddlepaddle开元的paddleClas超轻量图像分类方案
-
精度高的模型往往体积大,运算慢,尝尝难以满足实际部署需求
-
找到合适的模型后,往往还需要经验丰富的工程师进行调参,费时费力。
paddlecls为了解决以上难题,让分类模型的训练和调参更加容易,总结推出了实际轻量图像分类解决方案(PULC, Practical Ultra Lightweight Classification)。pulc融合了骨干网络、数据增广、蒸馏等多种前沿算法,可以自动训练得到轻量且高精度的图像分类模型。
pulc已经验证在多个场景中有效,用超轻量模型就可以实现与SwinTransformer模型接近的精度,预测速度提升40+倍
方案主要包括4部分,分别是:PP-LCNET轻量级骨干网络、SSLD预训练权重、数据增强策略集成(EDA)和SKL-UGI知识蒸馏算法。此外,我们还采用了超参搜索的方法,高效优化训练中的超参数。
4.1案例-有人/无人分类模型
4.1.1场景介绍
模型 | Tpr(%) | 延时(ms) | 存储(M) | 策略 |
---|---|---|---|---|
SwinTranformer_tiny | 95.69 | 95.30 | 111 | 使用 ImageNet 预训练模型 |
MobileNetV3_small_x0_35 | 68.25 | 2.85 | 2.6 | 使用 ImageNet 预训练模型 |
PPLCNet_x1_0 | 89.57 | 2.12 | 7.0 | 使用 ImageNet 预训练模型 |
PPLCNet_x1_0 | 92.10 | 2.12 | 7.0 | 使用 SSLD 预训练模型 |
PPLCNet_x1_0 | 93.43 | 2.12 | 7.0 | 使用 SSLD 预训练模型+EDA 策略 |
PPLCNet_x1_0 | 96.23 | 2.12 | 7.0 | 使用 SSLD 预训练模型+EDA 策略+SKL-UGI 知识蒸馏策略 |
从表中可以看出,backbone 为 SwinTranformer_tiny 时精度较高,但是推理速度较慢。将 backbone 替换为轻量级模型 MobileNetV3_small_x0_35 后,速度可以大幅提升,但是会导致精度大幅下降。将 backbone 替换为速度更快的 PPLCNet_x1_0 时,精度较 MobileNetV3_small_x0_35 高 20 多个百分点,与此同时速度依旧可以快 20% 以上。在此基础上,使用 SSLD 预训练模型后,在不改变推理速度的前提下,精度可以提升约 2.6 个百分点,进一步地,当融合EDA策略后,精度可以再提升 1.3 个百分点,最后,在使用 SKL-UGI 知识蒸馏后,精度可以继续提升 2.8 个百分点。此时,PPLCNet_x1_0 达到了 SwinTranformer_tiny 模型的精度,但是速度快 40 多倍。
4.1.2数据准备
数据格式说明
PaddleClas 使用 txt
格式文件指定训练集和测试集,以有人/无人场景为例,其中需要指定 train_list.txt
和 val_list.txt
当作训练集和验证集的数据标签,格式形如:
# 每一行采用"空格"分隔图像路径与标注 train/1.jpg 0 train/10.jpg 1 ...
标注文件生成
假设数据存放路径./train
,./train
中包含了每个类别的数据,类别号从0开始,每个类别的文件夹中又具体的图像数据。
train ├── 0 │ ├── 0.jpg │ ├── 1.jpg │ └── ... └── 1 ├── 0.jpg ├── 1.jpg └── ... └── ...
tree -r -i -f train | grep -E "jpg|JPG|jpeg|JPEG|png|PNG" | awk -F "/" '{print $0" "$2}' > train_list.txt
其中,如果涉及更多的图片名称尾缀,可以增加 grep -E
后的内容, $2
中的 2
为类别号文件夹的层级。
进入paddlecls目录
cd path_to_PaddleClas
进入 dataset/
目录,下载并解压有人/无人场景的数据。
cd dataset wget https://paddleclas.bj.bcebos.com/data/PULC/person_exists.tar tar -xf person_exists.tar cd ../
32G,这里就不做演示了
执行上述命令后,datasets/
下存在person_exists
目录,该目录中具有以下数据:
├── train │ ├── 000000000009.jpg │ ├── 000000000025.jpg ... ├── val │ ├── objects365_01780637.jpg │ ├── objects365_01780640.jpg ... ├── ImageNet_val │ ├── ILSVRC2012_val_00000001.JPEG │ ├── ILSVRC2012_val_00000002.JPEG ... ├── train_list.txt ├── train_list.txt.debug ├── train_list_for_distill.txt ├── val_list.txt └── val_list.txt.debug
其中 train/
和 val/
分别为训练集和验证集。train_list.txt
和 val_list.txt
分别为训练集和验证集的标签文件,train_list.txt.debug
和 val_list.txt.debug
分别为训练集和验证集的 debug
标签文件,其分别是 train_list.txt
和 val_list.txt
的子集,用该文件可以快速体验本案例的流程。ImageNet_val/
是 ImageNet-1k 的验证集,该集合和 train
集合的混合数据用于本案例的 SKL-UGI知识蒸馏策略
,对应的训练标签文件为 train_list_for_distill.txt
。
4.1.3使用标准分类配置进行训练
4.1.3.1 PP-LCNet(骨干网络)
PULC采用了轻量骨干网络pp-LCNet,相比同精度竞品速度快50%,直接使用pp-LCNet训练的命令为:
export CUDA_VISIBLE_DEVICES=0,1,2,3 python3 -m paddle.distributed.launch \ --gpus="0,1,2,3" \ tools/train.py \ -c ./ppcls/configs/PULC/person_exists/PPLCNet_x1_0_search.yaml
为了方便性能对比,paddlecls也提供了大型SwinTransformer_tiny 和轻量模型 MobileNetV3_small_x0_35 的配置文件,可以使用命令训练:
SwinTransformer_tiny:
export CUDA_VISIBLE_DEVICES=0,1,2,3 python3 -m paddle.distributed.launch \ --gpus="0,1,2,3" \ tools/train.py \ -c ./ppcls/configs/PULC/person_exists/SwinTransformer_tiny_patch4_window7_224.yaml
MobileNetV3_small_x0_35:
export CUDA_VISIBLE_DEVICES=0,1,2,3 python3 -m paddle.distributed.launch \ --gpus="0,1,2,3" \ tools/train.py \ -c ./ppcls/configs/PULC/person_exists/MobileNetV3_small_x0_35.yaml
训练得到的模型精度对比如下表。
模型 | Tpr(%) | 延时(ms) | 存储(M) | 策略 |
---|---|---|---|---|
SwinTranformer_tiny | 95.69 | 95.30 | 107 | 使用 ImageNet 预训练模型 |
MobileNetV3_small_x0_35 | 68.25 | 2.85 | 1.6 | 使用 ImageNet 预训练模型 |
PPLCNet_x1_0 | 89.57 | 2.12 | 6.5 | 使用 ImageNet 预训练模型 |
从中可以看出,PP-LCNet 的速度比 SwinTransformer 快很多,但是精度也略低。下面我们通过一系列优化来提高 PP-LCNet 模型的精度。
摘要
一种基于MKLDNN加速策略的轻量级卷积神经网络,能够用于多任务的轻量级模型。能在保持延迟不变的情况下提高模型准确率。
模型评估
python3 tools/eval.py \ -c ./ppcls/configs/PULC/person_exists/PPLCNet_x1_0.yaml \ -o Global.pretrained_model="output/PPLCNet_x1_0/best_model"
其中-o Global.pretrained_model="output/PPLCNet_x1_0/best_model"
指定了当前最佳权重所在的路径,如果指定其他权重,只需替换对应的路径即可。
模型预测
模型训练完成之后,可以加载训练得到的预训练模型,进行模型预测。在模型库的 tools/infer.py
中提供了完整的示例,只需执行下述命令即可完成模型预测:
python3 tools/infer.py \ -c ./ppcls/configs/PULC/person_exists/PPLCNet_x1_0.yaml \ -o Global.pretrained_model=output/PPLCNet_x1_0/best_model
结果如下:
[{'class_ids': [1], 'scores': [0.9999976], 'label_names': ['someone'], 'file_name': 'deploy/images/PULC/person_exists/objects365_02035329.jpg'}]
备注:
-
二分类默认的阈值为0.5, 如果需要指定阈值,可以重写
Infer.PostProcess.threshold
,如-o Infer.PostProcess.threshold=0.9794
,该值需要根据实际场景来确定,此处的0.9794
是在该场景中的val
数据集在千分之一 Fpr 下得到的最佳 Tpr 所得到的。
4.1.3.2 SSLD预训练权重
SSLD是百度自研的半监督蒸馏算法,在imagenet数据集上,模型精度可以提升3-7个点。我们发现,使用SSLD预训练权重,可以有效提升应用分类模型的精度。此外,在训练中使用更小的分辨率,可以有效提升模型精度。同时,我们也对学习率进行了优化。 基于以上三点改进,我们训练得到模型精度为 92.1%,提升 2.6%。
4.1.3.3 EDA数据增强策略
数据增强是视觉算法中常用的优化策略,可以对模型精度有明显提升。除了传统的
RandomCrop,RandomFlip 等方法之外,我们还应用了 RandomAugment 和 RandomErasing, 由于这两种数据增强对图片的修改较大,使分类任务变难,在一些小数据集上可能会导致模型欠拟合,我们将提前设置好这两种方法启用的概率。 基于以上改进,我们训练得到模型精度为 93.43%,提升 1.3%。
4.1.3.4 SKL-UGI模型蒸馏
模型蒸馏是一种可以有效提升小模型精度的方法,本文选择 ResNet101_vd 作为教师模型进行蒸馏。为了适应蒸馏过程,我们在此也对网络不同 stage 的学习率进行了调整。基于以上改进,我们训练得到模型精度为 95.6%,提升 1.4%。
教师模型训练
复用 ppcls/configs/PULC/person_exists/PPLCNet/PPLCNet_x1_0.yaml
中的超参数,训练教师模型,训练脚本如下:
export CUDA_VISIBLE_DEVICES=0,1,2,3 python3 -m paddle.distributed.launch \ --gpus="0,1,2,3" \ tools/train.py \ -c ./ppcls/configs/PULC/person_exists/PPLCNet_x1_0.yaml \ -o Arch.name=ResNet101_vd
验证集的最佳指标为 0.96-0.98
之间,当前教师模型最好的权重保存在 output/ResNet101_vd/best_model.pdparams
。
蒸馏训练
配置文件ppcls/configs/PULC/person_exists/PPLCNet_x1_0_distillation.yaml
提供了SKL-UGI知识蒸馏策略
的配置。该配置将ResNet101_vd
当作教师模型,PPLCNet_x1_0
当作学生模型,使用ImageNet数据集的验证集作为新增的无标签数据。训练脚本如下:
export CUDA_VISIBLE_DEVICES=0,1,2,3 python3 -m paddle.distributed.launch \ --gpus="0,1,2,3" \ tools/train.py \ -c ./ppcls/configs/PULC/person_exists/PPLCNet_x1_0_distillation.yaml \ -o Arch.models.0.Teacher.pretrained=output/ResNet101_vd/best_model
验证集的最佳指标为 0.95-0.97
之间,当前模型最好的权重保存在 output/DistillationModel/best_model_student.pdparams
。
4.1.3.5 总结
经过以上方法优化,PP-LCNet最终精度达到 95.6%,达到了大模型的精度水平。我们将实验结果总结如下表:
模型 | Tpr(%) | 延时(ms) | 存储(M) | 策略 |
---|---|---|---|---|
SwinTranformer_tiny | 95.69 | 95.30 | 107 | 使用 ImageNet 预训练模型 |
MobileNetV3_small_x0_35 | 68.25 | 2.85 | 1.6 | 使用 ImageNet 预训练模型 |
PPLCNet_x1_0 | 89.57 | 2.12 | 6.5 | 使用 ImageNet 预训练模型 |
PPLCNet_x1_0 | 92.10 | 2.12 | 6.5 | 使用 SSLD 预训练模型 |
PPLCNet_x1_0 | 93.43 | 2.12 | 6.5 | 使用 SSLD 预训练模型+EDA 策略 |
PPLCNet_x1_0 | 95.60 | 2.12 | 6.5 | 使用 SSLD 预训练模型+EDA 策略+SKL-UGI 知识蒸馏策略 |
4.1.3.6模型推理
paddle inference是飞桨的原生推理库, 作用于服务器端和云端,提供高性能的推理能力。相比于直接基于预训练模型进行预测,Paddle Inference可使用 MKLDNN、CUDNN、TensorRT 进行预测加速,从而实现更优的推理性能。更多关于 Paddle Inference 推理引擎的介绍,可以参考 Paddle Inference官网教程。
基于训练得到的权重导出inference模型
此处,我们提供了将权重和模型转换的脚本,执行该脚本可以得到对应的 inference 模型:
python3 tools/export_model.py \ -c ./ppcls/configs/PULC/person_exists/PPLCNet_x1_0.yaml \ -o Global.pretrained_model=output/DistillationModel/best_model_student \ -o Global.save_inference_dir=deploy/models/PPLCNet_x1_0_person_exists_infer
执行完该脚本后会在 deploy/models/
下生成 PPLCNet_x1_0_person_exists_infer
文件夹,models
文件夹下应有如下文件结构:
├── PPLCNet_x1_0_person_exists_infer │ ├── inference.pdiparams │ ├── inference.pdiparams.info │ └── inference.pdmodel
python预测引擎推理
# 使用下面的命令使用 GPU 进行预测 python3.7 python/predict_cls.py -c configs/PULC/person_exists/inference_person_exists.yaml # 使用下面的命令使用 CPU 进行预测 python3.7 python/predict_cls.py -c configs/PULC/person_exists/inference_person_exists.yaml -o Global.use_gpu=False
输出结果如下。
objects365_02035329.jpg: class id(s): [1], score(s): [1.00], label_name(s): ['someone']
备注: 二分类默认的阈值为0.5, 如果需要指定阈值,可以重写 Infer.PostProcess.threshold
,如-o Infer.PostProcess.threshold=0.9794
,该值需要根据实际场景来确定,此处的 0.9794
是在该场景中的 val
数据集在千分之一 Fpr 下得到的最佳 Tpr 所得到的。
5.车牌识别-PaddleOCR
车牌识别难点:
-
车牌在图像中的尺度差异大、在车辆上的悬挂位置不固定
-
车牌图像质量层次不齐: 角度倾斜、图片模糊、光照不足、过曝等问题严重
-
边缘和端测场景应用对模型大小有限制,推理速度有要求
针对以上问题, 本例选用 PP-OCRv3 这一开源超轻量OCR系统进行车牌识别系统的开发。基于PP-OCRv3模型,在CCPD数据集达到99%的检测和94%的识别精度,模型大小12.8M(2.5M+10.3M)。基于量化对模型体积进行进一步压缩到5.8M(1M+4.8M), 同时推理速度提升25%。
6.车辆检测-PP-YOLOE
PP-YOLOE是基于PP-YOLOv2的单阶段Anchor-free模型。PP-YOLOE有一系列的模型,即s/m/l/x,可以通过width multiplier和depth multiplier配置。
模型 | 数据集 | 类别数 | mAPval 0.5:0.95 | 下载链接 | 配置文件 |
---|---|---|---|---|---|
PP-YOLOE-l | BDD100K-DET | 10 | 35.6 | 下载链接 | 配置文件 |
PP-YOLOE-l | BDD100K-MOT | 8 | 33.7 | 下载链接 | 配置文件 |
PP-YOLOE-l | UA-DETRAC | 4 | 51.4 | 下载链接 | 配置文件 |
PP-YOLOE-l | PPVehicle9cls | 9 | 40.0 | 下载链接 | 配置文件 |
PP-YOLOE-s | PPVehicle9cls | 9 | 35.3 | 下载链接 | 配置文件 |
PP-YOLOE-l | PPVehicle | 1 | 63.9 | 下载链接 | 配置文件 |
PP-YOLOE-s | PPVehicle | 1 | 61.3 | 下载链接 | 配置文件 |