前言
上一篇我们在树莓派上安装了OpenVINO的环境,并跑了几个官方demo,作为关键点的模型转换工作,以各个版本的yolo实现为例,在这篇做一下实现。
首先,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 就转化成功了。
✎ Tip
其中必须指定数据格式为NHWC,以匹配 intel NCS2 上对应的格式。
✎ 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
3 初始化openvino环境
要在Windows 或 linux主机上做转换,需要安装 OpenVINO 开发工具套件。
"C:\Program Files (x86)\IntelSWTools\openvino\bin\setupvars.bat"
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
✎ 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
Yolov5 应用
Yolov5 主要引入了马赛克增强,自适应锚框,这些新特性,结构上与 Yolov4 的差异不大,不过v5的开源版本是 pytorch 的,相对 darknet 来说更容易转化到各个平台上部署些。
工作流:
另一种主流框架 Pytorch 若要用 openvino 做优化的话,那其转换流程为,先将 pytorch 的模型文件 .pt,转化为 onnx 格式,然后再转化成 IR 模型,即可部署到神经棒上了。
接下来我们用最新版的 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****
********
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 模型了,接着将文件传输到树莓派上。
✎ 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
yolov5s 的 FPS 才 2 帧左右,相比 yolov4-tiny 来说速度不算快,input shape 640 比 yolov4 的416大了不少,主要耗时集中在神经棒的推理之中,需耗费 377ms,还是蛮可观的。
要追求极致的检测速度,还有几个方向可以尝试:
多个神经棒分布式推理;
使用多线程推理;
采用异步方式刷新屏幕;
选用更小的模型;
推理代码由 Python 改为 C++
特别是最近优图开源了一个yolo-fastest版本,backbone为EfficientNet-lite 使得训练的模型权重才1.2M,yolo-fastest-xl 也才3.3M,非常的小巧。
这个 MobileNet SSD 竟然在树莓派4 + 5个 NCS2 上跑到了 FPS 40以上,Amazing!!!
这篇主要介绍了 Tensorflow 和 Pytorch 两种主流框架的转换到 OpenVINO模型的方式。
.weight --> .pb --> .xml .bin
.pt --> onnx --> .xml .bin
其实还有更多AI框架,大致也是通过 pb,onnx,ir,这类中间模型来相互转化,比如应用于 TensorRT,Tensorflow Lite 等等。
一般只要了解,输入输出层的结构,每种模型对应的权重和网络结构文件,注意op算子的支持,就能用框架提供的 pipeline 来做转换了。
最后的手段,就是重写网络拓扑,用类似 load_weight 的方法来导入权重,再 save 到目标框架中了。代码下载
本期相关文件资料,可在公众号后台回复:“rpi09”,获取下载链接。
下一篇
我们将介绍树莓派上的代理软件,
部署Openwrt软路由,
打造一劳永逸的上网环境,
敬请期待...