背景与工程定位
背景
项目组基于深度进修实现了视频风格化和人像抠图的功能,但这是在PC/办事端上跑的,如今须要移植到移动端,是以须要一个移动端的深度进修的计算框架。
同类型的库
全称为GL_SHADER_STORAGE_BUFFER,用于存储自定义类型的数据(重要就是卷积层和内积层的参数)。
caffe-Android-lib 今朝应当是最便于集成应用的深度进修框架库。
tensorflow和mxnet据说也有对应的android库,因时光原因暂未测试。
renderscript 作优化的深度进修框架,不过就代码实现和实际测试结不雅来看,机能一般。
工程定位
实现可及时、体积小、通用的深度进修猜测框架。
可及时
跟PC或办事器不合,移动设毕喔赡GPU可不必定有CPU强悍若干好多线程+neon/vfp),但在须要及时F算的场景(主如果相机预览和视频播放),往往都是基于OpenGL衬着情况的。
及时的情况下,深度进修框架的输入和输出都在GPU端,应用CPU进行计算往往须要拷贝图像出来,算好后再传到GPU端,是以基于GPU实现的深度进修的库能持平CPU版本的效力就有足够优势了。
对每一帧相机预览产生的数据,体系将其映射为opengl 的一个external texture,然后须要 计算出一个 mask texture,与本来的texture作混淆,显示出来。如不雅mask texture 的计算在cpu长进行,则须要每帧先把 graphicbuffer 的数据拷贝出来,计算出mask后上传到 mask texture 去,产生一来一回两次额外拷贝。
通用
本工程须要支撑 caffe 产出的模型文件,支撑常见的收集如lenet、ResNet等等。这个工作量包含编写响应层的算子,设计收集构造,解析caffe模型的参数等。
所幸的是,今朝在移动端做好深度进修的猜测就足够了,比拟于兼顾练习的构造至少省去2/3的工作量。
工程实现
筹划选型
GPU加快的API

应用GPU加快有如下一些筹划:
CUDA、OpenCL、OpenGL(ES)、RenderScript、Metal
对于OpenCL,固然有不少移动GPU已经支撑,比如 Arm 的 mali 系列(T628之后),且有响应的支撑库。然则,一方面因为Android在体系层面膳绫腔有支撑,没有响应的体系API,兼容性照样比较差,另一方面,OpenCL 操作完成后的内存传到OpenGL照样须要同步一下,会影响效力。
最后就只剩下 OpenGL ES,为了开辟便利,用 Computer shader 实现,尽管会有必定的兼容性就义(Android 5.1 及以上,GPU支撑openGLES 3.1),但推敲到下面两点是值得的:
1、走衬着管线去实现通用计算,编程复杂且轻易掉足,调优也很麻烦。有 computer shader之后,编程就跟opencl、metal类似,这些工作量可以大年夜幅降低,大年夜大年夜加快开辟。
2、支撑OpenGLES 3.1版本的GPU一般都是相对较新的,机能不会太差,可以或许实现加快的目标。
运算的分派
CNNdroid中仅用GPU加快卷积层的运算,其他照样由CPU+多线程履行。以前我们在早期作gpu加快的预研时,也有过类似的测验测验,然则数据传输和同步的机能消费弘远年夜于协同计算带来的机能晋升。是以这个工程中,收集中的计算全部由GPU完成,避免数据在CPU和GPU之间反复传输或同步。
RenderScript 这个坑比较多,文档极少,并且会有跟OpenCL一样的须要跟OpenGL同步的问题,不做推敲。
别的,GPU驱动在申请内存(分派纹理所须要内存空间)的时光消费在移动设备端是弗成忽视的,是以,不克不及在运算过程中临时创建纹理或其他Buffer,必须事先分派好。
优化留意点
1、向量化运算
CUDA只实用到NVIDIA的GPU,Metal只实用于apple系列,这两个对android设备而言根本不消推敲。
猜测时,我们输入神经收集的数据可表示为
对于卷积层和内积层,我们把参数存储为mat4的数组,然后其计算就美满是vec4级的向量化运算。
2、合适的localsize设计
与OpenCL不一样,computer shader 必须手动指定 workgroup 的大年夜小,并且指定运行的 workgroup 数量。这两组维度,都是越大年夜越好。
local size 一般而言越大年夜越好,但 computer shader 所须要的存放器越多,local size 的最大年夜值就越小,推敲到最耗时的卷积shader所能应用的local size 一般也就 64,保守起见都定为64(8乘8)。
不克不及对齐的情况在shader中处理,比如下面的代码:
void main(){ ivec3 pos = ivec3(gl_GlobalInvocationID); if (pos.x < MAX_WIDTH && pos.y < MAX_HEIGHT) { /*Do something*/ }}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
3、适本地归并/去除layer
如正则层可以直接和上一层归并(末尾加个max处理就行),dropout层可以直接丢弃。
CNNdroid,网址https://zhuanlan.zhihu.com/p/25259452,这个是用
归并可以晋升机能(不过不会太多),但最重要的是削减亮闼殇内存。
框架设计
分为两个子模块,引擎模块在客户端上运行,对象模块用来转换caffe的模型文件。
推荐阅读
比来几年,在DDD的范畴,我们经常会看到CQRS架构的概念。我小我也写了一个ENode框架,专门用来实现这个架构。CQRS架构本身的思惟其实异常简单,就是读写分别。是一个很好懂得的思惟。就像>>>详细阅读
地址:http://www.17bianji.com/lsqh/36068.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示