OpenVINO安装和使用
Openvino对平台系统的要求,他不是所有平台和硬件条件下都适配的,具体要求
要求的处理器和对应的操作系统如下图:
1.环境安装与测试
参考:
https://blog.csdn.net/random_repick/article/details/115753165
1、在官网下载安装包到本地,l_openvino_toolkit_p_2020.4.287.tgz,解压
2、sudo -E ./install_openvino_dependencies.sh
3、执行
sudo ./install_GUI.sh
4、安装依赖项
cd /opt/intel/openvino/install_dependencies sudo -E ./install_openvino_dependencies.sh
5、设置环境变量:
source /opt/intel/openvino/bin/setupvars.sh
为了不需要每次运行代码时都要先激活环境,直接在~/.bashrc中配置即可,gedit ~/.bashrc 打开配置文件,将上面代码复制赞帖到最后一行即可人后关闭文件,激活文件source ~/.bashrc
6、配置模型优化器
cd /opt/intel/openvino/deployment_tools/model_optimizer/install_prerequisites
sudo ./install_prerequisites.sh
7、验证
cd /opt/intel/openvino/deployment_tools/demo
./demo_squeezenet_download_convert_run.sh
./demo_security_barrier_camera.sh
安装成功
2.验证自己训练的模型
我这里使用的是tensorflow框架训练的一个ssd_mobilenet_v2模型,通过模型训练并export得到了一个.pb的模型文件。(当然我这里是根据自己具体的需求对模型做了修改,但是不影响)。
①模型转换
OpenVINO推理时使用的是二进制IR模型,所以首先需要把tensorflow的pb模型文件通过模型优化器,优化处理成为二进制IR模型(.xml 描述网络拓扑结构.bin描述权重和偏置的二进制数据)
首先cd /home/s2/intel/openvino/deployment_tools/model_optimizer位置,找到mo_tf.py文件
然后执行
python mo_tf.py --input_model=***.pb --output_dir=./***
在mo_tf.py中还有其他的参数指令如下图:
指令 | 释义 |
---|---|
–inputmodel | pb模型文件 |
–tensorflow_use_custom_operation_config | 描述TensorFlow |
–tensorflow_use_custom_operation_config | 训练pb的pipeline.config文件 |
–data_type=FP16 | 指定数据类型为FP16 |
–reverse_input_channels | 因在训练模型时是基于RGB通道进行训练的,而Intel的Inference Engine是基于BGR通道来进行推理的。所以需要进行RGB转BGR |
–output_dir | IR模型的保存路径 |
–model_name | IR模型的文件名 |
根据需要选择相应的参数指令,我这里紧使用了最简单的参数进行模型转换,转换成功如下图所示:
在指定的保存路径下会产生如下所示的三个文件
此时模型转换成功
②模型推理:
因为我使用的是ssd_mobilenet_v2,里面有一个算子为anchors,openvino是不支持的,所以在进行模型推理的时候,我需要单独把anchor算子抽离出来,在进行推理的时候再加载进去,代码块如下:
model_name ='./models/×××.pb'
graph = load_graph(model_name)
session = tf.Session(graph = graph)
input_ph = graph.get_tensor_by_name('normalized_input_image_tensor:0')
anchors_ph = graph.get_tensor_by_name('anchors:0')
inp = np.ndarray(shape=(1, 224, 224,3))
anchors = session.run([anchors_ph], feed_dict = {input_ph: inp})
f = open('anchors1.bin', 'wb')
pickle.dump(anchors, f)
f.close()
将anchors参数保存为一个.bin的二进制文件,在进行模型推理时直接加载进去即可
下面进行模型推理
import cv2
import numpy as np
from openvino.inference_engine import IECore
from utils import py_nms
import pickle
class OpenvinoDetector:
def __init__(
self,
model_xml="./models/***.xml",
model_bin="./models/***.bin",
anchors_filename="./models/anchors.bin",
inp_n=1, inp_h=257, inp_w=385, inp_c=3,
):
self.ie = IECore()
self.inp_n = inp_n
self.inp_h = inp_h
self.inp_w = inp_w
self.inp_c = inp_c
self.X_SCALE = 10.0
self.Y_SCALE = 10.0
self.H_SCALE = 5.0
self.W_SCALE = 5.0
# 加载anchors
anchors_file = open(anchors_filename, 'rb')
self.anchors = pickle.load(anchors_file)
if anchors_file is not None:
anchors_file.close()
# 加载解析二进制IR文件
self.net = self.ie.read_network(model=model_xml, weights=model_bin)
self.session = self.ie.load_network(network=self.net, device_name="CPU")
def detect(self, image=None, cls_thresh=0.5, nms_thresh=0.45):
if image is None:
return None
H, W, C = image.shape
x_in = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
x_in = cv2.resize(x_in, dsize=(self.inp_w, self.inp_h))
x_in = (x_in - 123.0) / 58.0
x_in = x_in.transpose((2, 0, 1))
inp = np.ndarray(shape=(self.inp_n, self.inp_c, self.inp_h, self.inp_w))
inp[0] = x_in
# 模型推理
rets = self.session.infer(inputs={"normalized_input_image_tensor": inp})
classes = rets['convert_scores'][0]
boxes = rets['Squeeze'][0]
ycenter = boxes[:, 0] / self.Y_SCALE * self.anchors[:, 2] + self.anchors[:, 0]
xcenter = boxes[:, 1] / self.X_SCALE * self.anchors[:, 3] + self.anchors[:, 1]
h = np.exp(boxes[:, 2] / self.H_SCALE) * self.anchors[:, 2]
w = np.exp(boxes[:, 3] / self.W_SCALE) * self.anchors[:, 3]
_ymin = (ycenter - h * 0.5)
_xmin = (xcenter - w * 0.5)
_ymax = (ycenter + h * 0.5)
_xmax = (xcenter + w * 0.5)
ymin = _ymin * H
xmin = _xmin * W
ymax = _ymax * H
xmax = _xmax * W
prob = classes[:, 1]
type_ = np.ones_like(prob)
decoded_location = np.stack([xmin, ymin, xmax, ymax, prob, type_], axis=1)
decoded_location = decoded_location[prob > cls_thresh, :]
nms_keep = py_nms(decoded_location, nms_thresh)
results = decoded_location[nms_keep]
return results
if __name__ == '__main__':
objs_detector = OpenvinoDetector()
image = cv2.imread("./images/1.jpg")
cls_thresh = 0.5
nms_thresh = 0.45
objs = objs_detector.detect(image, cls_thresh, nms_thresh)
for obj in objs:
prob = obj[-2]
label = obj[-1]
obj = obj[0:4]
xmin, ymin = int(obj[0]), int(obj[1])
xmax, ymax = int(obj[2]), int(obj[3])
cv2.rectangle(image, (xmin, ymin), (xmax, ymax), (0, 0, 255), 2)
cv2.imwrite("./output2.jpg", image)
得到下入的推理效果:
测试结果OK!
在同样的环境下,找了一个3分钟的视频进行推理,对比使用openvino和不适用OpenVINO推理的参数值,如下
通过对比发现,速度提升了将近3倍,还是很nice的