用树莓派4b构建深度学习应用(九)Yolo篇

前言

上一篇我们在树莓派上安装了OpenVINO的环境,并跑了几个官方demo,作为关键点的模型转换工作,以各个版本的yolo实现为例,在这篇做一下实现。

image

image

目标检测是人工智能应用比较成熟的领域,不仅要能够识别出图片的目标,还要定位其位置,在自动驾驶方面会是一个基础的场景。一般分为两大类别,一类是two-stage的,基于R-CNN,Fast R-CNN, Faster R-CNN等等,先生成待选框(Region Proposal),再进行分类获取类别,回归获取位置;另一类就是Yolo,SSD这种one-stage算法,直接用CNN网络获取目标和位置。相对来说,R-CNN系的精度更高,但速度慢,Yolo系的则速度快,准确率低些。在很多CV领域里,只要保证分类的准确率,检测速度比定位精度重要的多,而one-stage的模型部署有着天然的优势,极大的减轻算力有限的边缘设备的计算压力。
image

Yolo则是目标检测类优化速度的代表,而转换为Openvino后,速度还能更进一步。这篇主要介绍两种主流框架 Tensorflow 和 Pytorch 的模型转换到 Openvino的方法。
image

首先,Tensorflow 模型的转化流程是,先将权重文件.weight 转换成静态图 .pb文件,再转化成 IR 模型的 .bin 和 .xml,最后部署到神经棒运行。我们先来跑一个yolov4-tiny的应用来体验一下。Yolov4 应用

1 下载源码

git clone https://github.com/TNTWEN/OpenVINO-YOLOV4.git

2 将 weight --> pb

下载 yolov4.weight 和 yolov4-tiny.weight 放入该目录下

python convert_weights_pb.py --class_names cfg/coco.names --weights_file yolov4-tiny.weights --data_format NHWC --tiny

目录下有输出 frozen_darknet_yolov4_model.pb 就转化成功了。


image

✎ Tip

其中必须指定数据格式为NHWC,以匹配 intel NCS2 上对应的格式。

image

✎ Tip

如遇到有 ‘cloud’ 导入错误的信息,那是由于编译 TF 时开启了 --nogcp 标志,导致 tensorflow/contrib/cloud 没有被加入 pip 的安装包。这里只要将 init 里的两行代码注释掉即可修复这个bug了。其中必须指定数据格式为NHWC,所以这里需要 reverse_input_channels 翻转一下对应的输入通道。

/home/pi/my_envs/tensorflow/lib/python3.7/site-packages/tensorflow/contrib/__init__.py
image

3 初始化openvino环境

要在Windows 或 linux主机上做转换,需要安装 OpenVINO 开发工具套件。

image
"C:\Program Files (x86)\IntelSWTools\openvino\bin\setupvars.bat"
image

4 将 pb --> ir

切换到 OpenVINO-YOLOV4 目录下,将 pb 文件 转化为 xml 和 bin 文件。

python "C:\Program Files (x86)\IntelSWTools\openvino_2020.4.287\deployment_tools\model_optimizer\mo.py" --input_model frozen_darknet_yolov4_model.pb --transformations_config yolo_v4_tiny.json --batch 1 --reverse_input_channels
image

✎ Tip

转换 IR 模型前一定要注意 op 算子的兼容性,以及对应平台的数据精度。 以下这个页面可以查询到具体信息,很多模型转化失败是由于还没有得到支持。

https://docs.openvinotoolkit.org/latest/openvino_docs_IE_DG_supported_plugins_Supported_Devices.html

5 运行模型

在树莓派上运行模型,FPS 稳定在 6-7 帧左右

source ~/my_envs/tensorflow/bin/activate
image

Yolov5 应用

Yolov5 主要引入了马赛克增强,自适应锚框,这些新特性,结构上与 Yolov4 的差异不大,不过v5的开源版本是 pytorch 的,相对 darknet 来说更容易转化到各个平台上部署些。

image

工作流:

另一种主流框架 Pytorch 若要用 openvino 做优化的话,那其转换流程为,先将 pytorch 的模型文件 .pt,转化为 onnx 格式,然后再转化成 IR 模型,即可部署到神经棒上了。

image

接下来我们用最新版的 Yolov5 来跑一下这个过程。

1 在 Ubuntu 上安装 OpenVINO 开发工具

下载安装包 2020年4月的 linux 版本

cd ~/Downloads/

2 安装依赖

pip3 install defusedxml

3 ****建立虚拟环境****

Python>=3.8,PyTorch==1.5.1,ONNX>=1.7。

conda activate openvino  # 进入ubuntu 的虚拟环境

4 ****导出在 pytorch 上训练好的 yolov5 模型****

先下载 yolov5s.pt(或者训练自有数据集的yolov5模型),放入目录下

wget https://github.com/ultralytics/yolov5/releases/download/v2.0/yolov5s.pt

✎ Tip

要下载 v2.0 with nn.LeakyReLU(0.1) 的版本,因为 3.0 的 nn.Hardswish 还没有被支持。

5 修改激活函数

由于onnx和openvino 还不支持 Hardswitch,要将 Hardswish 激活函数改成 Relu 或者 Leaky Relu。

# yolov5/models/common.py

6 修改 yolo.py

# yolov5/models/yolo.py

修改输出层堆叠,不包含输入层

    c=(y[..., 0:2] * 2. - 0.5 + self.grid[i].to(x[i].device)) * self.stride[i]  # xy

7 修改 export.py

# yolov5/models/export.py

因为版本为10的 opset 能支持 resize 算子,要修改 opset 版本号。

# yolov5/models/export.py

✎ Tip

务必确保 torch==1.15.1,torchvision==0.6.1,onnx==1.7,opset=10。激活函数为 Relu,并修改了网络推理层。

8 ****将 pt --> onnx****

****
image

****

export PYTHONPATH="$PWD"  

显示导出为 onnx 和 torchscript 文件即可。

ONNX export success, saved as ./yolov5s.onnx

9 ****将 onnx --> ir****

python3 /opt/intel/openvino_2020.4.287/deployment_tools/model_optimizer/mo.py 

顺利的话,就能在 out 目录下生成 yolov5s 的 IR 模型了,接着将文件传输到树莓派上。

image

✎ Tip

这里要匹配 yolov5s 的 input shape 为 [ 1, 3, 640, 640 ]。

10 ****修改参数匹配训练模型****

git clone https://github.com/linhaoqi027/yolov5_openvino_sdk.git

修改推理设备和输入 shape

# device = 'CPU'

修改类别信息

# label_id_map = {

修改多类别输出

        for idx, proposal in enumerate(data):

11 推理输出

if __name__ == '__main__':
python inference.py 
image

yolov5s 的 FPS 才 2 帧左右,相比 yolov4-tiny 来说速度不算快,input shape 640 比 yolov4 的416大了不少,主要耗时集中在神经棒的推理之中,需耗费 377ms,还是蛮可观的。

另外,转换后的 IR 模型在 CPU 上和 MYRIAD 上推理的置信度差异也很高,看来 yolov5 还有很大的优化空间。
image

要追求极致的检测速度,还有几个方向可以尝试:

  • 多个神经棒分布式推理;

  • 使用多线程推理;

  • 采用异步方式刷新屏幕;

  • 选用更小的模型;

  • 推理代码由 Python 改为 C++

image

特别是最近优图开源了一个yolo-fastest版本,backbone为EfficientNet-lite 使得训练的模型权重才1.2M,yolo-fastest-xl 也才3.3M,非常的小巧。

image

这个 MobileNet SSD 竟然在树莓派4 + 5个 NCS2 上跑到了 FPS 40以上,Amazing!!!

image

这篇主要介绍了 Tensorflow 和 Pytorch 两种主流框架的转换到 OpenVINO模型的方式。

  • .weight --> .pb --> .xml .bin

  • .pt --> onnx --> .xml .bin

其实还有更多AI框架,大致也是通过 pb,onnx,ir,这类中间模型来相互转化,比如应用于 TensorRT,Tensorflow Lite 等等。

image

一般只要了解,输入输出层的结构,每种模型对应的权重和网络结构文件,注意op算子的支持,就能用框架提供的 pipeline 来做转换了。

最后的手段,就是重写网络拓扑,用类似 load_weight 的方法来导入权重,再 save 到目标框架中了。代码下载

image

本期相关文件资料,可在公众号后台回复:“rpi09”,获取下载链接。

下一篇

我们将介绍树莓派上的代理软件,
部署Openwrt软路由,
打造一劳永逸的上网环境,
敬请期待...

你可能感兴趣的:(用树莓派4b构建深度学习应用(九)Yolo篇)