ONNX 浅析:如何加速深度学习算法工程化?
AlphaGo击败围棋世界冠军李世石以来,关于人工智能和深度学习的研究呈现井喷之势。
各种新的算法和网络模型层出不穷,令人眼花缭乱。与之相随的,深度学习的训练和推理框架也在不断的推陈出新,比较著名的有:微软的CNTK、Google的TensorFlow、Facebook的PyTorch、Apple的CoreML、Intel 的OpenVINO、英伟达的cuDNN和TensorRT、腾讯的TNN和NCNN、阿里的MNN等等。
这些框架都有相似之处,他们的输入是一个或者一组多维数据,数据经过多层运算单元之后输出运算结果。训练框架支持BackPropogation等训练方法,可以自动调整模型参数,用于算法设计。推理框架则是单纯只能用于模型推理运算,不能调整模型本身,用于算法部署落地。
这些框架中,Google的TensorFlow的这个名字尤其具有美感。多维数据是为张量(Tensor),数据在多层运算单元中的运算和传递是为流(FLow),看到这个词就仿佛看到了一个数据和运算的图(Computation Graph),真可谓妙手偶得之佳作。这些框架都需要构建算子,并且将这些算子按照一定的次序连接起来,可以称之为网络模型。
01
Why ONNX?
每个深度学习框架都有自己独有的格式来解释和存储网络模型,并且这些框架的侧重点不同,有些用于训练学习,有些用于部署推理。在深度学习算法开发中,在不同的阶段会选择不同的框架,所以模型描述格式的不同,在客观上造成了深度学习算法开发和落地的困难。
笔者之前曾开发深度神经网络算法,当时选择的训练框架是Caffe,需要落地部署到Linux、iOS、Android等多个平台。Linux选择的是Nvidia的cuDNN;iOS选择的是CoreML;Android选择的是NNAPI,Caffe的模型描述格式是caffemodel。
它使用自定义的Protobuf (https://github.com/BVLC/caffe/tree/master/src/caffe/proto),但是显然,无论是cuDNN、CoreML、NNAPI都无法直接使用caffemodel,CoreML的模型描述使用另一种定义 (https://apple.github.io/coremltools/mlmodel/index.html),cuDNN和NNAPI都是low-level的推理引擎,需要使用者将这个模型组装起来。
对于CoreML来说,我们需要把caffemodel转为coremlmodel格式,对于 cuDNN和NNAPI,我们需要解析caffemodel,然后自己组装出完整的网络模型。这个过程繁琐而且容易出错,当时有强烈的冲动,希望定义一个统一的模型描述格式,所有的训练框架训练所得的网络模型,都是用这个格式来描述,在设备上部署推理时,相应的推理引擎支持解析这个统一的描述格式,直接完成部署落地,岂不美哉。
当然此事并不容易,要定义个统一的模型描述格式,不仅仅需要对机器学习技术有深入的理解,而且将之推广成为事实上的行业标准,更需要有很大的行业影响力,并不是如笔者这样的无名小卒可以为之。所幸已经有社区在做这个事情了,这就是Open Neural Network Exchange(ONNX)。
用ONNX自己的话来说,ONNX是一个对计算网络(Computation Graph)的一个通用描述(Intermediate Representation)。它希望被设计成为开放的网络描述格式,减少开发者在各个训练和推理框架间切换的代价,可以让开发者专注于算法和优化。虽然ONNX还处于比较早期的阶段,不过已经有约来越多的人开始关注到它,未来会有机会得到更广泛的应用。
02
计算模型描述
ONNX有两个分类:基础的ONNX主要用于描述神经网络、ONNX-ML是对基础ONNX的扩展,增加了神经网络之外的其他机器学习算法的支持。本文不会涉及ONNX-ML,接下来的文字以一个简单的ONNX模型为例,介绍一下 ONNX是如何来描述一个计算网络的。该模型可以在ONNX的Github上下载(https://github.com/onnx/models/blob/master/vision/classification/mobilenet/model/mobilenetv2-7.onnx).
ONNX的模型描述采用了Google的Protocol Buffer语言。最外层的结构是ModelProto,它的定义如下:
message ModelProto { int64 ir_version = 1; repeated OperatorSetIdProto opset_import = 8; string producer_name = 2; string producer_version = 3; string domain = 4; int64 model_version = 5; string doc_string = 6; GraphProto graph = 7; repeated StringStringEntryProto metadata_props = 14; repeated TrainingInfoProto training_info = 20; repeated FunctionProto functions = 25;}
比较重要的字段有:
lr_version : 当前的ONNX模型文件的版本,目前发布的最新版本为IR_VERSION_2019_3_18 = 6. 发布于2019年,版本7还在制定中。
opset_import: 当前的模型文件所依赖的算子domain和版本。
graph: 这个模型执行的运算图,这个是最重要的字段。
GraphProto的定义如下:
message GraphProto { repeated NodeProto node = 1; string name = 2; // namespace Graph repeated TensorProto initializer = 5; repeated SparseTensorProto sparse_initializer = 15; string doc_string = 10; repeated ValueInfoProto input = 11; repeated ValueInfoProto output = 12; repeated ValueInfoProto value_info = 13; repeated TensorAnnotation quantization_annotation = 14;}
比较重要的字段有:
initializer : 模型的每一网络层的参数, 模型训练完成之后参数就被固定下来。
input : 模型的输入格式。
output : 模型的输出格式。
nodes : 定义了模型的所有运算模块, 依照推理的次序排布。
NodeProto的定义如下:
message NodeProto { repeated string input = 1; // namespace Value repeated string output = 2; // namespace Value string name = 3; // namespace Node string op_type = 4; // namespace Operator string domain = 7; // namespace Domain repeated AttributeProto attribute = 5; string doc_string = 6;}
比较重要的字段有:
input : 输入参数的名字。
output : 输出参数的名字,这里需要留意的是,每一个网络层之间的连接使用输入和输出的名字来确立的。
op_type : 算子的类型。
attributes : 算子的属性, 其解析取决于算子的类型。
ONNX中最复杂的部分就是关于各种算子的描述,这也可以理解,构成神经网络的主体就是这些算子。attributes 就是算子的一组带名字的属性。
本文中,我们介绍一个在mobilenetv2-7.onnx使用最多的算子: conv。
卷积神经网络在语音,图像,视频等处理上获得了巨大成功. ONNX关于卷积网络层的属性定义主要有:
dilations: 扩展卷积,默认为1,即普通卷积。其数学定义如下:
group: 分组卷积, 其定义见文献14. 默认为1, 即不分组。
kernel_shape: 定义了卷积核的大小。
pads: 定义了上下左右填充的像素数。
strides: 定义了卷积运算的步长。
03
ONNX的支持情况
各家的训练和推理框架还在继续发展,ONNX想成为行业标准显然还为时尚早,但是目前尚没有看到其他更好的通用模型描述格式,我们简单归纳一下现在的ONNX的支持情况(不完整):
参考文献
[1] ONNX: https://github.com/onnx/onnx
[2] TENSORFLOW: https://www.tensorflow.org/
[3] CNTK: https://github.com/Microsoft/CNTK
[4] PYTORCH: https://pytorch.org/
[5] TNN: https://github.com/Tencent/TNN
[6] MNN: https://github.com/alibaba/MNN
[7] CUDNN: https://developer.nvidia.com/zh-cn/cudnn
[8] TENSORRT: https://developer.nvidia.com/zh-cn/tensorrt
[9] COREML: https://developer.apple.com/documentation/coreml
[10] NCNN: https://github.com/Tencent/ncnn
[11] NNAPI: https://developer.android.com/ndk/guides/neuralnetworks
[12] Protocol Buffers: https://developers.google.com/protocol-buffers
[13] Dilated Convolutions https://arxiv.org/abs/1511.07122
[14] Dynamic Group Convolutions https://arxiv.org/abs/2007.04242
往
期
回
顾
资讯
GitHub的AI编程代码漏洞40%
简历
你和大厂的距离有多长?
资讯
英伟达用 AI 给自家纪录片配音
转载
人脸识别模型的动手实践!
分享
点收藏
点点赞
点在看
ONNX 浅析:如何加速深度学习算法工程化?相关推荐
- 高性能加速深度学习算法
1. 深度学习 深度学习是机器学习研究中的一个新的领域,其动机在于建立.模拟人脑进行分析学习的神经网络,它模仿人脑的机制来解释数据,例如图像,声音和文本.深度学习典型应用为图像识别和语音识 ...
- win10+anaconda+cuda配置dlib,使用GPU对dlib的深度学习算法进行加速(以人脸检测为例)...
win10+anaconda+cuda配置dlib,使用GPU对dlib的深度学习算法进行加速(以人脸检测为例) 转载于:https://www.cnblogs.com/zhehan54/p/8540 ...
- 基于FPGA的深度学习算法加速
学习总结--基于FPGA的深度学习算法加速 1.深度学习算法加速的方法 2.为什么用FPGA来加速YOLOV2 3.FPGA简介 4.PYNQ框架与HLS加速理论 5.实验结果 1.深度学习算法加速的 ...
- 岗位推荐 | 百度招聘计算机视觉、深度学习算法工程师(可实习)
PaperWeekly 致力于推荐最棒的工作机会,精准地为其找到最佳求职者,做连接优质企业和优质人才的桥梁. 如果你需要我们来帮助你推广实习机会或全职岗位,请添加微信号「pwbot02」. 工作地点: ...
- NVIDIA教你用TensorRT加速深度学习推理计算 | 量子位线下沙龙笔记
主讲人:Ken(何琨)| NVIDIA开发者社区经理 张康 屈鑫 编辑整理 量子位 出品 | 公众号 QbitAI 12月22日,量子位联合NVIDIA英伟达举行了线下交流会,跟现场近百位开发者同学共 ...
- 如何使用TensorRT加速深度学习推理
文章目录 1.TensorRT 简介 2.一个简单的TensorRT示例 3.简要代码演练 3.1.批量输入 4.配置文件 5.优化您的应用 6.使用混合精度计算 7.设置最大工作区大小 8.重用Te ...
- PaddleX 结合 OpenVINO 工具套件 ,优化深度学习算法CPU部署性能
引言 当今世界,深度学习技术正得以广泛应用,为工业质检.安防巡检.金融.医疗.能源等各行各业降本增效.然而,深度学习算法往往需要较高性能的计算芯片作为支撑,以满足大计算量.高推理速度等产业需求,这为众 ...
- 强生进军医疗机器人、Deepmind利用深度学习算法检查乳腺癌X光,AI医疗的风口已到来?...
合作是AI在医疗领域快速赋能的一大解决方式. 一直以来,强迫症.忧郁症等情绪类精神疾病都被业界认为是没有办法从生理上进行治愈的疾病,最近,在<自然>杂志上公布的最新AI+医疗的神经算法就可 ...
- 基于深度学习的恶意样本行为检测(含源码) ----采用CNN深度学习算法对Cuckoo沙箱的动态行为日志进行检测和分类...
from:http://www.freebuf.com/articles/system/182566.html 0×01 前言 目前的恶意样本检测方法可以分为两大类:静态检测和动态检测.静态检测是指并 ...
最新文章
- 强哥原创管理方法论之“掌纹管理学”
- php中的函数调简单 传入参数即可,php函数与传递参数的简单示例
- 更改MOSS所有列表的标题底色
- 10. Leetcode 209. 长度最小的子数组 (数组-同向双指针-滑动窗口)
- boost::python::iterator相关的测试程序
- QT乱码总结3.UNICODE有无BOM
- python弹出窗口后卡死_python的tkinter模块GUI编程为啥用了while循环之后就会使得程序出现卡死未响应崩溃?...
- 不定宽高的DIV,垂直水平居中
- JavaScript(一)基本语法
- iOS 后台运行实现总结
- 输错密码?这个 sudo 会“嘲讽”你
- python3安装MySQLdb
- Numpy下载并安装
- 认识RAW修图基础知识
- 四六级对计算机考研有影响吗,英语四六级对考研有多大影响
- 宗地自动编号及属性赋值
- Android 交互动画的统一实践
- Git之版本回退和分支合并
- html5 ios keychain,iOS10适配之Keychain读写失败
- tokudb分区表建立cluster index报错