PyTorch + OpenVINO™ 开发实战系列教程 第二篇

openlab_4276841a 更新于 2年前

第2章 OpenVINO™ 介绍与开发准备

前面一章主要介绍Python与Pytorch开发环境搭建,以及一些概念与术语解释,Pytorch基础代码与常见操作的函数演示。本章我们将重点介绍OpenVINO™ 开发框架,系统化介绍OpenVINO™ 下载安装、测试验证、组件功能、开发环境配置与代码测试,使用其包含的OpenCV如何实现基本的图象与视频读写、基本图形绘制与显示等。

希望通过本章学习之后读者,读者可以开始了解并建立起对OpenVINO™ 开发框架的基本认知,为下一步与Pytorch的联合编程与使用打下良好基础。

1.1 OpenVINO™ 框架介绍


深度学习项目的开发大致可以分为两个阶段,第一个阶段是训练,这个阶段最重要的事情就是搞好数据采集、模型设计、训练参数调试,找到合适模型并努力训练到满足或者超过项目实际需要的精度;第二个阶段是部署,这个阶段最重要的事情就是把模型移植部署到各种不同的计算设备上,通过尽可能的实现模型规模的小型化、推理预测过程的加速,相比Pytorch、tensorflow等训练框架为开发者所熟知、推理部署的框架显得有些默默无闻,但是它确在深度学习模型落地过程中发挥着不可替代的作用。正是在这样的背景之下,英特尔在2018发布专门针对CPU、iGPU(集成显卡)、FPGA、ARM等硬件单元加速的模型部署与加速推理框架OpenVINO™ 。

2.1.1 OpenVINO™ 框架概述


OpenVINO™ ToolKit是英特尔发布的一套支持快速开发视觉、语音识别、自然语言处理应用开的框架,受益于人工智能技术的快速发展,框架采用了最新的人工智能神经网络包括卷积神经网络、循环神经网络、注意力机制网络等模型。实现视觉与非视觉任务的底层硬件加速、达到最佳性能。支持人工智能应用从云端到边缘的部署与推理全链路技术。OpenVINO™ ToolKit主要功能包含:

1)在边缘侧支持卷积神经网络的推理加速

2)支持在英特尔CPU、HD卡、NCS2、FPGA等设备上的混合执行/异构计算执行

3)通过大量的预训练模型库做到加速从产品原型到市场化的过程

4)支持传统的计算机视觉标准库中的操作包括OpenCV、OpenCL等

人工智能应用/模型的开发在第二阶段模型部署中,可以借助OpenVINO™ ToolKit的压缩量化、推理加速能力达到模型推理时候的最佳性能(速度与精度)。相比第一阶段,考虑到硬件成本等因素影响,第二阶段更为重要,它决定模型最终是否可以实现商业目标,带来商业价值。英特尔发布的开源版本OpenVINO™ ToolKit支持从云端到端侧的模型部署,通过自身人工智能技术优势着力解决人工智能落地环节的商业痛点。

其中矩形框内的部分是OpenVINO™ 的核心功能。矩形框表示第三方提供的模型与上层应用。

2.1.2 功能与组件模块


OpenVINO™ ToolKit工具包中包括以下主要的功能模块与组件模型,这些功能模块与组件模型可以帮助开发者快速的了解OpenVINO™ 工具套件的主要功能,应用场景,技术路线等,下面就是它们的详细介绍与说明:

· 深度学习模型优化器(Deep Learning Model Optimizer)

跨平台的命令行工具包支持导入来自主流的深度学习框架的模型,模型文件可能来自tensorflow、pytorch、caffe、MXNet、ONNX等深度学习框架与工具生成。模型优化器支持对导入模型的转换、优化、导出中间格式文件。

· 深度学习推理引擎(Deep Learning Inference Engine)

一个统一的API接口层,支持对深度学习模型的高效推理,支持跨操作系统、多种底层硬件的异构模式推理计算,这些硬件包括Intel CPU、Intel集成显卡、NCS2计算棒、VPU、FPGA等。

· 推理引擎样例(Inference Engine Sample)

一系列的示例代码文件,通过控制台运行演示了如何在第三方应用中集成推理引擎开发。

· 深度学习工作台(Deep Learning Workbench)

一个基于WEB端的智能化图形交互界面,允许你更加灵活的尝试OpenVINO提供各种组件功能。

· 后训练优化工具(Post-Training Optimization tool)

一个验证与执行量化INT8精度的工具,此功能包含在模型优化器命令行文件夹下面。

· 开放的模型库(Open Model Zoo)

该部分主要有三个部分,其中第一部分是Demos教程,主要包括Python与C++的SDK教程,教程主要涉及计算机视觉与语音识别相关的内容。教你如何在自己应用中通过统一API接口集成推理引擎功能。第二部分与第三部分都是模型,分别是Intel提供与其它公开支持OpenVINO™ 部署推理的public模型,提供的模型总数超过240+,对很多常见的视觉任务我们都无需再训练模型,直接使用模型通过推理引擎部署即可,需要注意的是public部分的模型,需要开发者自己首先转换为IR格式中间文件,才可以通过推理引擎部署调用。

· OpenCV组件

OpenVINO™ ToolKit在支持深度学习模型部署的同时,还把OpenCV作为支持传统视觉算法处理的组件,集成到了OpenVINO™ ToolKit安装包中,因而可以自动获取OpenCV框架的支持,这对熟悉OpenCV框架的开发者来说是一个大大福利!而且OpenVINO™ 提供的官方教程中,图象预处理与推理引擎输出的后处理,图像与图形绘制等均采用了OpenCV相关函数完成,对大多数OpenCV开发者来说看这些代码是毫无违和感。

此外最新版本OpenVINO2021.4还发布了扩展模块支持,支持模型在ARM上的加速推理,支持pytorch模型一键转换为IR格式等功能,进一步扩大了OpenVINO™ 开发者生态。

2.1.3 下载与安装


当前OpenVINO™ ToolKit的开发包可以直接通过官方网站下载,分为长期支持版本与发布版本,下载地址如下:

https://software.intel.com/content/www/us/en/develop/tools/openvino-toolkit/download.html

从页面选择适配的操作系统,然后注册登记完成就可以免费下载使用!此外如果你是一个高阶的开发者,你还可以从github下载源码,自己编译完成开发配置。

OpenVINOTM ToolKit开源版本在github的主页地址如下:https://github.com/openvinotoolkit/openvino

假设你是一个初次接触OpenVINO™ 工具套件的开发者,在Windows系统下你只需要跟随下面几步就可以完成OpenVINO™ 工具套件的安装与测试程序运行。在开始安装之前首先要确保你已经成功安装了下面版本的软件:

· VS2015或者VS2017或者VS2019版本的VC++

· Python3.6.5或者Python3.7或者Python3.8 64bit

· CMake 3.17以上

· Windows 10 64bit

然后你首先需要下载好OpenVINO2021.4版本,然后双击安装文件,运行截图如下:



这个时候你只需要点击【Next】按钮就可以完成默认安装。安装完成之后默认的安装路径为:

C:\Program Files (x86)\Intel\openvino_2021.4.582 (%install_dir%)。在安装目录下执行如下脚本:


然后切换到演示目录下,执行下面的脚本文件,相关的命令行如下:


经过一系列的脚本运行之后,如果一切顺利,运行结果显示如下:


看到这个界面,恭喜你OpenVINO™ ToolKit软件安装成功了,它是一个车辆检测、车牌识别、车辆属性识别三个深度学习模型联合的应用演示。相信到这里你已经迫不及待想要知道如何把这样一个推理引擎演示程序集成到你的应用中去了,作为开发者,需要学习下面的三个首要模块才有可能完成应用集成,它们是:

· 模型优化器(MO):

负责模型转换、优化与中间层格式导出

· 中间层表示(IR):

模型优化器的输出内容,该格式可以更好的被Intel的硬件理解与加速达到最佳性能。

· 推理引擎(IE):

一套统一的开发SDK库接口,可以适配加载IR格式的模型文件并高效执行推理。

怎么样,是不是迫不及待想要知道如何使用OpenVINO™ 框架提供这些首要组件?我们将会在本书后续章节中继续展开说明。

如果你在OpenVINO™ 工具套件的安装与开发中遇到任何技术问题,欢迎关注OpenVINO™ 中文社区微信公众号,寻求我们技术自愿者的答疑与帮助。

2.2 OpenVINO™ 开发环境配置


通过前面一节的内容学习,我们安装好了OpenVINO™ 开发包,运行了自带的演示程序,验证安装程序完整性与正确性。本节我们将在Pycharm IDE中配置OpenVINO™ 的开发环境搭,完成代码测试。

2.2.1 Windows下开发环境配置


前面第一章中我们已经完成了Python SDK与Pycharm IDE的安装与配置,要完成OpenVINO™ 与Pycharm IDE的集成开发配置,完整的配置只需要两步就可以完成。

· 第一步:配置环境变量与Python路径

首先配置好OpenVINO™ 的环境变量,图示如下:


在Windows的系统环境变量path中,添加如图2-7矩形框所示的几个目录路径,点击确定。然后新建环境变量PYTHONPATH,添加如下两个路径(中间用分号分隔),

C:\Program Files (x86)\Intel\openvino_2021.4.582\python\python3.6

C:\Program Files (x86)\Intel\openvino_2021.4.582\deployment_tools\model_optimizer

分别指向OpenVINO™ Python版本对应的SDK目录与模型优化器python工具包目录,该配置如下图所示:


· 第二步:开发环境验证,分别在控制台与Pycharm IDE验证开发配置

首先打开Windows控制台,然后运行如下命令行,图示如下:


如图2-9所示表示能够正常导入OpenVINO™ 的Python语言支持包,说明开发环境配置正确,这个时候就可以打开Pycharm IDE,在之前创建的项目中新建一个Python文件,输入下面的代码:

from openvino.inference_engine import IECore

ie = IECore()

for device in ie.available_devices:

print(device)

在作者的笔记本上运行结果如下(注:不同型号的PC/笔记本运行结果可能稍有差异):

CPU

GNA

GPU

上面代码的第一行是导入OpenVINO™ 包支持,剩下的三行代码分别是初始化推理引擎、查询支持的设备并打印,输出结果中的GPU表示自带的集成显卡支持。


2.2.2 OpenVINO™ SDK支持


OpenVINO-Python的SDK支持主要体现从卷积神经网络模型的读取、图象文件与视频读取与处理,模型的输入与输出设置、模型推理、模型推理的后处理等环节。首先需要成功完成初始化,才可以继续调用IECore的相关函数与方法实现后续操作;通过read_network函数实现对模型文件的读取,读取之后通过load_network函数转换位可执行网络就可以用预先读取处理好的图象数据输入模型完成推理环节与后处理,实现整个流程。这个过程中会涉及到一系列的OpenVINO函数调用与参数设置,同时也会涉及到使用OpenCV完成前处理与后处理。

首先需要的是导入OpenVINO™ 开发包,初始化推理引擎IECore,相关的代码支持只要初始化IECore的实例对象即可。代码如下:

from openvino.inference_engine import IECore

ie = IECore()

一旦完成初始化之后通过调用read_network函数实现深度神经网络模型的加载读取,该函数极其相关参数的详细说明如下:

def ie_api.IECore.read_network(

self,

model,

weight****r>
init_from_buffer

)

参数model支持读取IR格式的.xml文件或者ONNX格式文件或者prototxt格式文件;参数weights支持读入IR格式的bin文件;init_from_buffer参数默认为False,表示前面两个参数为IR格式的.xml与.bin文件,True表示支持IR格式的Python字节内容。使用该函数读取支持的模型之后,需要把网络模型跟特定计算设备绑定,创建可执行的推理网络,这步需要调用load_network函数,该函数极其参数的解释如下:

def ie_api.IECore.load_network(

self,

network,

device_name,

config = None,

num_requests = 1

)

参数network表示的read_network函数读取之后的网络模型;device_name表示目标插件(计算资源硬件名称);config表示相关配置文件路径,默认为空;num_requests默认为1表示创建的可执行网络的数目。read_network与load_network函数一起使用的一个简单的代码演示如下:

ie = IECore()

net = ie.read_network(model=path_to_xml_file, weights=path_to_bin_file)

exec_net = ie.load_network(network=net, device_name="CPU", num_requests=2)

上面的代码创建推理引擎实例ie、然后读取网络模型文件、最后加载创建可执行网络。调用可执行网络(exec_net)实例的infer方法用图象数据作为输入参数就可以完成模型预测得到输出。infer函数极其参数解释如下:

def ie_api.ExecutableNetwork.infer(

self,

inputs = None

)

参数inputs表示输入的图象数据,最常见的格式为NCHW的四维数组,其中N表示图象数目、C表示图象通道数、H跟W分别表示图象高与宽。

上面几个函数是OpenVINO™ SDK应用开发集成中最常用的几个函数,另外这里想介绍几个在前处理与后处理中常用的OpenCV/Numpy包中的函数。首先介绍图象读取函数,该函数极其参数解释如下:

retval = cv.imread(filename[, flags])

参数filename表示图象文件路径;flags表示支持各种读入支持,默认IMREAD_COLOR表示读入数据为三通道彩色图象,通道顺序为BRG(蓝、绿、红)。读取图象之后的显示图象函数为imshow,该函数极其参数解释如下:

None= cv.imshow( winname, mat )

参数winname表示显示图象的窗口标题,mat表示对应的图象数据。

2.2.4 OpenCV代码测试


根据前面介绍的相关基础知识,这里简单的通过pycharm运行一段测试代码,完成基础的图象加载与文字显示,这段代码是后续会经常用的基础代码,所以也算在这里小小的热身一下,为后续学习打下一个良好的基础,如果你已经对OpenCV-Python的相关基础知识比较熟悉可以跳过本小节。测试代码的实现了读取图象,显示图象并在图象上绘制文字的功能,代码如下:

import  cv2 as cv

image = cv.imread("D:/images/lena.jpg")

cv.putText(image, "Hello, OpenVINO", (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255), 2, 8)

cv.imshow("input", image)

cv.waitKey(0)

cv.destroyAllWindows()

其中putText函数实现了文字绘制的相关功能,其中(50, 50)表示文字绘制的起始位置、(255,255,255)表示白色,运行结果如下:


本小节只是简单的测试一下图象读取与显示函数,更多OpenCV前处理与后处理的相关函数知识点将会在下一节中详细介绍。

2.3 图象基础操作


本节的主要目的是帮助大家掌握使用OpenVINO™ 推理模型时必须知道的图象前处理与后处理的相关知识,本书中我们主要使用OpenCV来完成模型推理时图象数据的前处理与后处理。涉及到的相关知识点主要包括图象的加载、显示与保存;视频文件与摄像头读取;图象通道转换与resize操作、像素遍历与数组操作、ROI区域截取、基本的矩形框与文字绘制等常见操作。

2.3.1 图象与视频读取


通过前面一小节的学习读者已经知道通过OpenCV的imread与imshow两个函数可以实现图象的加载与显示,但是对视频文件或者摄像头视频流,我们该如何读取与显示呢?这里介绍一个重要的OpenCV对象VideoCapture,通过该对象实例就可以实现视频文件或者摄像头或者视频流的读取,该函数与其参数解释如下:

= cv.VideoCapture(filename[, apiPreference])

= cv.VideoCapture(index[, apiPreference])

上面是VideoCapture对象两种不同的参数调用方式,第一种方式支持视频文件与视频流,参数filename表示视频文件路径或者视频流的地址;第二种方式支持webcam的摄像头,参数index表示摄像头的编号索引,对笔记本电脑自带的摄像头默认编号一般为零;参数apiPreference表示支持或者选用的编解码库,默认会自动选择,一般情况下请勿手动设置,因为在不同的系统平台下,OpenCV支持的编解码库稍有差异,手动指定可能导致程序移植问题,默认自动选择会比较好。

既然已经了解了VideoCapture对象的参数含义,下面通过一个视频文件读写的例子来演示VideoCapture实例读取视频文件并通过imshow函数显示,同时支持通过VideoCapture实例对象查询与设置视频的各种属性。演示代码如下:

cap = cv.VideoCapture(video_path)

w = cap.get(cv.CAP_PROP_FRAME_WIDTH)

h = cap.get(cv.CAP_PROP_FRAME_HEIGHT)

fps = cap.get(cv.CAP_PROP_FPS)

print("width: ", w, " height: ", h, " FPS ", fp****r>
cv.namedWindow("frame", cv.WINDOW_AUTOSIZE)

while True:

ret, frame = cap.read()

if ret is not True:

break

cv.imshow("frame", frame)

c = cv.waitKey(50)

if c == 27: # ESC

break

cv.destroyAllWindows()

其中video_path可以是文件路径或者视频流地址,w, h是视频帧的宽高,cap.read()表示读取一帧,然后显示,返回值ret是True表示正常读取,为false表示无法读取,跳出while循环。waitKey(50)表示暂停50毫秒,需要特别注意的是一般情况视频读取与显示时都应该使用waitKey(1),按ESC键退出视频循环读取显示。

2.3.2 像素遍历与类型转换


很多时候在图象前处理或者后处理时候会要求遍历每个输出通道的每个像素(特征)值,在python语言中遍历像素是一种高耗时操作,要尽量避免。读取图象并遍历每个像素点的代码如下:

image = cv.imread("D:/images/lena.jpg")

h, w, c = image.shape

for row in range(h):

for col in range(w):

b, g, r = image[row, col]

image[row, col] = (255-b, 255-g, 255-r)

cv.imshow("pixel-demo", image)

cv.waitKey(0)

cv.destroyAllWindows()

上面的代码先读取图象,然后获取图象高(h)、宽(w)、通道数(c),然后循环读取每个像素点的像素值,重新改写之后再赋值回对应像素点。

使用OpenVINO™ 推理时预处理很多时候要求resize原图到指定的大小图象作为输入,把像素数组维度从HWC格式转换为CHW格式,并图象数据转换为浮点数类型。这几步操作可以通过调用OpenCV几行代码完成,演示代码如下:

src = cv.imread("D:/images/lena.jpg ")

image = cv.resize(src, (w, h))

image = image.transpose(2, 0, 1)

image = np.float32(image) / 255.0

上面的代码第一行加载图象,然后resize到指定的大小(w表示宽、h表示高),把像素数组转换为CHW格式,最后转换为0~1之间的浮点数数据。

2.3.3 图形绘制支持


在OpenVINO™ 推理的图象数据后处理中经常需要绘制不同几何形状,OpenCV支持矩形、圆、多边形的绘制与填充,同时支持文字(非中文)的绘制,可以很好的满足后处理图象显示的要求,实现预测显示。

图象分类的结果经常是文字形式显示在图象中,借助OpenCV的putText函数就是可以完成图象类别名称在图象上的显示,在图象上绘制文字的函数putText极其参数解释如下:

cv.putText(

img, // 图象

text,// 文字

org, // 位置起始位置

fontFace, // 字体

fontScale, // 大小

color // 颜***r>
[, thickness[, lineType[, bottomLeftOrigin]]] // 可选项

)

在对象检测的后处理中,除了要求显示对象名称还会要求显示对象的位置矩形框,OpenCV中函数rectangle可以完成绘制矩形框,其函数与参数解释如下:

cv.rectangle(

img, // 图象

pt1, // 矩形左上角点

pt2, // 矩形右下角点

color // 颜***r>
[, thickness[, lineType[, shift]]]

)

特别注意:颜色之后的下一个参数thickness,当赋值thickness大于0表示按指定线宽绘制矩形、小于零表示填充矩形。

下面的代码演示了文本与矩形框的绘制,其中对文字区域首先填充背景为白色,然后再绘制文字,使用函数getTextSize或者文本长度与高度属性。完整的演示代码如下:

image = cv.imread("D:/images/lena.jpg")

cv.rectangle(image, (225, 229), (365, 392), (0, 0, 255), 2, 8)

f****ase = cv.getTextSize("face", cv.FONT_HERSHEY_PLAIN, 1.0, 1)

cv.rectangle(image, (225, 229-fs[1]), (225+fs[0], 229), (255, 255, 255), -1, 8)

cv.putText(image, "face", (225, 229), cv.FONT_HERSHEY_PLAIN, 1.0, (255, 0, 0), 1, 8)

cv.imshow("image", image);

cv.waitKey(0)

cv.destroyAllWindows()

其中cv.putText函数使用的字体与线宽必须与之前的cv.getTextSize中字体跟线宽保持一致。代码运行结果如下:


2.4 小结


本章介绍了什么是OpenVINO™ 工具套件,以及OpenVINO™ 工具套件重要的几个组件,OpenVINO™ 工具套件的安装与测试;OpenVINO™ 开发环境的搭建与测试,使用OpenVINO™ 开发的必要OpenCV基础知识,这些基础知识主要包括图象与视频加载与显示、基本的放缩与归一化、通道转换与维度转换、基本的绘制函数使用等。

本章的目标是帮助初学者安装与搭建好OpenVINO™ 工具套件的开发环境,完成一些基础代码测试与基础函数代码演示。这些都是后续学习的前置知识,掌握这些知识有助于本书后续章节更好的学习。

0个评论