选自LinkedIn机器之心编译参与:吴攀、蒋思源、李亚洲

深度学习的力量为其在真实世界的应用创造出了巨大的机会。但深度学习的训练往往需要巨大的计算能力,有时候我们却没法(或没钱)去使用强大的服务器或 NVIDIA 的 Jetson 那样的嵌入式加速平台。假如你需要使用一块树莓派开发板为你家的小院子开发一个目标跟踪器呢?换句话说,如果你需要在没有加速器的 ARM CPU 上运行一个 CNN,你该怎么做?德国 BuddyGuard GmbH 的机器学习工程师 Dmytro Prylipko 近日在 LinkedIn 上发表了一篇文章,分享了他在弱硬件上运行深度神经网络的经验方法。

机器学习社区已经在加速神经网络推理上进行了很长一段时间的研究了,也已经出现了大量可能有效的解决方案。在这篇文章中,我将尝试回答一个简单的问题:什么软件库/工具包/框架可以帮助改善我们训练好的模型的推理时间?出于文章篇幅的考虑,这篇文章我不会考虑修改网络架构(尽管这确实是一个好方法,比如 SqeezeNet),而是仅仅探讨那些已经可以在 ARM 设备上投入生产并且提供了 C/C++ 接口(因为我们很少在嵌入式设备上使用 Lua 或 Python)的工具包和软件库。所以在这里我仅仅实验了 Caffe、TensorFlow 和 MXNet。

我们可以做什么

要加速你的计算,我们有两个主要的大方向:1)修改模型;2)加速框架。当然,也可能是将这两者结合起来(而且确实是不错的想法)。前一种方法往往需要使用更低的权重精度(也被称为量化(quantization))和/或权重剪枝(weights pruning)。剪枝背后的思想是深度学习模型中的重要参数化冗余,而低精度方法(为浮点数使用了定点或动态定点表示)则利用了这样一个事实——即推理过程并不需要高精度:因为运算的线性本质和非线性的动态范围压缩(dynamic range compression),量化误差(quantization errors)往往倾向于亚线性地(sub-linearly)传播,而不会引起数值不稳定性(Vanhoucke, V., Senior, A., & Mao, M. (2011). Improving the speed of neural networks on CPUs)。此外,我们甚至可以使用低精度乘法来训练模型。结合 SIMD 指令(比如 SSE3),参数量化可以实现非常有效的计算加速。但是目前我们还很难找到同时使用了这两者的解决方案。比如 Ristretto 可以执行自动量化,但它却并没有利用其来降低计算成本。TensorFlow 也可以执行量化,但其推理时间实际上却增加了 5 到 20 倍,因为其向图(graph)中还引入了辅助量化/去量化节点(auxiliary quantize/dequantize nodes)。所以,如果空间上的考虑很重要,那么实际上我们可以将量化仅仅看作是一种压缩网络权重的方法。至少对于当前的状态而言,我们可以这样考虑。

另一方面,我们也有用于框架的加速执行时间(execution time)的方法,而不会影响到模型参数。这些方法基本上都是试图优化矩阵之间的乘法(GEMM)的通用计算技巧,并因此会同时影响卷积层(其计算通常是 im2col + GEMM)和全连接层。除此之外是 NNPACK:一个用于深度学习框架的加速包。这个加速包还曾得到过 Yann LeCun 的推荐!就我所知,NNPACK 使用了 FFT 来将时间域中的卷积运算替换成了频域中的乘法计算。

另一个方法是将网络定义和权重翻译成针对目标进行优化过的代码,而不是将它们运行在同样一个框架内。这种方法的典型案例是 TensorRT。还有 CaffePresso 可以将 Caffe prototxt 翻译成针对各种不同后端的更低级的规格。但是,TensorRT 的运行需要 CUDA,而且只能在 NVIDIA GPU 上使用,而 CaffePresso 也需要某种硬件加速器(DSP、FPGA 或 NoC),所以这两种都不适合用于我的测试硬件——树莓派。

相关链接:

Ristretto:http://lepsucd.com/?page_id=621NNPACK:http://github.com/Maratyszcza/NNPACKTensorRT:http://developer.nvidia.com/tensorrt CaffePresso:http://github.com/gplhegde/caffepresso

调测配置

当谨慎地评估现存的解决办法后,我发现下列方法能够加速当前流行的可用模型的推理:

如果你的构架使用了 OpenBLAS,你可以尝试其为深度学习进行过优化的分支:http://github.com/xianyi/OpenBLAS/tree/optimized_for_deeplearning NNPACK 能和其他一些框架(包括 Torch、Caffe 和 MXNet)联合使用:http://github.com/Maratyszcza/NNPACK当在树莓派上使用 TensorFlow 时,你可以使用 NEON 指令集提供一些 optimization flags:http://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/makefile#raspberry-pi

通过这些,我能列出以下调测配置:

带有 OpenBLAS 主分支(master branch)的 Caffe 作为后端(caffe-openblas)带有 OpenBLAS 的深度学习优化分支(caffe-openblas-dl)的 Caffe使用 OPTFLAGS="-Os" (tf-vanilla) 编译的 TensorFlow使用 OPTFLAGS="-Os -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize" (tf-neon-vfpv4) 编译的 TensorFlow带有用于线性代数计算的 OpenBLAS (mxnet-openblas) 的 Vanilla MXNet带有 OpenBLAS 的深度学习优化分支 (mxnet-openblas-dl) 的 MXNet

你可能会疑惑:配置中怎么没有 NNPACK?这确实有点复杂,由 ajtulloch 制作的 Caffe 分支提供了使用 NNPACK 的最直接的方法。然而自从它被集成进去以后,NNPACK API 就已经改变了,并且目前我们不能编译它)。Caffe2 对 NNPACK 有原生支持,但我不会考虑 Caffe2,因为它处于实验性阶段并且几乎对 Caffe 进行了重构,相关的文档也不多。另外一个选项就是使用 Maratyszcza/caffe-nnpack,虽然它比较老旧且没有什么维护。

另外一个问题就是 NNPACK 自身。它并不提供在 Linux/ARM 上的交叉编译(cross-compilation)配置,只有在 Android/ARM 上的交叉编译(cross-compilation)配置。我的实验性构建在与 MXNet 结合的目标平台上无法工作。我只能在台式电脑上运行它,但是我并没有看到使用 OpenBLAS 会有更优秀的表现。由于我的目标是评估已经可用的解决方法,所以我只能以后再做 NNPACK 的实验了。

相关链接:

ajtulloch 制作的 Caffe 分支:http://github.com/ajtulloch/caffe/tree/nnpack-pr NNPACK API 编译问题:https://github.com/Maratyszcza/NNPACK/issues/1#issuecomment-266416638Maratyszcza/caffe-nnpack:http://github.com/Maratyszcza/caffe-nnpackNNPACK Linux/ARM 问题:https://github.com/Maratyszcza/NNPACK/issues/35

硬件

所有的这些评估都是在四核 1.3 GHz CPU 和 1 GB RAM 的树莓派 3 上执行。操作系统是 32 位的 Raspbian,所以 CPU 不是 ARMv8 架构,而是 ARMv7 架构。

model name : ARMv7 Processor rev 4 (v7l)BogoMIPS : 38.40Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32CPU implementer : 0x41CPU architecture: 7CPU variant : 0x0CPU part : 0xd03CPU revision : 4

测试草案

为了评估上述每个配置的性能,我们会使用相同的神经网络。也就是一个有 3 个卷积层和两个全连接层且在顶部有 softmax 的微型卷积神经网络:

conv1: 16@7x7relu1pool1: MAX POOL 2x2conv2: 48@6x6relu2pool2: MAX POOL 3x3conv3: 96@5x5relu3fc1: 128 unitsfc2: 848 unitssoftmax

该卷积神经网络有 1039744 个参数。虽然非常小,但它足够处理许多计算机视觉任务。

该网络使用 Caffe 进行训练人脸识别任务,并将其转换为 TensorFlow 和 MXNet 格式从而使用这些框架进行评估。为了评估前向通过时间(forward pass time),从 1 到 256 的批大小都进行了测试,因为批大小对性能有很大的影响。而对于每个批大小,网络执行了 100 次前向通过,并为每一张图像计算了平均时间。

评估结果和讨论

在下面的表格中,列出了平均前向通过的时间。其中,A 是 caffe-openblas, B 是 caffe-openblas-dl, C 代表 tf-vanilla, D 是 tf-neon-vfpv4, E 是 mxnet-openblas, F 是 mxnet-openblas-dl。

在对数尺度(logarithmic scale)尺度上我们来看一下:

这些结果让我大吃一惊。首先,我没有预料到在 CPU 上运行 MXNet 有如此差的表现。但这看起来已经是一个众所周知的问题。此外,因为存储限制,它无法运行 256 张图片的 batch。第二个惊奇是优化过的 TensorFlow 竟有如此好的表现。它甚至比 Caffe 的表现还好(在超过 2 的批大小上);光是从原始框架上看是很难预料这个结果的。但小心:不保证你能在任意 ARM 设备上使用这些 flags。

众所周知,Caffe 的速度非常快。如果你要一张接一张地处理图片,使用优化过的 OpenBLAS 的 Caffe 将会是你最好的选择。想要有 10ms 的改进,你所要做的就只是简单的输入:

cd OpenBLASgit checkout optimized_for_deeplearning

为了将我的小研究转变成正式的东西,我仍需要做大量的工作:评估更多的模型,集成 NNPACK,以及研究更多的框架与 BLAS 后端的结合。但我希望它能帮助你了解目前最流行的解决方案的推理速度。

硬件不给力,如何穷玩深度神经网络?相关推荐

  1. 深度 | 硬件不给力,如何穷玩深度神经网络?

    深度学习的力量为其在真实世界的应用创造出了巨大的机会.但深度学习的训练往往需要巨大的计算能力,有时候我们却没法(或没钱)去使用强大的服务器或 NVIDIA 的 Jetson 那样的嵌入式加速平台.假如 ...

  2. 深度神经网络全面概述:从基本概念到实际模型和硬件基础

    本文转载自:深度神经网络全面概述:从基本概念到实际模型和硬件基础 本文旨在提供一个关于实现 DNN 的有效处理(efficient processing)的目标的最新进展的全面性教程和调查. 作者:机 ...

  3. 【深度学习 论文综述】深度神经网络全面概述:从基本概念到实际模型和硬件基础

    本文转载自:深度神经网络全面概述:从基本概念到实际模型和硬件基础 本文旨在提供一个关于实现 DNN 的有效处理(efficient processing)的目标的最新进展的全面性教程和调查. 作者:机 ...

  4. 焦李成教授谈深度神经网络发展历程

    来源:西电人工智能学院 摘要:焦李成教授谈深度神经网络发展历程 2018年11月18日下午,计算机科学与技术学部主任.人工智能学院焦李成教授在成都参加了由中国人工智能学会主办的人工智能大讲堂并做特邀报 ...

  5. 玩深度学习选哪块英伟达 GPU?有性价比排名还不够!

    本文來源地址:https://www.leiphone.com/news/201705/uo3MgYrFxgdyTRGR.html 与"传统" AI 算法相比,深度学习(DL)的计 ...

  6. 神经网络 深度神经网络,最新的深度神经网络

    深度学习的职业发展方向有哪些? 当前,人工智能发展借助深度学习技术突破得到了全面关注和助力推动,各国政府高度重视.资本热潮仍在加码,各界对其成为发展热点也达成了共识. 本文旨在分析深度学习技术现状,研 ...

  7. 2021-IEEE论文-深度神经网络在文档图像表格识别中的应用现状及性能分析

    2021年5月12日收到, 2021年6月4日接受, 出版日期2021年6月9日, 当前版本日期2021年6月24日. 原论文下载地址 摘要 - Abstract   表格识别的第一阶段是检测文档中的 ...

  8. 神经网络 深度神经网络,主流的神经网络的框架

    有哪些深度神经网络模型 目前经常使用的深度神经网络模型主要有卷积神经网络(CNN).递归神经网络(RNN).深信度网络(DBN).深度自动编码器(AutoEncoder)和生成对抗网络(GAN)等. ...

  9. 通过深度神经网络和树搜索掌握围棋游戏

    Article 作者:David Silver*, Aja Huang*, Chris J. Maddison etc. 文献题目:通过深度神经网络和树搜索掌握围棋游戏 文献时间:2016 发表期刊: ...

最新文章

  1. 64位Fedora运行32位C++程序所需的类库
  2. Chapter34 创建主窗口/实现应用程序功能
  3. 七牛技术总监陈超:记Spark Summit China 2015
  4. 妙啊,这条命令可以查出哪些端口被防火墙阻止了
  5. windows7如何查看端口被占用
  6. ASP.NET实现微信功能(2)(服务号高级群发)
  7. 数据结构和算法之单链表
  8. word2vec的通俗理解
  9. C#基础:理解装箱与拆箱
  10. c语言中x的n次方怎么表示_线性代数的本质及其在AI中的应用
  11. 【转】4.2SharePoint服务器端对象模型 之 使用CAML进行数据查询(Part 2)
  12. Contours 等高线图
  13. 数据库系统原理教程-作业
  14. 串口UART学习笔记(一)
  15. 传智播客java测试题_传智播客java测试题
  16. Linux的时间戳换算
  17. java info()方法_Java Provider getInfo()用法及代码示例
  18. 寄存器(RAL)模型中的write方法
  19. java 媒体框架_Java 媒体框架 之 JMF
  20. 申报高新技术企业需要注意的问题

热门文章

  1. 大数据处理实验(三)HDFS基本操作实验
  2. 【Mysql数据库全套教程笔记-SELECT使用篇】
  3. python数据库环境详解_python中MySQL数据库相关操作
  4. js学习笔记---(学习)
  5. 解决以太网适配器的驱动程序可能出现问题
  6. 华大芯片HC32F4A0实现RS485通讯DMA收发
  7. Ansible的基本搭建安装与配置及各参数选项的作用
  8. Consumer<T>和BiConsumer<T,U>
  9. 学生信息管理系统总体设计说明书
  10. XLM解读(论文 + PyTorch源码)