图1 MOT 行人检测[1]
多对象追踪(Multi- Object Tracking, MOT) 在计算机视觉领域有着广泛且重要的应用。大到可以用在多目标导弹跟踪、市中心人流统计, 小到可以用在统计鱼池里的观赏鱼类等等。本篇文章将会带您了解百度飞桨目标检测套件PaddleDetection项目里的 FairMOT模型,并通过OpenVINO™ 工具套件将其转换成ONNX通用模型,最终在计算机上运行此AI模型实现行人检测项目。
百度飞桨目标检测套件PaddleDetection在去年5月20号加入了对FairMOT模型的支持。FairMOT是一款短小精干模型, 它的单镜头跟踪功能包括行人跟踪、车辆跟踪、多类别跟踪、小目标跟踪以及流量统计,是一款实用性非常广的AI模型。该模型主要是基于原始的FairMOT模型构架进行了优化,实现了实时跟踪的效果,同时基于不同场景提供了针对性的训练模型[2]。
本文采用的FairMOT模型在MOT-17数据集上测试结果达到了MOTA65.3。这篇文章将专注于展示如何将FairMOT转换为通用格式的ONNX模型,并且部署到CPU上,使用OpenVINO™ 来做预测。
面对当下众多流行的深度学习框架,每个框架都有自己特殊的神经网络结构和文件类型,每个框架内的设计也不尽相同,如此训练出来的模型则千差万别,这对软件开发和重用造成了一定的麻烦。
是否有一种工具可以在最后部署环节拥有统一的接口,可重用代码呢?
答案是肯定的。OpenVINO™ 工具套件(以下简称OV)就是这样的一款工具。OV是Intel发布的一个综合性工具套件, 其是用于快速开发解决各种任务的应用程序和解决方案。 它包括视觉、自动语音识别、自然语言处理、推荐系统等。该工具包基于最新一代人工神经网络,包括卷积神经网络(CNN)、Recurrent Network和基于注意力的网络,可跨英特尔® 硬件扩展计算机视觉和非视觉工作负载,从而最大限度地提高性能。有了它的帮助,AI工程师可以在模型构建和训练阶段,选择自己熟悉的AI框架来搭建起符合要求的个性化神经网络,而在后期使用OpenVINO™ 快速构建起专属的解决方案,提供统一的接口,并在英特尔的硬件上优化性能以及运行。
重点:一步一步演示怎样使用已经训练好的模型,以及展示怎样将飞桨模型转换成ONNX格式,并且用代码验证转换后的模型的正确性,直至部署到CPU上为止。每一步我都会提供相应的官方网址,一步一步带领读者找到正确的官网文档,少走弯路。
非重点:这篇文章不讲解怎样安装Python,Anaconda,OpenVINO™ 这样的基础需求框架。以上几个产品的官方网站教程都做的非常详细,而且会实时更新,相信对于每个不同的技术,阅读相对应的官方文档可以省去很多麻烦。
本文面向的读者是具有一定编程能力和经验的开发人员,例如AI模型开发员,熟悉Python语言并使用Anaconda,已有训练好的模型,期待能部署到边缘设备上来投入实际生产中。对于0基础的读者也是一个很好的机会,通过一篇文章一并了解以上的几个技术以及怎样综合使用这些技术,让它们成为您得心应手的工具来帮助您最快的实现AI部署。
Anaconda,Python(创建Anaconda虚拟环境的时候会自带),OpenVINO™, 飞桨框架,PaddleDetection,Paddle2ONNX,Mamba(可选)。
了解以上概念和工具后, 我们接下来就可以正式动工啦。由于本文用到的PP-Tracking下的FairMOT的目标检测模型是来自于PaddleDetection的Model Zoo,所以需要先安装飞桨框架,然后再安装PaddleDetection。
第一步: 创建一个conda 虚拟环境,并激活环境:
conda create -n "paddle" python=3.8.8 ipython
conda activate paddle
第二步: 安装GPU或者CPU版本的飞桨框架:
对于选择GPU还是CPU版本的飞桨框架,主要是根据您的硬件配置。如果您有NVIDIA最近几年的显卡例如:RTX 3080,RTX 2070, RTX 1060等,那么请选择安装GPU版本。查看CUDA对GPU支持的详细信息,请阅读NVIDIA官网的GPU Compute Capability。
conda install cudnn
安装的时候也可以把conda 换成Mamba,从而得到更快的下载速度。
图2:使用 Mamba 安装 cudnn
这里快速介绍一下Mamba。它是Conda的C++实现,相比于Conda, 它提供多线程下载, 这也就意味着它可以比Conda更好的利用网络资源, 下载的更快。同时它也能更快的解析依赖项。估计用Conda多的朋友应该会遇到过, Conda有时候查找依赖项非常慢 很耽误时间。Mamba是您的好朋友。以下教程种再看到conda的命令,大家都可以自动替换成Mamba来提高速度, 让您的效率飞起来~!
2)安装飞桨框架
安装飞桨的时候, 可以在飞桨的官网获取最新的指南,我以Ubuntu 20.04的系统为例(如果您用其他的系统,那么请选择相应的选项)。
图3:安装飞桨框架
具体命令如下:
conda install paddlepaddle-gpu==2.2.1 cudatoolkit=11.2 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ -c conda-forge
3)安装PaddleDetection
安装完底层框架之后,就可以开始安装PaddleDetection啦。同理, 您的好朋友是它的Github仓库。安装代码如下:
pip install paddledet
模型转换的思路分为4个步骤:
1. 导出已经训练好的模型 →
2. 转换到ONNX模型 →
3. 通过ONNX模型转换到OpenVINO™ 的 IR模型 →
4. 最后编译IR模型成为.blob模型(只适用于Intel VPU,神经棒等, 部署到CPU时不需要)
图4: AI模型的转换过程
这里要指明的是, 其实OpenVINO™ (OV)不仅可以支持直接运行Blob格式的模型以及IR格式的模型, 更令人兴奋的是OV还可以直接支持使用ONNX模型~! 其中的好处不言而喻。譬如: 可以节省下来不少在模型转换步骤中所费的时间; 很多其他框架的模型都可以拿来快速的转换成ONNX模型然后直接进行代码试验, 省去了太多不必要的步骤。这绝对是一个Killer feature~!
本篇文章将展示在OV中直接使用ONNX格式的模型进行推理。
本文以飞桨官方的PaddleDetection Github代码库下的FairMot模型为例来演示。
图5: FairMOT的概述图[1]
百度在PaddleDetection的Python段预测部署里提供了已经转换成静态模型的FairMOT。下载地址如下:
https://bj.bcebos.com/v1/paddledet/models/mot/fairmot_hrnetv2_w18_dlafpn_30e_576x320.tar
本篇文章使用到的是 fairmot_hrnetv2_w18_dlafpn_30e_576x320, 更多不同尺寸和准确度的FairMOT模型可以在这里(FairMOT: Onthe Fairness of Detection and Re-Identification in Multiple Object Tracking)找到
第一阶段结束。如果对怎样导出飞桨模型的过程感兴趣,请查看本系列之前的文章中的4.1章节。
模型导出后第一道转换现在开始了。飞桨提供了转换工具Paddle2ONNX,安装如下:
pip install paddle2onnx
将飞桨模型转化成ONNX格式:(请确保指向模型的路径是正确的)
paddle2onnx --model_dir . --model_filename model.pdmodel \
--params_filename model.pdiparams \
--input_shape_dict "{'image': [1, 3, 320, 576], 'scale_factor': [1,2], 'im_shape': [1, 2]}" \
--save_file fairmot_576_320_v2.onnx \
--opset_version 12 \
--enable_onnx_checker True
这里要特别指出两点:
1.PaddleDetection下的FaiMOT模型并没有固定下来模型的 input(见图6),但是OpenVINO™ 不接受非固定input。所以解决的方法也很明确,就是要把飞桨模型中未固定的参数固定下来。
在Paddle2ONNX的命令行参数中,有一个参数叫做input_shape_dict,我们可以通过这个参数做文章把需要固定下来的参数都指定好。
那么自然,我们就要知道到底有哪些参数要固定下来呢?
2.FairMOT在input里需要3个参数,分别是input_shape, scale_factor 和im_shape。
而这3个参数是如何发现的呢? 一个小技巧就是用模型可视化工具(VisualDL)先来看一下这个模型:
图6: FairMOT的概述图[1]
由上图可以看出在INPUTS里面有3个部分,分别是之前提到过的:scale_factor,image以及im_shape。这样我们就知道该如何构建input_shape_dict的参数值。
{'image': [1, 3, 320, 576],'scale_factor': [1, 2], 'im_shape': [1, 2]}
接下来记住将 model_dir,model_filename,以及params_filename和save_file替换成自己的文件路径,之后类似的路径也请替换成自己电脑上的相应路径,不再赘述。
--model_dir是转换后的模型要保存的目录
--enable_onnx_checker 启动它可以让转换程序帮我们检查模型
您可能遇到的问题:
Opset_version的默认值是9, 如果您的框架比较新,需要把这个opset_version调高到12。
在ONNX模型转换好后,我们可以快速看一下FairMOT模型有哪些输出。
7: FairMOT的输出结构[1]
这2个通道的结果,正是FairMOT检测出来的 detections和embeddings,之后我们便会用到。
接下来是最重要的过程。整体思路是:
1. 首先我们需要得到一个ExecutableNetwork;
2. 然后还要得知输入输出频道的名字;
3. 准备好输入数据(即对输入图像调整大小resize, 标准化normalize)。在标准化的时候,mean和std很重要。如果在自己预处理输入图像的时候,用的标准化参数mean,std的值和模型训练时候用的数值有所不同,那么会严重影响预测精准度。这个mean和std的数值可以在PaddleDetection项目中相应的模型配置文件fairmot_hrnetv2_w18_dlafpn_30e_576x320.yml中找到。
4. 把已处理好的图像传递到ExecutableNetwork里的infer()中即可得到预测结果。
5. 最后我们需要将得到的预测结果:pred_dets, pred_embs 做postprocess,便可得到最后的结果。
完整代码可以在这里查看:Intel-OpenVINO-Paddle(https://github.com/franva/Intel-OpenVINO-Paddle/tree/main/PaddleDetection/FairMot)
我们来看一下成果。
图8: FairMOT检测结果
可以看出识别率还是非常之高,如果想更加谨慎一些,可以通过增加postprocess()中的threshold来确保降低误判率。
测试好模型之后,我们还可以检查一下模型的性能和吞吐量。幸运的是,Intel® DevCloud已经提供了现有的工具来帮助我们快速完成这项工作。这里是它的Jupyter Notebooks平台,在使用前需要先注册账户。
Jupyter Notebooks平台:
https://devcloud.intel.com/zh/edge/advanced/connect_and_create/
随机挑选几套硬件搭配,来看一下刚转换好的ONNX模型性能:
表格1:Benchmark ofPP-Tracking FairMOT 576*320 模型
关于如何使用 Intel® DevCloud,更详细的步骤请参考:《使用OpenVINO优化和部署DenseNet模型并在DevCloud上完成性能测试-上篇》、《使用OpenVINO™ 优化和部署DenseNet模型并在DevCloud上完成性能测试-下篇》。
至此,整个流程结束。恭喜大家成功的转换了模型并且部署到了设备上。期待看到你们更多的精彩应用!
Github链接:
https://github.com/franva/Intel-OpenVINO-Paddle/tree/main/PaddleDetection/FairMot
本文开头介绍了多目标追踪MOT的广泛的适用性,阐述了用DevCloud部署模型的重要性。快速介绍了OpenVINO™ 工具套件。然后以一个训练好的百度飞桨模型为例开始,逐步地带着大家把模型转换到了通用型ONNX格式,这和之前的教程不同,同时详细介绍了OV和FairMOT的工作流程以及代码。相信大家对于不同的模型,只需要做适量的改动,便可以快速独立的开发属于自己的AI应用程序。