OpenVINO工具包配置TensorFlow模型(一)

最近领导考虑到生产成本的问题,想要在CPU上运行神经网络,于是研究了一阵Intel推出的OpenVINO工具包。下面主要是介绍在Ubuntu16.04上使用OpenVINO配置TensorFlow模型。

OpenVINO深度学习部署工具套件

OpenVINO的深度学习部署工具套件主要包括两部分,一个是模型优化器,另外一个是推理引擎。模型优化器是由Python编写的,推理引擎是一套C++函数库以及C++的类。

工作原理是对训练产生的网络模型进行优化,优化结果转换成中间表示文件,得到IR文件(xml文件和bin文件)。xml文件中包含优化以后的网络拓扑结构,bin文件优化之后的模型参数和模型变量。

对于TensorFlow框架,对应的模型为pb文件。

环境准备工作

安装

首先,官网上有详细的安装步骤:Install the Intel® Distribution of OpenVINO™ toolkit for Linux*

但是,配置环境总是一件麻烦的事,鬼知道会缺失什么依赖包,到头来没装好不说,还可能影响已有的环境┑( ̄Д  ̄)┍。在即将入坑之际,我发现了现成的docker image,于是果断选择跳过官方指导。。。

sudo docker run -it cortexica/openvino /bin/bash

(使用sudo docker search openvino命令可找到很多相关的images,cortexica/openvino这个image的描述里提到了Ubuntu16.04,所以我选择了这一个)

配置模型优化器

运行容器,进入模型优化器 prerequisites文件夹(不同images中的路径可能有差异,但从deployment_tools这层目录开始应该都一样)

cd  /opt/intel/computer_vision_sdk/deployment_tools/model_optimizer/install_prerequisites

运行脚本

sudo ./install_prerequisites.sh

运行demo验证安装成功

这一步我跳过了,具体操作可以参考Use the Demo Scripts to Verify Your Installation

转换TensorFlow模型

先来关注一下可以转的层:Supported TensorFlow Layers

PS:点名RandomUniform是Not supported。。。什么仇什么怨,不支持别写在表里好不好

其实转的过程很简单,就两小步:

1、进入model_optimizer文件夹

cd  /opt/intel/computer_vision_sdk/deployment_tools/model_optimizer

2、使用mo_tf.py脚本将pb文件转为IR文件

python mo_tf.py --input_model .pb --output_dir

幻想是丰富的,现实是残酷的,如果真这么简单就能成功,那还记录个啥哦(*/ω╲*) 

对于大部分模型来说,直接运行mo_tf.py得到的应该都是各种各样的ERROR,下面正文正式开始

使用转化参数

mo_tf.py文件除了--input_model和--output_dir这个两个参数以外,还有一大波:

mo_tf文件可输入参数

下面介绍几个比较重要的

Mean and Scale Values

一般来说在训练时我们都会使用归一化的输入,比如从0~255归一化到0~1。还有在使用Image Net等公开数据集的时候,会进行一个去均值的操作。这些都属于简单的数据预处理,乍一看好像和网络没啥关系,但其实影响很大,重点在于预处理部分的代码有没有被写进TensorFlow的拓扑结构里。

如果预处理部分被写进拓扑结构里了,这种主要就是在训练网络时直接读取的原始数据,然后用tf里的函数进行预处理的情况。这种情况下得到的模型,在pb文件里会有预处理相关的node,这些node也会直接转化到xml文件中(前提是OpenVINO支持。。。我在预处理结中使用的tf.map_fn对多图进行处理就一直报错)。

另一种情况是拓扑结构里没有预处理部分,举例就是用numpy对原始数据进行了处理,然后作为tf网络的输入,输入到网络中。由于拓扑结构中没有预处理部分,虽然pb转IR的时候也可以成功,但之后推理的结果肯定是错的。这个时候就需要用到相关参数--scale、 --scale_values,、--mean_values。当mean value和scale value被同时指定时,数据先减去mean value,再除以scale value。

python mo_tf.py --input_model .pb --scale_values [59,59,59] --mean_values [177,177,177]

至于怎么看拓扑结构里有没有预处理部分,restore pb文件打印出所有node是一种办法,再直观一点,使用Netron,把pb文件导进去可以直接可视化网络~

这一个参数其实并不影响模型转化的成功与否,只不过没注意的话,转化笑嘻嘻,推理mmp。

接下来的参数会直接影响转化的成败。

Input Shapes

在TensorFlow中, 输入的placeholderr的shape可以被设成None或者-1。这种设置在对输入任意尺寸图片和调整batch size时非常方便。但遗憾的是OpenVINO不接受这么随意的输入。。。

如果在pb文件中,输入没有明确的尺寸的话,需要加入--input_shape参数指定shape,比如[1,128,128,3]。对于batch size不定的情况,再调用mo_tf.py后面加上-b。这两个参数不能同时使用。

python mo_tf.py --input_model .pb --input_shape [1,128,128, 3]

python mo_tf.py --input_model .pb -b 1

Is_Training

神经网络的输入除了输入数据,一般还会有一个区分train和valid(test)状态的is_training,用来控制batch norm和dropout的状态。这里也有两种情况:

1、train和valid是两份代码,这种情况下,is_training在各自的代码里是True和False的定值,并不会再程序运行中切换,此时的pb文件应该固定的是valid代码中狗的graph,再pb转IR的过程中也无需多加参数;

2、在train的过程中同时进行valid,此时is_training是一个placeholder,会在train时传入True,再valid时传入False,在pb文件中也会存在这个node,此时就需要使用参数--freeze_placeholder_with_value,将is_training(node的名字以自己网络中的为准)的值定为False。

python mo_tf.py --input_model .pb --freeze_placeholder_with_value “is_training->False"

Tensorflow模型特有的参数

--tensorflow_use_custom_operations_config

这个参数我没有用到,主要是使用TensorFlow Object Detection API中的模型时会用到,需要传入相应的json配置文件。网上很多在转SSD、Faster RCNN、YOLO等模型发生错误时,使用这个参数导入配置文件后都成功了。

--disable_nhwc_to_nchw

这个参数主要是转换输入维度的,NHWC和NCHW,默认会从NHWC转为NCHW。

实验结果

我自己转换了一个4分类模型,转好后的IR文件存在/opt/intel/computer_vision_sdk/deployment_tools/model_optimizer/model路径下

进入推理引擎文件夹

cd /opt/intel/computer_vision_sdk/deployment_tools/inference_engine/samples/build/intel64/Release

进行推理

./classification_sample -d CPU -i -m

在i7-8700KCPU3.70GHz硬件条件下,分类50张图片,

直接使用CPU前传pb文件耗时903.15 ms,使用OpenVINO引推理引擎耗时176.72 ms

总结:加速效果还是明显的,但使用自己的模型转IR文件还是很复杂的,自定义层的转化还需要多多研究~

参考

Intel OpenVINO配置和使用 - James的博客 - CSDN博客

Using the Model Optimizer to Convert TensorFlow* Models | Intel® Software

Model Optimizer Developer Guide | Intel® Software

你可能感兴趣的:(OpenVINO工具包配置TensorFlow模型(一))