一、前言
PyTorch是开源的深度学习框架,目的是加速从研究原型到产品开发的过程。其SDK主要基于Python。而其模型训练支持CPU与GPU、支持分布式训练、云部署,针对深度学习特定领域有不同的丰富的扩展库。
深度学习项目的开发大致可以分为两个阶段:
- 第一个阶段是训练阶段。这个阶段最重要的事情就是数据采集、模型设计、训练参数调试,找到合适的模型并努力训练到满足或者超过项目实际需要的精度。
- 第二个阶段是部署阶段。这个阶段最重要的事情就是把模型移植部署到各种不同的计算设备上,尽可能地实现模型规模的小型化、推理预测过程的加速。
相比于PyTorch、TensorFlow等为开发者所熟知的训练框架,推理部署的框架却显得有些默默无闻,但是它在深度学习模型落地过程中发挥着不可替代的作用。正是在这样的背景之下,英特尔在2018年发布了专门针对CPU、iGPU(集成显卡)、FPGA、ARM等硬件单元加速的模型部署与加速推理框架OpenVINO™。
OpenVINO™是英特尔发布的一套支持快速开发视觉、语音识别、自然语言处理应用的框架,受益于人工智能技术的快速发展,框架采用了最新的人工智能神经网络包括卷积神经网络、循环神经网络、注意力机制网络等模型。实现视觉与非视觉任务的底层硬件加速、达到最佳性能,支持人工智能应用从云端到边缘的部署与推理全链路技术。
二、PyTorch
1. 安装
建议使用 Conda 安装 PyTorch ,本篇笔记也将以Conda安装方式为例。笔者的环境是Windows11 + Anaconda + CUDA11.6,而Linux或Mac平台的环境配置大同小异,这里就不过多赘述。
1) CUDA版本
以CUDA11+为例,首先需要安装CUDA驱动
安装完成后,检测安装版本
1 | nvidia-smi |
- 安装CUDA版本
1
conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch
2) CPU版本
若没有NVIDIA系显卡或其不支持CUDA加速,则可选择安装仅CPU版本。
- 安装仅CPU版本
1
conda install pytorch torchvision torchaudio cpuonly -c pytorch
2. 检验
在终端进入Python3控制台(笔者python
命令默认链接到Python3)
1 | python |
导入PyTorch
1 | import torch |
测试torch.rand()
函数
1 | torch.rand(5, 3) |
若安装成功,则会出现类似于以下的输出
测试是否支持CUDA
1 | import torch |
3. 概念
很多人学习深度学习框架面临的第一个问题就是其专业术语跟基本的编程概念与传统面向对象编程不同,这是初学者面临的第一个学习障碍。
在主流的面向对象编程语言中,结构化代码最常见的关键字是if
、else
、while
、for
等关键字,而在深度学习框架中编程模式主要是基于计算图、张量数据、自动微分、优化器等组件构成。
面向对象编程运行的结果是交互式可视化的,而深度学习通过训练模型生成模型文件,然后再使用模型预测、本质数据流图的方式工作。所以学习深度学习框架首先必须理清深度学习编程中计算图、张量数据、自动微分、优化器这些基本术语概念,下面分别解释如下:
1) 张量
张量(Tensor)是深度学习框架中需要理解的最重要的一个概念,张量的本质是数据,在深度学习框架中一切的数据都可以看成张量。
深度学习中的计算图是以张量数据为输入,通过算子运算,实现对整个计算图参数的评估优化。但是到底什么是张量?可以看下面这张图:
上图中标量、向量、数组、3D、4D、5D数据矩阵在深度学习框架中都被称为张量。可见在深度学习框架中所有的数据都是张量形式存在,张量是深度学习数据组织与存在一种数据类型。
2) 算子/操作数
深度学习主要是针对张量的数据操作。这些数据操作从简单到复杂,多数都是以矩阵计算的形式存在。最常见的矩阵操作就是加减乘除,此外卷积、池化、激活也是模型构建中非常有用的算子/操作数。Pytorch支持自定义算子操作,可以通过自定义算子实现复杂的网络结构,构建一些特殊的网络模型。张量跟算子/操作数一起构成了计算图,它们是也是计算图的基本组成要素。
3) 计算图
深度学习基于计算图完成模型构建,实现数据在各个计算图节点之间流动,最终输出。因此计算图又被称为数据流图。
根据构建计算图的方式不同还可以分为静态图与动态图。Pytorch默认是基于动态图的方式构建计算图。
动态图采用类似Python语法,可以随时运行,灵活修改调整。
而静态图则是效率优先,但是在图构建完成之前无法直接运行。
可以看出动态图更加趋向于开发者平时接触的面向对象的编程方式,也更容易被开发者理解与接受。
下图是一个简单的计算图示例:
图中最底层三个节点表示计算图的输入张量数据节点(a、b、c),剩下节点表示操作,带箭头的线段表示数据的流向。
4) 自动微分
使用Pytorch构建神经网络(计算图)模型之后,一般都是通过反向传播进行训练,反向传播算法使用损失函数功能对神经网络中每个参数根据梯度进行参数值的调整。
为了计算这些梯度完成参数调整,深度学习框架中都会自带一个叫做自动微分的内置模块,来自动计算神经网络模型训练时的各个参数梯度值并完成参数值更新,这种技术就是深度学习框架中的自动微分。
4. PyTorch基础操作
1) 张量的定义与声明
张量在PyTorch深度学习框架中表示数据,有几种不同的方式来创建与声明张量数据。
a. 常量声明
1 | import torch |
输出
1 | tensor([[2., 3.], |
其中torch.tensor()
默认的数据类型是flaot32,这点从a.dtype
的打印结果上也得了印证。
b. 转换声明
torch.tensor
函数支持从NumPy数组直接转换为张量数据。
1 | import numpy as np |
输出
1 | tensor([[1, 2], |
函数返回的数据类型将会根据NumPy数组自动识别。
c. 初始化声明
PyTorch框架支持类似MATLAB的数组初始化方式,可以定义数组的维度,然后初始化为零。
1 | import torch |
输出
1 | tensor([[0., 0., 0., 0.], |
可使用torch.ones()
函数初始化为1
1 | import torch |
输出
1 | tensor([[1., 1., 1., 1.], |
d. 随机初始化声明
在实际的开发中,经常需要随机初始化一些张量,可通过torch.rand()
等函数实现
1 | import torch |
输出
1 | v1: tensor([[0.6751, 0.0717, 0.4391], |
2) 张量的操作
a. 计算图操作
以上图为例,用代码将它实现出来:
1 | import torch |
输出
1 | y: tensor([[ 5.8000], |
b. 数据类型转换
可用如下代码进行常见的数据类型转换:
1 | import torch |
输出
1 | tensor([1., 2., 3., 4., 5., 6.]) torch.float32 |
c. 维度转换
可用如下代码进行常见的维度转换:
1 | import torch |
输出
1 | a: tensor([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.]) |
除此之外,还可以使用基于tensor
的维度转换函数tensor.view()
1 | import torch |
输出
1 | a: tensor([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11.]) |
d. 通道交换
通道交换是PyTorch中处理张量数据常用操作之一。
1 | import torch |
输出
1 | x: tensor([[[-0.9932, -2.1915, -0.8266, -1.8298, 0.5624], |
e. 寻找最大值
寻找最大值是PyTorch中处理张量数据常用操作之一。
1 | import torch |
输出
1 | x: tensor([ 2., 3., 4., 12., 3., 5., 8., 1.]) |
f. CPU与GPU运算支持
PyTorch支持CPU与GPU计算,默认创建的tensor是CPU版本的,要想使用GPU版本,首先需要检测GPU支持,然后转换为GPU数据,或者直接创建为GPU版本数据
1 | import torch |
输出
1 | name: NVIDIA GeForce RTX 2060 |
5. 线性回归预测
线性回归的本质就是根据给出二维数据集来拟合生成一条直线,如下图:
左图是一组圆点表示的二维坐标点数据集,直线是根据线性回归算法生成的。
右图则是根据坐标点数据集生成的一个非线性回归例子。
现在我们已经可以很直观地了解什么是线性回归了,但线性回归是怎么找到这条直线的?
我们可以通过PyTorch构建一个简单的计算图来不断学习,最终得到一个足够逼近真实直线的参数方程,这个过程被称为线性回归的学习/训练过程。
1) 原理
最常见的直线方程如下:
假设有一组二维坐标点数据集:
一 | 二 | 三 | 四 | 五 | 六 | |
---|---|---|---|---|---|---|
x | 1 | 2 | 0.5 | 2.5 | 2.6 | 3.1 |
y | 3.7 | 4.6 | 1.65 | 5.68 | 5.98 | 6.95 |
随机赋值初始k、b两个参数,根据直线方程,通过x可以得到对应的
假设当前参数为A(k, b),新参数为B(k, b),我们可以通过下面的公式来更新k、b两个参数:
其中η称为学习率,grad(η)是对应的参数梯度,可根据深度学习框架的自动微分机制得到。这样就实现了线性回归模型的构建与训练过程,最终可根据输入的迭代次数运行并输出回归直线的两个参数,从而完成线性回归的求解。
2) 实现
PyTorch提供了丰富的函数,可以帮助我们快速搭建线性回归模型并完成训练预测。
a. 构建数据集
1 | import numpy as np |
b. 构建线性回归模型
1 | # 继承torch.nn.Module |
c. 创建损失功能与优化器
1 | data_input_dim = 1 # 输入维度为1 |
d. 迭代训练
1 | # 迭代训练 |
e. 绘制结果
1 | predicted_y = model(torch.from_numpy(data_x).requires_grad_()).data.numpy() # 得到预测结果 |
最终完整代码为:
1 | import numpy as np |
最终得到:
三、OpenVINO™
1. 概念
OpenVINO™ ToolKit主要功能包含:
- 支持边缘卷积神经网络的推理加速
- 支持在英特尔CPU、HD卡、NCS2、FPGA等设备上的混合执行/异构计算执行
- 通过大量的预训练模型库做到加速从产品原型到市场化的过程
- 支持传统的计算机视觉标准库,包括OpenCV、OpenCL等
人工智能应用/模型的开发在第二阶段模型部署中,可以借助OpenVINO™ ToolKit的压缩量化、推理加速能力达到模型推理时的最佳性能(速度与精度)。相比第一阶段,第二阶段更为重要,它决定模型最终是否可以实现商业目标,带来商业价值。英特尔发布的开源版本OpenVINO™ ToolKit支持从云端到边缘的模型部署,通过自身人工智能技术优势着力解决人工智能落地环节的商业痛点。
上图中矩形框内的部分是OpenVINO™的核心功能。矩形框外表示第三方提供的模型与上层应用。
2. 功能与组件
深度学习模型优化器(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)
OMZ主要有两个部分。
第一部分是Demos教程,主要包括Python与C++的SDK教程,教程主要涉及计算机视觉与语音识别相关的内容。
第二部分是模型,包含Intel提供与其它公开支持OpenVINO™部署推理的模型,总数超过240+,对于很多常见的视觉任务都无需再训练模型,直接使用模型再通过推理引擎部署即可。
需要注意的是public
(非Intel提供)部分的模型,需要开发者自己转换为IR格式中间文件,才能通过推理引擎部署调用。
OpenCV组件
OpenVINO™ ToolKit在支持深度学习模型部署的同时,还把OpenCV作为支持传统视觉算法处理的组件,集成到了OpenVINO™ ToolKit中,因而可以自动获取OpenCV框架的支持,这对熟悉OpenCV框架的开发者来说是一个大大的福利!并且OpenVINO™提供的官方教程中,图像预处理与推理引擎输出的后处理,图像与图形绘制等均采用了OpenCV相关函数完成,对大多数OpenCV开发者来说看这些代码毫无违和感。
3. 安装
打开Intel® Distribution of OpenVINO™ Toolkit
如上图,由于后续基本上采用Python开发,所以我们选择PIP的方式安装
选择PyTorch框架,得到如下安装代码:
1 | pip install openvino-dev[pytorch]==2022.1.0 |
未完待续…