CNNdroid:在 Android 上利用 GPU 加速执行 CNN (卷积神经网络)

摘要

智能设备和可穿戴设备都将受益于深度学习算法(比如CNN)的准确性和可扩展性。然而,性能和能耗等现实的问题使得在移动端设备上这类密集计算的算法变得非常受限。我们开发了CNNdroid这个GPU加速库,可以在Android设备上实现CNN网络的训练。通过实验,CNNdroid在移动设备上实现了60倍速的提升,以及130倍速的节能。CNNdroid这个库已经开源在Github上,可以从Github项目页面下载。

关键词

Deep Learning, Deep Convolutional Neural Network (CNN), Mobile GPU, Performance Optimization, Low Energy Con- sumption, Open Source Software, Android, RenderScript

1.介绍

智能手机、可穿戴设备、微型机器人、物联网等越来越多的移动平台都在深度学习的领域找到了相应的应用方向(如图1)。例如在移动设备上,语音识别和图像识别等许多App都受益于机器学习的本地算法。如果允许将模型等数据直接放在客户端,就可以避免和服务器的上下行数据交互而导致的网络延迟等体验的问题。CNN卷积网络在预测的精确性和可扩展性上都取得了很先进的成果,然而像此类密集计算型的网络结构必须依赖硬件级加速才可能在移动设备上得到广泛的应用。

图1:CNN在移动设备上的应用

许多基于深度学习的硬件加速平台都有相应的解决方案了,IBM也正在开发一种用于神经网络的CMOS的芯片,用于在移动设备和物联网设备上。与此同时,类似的解决方案依然处于早期的研发阶段,也并没有商用到现有的移动设备上。

和基于硬件的加速平台不同的是,GPU已经大规模的商用到现在的移动设备上了,同时在软件层面的编码支持也做的非常完善了。利用GPU现成的并行计算能力去实现CNN神经网络在移动端设备上的计算加速是完全可行的。

现存的GPU加速方案的深度学习CNN的开源库有很多种,都是基于服务器和桌面平台的[见附录的6, 7, 8, 9, 10, 11, 12].然而,由于平台架构的差异,简单的把这些开源库移植到移动端上,在某些Case下效果是欠佳的(见2.2节)。目前在移动端上,据我们所知,并没有相应的带有GPU加速的深度学习计算框架的开源库,这些库 [见附录的13, 14, 15, 16]仅仅能够利用移动设备的CPU多核计算能力,而这样局限性很大。

如今,我们提供一个支持GPU加速的开源库,称为“CNNdroid”,可以在Android平台用来通过训练数据集的方式设计和优化CNN的网络。以下是CNNdroid的几个主要亮点。

1. 支持几乎所有的CNN的Layer Type(Section 3.1)

2. 兼容Caffe[6]、Torch[7]、Theano[8]这些开源框架在PC平台、服务器平台上已经训练好的模型(Section 3.2)

3. 现有的Android App可以快速的加入这个库,无需额外的软件依赖(Section 3.3)

4. 开发者可以指定最大的内存消耗(Section 3.4)

5. CNN Layer的GPU和CPU加速均支持(Section 3.5)

6. 自动的硬件条件检测(Section 3.6)

7. 在移动设备上超过60倍的性能提升以及减少130倍的能耗(Section 4)

背景知识以及相关介绍

2.1移动设备的GPU和桌面平台的GPU的区别

现代图形处理单元(GPU)不仅仅能做图形计算,也能够被用来做可编程的通用计算。台式机的GPU长期以来都是可编程的,近期移动设备上的GPU也开放了通用计算的硬件级支持。但受限于GPU的尺寸和功耗,移动GPU和桌面GPU设备还是有很大的差异。

现代移动GPU的Shader Cores(SC)通常成为若干可编程并行计算单元。每个Shader Core都是由若干个ALU并行组成。比如,三星的Exynos 5433芯片是由ARM A53/A57 CPU和Mali T-760 GPU组成(见图2)。T-760 GPU中的每一个SC都具有两个VLIW格式的128位ALU。每个128位ALU能够执行SIMD操作,即并行的两个64位,四个32位或八个16位操作[17]。与桌面平台GPU相比,移动设备的并行ALU架构在并行线程的有效执行中更多地依赖于软件和编译器,而不是动态硬件调度器。

图2: Exynos 5433 mobile processor with ARM A53 / A57 CPU and Mali T-760 GPU
(SC: Shader Core, VLIW: Very Long Instruction Word, SIMD: Single Instruction Multiple Data

更重要的是,在桌面GPU中广泛应用的线程块快速内存共享机制在移动GPU中并不可用,同时许多基于CUDA的桌面平台的Library在移动GPU上也不可以用。

更不幸的是,在软件层面这两端的差异也是巨大的。比如Android提供的RenderScript[18]是一个用于并行计算的库,但是并发线程的机制并不可用。另外,并行线程和并行线程使用的内存中的数据部分必须是一对一的关系。

2.2 CNNdroid 和桌面平台相关库的比较

在服务器和桌面端,已经有很多现成的基于GPU加速的并行计算框架可用于CNN网络,诸如Caffe[6],Torch [7], Theano [8],Tensor- Flow [9], cuDNN [10], cuda-convnet [11],,and Velesnet [12],然而由于两端的硬件和软件的差异,这种加速和并行计算的方法并不能直接的被移植到移动设备上。比如说,Caffe[6]中的卷积操作被展开并转换为矩阵乘法,这些操作对内存的要求比较高,这在移动设备上是不现实的。再举一个例子,Theano [8]中的并行算法虽然与CNNdroid类似,但是在移动GPU中没有使用SIMD单元(详见Section 3.5)。

更不幸的是,桌面的计算库利用桌面GPU和CUDA框架提供的线程管理功能,如快速共享内存和线程同步,这些在移动GPU和Android提供的RenderScript中均不可用。

2.3 CNNdroid和移动平台相关库的比较

在移动设备上,就目前所知的支持CNN深度学习的框架只有[13,14,15,16]。包括了Caffe Mobile[13]和Torch Mobile[14],均受限于多核的CPU计算能力,而只有CNNdroid支持CPU和GPU(详见Section 3.5)。

另外,CNNdroid还兼容Caffe[6]、Torch[7]、和Theano[8]训练出来的CNN模型,方便快速将模型部署到移动设备上(详见Section 3.2)。

开发环境上,不需要安装Android NDK,只需要安装Android SDK即可。

3.CNNdroid库

3.1 CNNLayer Types

CNNDroid库支持几乎大部分的CNN Layers,比如说卷积层,max/mean池化层,全链接层,ReLu(Rectified Linear Units)激活函数,LRN(Local Response Normalization)层,Softmax等。相关的描述和每一层的参数设置在开源库中的文档里有说明[1]。由于库的开源特性,其它的层也可以随时加入。

3.2 模型的准备

模型转换脚本:图3展示了如何将训练好的模型部署到移动端
CNNdroid库提供了一系列的脚本,可以把不同框架训练的库转成CNNdroid格式的模型,目前已经支持Caffe[6],Torch[7],Theano[8],因此可以使用以上框架训练模型然后转为CNNdroid库支持的格式,最终运行在Android移动设备上。当然你也可以模仿这些脚本写出其它平台的转换脚本,CNNdroid使用MessagePack序列化和存储模型中不同层的参数。具体的细节可以参考开源库的说明文档[1]。

图3:CNNdroid的模型部署流程

NetFile:开发者需要准备一个名为NetFile.txt的文本文件,类似于Caffe的.prototxt配置文件,NetFile.txt文件用于配置已经训练好的模型的层次,比如说,CNN Layer的各层的顺序,卷积层中的Padding和Stride的值。图4是一个该文件的样例,更详细的细节可以参考说明文档[1]。

NetFile中也可以配置如下参数,allocated_ram:用于指定本框架可以分配的最大内存上线(见Section 3.4),execution_mode:用于指定是采用并行模式还是串行模式(见Section 3.5),auto_tuning:用于指定auto-tuning是否默认开启(见Section 3.6)。

图4:NetFile示例,如何配置AlexNet[20]的三层网络结构, 以及allocated_ram, execution_mode,auto_tuning参数的配置

3.3模型的执行

一旦将训练好的模型和相应的NetFile文件上传到了移动设备后(图3),这个模型可以被所在的Android App轻易的调用(图5),具体的有如下几个步骤:

第一步,在自己的App中依赖CNNdroid库,CNNdroid库只依赖Android SDK,而不需要安装Android NDK的,也就是说,不依赖其他的第三方库。

第二步,构造RenderScript和CNNdroid对象(图5所示的Steps 2和3)。CNNdroid的构造函数需要提供NetFile文件作为输入,并会自动的创建相应的网络层次。

最后,compute函数负责利用训练好的模型,计算传入的单个图像或者批量图像并返回结果。

图5: 使用CNNdroid库的几个关键调用步骤,
详细的使用方法可以参见开源库中的说明文档 [1].

3.4 内存分配

我们将已经训练好的CNN模型,上传到手机的SD卡上,这些模型中包含了矩阵式的各层参数。在执行每一层前,在compute函数里(图5,step5),相应层的矩阵参数被自动的从SD卡上加载内存里,这会导致大量的内存开销。

为了减少这种内存开销,CNNdroid采用的方法是:保持一部分的层长期驻留在内存中,而其他的层每次都会被创建和销毁。该选择过程开发者无需关心,在CNNdroid构造函数中自动完成(图5,step3)。选择器从最大的层开始,让尽量多的层进入选择器,直到达到NetFile中allocated_ram参数指定的内存上限。

注意:allocated_ram参数不宜设置的过大,比如说,Android 5.0在系统层就会限制每个App的内存上限为512MB。

3.5 加速的方法

在CNNdroid中,不同的层有不同的加速方法。比如数据并行的卷积层和需要大量密集计算的全连接层,就需要用到RenderScript的框架来实现移动端的GPU加速。

这两层的大部分计算可以表示为点积。具体地来说,在卷积层中kernels与input frames进行卷积;而在全连接层中,计算可以表示为矩阵和向量的乘法。在移动设备上使用GPU的SIMD单元可以高效的进行点积的计算。因此,我们分离了大量的向量,并且使用基于RenderScript框架的预定义点积函数来完成运算。也就是说,我们在软件层面体现了这种计算的并行性,而不像是基于CUDA的桌面计算框架库那样把这类问题交给GPU的硬件调度程序。

相对于卷积层和全连接层,其它层的密集型计算相对较少。因此,它们通过多线程并发在多核CPU上进行加速。比较特殊的是,由于ReLU层通常出现在卷积层或全连接层之后,所以把它嵌入到之前的层中,可以在将多个图像传输时提高CNNdroid的性能。

除了上述并行计算的实现之外,CNNdroid还包括所有层的单线程顺序执行的实现。可以通过配置NetFile中的execution_mode参数,指定执行将是顺序模式还是并行模式(图4)。

3.6 自动调整

为了能够在移动设备上达到最好的性能,CNNdroid框架的GPU并行加速算法支持在每个GPU线程上执行自动配额,比如说调配该GPU线程的工作量以及SIMD ALUs的工作量。配额的参数调整决定了并行的粒度。

如果在NetFile(图4)中打开了auto-tuning,那么auto-tuner就会在Android App首次启动时执行。auto-tuner会记录该移动设备上多个预定义的情景下CNN模型的运行时长,用于调整最佳的配额参数。因此,首次启动App需要花费较长的时间。为了公平性以及更清晰的表述我们的实验,在第4节中,我们将关掉auto-tuning。

4.实验评估

我们在三星的Galaxy Note 4和HTC One M9进行了实验。采用的模型是几个标准的CNN网络:LeNet network for MNIST dataset [21],Alex Krizhevsky’s network for CIFAR-10 (Alex’s CIFAR-10) [22], Alex Krizhevsky’s network for ImageNet 2012 dataset (AlexNet) [20].

基准CNN的层设置如图6所示。当移植到CNNdroid格式时,我们还统计了文件大小和内存占用。具体的结果如图7所示。

我们的实验环境是将手机充满电,同时进入飞行模式并且将屏幕亮度调为最低。以下的实验中,并没有每次都从SD卡加载配置和模型,因为在第一次运行时候就加载到内存中了。每次我们都会将16张图片作为输入传给CNNdroid App,接下来测量输出的准确性以及运行耗时和耗电量。

图6: 三种标准的CNN网络的层次

图7: 在CNNdroid格式下使用三种标准CNN网络的文件大小以及内存消耗

4.1准确度

为了测量CNNdroid的准确度,我们同时使用了CNNdroid和Caffe作对比实验。结果显示两者的结果方差是10的-12次方,也就意味着CNNdroid的准确度和Caffe几乎一样。

4.2性能

图8显示了仅使用CPU的线性运行CNN的运行耗时以及使用GPU加速的运行耗时和加快的倍速。报告显示的值是十次运行结果的平均值。

图8:(a)是CNN运行的平均耗时和加速的速率,(b)是整个CNN中最耗时的卷积层的耗时和加速速率

4.3能耗

我们使用“Qualcomm Trepn Profiler”应用程序[25]测量HTC One M9手机基于AlexNet网络结构的每一幅图像的功耗和能耗。
GPU加速执行时,消耗约523 mW功率和0.4 J能量,而仅仅使用CPU执行时消耗2338 mW功率和51.6 J能量。 因此,GPU加速执行消耗的电池消耗减少51.6÷0.4 = 129X。值得注意的是,我们的测量中有大约20%的波动。

5.结论

我们介绍了CNNdroid:一个在Android平台上基于GPU加速CNN网络的开源库。经过实验评估证明该库可以提升60倍速,以及130倍的能耗节省。相关的代码以及说明文档都已经开源并发布在Github上[1]。

6. 相关引用

[1] CNNdroid open source GPU-accelerated library.

https://github.com/ENCP/CNNdroid

[2] Inchul Song, Hyun-Jun Kim, and Paul Barom Jeon. Deep learning for real-time robust facial expression recognition on a smartphone. In IEEE International Conference on Consumer Electronics, pages 564–567, Jan 2014.

[3] Yu-Hsin Chen, Tushar Krishna, Joel Emer, and Vivienne Sze. 14.5 eyeriss: an energy-e cient reconfigurable accelerator for deep convolutional neural networks. In IEEE International Solid-State Circuits Conference, pages 262–263, Jan 2016.

[4] Mohammad Motamedi, Philipp Gysel, Venkatesh Akella, and Soheil Ghiasi. Design space exploration of fpga-based deep convolutional neural networks. In Asia and South Pacific Design Automation Conference, pages 575–580, Jan 2016.

[5] Paul A Merolla, John V Arthur, Rodrigo Alvarez-Icaza, Andrew S Cassidy, Jun Sawada, Filipp Akopyan, Bryan L Jackson, Nabil Imam, Chen Guo, Yutaka Nakamura, Bernard Brezzo, Ivan Vo, Steven K Esser, Rathinakumar Appuswamy, Brian Taba, Arnon Amir, Myron D Flickner, William P Risk, Rajit Manohar, and Dharmendra S Modha. A million spiking-neuron integrated circuit with a scalable communication network and interface. Science, 345(6197):668–673, 2014.

[6] Yangqing Jia, Evan Shelhamer, Jeff Donahue, Sergey Karayev, Jonathan Long, Ross Girshick, Sergio Guadarrama, and Trevor Darrell. Caffe: Convolutional architecture for fast feature embedding. arXiv preprint arXiv:1408.5093, 2014.

[7] Torch. http://torch.ch/ . Accessed 2016-08-01.

[8] James Bergstra, Olivier Breuleux, Fr ́ed ́eric Bastien,
Pascal Lamblin, Razvan Pascanu, Guillaume Desjardins, Joseph Turian, David Warde-Farley, and Yoshua Bengio. Theano: a CPU and GPU math expression compiler. In Proceedings of the Python for Scientific Computing Conference, 2010.

[9] TensorFlow. https://www.tensorflow.org . Accessed 2016-08-01.

[10] Nvidia cuDNN. https://developer.nvidia.com/cudnn  . Accessed 2016-08-01.

[11] cuda-convent. https://code.google.com/p/cuda-convnet/  . Accessed 2016-08-01.

[12] Velesnet. https://velesnet.ml/  . Accessed 2016-08-01.

[13] Caffe Android Library.
https://github.com/sh1r0/caffe-android-lib  . Accessed 2016-08-01.

[14] Torch-7 for Android.
https://github.com/soumith/torch-android  . Accessed 2016-08-01.

[15] A convolutional neural network for the Android
phone. https://github.com/radiodee1/  
awesome-cnn-android-python. Accessed 2016-08-01.

[16] Facial attractiveness prediction on Android. https://github.com/eldog/fmobile  . Accessed 2016-08-01.

[17] ARM. Mali-T600 Series GPU OpenCL, Version 1.1.0,
Developer Guide. Accessed 2016-08-01.

[18] Android RenderScript Developers Guide.
http://developer.android.com/guide/topics/  
renderscript/compute.html. Accessed 2016-08-01.

[19] Messagepack. http://msgpack.org/index.html.

[20] Alex Krizhevsky, Ilya Sutskever, and Geoffrey E.Hinton. Imagenet classification with deep convolutional neural networks. In Advances in Neural Information Processing Systems, 2012.

[21] Y. Lecun, L. Bottou, Y. Bengio, and P. Haffner. Gradient-based learning applied to document recognition. Proceedings of the IEEE, 86(11):2278–2324, Nov 1998.

[22] Alex Krizhevsky. Learning multiple layers of features from tiny images. Technical report, University of Toronto, 2009.

[23] Trepn power profiler. https://developer.qualcomm.com/software/trepn-power-profiler  .

本文编译自:CNNdroid: GPU-Accelerated Execution of Trained Deep Convolutional Neural Networks on Android

本文作者:恒亮

本文转自雷锋网禁止二次转载,原文链接

时间: 2024-09-28 14:58:15

CNNdroid:在 Android 上利用 GPU 加速执行 CNN (卷积神经网络)的相关文章

利用 GPU 加速人工智能:新型计算模式

纽约大学本周有一场探讨 "人工智能的未来" 的年度座谈会,Yann LeCun 邀请NVIDIA 联合创始人兼首席执行官黄仁勋 (Jen-Hsun Huang)先生在座谈会上发言.这场完美的盛会聚集了人工智能领域中的诸多翘楚以探讨人工智能的发展现状以及不断取得的进展.以下为黄仁勋先生的发言主题,即为什么说深度学习是一种需要新型计算模式的全新软件模式:为什么人工智能研究人员采用 GPU 加速的计算模式:随着这种模式迅速流行,NVIDIA 为推动人工智能的进步正在开展哪些工作.以及为什么人

一篇文章为你详解什么是 GPU 加速

众所周知,网页不仅应该被快速加载,同时还应该流畅运行,比如快速响应的交互,如丝般顺滑的动画-- 一. GPU 加速能做什么? 首先我们要了解什么是 16ms 优化 大多数设备的刷新频率是 60 次/秒,(1000/60 = 16.6ms)也就说是浏览器对每一帧画面的渲染工作要在 16ms 内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验. 浏览器在一帧里面,会依次执行以下这些动作.减少或者避免 layout,paint 可以让页面不卡顿,动画效果更加流畅. 1. JavaScrip

ndk jni c++ android-Android上利用JNI调用OpenCV函数时出现Fatal signal 11错误

问题描述 Android上利用JNI调用OpenCV函数时出现Fatal signal 11错误 我想在Android上用OpenCV实现人脸识别功能,即事先有一个我提供的人脸训练库,然后检测出人脸后,识别他和训练库中的哪类人最像. 我已在windows平台实现了该功能,并将训练好的FaceRecognizer通过save的方式存储成了xml.我将xml文件放入了Android手机某目录下,然后想利用JNI的方式在Android app中使用OpenCV载入该数据库,但运行到这一行就会报错: F

在Mac OS X上使用HAXM加速Android Emulator

现在换了Mac Air作为工作笔记本,偶尔还是会在Mac上使用Android Emulator跑跑Android App之类的:为了解决Emulator启动和运行很慢的问题,当然使用以前同事对Mac上android emulator进行加速的软件HAXM(Hardware Accelerated Execution Manager).HAXM利用硬件上的Intel VT技术,加速emulator的运行,类似于KVM加速QEMU. 本文中的Mac系统是10.8.4:HAXM版本是1.0.6. 注意

绘图-android 如何利用双缓存将缓存区域的某张图复制其中的某一部分到画布上。

问题描述 android 如何利用双缓存将缓存区域的某张图复制其中的某一部分到画布上. 跪求各位大侠,请各位大侠指导下,android中有没这样的方法可以做到.

如何利用程序自动执行ftp上传下载操作?

问题描述 如何利用程序自动执行ftp上传下载操作? 最近工作中反复要用ftp工具,对某些固定的文件做下载,修改,再上传的操作,觉得很麻烦.想 编一个程序,可以自动执行ftp链接,对于某个设置好的路径和文件进行上传下载,想请教大家实现的方法,比如可以调用哪些API之类的?非常感谢 解决方案 可以使用perl,python等语言完成. python可以使用ftplib. import ftplib session = ftplib.FTP('xxx.xxx.xxx.xxx','username','

NVIDIA:CUDA通过GPU加速提升高性能计算

CUDA(Compute Unified Device Architecture),显卡厂商NVidia推出的运算平台.随着显卡的发展,GPU越来越强大,而且GPU为显示图像做了优化.在计算上已经超越了通用的CPU.如此强大的芯片如果只是作为显卡就太浪费了,因此NVidia推出CUDA,让显卡可以用于图像计算以外的目的. 目前只有G80平台的NVidia显卡才能使用CUDA,工具集的核心是一个C语言编译器.G80中拥有128个单独的ALU,因此非常适合并行计算,而且数值计算的速度远远优于CPU.

《面向机器智能的TensorFlow实践》一2.5 源码构建及安装实例:在64位Ubuntu Linux上安装GPU版TensorFlow

2.5 源码构建及安装实例:在64位Ubuntu Linux上安装GPU版TensorFlow 如果希望使用带有GPU支持的TensorFlow,那么最可能的选择是从源码构建和安装.本节给出了一个完整的安装参考实例,详细介绍了安装和运行TensorFlow所需的每一具体步骤.请注意,本示例中的操作系统为64位Ubuntu Linux发行版,因此如果你使用的是其他Linux发行版,则可能需要对某些命令进行修改(如apt-get).如果希望在Mac OS X上从源码构建TensorFlow,笔者推荐

编译可在Android上运行的依赖库(一):glib库

编译可在Android上运行的依赖库(一):glib库 作者:寻禹@阿里聚安全 前言 这是系列文章,它们由<编译可在Android上运行的glib库>及其他4篇文章组成,这4篇文章在"编译依赖库"一节中列出.由于glib库依赖于其他第三方库,所以需要先将依赖的第三方库交叉编译到Android平台上才能成功的编译glib库,系列文章中除<编译可在Android上运行的glib库>外的其他交叉编译文章均是介绍如何对glib依赖库进行交叉编译.以上,所以叫系列文章,因