本文翻译自 Vishwesh Shrimali 的  "Using OpenVINO with OpenCV"

原文链接: https://www.learnopencv.com/using-openvino-with-opencv/

翻译:coneypo,working in Intel for IoT,有问题或者建议欢迎留言交流

在这篇文章中,我们会介绍如何利用 Intel 的 OpenVINO 软件包来,发挥 OpenCV 中 Deep Neural Network (DNN) / 深度神经网络 模块的的最大性能;

我们也对 CPU 上 OpenCV 和其他深度学习库的性能进行了比较;

OpenCV 中基于 DNN 实现的模型,在很多深度学习任务中,如分类,目标检测,目标追踪和姿态估计,都表现出色;

我们会在这篇文章中探究,是否可能通过 Intel OpenVINO + OpenCV 这样的组合来进行加速;

0. 目录

1. 训练与推理

6. OpenCV 和 OpenCV+IE 的性能比较

1. 训练和推理

在开始介绍之前,我们要强调这篇文章专注于 Speeding up inference / 加快推理 而不是训练;让我们来看看两者区别:

1. Training / 训练

把深度神经网路视为一个有很多 knobs (parameters) / 旋钮 的黑盒,当旋钮的设置是正确的时候,神经网络就会比较高可能性的给出正确答案;

训练就是来给网络投喂百万级别的训练数据点,以至于神经网络可以按部就班的调整这些旋钮,使得接近正确值;

这种百万级别的数据处理经常是通过 GPU 来进行运算的;

当前 OpenCV 没有提供训练一个 DNN 的方法,然而你可以利用比如 Tensorflow, MxNet, Caffe 等等框架来进行 DNN 模型的训练,然后在你的代码里导入;

2. Inference / 推理

一旦网络训练完成,就可以输入新的数据来获取输出;使用一个训练好的模型,进行输入输出的过程,就叫做 inference / 推理

一个推理引擎会将输入的数据通过神经网络产生输出结果,这里有很多优化方式来加速推理过程;

比如一个高效的推理引擎可以进行神经网络的 pruning / 修剪,将多个 Layers 融合到一步计算过程;

如果硬件支持 16-bit 浮点数运算 (2倍于 32-bit 浮点数运算),一个推理引擎会提高两倍推理速度,而且不会丢失精度,这种方式称之为 quantization / 量化

2. OpenVINO Toolkit 介绍

OpenVINO 代表 Open Visual Inferencing and Neural Network Optimization / 开放视觉推理和神经网络优化

正如 OpenVINO 名称所描述,OpenVINO 被设计用来给网络加速,在视觉推理任务中,比如图像分类和目标检测;

几乎所有用来解决视觉任务的 DNN 是 Convolutional Neural Networks (CNN) / 卷积神经网络

OpenVINO 对于特定的硬件有特定的硬件加速方式来加速计算过程;

2.1 为什么使用 OpenVINO?

如果你 AI 新入门,或者对于 AI 不是很了解,你会发现这块会很有意思;

当我们想起 AI,我们经常会想起一些公司,比如 Google, Facebook, Amazon, IBM, Baidu 等等;

确实他们推动了算法的发展,但是 AI 不仅在 Training / 训练 上对于算力要求高,在 Inferencing / 推理 的时候对于资源的要求也高;

因此,我们在 AI 兴起的时候,也应该去关注一些硬件公司;

Convolutional Neural Networks (CNN) / 卷积神经网络 经常在 GPU 上进行训练;

NVIDIA 能够提供几乎最好的的硬件 GPU,与此同时软件上面使用 CUDA 和 cuDNN 进行深度学习;

NVIDIA 几乎垄断了深度学习的市场,当训练模型的时候;

然而 GPU 过于昂贵,往往在推理的时候也是不需要的;事实上,大多数的推理是在 CPU 上进行的;

比如 Dropbox 使用 CPU farm 来进行文档的 OCR;

在低成本的设备上进行深度学习,GPU 往往是开销最大;比如你几乎不可能花费几百刀去买一个 GPU 去给一个监控摄像头;

这些小设备,比如监控摄像头或者树莓派,经常被称为 Edge devices / 边缘设备 或者 IoT devices / 物联网设备

在推理领域,Intel 占有很大份额;除了制造 CPU,Intel 也生产继承了 GPU 的 Vision Processing Units (VPU) 和 FPGA,这些都用来做推理;

Intel 明白尽管选择很多会很好,但是这也是 AI 开发者的噩梦,因为要在不同平台上进行开发就要学习和适应不同平台的开发环境;

幸运的是,Intel 通过 OpenVINO 解决了这种问题,给 AI 开发者提供了一种 Unified Framework / 统一的框架

OpenVINO 使得可以边缘端进行 CNN-based 深度学习推理,支持跨平台的异构执行,通过一些 OpenCV 和 OpenVX 中一些函数库和预优化的核来加速产品落地时间;

2.2 计算机视觉 Pipeline 和 OpenVINO 

上面框图中,除了有最左边 Custom Code / 定制代码 实现的任务;

除此之外,你有右边两种模块:

  1. CV/non-DL, 非基于深度学习的计算机视觉任务

  2. DL, 基于深度学习的计算机视觉任务

首先,它会优化 OpenCV 中实现的,许多基于传统计算机视觉算法的很多 calls,然后它对于深度学习推理也有特定的优化;

我们如果将 OpenCV 和 OpenVINO 一起使用会从中受益;

3. 使用 OpenVINO 进行深度学习

这一节中,我们会介绍如何在深度学习应用中使用 OpenVINO。

3.1 训练一个深度学习模型

正如我们之前所提到过,OpenCV 或者 OpenVINO 不会给你提供训练神经网络的工具(OpenVINO 专注于 Inference 而不是 Training);

你可以通过下列任一支持的类型模型来训练神经网络,或者从 zoo 模型下载:

  1. Caffe Model Zoo

  2. Tensorflow  Model Zoo

  3. MxNet Model zoo

  4. Open Neural Network Exchange (ONNX)  Model zoo

3.2 优化模型和创建一个 Intermediate Representation (IR) / 中间表示 

之前步骤获得的模型往往没有进行性能的优化,因此,我们利用 OpenVINO 提供的 Model Optimizer / 模型优化器, 来创建一个称之为 Intermediate Representiation (IR) / 中间表示文件 的优化模型;

IR 完全与硬件无关,只取决于神经网络的架构;

下图中展示了用 OpenVINO 部署方式和大多数深度学习框架部署方式的区别:

可以看到模型优化器通过以下机制来优化模型:

  1. 对模型进行修剪:移除部分在训练时候需要的,而推理时候不需要的网络;DropOut 就是这种网络层的一个例子;

  2. 融合操作:有些时候多步操作可以融合成一步,模型优化器检测到这种就会进行必要的融合;

优化过程结束后会生成一个 IR model / 中间表示模型,模型可以被分成两部分:

  1. model.xml: XML 文件包含网络架构;

  2. model.bin: bin 文件包含 Weights / 权重 Biases / 误差

3.3 OpenVINO 推理引擎: 硬件特殊优化

IR 模型与硬件无关,但是 OpenVINO 通过 Inference Engine plugin / 推理引擎插件 在特定的硬件上进行优化;

这个 Plugin 在所有 Intel 的硬件上 (GPUs, CPUs, VPUs, FPGSs) 都可以获得:

3.4 OpenVINO 和 OpenCV

尽管 OpenCV 的 DNN 已经被高度优化,通过推理引擎我们可以进一步提高性能;

下图中展示了使用 OpenCV DNN 的两种方式;如果在您的平台上可以使用,我们高度推荐 OpenVINO + OpenCV 的组合;

4. Linux 中安装 OpenVINO Toolkit

这一节我们会介绍如何在 Linux 中安装和测试 OpenVINO;

Windows 中的 Openvino 安装可以参考 Intel’s website.

4.1 OpenVINO Toolkit 安装

1. 首先去 OpenVINO Toolkit Download page 注册并下载适合你系统的正确版本,这里我们介绍 Linux 系统中的安装:

2. 你会下载下来如 “l_openvino_toolkit_p_2020.1.023.tgz” 这样一个压缩文件,解压然后安装;

  cd ~/Downloads/
tar -zxvf l_openvino_toolkit_p_2020.1.023.tgz cd l_openvino_toolkit_p_2020.1.023/
sudo ./install_openvino_dependencies.sh
sudo ./install_GUI.sh

  

注意: 如果你 sudo ./install_GUI.sh 的话,路径会是 "/opt/intel/openvino_2020.1.023/" 这种;

如果不是 sudo 身份安装,路径会是 "/home/user/intel/openvino_2020.1.023/";

3. 修改环境变量

vim /home/user/.bashrc

在最后一行加入

source /opt/intel/openvino_2020.1.023/bin/setupvars.sh

4. 打开一个新的 Terminal,可以看到 "OpenVINO enviroment initialized"

5. 配置模型优化器,让我们去模型优化器的路径,然后安装所需文件:

cd /opt/intel/openvino_2020.1.023/deployment_tools/model_optimizer/install_prerequisites/
sudo ./install_prerequisites.sh

4.2 测试 OpenVINO 安装

我们可以用 Image Classification demo 来测试安装:

cd /opt/intel/openvino_2020.1.023/deployment_tools/demo/
sudo ./demo_squeezenet_download_convert_run.sh

可以看到 "Demo completed successfully":

还可以去跑 Inference Pipepline demo:

sudo ./demo_security_barrier_camera.sh

可以看到输出的检测结果:

5. 使用 OpenCV 和 OpenVINO IE 进行图像分类

现在让我们来看看如何利用 OpenVINO IE + OpenCV 进行图像分类。

1. 首先需要加载需要的模块:

C++

 #include <fstream>
#include <sstream>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream> using namespace std;
using namespace cv;
using namespace cv::dnn;

Python

 import numpy as np
import time
import cv2

2. 下一步指定 Caffe 的根路径和模型路径:

C++

 string caffe_root = "/home/zt/caffe/";
Mat image = imread("/home/zt/caffe/examples/images/cat.jpg");
string labels_file = "/home/zt/caffe/data/ilsvrc12/synset_words.txt";
string prototxt = "/home/zt/caffe/models/bvlc_reference_caffenet/deploy.prototxt";
string model = "/home/zt/caffe/models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel";

Python

 caffe_root = '/home/zt/caffe/'
image = cv2.imread('/home/zt/caffe/examples/images/cat.jpg')
labels_file = caffe_root + 'data/ilsvrc12/synset_words.txt'
prototxt = caffe_root + 'models/bvlc_reference_caffenet/deploy.prototxt'
model = caffe_root + 'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'

3. 接下来就是常用的图像分类代码,加了一点轻微改动;

我们会声明优先选取 cv2.dnn.DNN_BACKEEND_INFERENCE_ENGINE;

C++

 // load the labels file
std::ifstream ifs(labels_file.c_str());
if (!ifs.is_open())
CV_Error(Error::StsError, "File " + labels_file + " not found");
string line;
while (std::getline(ifs, line))
{
classes.push_back(line);
}
}
blobFromImage(image, blob, , Size(, ), Scalar(,,));
cout << "[INFO] loading model..." << endl;
Net net = readNetFromCaffe(prototxt, model);
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(DNN_TARGET_CPU); // set the blob as input to the network and perform a forward-pass to
// obtain our output classification
net.setInput(blob)
preds = net.forward() double freq = getTickFrequency() / ;
std::vector<double> layersTimes;
double t = net.getPerfProfile(layersTimes) / freq;
cout << "[INFO] classification took " << t << " ms" << endl;

Python

 // load the labels file
rows = open(labels_file).read().strip().split("\n")
classes = [r[r.find(" ") + 1:].split(",")[0] for r in rows] blob = cv2.dnn.blobFromImage(image,1,(224,224),(104,117,123))
print("[INFO] loading model...")
net = cv2.dnn.readNetFromCaffe(prototxt,model)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_INFERENCE_ENGINE)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
# set the blob as input to the network and perform a forward-pass to
# obtain our output classification
net.setInput(blob)
start = time.time()
preds = net.forward()
end = time.time()
print("[INFO] classification took " + str((end-start)*1000) + " ms")

就是这样,仅仅需要用 OpenVINO IE 来替代原生的 OpenCV (cv2.dnn.DNN_BACKEDN_OPENCV);

6. OpenCV 和 OpenCV + IE 的比较

这些比较任务在一台使用 OpenCV-3.4.3,只有 CPU 的 Ubuntu 16.04 AWS 机器上测试;

取100次的平均时间;

Image Classification / 图像分类

Object Detection / 目标检测

Pose Estimation / 姿态估计

从这些数据中可以很清楚的看到,使用 OpenCV + OpenVINO 可以提高计算机视觉库的性能;

# 英文版权 @ Vishwesh Shrimali

# 翻译中文版权 @ coneypo

# 转载请注明出处

【翻译】如何使用 OpenVINO 来优化 OpenCV的更多相关文章

  1. 【翻译】OpenVINO Pre-Trained 预训练模型介绍

    OpenVINO 系列软件包预训练模型介绍 本文翻译自 Intel OpenVINO 的  "Overview of OpenVINO Toolkit Pre-Trained Models& ...

  2. 【翻译】借助 NeoCPU 在 CPU 上进行 CNN 模型推理优化

    本文翻译自 Yizhi Liu, Yao Wang, Ruofei Yu.. 的  "Optimizing CNN Model Inference on CPUs" 原文链接: h ...

  3. Unity渲染优化中文翻译(三)——GPU的优化策略

    如果游戏的渲染瓶颈来自于GPU 首要任务就是找出造成GPU瓶颈的因素所在,通常GPU的性能受到像素分辨率的影响,特别是在移动客户端的游戏,但是内存带宽和顶点计算的影响也需要注意.这些因素的影响都需要实 ...

  4. 【官网翻译】性能篇(四)为电池寿命做优化——使用Battery Historian分析电源使用情况

    前言 本文翻译自“为电池寿命做优化”系列文档中的其中一篇,用于介绍如何使用Battery Historian分析电源使用情况. 中国版官网原文地址为:https://developer.android ...

  5. OpenCV中的SVM参数优化

    OpenCV中的SVM参数优化 svm参数优化opencv SVMSVR参数优化CvSVMopencv CvSVM        SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最常用的 ...

  6. 开源软硬一体OpenCV AI Kit(OAK)

    开源软硬一体OpenCV AI Kit(OAK) OpenCV 涵盖图像处理和计算机视觉方面的很多通用算法,是非常有力的研究工具之一,且稳居开发者最喜爱的 AI 工具/框架榜首. 1.会不会被USA禁 ...

  7. 漫谈CUDA优化

    ​ 作者:Lawliet 翻译:仿佛若有光 前言: 几个月前,我根据 Simoncelli 2016 年的论文编写了自己的自动编码器,用于研究目的.一开始,我想使用一些流行的深度学习框架(例如 Ten ...

  8. jvm系列(十):如何优化Java GC「译」

    本文由CrowHawk翻译,是Java GC调优的经典佳作. 本文翻译自Sangmin Lee发表在Cubrid上的"Become a Java GC Expert"系列文章的第三 ...

  9. 干货|人人都是翻译项目的Master

    在平时的工作中,我们都会经常查阅一些英文文档来解决平时遇到的问题和拓宽视野.看到好的文章或者书籍有没有想要和小伙伴分享的冲动,那么我们一起来翻译吧- 翻译主张 "信 达 雅" .& ...

随机推荐

  1. 分析Android中View的工作流程

    在分析View的工作流程时,需要先分析一个很重要的类,MeasureSpec.这个类在View的测量(Measure)过程中会用到. MeasureSpec MeasureSpec是View的静态内部 ...

  2. Jun

    Contents 数据来源 代码演示 讨论 一.数据来源 为了节省时间,我直接用了官方所给的数据,分别是雄性和雌性小鼠的肝脏芯片数据 Female Data Male Data 二.代码演示 数据输入 ...

  3. SpringMVC 使用注解完成登录拦截

    目录 为了实现用户登录拦截你是否写过如下代码呢? 1. 基于Filter 2. 基于Struts 3. 基于SpringMVC 如何使用自定义注解完成自定义拦截呢? 登录注解 SpringMVC 拦截 ...

  4. CSS——NO.8(代码简写)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  5. py基础之列表生成式

    列表生成式就是用一句语句生成一个列表,格式基本是:x for i in L下面是使用for循环迭代dict而生成的一个复杂表达式,将输出后的字符串保存为html文档可以生成一个表格d = {'adam ...

  6. 微信小程序中图片上传阿里云Oss

    本人今年6月份毕业,最近刚在上海一家小公司实习,做微信小程序开发.最近工作遇到一个小问题. 微信小程序图片上传阿里云服务器Oss也折腾了蛮久才解决的,所以特意去记录一下. 第一步:配置阿里云地址: 我 ...

  7. tensorflow feature_column踩坑合集

    踩坑内容包含以下 feature_column的输入输出类型,用一个数据集给出demo feature_column接estimator feature_column接Keras feature_co ...

  8. 【MySQL】:事务四大特性与隔离级别

    目录 一.事务的概念 二.事务的四大特性 1.原子性 2.一致性 3.隔离性 4.持续性 三.事务语句 1.开启事务:start transaction 2.事务回滚:rollback 指定回滚点 3 ...

  9. 超详细的网络抓包神器 tcpdump 使用指南

    原文链接:Tcpdump 示例教程 本文主要内容翻译自<Tcpdump Examples>. tcpdump 是一款强大的网络抓包工具,它使用 libpcap 库来抓取网络数据包,这个库在 ...

  10. Node的require和module.exports

    node编程中最重要的思想之一就是模块,在 Node.js 模块系统中,每个文件都被视为独立的模块.这是这个思想,让javascript的大规模工程成为可能.模块化编程在前端大肆盛行,在node中导出 ...