跨平台卷积神经网络控制系统及方法、信息数据处理终端
技术领域
本发明属于计算机软件技术领域,尤其涉及一种跨平台卷积神经网络控制系统及方法、信息数据处理终端。
背景技术
目前,业内常用的现有技术是这样的:随着人工智能和深度学习技术的发展,移动端成为深度学习成为一个重要的使用场景。目前的移动端的深度学习方案,在IOS上有苹果推出的CoreML,以及能够同时在IOS和Android上利用的cpu进行计算的谷歌推出的tesorflow和facebook推出的caffe2。目前能够做到跨平台的移动端的深度学习框架都只利用了cpu进行计算,由于在移动端开发环境及语言的限制没有利用上使用gpu。pc及服务器上利用gpu使用cuda,在移动端不支持。opencl是一种移动端上支持gpu的逻辑计算语言,但是ios不支持,android部分手机支持。所以移动端的核心问题是缺乏开发环境和开发语言的支持。opengles并不是一种像c语言的通用逻辑语言,只是一种用于进行图像渲染的标准,所以来进行数学逻辑计算是非常不方便的,没有人想到,想到的觉得无法实现。能够利用gpu的只能在IOS上基于metal开发或者直接使用苹果的CoreML。
综上所述,现有技术存在的问题是:
(1)android上没有有效的能够利用gpu进行计算的方案
(2)ios上利用gpu的方案不能在android上使用,无法实现跨屏,增加了开发的难度和工作量。
解决上述技术问题的难度和意义:移动端上利用gpu进行数学计算的编程语言一般使用opengcl,但是opengcl在ios上并不支持,在android上部分手机支持。唯一广泛被使用的gpu语言为opengles,ios最高支持到3.0,android支持到3.1,但是opengles作为一种图形处理与渲染标准,并不适合于通用的逻辑与数学计算,本发明提出了一种利用opengles的渲染过程来实现卷积计算的方案,从而实现一个利用gpu计算卷积神经网络的方法。
发明内容
针对现有技术存在的问题,本发明提供了一种跨平台卷积神经网络控制系统及方法、信息数据处理终端。
本发明是这样实现的,一种跨平台卷积神经网络控制系统,所述跨平台卷积神经网络控制系统包括:
卷积运算单元和池化运算单元,卷积运算单元与池化运算单元连接,通过 OpenGLES的fbo渲染来实现gpu计算。
全连接运算单元,与卷积运算单元或者池化运算单元连接,使用cpu的neon 指令实现;卷积运算前需要给各个通道添加padding,将padding操作和卷积运算或者池化运算结合。
本发明的另一目的在于提供一种所述跨平台卷积神经网络控制系统的跨平台卷积神经网络控制方法,所述跨平台卷积神经网络控制方法包括以下步骤:
步骤一,计算绑定fbo的输出的纹理尺寸,也即是fbo渲染过程的视窗大小,定义卷积计算中有k个卷积核,输出纹理有k个通道;输出通道平铺在输出纹理中;
步骤二,计算顶点坐标:渲染按照GL_TRIANGLES方式,每个通道包括2 个三角形;
步骤三,计算shader变量:定义attribute类型变量textureCoordinate,textureCoordinate.xy为当前输出的像素坐标对应于输入纹理在通道内的卷积计算起始坐标,textureCoordinat.z为当前像素所在的输出通道;
步骤四,在fragment shader的卷积计算,经过fbo渲染过程,绑定fbo的纹理中内容即为卷积层或者池化层的计算结果。
步骤五,循环步骤一到步骤四,完成所有卷积层的计算;
步骤六,循环计算全连接层。
进一步,所述步骤一中纹理尺寸:x方向和y方向通道数计算公式分别为:
float power=log2(k/4);
intc_x_count=pow(2,ceil(power/2));
intc_y_count=pow(2,floor(power/2));
定义输入纹理的每个通道的宽为c_width,高为c_height,padding尺寸为 c_padding,输出纹理每个通道的padding为next_padding,当前卷积计算的下一层为池化运算,则next_padding为0,输出纹理的大小为:
intout_width=(c_width+2*next_padding)*c_x_count;
intout_height=(c_height+2*next_padding)*c_y_count。
进一步,所述步骤二中计算顶点坐标对于第(xi,yi)个通道,4个顶点坐标为:
pi0_x=-1.0+((c_width+2*next_padding)*xi+next_padding)*1.0/out_width;
pi0_y=-1.0+((c_height+2*next_padding)*yi)*1.0/out_height;
pi1_x=-1.0+((c_width+2*next_padding)*xi+next_padding+ c_width)*1.0/out_width;
pi1_y=-1.0+((c_height+2*next_padding)*yi+next_padding)*1.0/out_height;
pi2_x=-1.0+((c_width+2*next_padding)*xi+next_padding)*1.0/out_width;
pi2_y=-1.0+((c_height+2*next_padding)*yi+ next_padding+c_height)*1.0/out_height;
pi3_x=-1.0+((c_width+2*next_padding)*xi+next_padding+ c_width)*1.0/out_width;
pi3_y=-1.0+((c_height+2*next_padding)*yi+ next_padding+c_height)*1.0/out_height;
顶点顺序为0 1 2 1 2 3。
进一步,所述步骤三中textureCoordinate的值为:
ci0_x=0.0;
ci0_y=0/0;
ci0_z=(yi*c_x_count+xi)*4;
ci1_x=c_width*1.0/out_width;
ci1_y=0.0;
ci1_z=(yi*c_x_count+xi)*4;
ci2_x=0.0;
ci2_y=c_height*1.0/out_height;
ci2_z=(yi*c_x_count+xi)*4;
ci3_x=c_width*1.0/out_width;
ci3_y=c_height*1.0/out_height;
ci3_z=(yi*c_x_count+xi)*4。
进一步,所述步骤四具体包括:
(1)循环遍历输入纹理的通道,在(wi,hi)通道中,用于卷积计算的起始点坐标:
highp float x=float(wi*channel_size[0])*texture_step[0]+textureCoordinate.x;
highp float y=float(hi*channel_size[1])*texture_step[1]+textureCoordinate.y;
计算右侧kernel_size-1个点以及下侧kernel_size-1个点共 kernel_size*kernel_size个点的坐标,在inputImageTexture[0]中进行采样,得到其颜色值。定义其颜色值分别为color_00-color_kk;
(2)计算color_00-color_kk对应的卷积核,卷积核的起始坐标为:
intci=hi*channel_count[0]+wi;
float w_x=kernelCoordinate.x+float(ci*kernel_size)*kernel_step[0]+kernel_step[0]/2.0;
float x_y=kernelCoordinate.z*kernel_size*kernel_step[1];
同样对右侧kernel_size-1个点以及下侧kernel_size-1个点共 kernel_size*kernel_size个点计算坐标,在inputImageTexture[1]进行采样,得到其颜色值conv0_00-conv0_kk;
(3)∑dot(color_ii,conv_ii)即为当前位置的卷积计算结果。由于每个像素有rgba4个通道,获取kernelCoordinate.z+1、kernelCoordinate.z+2、 kernelCoordinate.z+3的卷积核,分别定义为conv1、conv2、conv3,则当前像素的输出:
out_color=vec4(∑dot(colorii,conv0_ii),∑dot(color_ii,conv1_ii),∑dot(color_ii,conv2_ii),∑dot(color_ii,conv3_ii))。
进一步,所述步骤四具体包括池化运算模块在fragment shader中的实现:
(1)从当前点开始遍历输入纹理中右侧及下侧共pool_size*pool_size个点,进行纹理采样,得到像素颜色color_00-color_pp;
(2)分别计算color_00-color_pp在r、g、b、a4个通道上的最大值,记为 max_r、max_g、max_b、max_a;
(3)当前像素的输出为out_color=vec4(max_r、max_g、max_b、max_a);
所述步骤六具体包括全连接运算模块的实现:
1)通过PBO将最后一个卷积层或者池化层的输出从gpu内存拷贝到cpu 内存中;
2)借住neon指令对全连接层进行计算,为当前全连接层的输出;
3)有多层全连接层,后面的全连接层的输入为上一层全连接层的输出;
4)最后一层全连接层的输出即为整个神经网络的输出。
本发明的另一目的在于提供一种实现所述跨平台卷积神经网络控制方法的计算机程序。
本发明的另一目的在于提供一种实现所述跨平台卷积神经网络控制方法的信息数据处理终端。
本发明的另一目的在于提供一种计算机可读存储介质,包括指令,当其在计算机上运行时,使得计算机执行所述的跨平台卷积神经网络控制方法。
综上所述,本发明的优点及积极效果为:为了充分利用移动端cpu和gpu 的计算力,和解决不同终端设计框架不同的问题,本发明同时利用cpu和gpu 来加快神经网络的计算,同时实现一个跨平台的方案,来减少应用开发人员在框架使用上的成本。OpenGL及移动端上的标准OpenGL ES作为一个用于图像渲染的国际标准,被各个终端厂商支持。本发明利用OpenGL ES来实现卷积计算的方法,达到了利用gpu的优秀浮点计算性能来加快卷积神经网络的计算,同时实现不同系统的跨平台。提高了计算效率,mnist手写体识别的例子,在iphone5s上计算一帧的时间为13毫秒。
附图说明
图1是本发明实施例提供的跨平台卷积神经网络控制系统结构示意图;
图中:1、卷积运算单元;2、池化运算单元;3、全连接运算单元。
图2是本发明实施例提供的跨平台卷积神经网络控制方法流程图。
具体实施方式
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。
本发明基于OpenGL ES实现的卷积神经网络计算框架,解决了利用cpu和gpu并行计算的问题,同时实现了不同终端的跨平台设计。opengl es是一种图像处理标准。fbo:帧缓冲对象,是opengles的一次渲染过程的结果,可以理解为一张图。padding:在卷积计算前,需要在图片周边加上一圈0,0的圈数=卷积核大小/2。fragment shader:opengles的具体实现脚本,类似于c语言的c代码。 fbo:帧缓冲对象。fbo渲染过程实际就是opengles生成一张图片的过程。手机屏幕上的图像就是这样渲染出来的。neon指令是cpu的一种浮点计算加速方法,和gpu没有关系,和opengles shader也没有关系。
如图1所示,本发明实施例提供的跨平台卷积神经网络控制系统包括:卷积运算单元1、池化运算单元2、全连接运算单元3。
其中卷积运算单元1和池化运算单元2,卷积运算单元1与池化运算单元2 连接,通过OpenGL ES来实现gpu计算。
全连接运算单元3,与卷积运算单元1或池化运算单元2连接,使用cpu的 neon指令实现;其中,每次卷积运算前需要给各个通道添加padding,将padding 操作和卷积运算或者池化运算结合。
如图2所示,本发明实施例提供的跨平台卷积神经网络控制方法包括以下步骤:
S201:计算输出的纹理尺寸,定义卷积计算中有k个卷积核,输出纹理有k 个通道;输出通道平铺在输出纹理中,应当尽量保证纹理接近方形以获得最优性能;
S202:计算顶点坐标:渲染按照GL_TRIANGLES方式,每个通道包括2 个三角形;
S203:计算shader变量:定义attribute类型变量textureCoordinate,textureCoordinate.xy为当前输出的像素坐标对应于输入纹理在通道内的卷积计算起始坐标,textureCoordinat.z为当前像素所在的输出通道;
S204:在fragment shader的卷积计算。
下面结合附图对本发明的应用原理作进一步的描述。
1、卷积神经网络包括3个基本运算单元:卷积运算单元1、池化运算单元 2、全连接运算单元3。其中卷积运算单元1和池化运算单元2通过OpenGL ES 来实现gpu计算,全连接运算单元3使用cpu的neon指令实现。其中,每次卷积运算前需要给各个通道添加padding,本发明可以将padding操作和卷积运算或者池化运算结合。
1、卷积运算单元1设计如下:
1)输入为一个存储多通道的纹理图像,如图3所示为1个4通道的输入,在每个通道的边缘填充padding。纹理可以使用RGBA8位纹理或者RGBA32位纹理,如果使用8位纹理则用RGBA4个byte按照浮点数的格式进行拼装表示一个浮点数,如果使用RGBA32位纹理,则每个像素可以表示4个浮点数,这样图中每个通道区实际为4个通道,图3中共有16个通道。以下以RGBA32位纹理为例说明。
2)卷积核使用一个RGBA32位浮点纹理存储,以图3所示的16通道输入、4个卷积核、3*3卷积核大小为例说明,如图4。纹理的前3行为第一个卷积核,每3列为一个通道,每个像素有RGBA4个单元可以存储4个浮点数,这样每相邻9个像素可以存储1个卷积核中的4个通道,所以卷积核用一个12*12 的RGBA32位浮点纹理来存储。
3)卷积的计算过程在OpenGL ES中的实现步骤。
i)计算输出的纹理尺寸:定义卷积计算中有k个卷积核,也即输出纹理有k 个通道。输出通道平铺在输出纹理中,应当尽量保证纹理接近方形以获得最优性能。x方向和y方向通道数计算公式分别为:
float power=log2(k/4);
intc_x_count=pow(2,ceil(power/2));
intc_y_count=pow(2,floor(power/2));
定义输入纹理的每个通道的宽为c_width,高为c_height,padding尺寸为c_padding,输出纹理每个通道的padding为next_padding,如果当前卷积计算的下一层为池化运算,则next_padding为0。那么输出纹理的大小为:
intout_width=(c_width+2*next_padding)*c_x_count;
intout_height=(c_height+2*next_padding)*c_y_count;
ii)计算顶点坐标:渲染按照GL_TRIANGLES方式,每个通道包括2个三角形。对于第(xi,yi)个通道,其4个顶点坐标为:
pi0_x=-1.0+((c_width+2*next_padding)*xi+next_padding)*1.0/out_width;
pi0_y=-1.0+((c_height+2*next_padding)*yi)*1.0/out_height;
pi1x=-1.0+((c_width+2*next_padding)*xi+next_padding+ c_width)*1.0/out_width;
pi1_y=-1.0+((c_height+2*next_padding)*yi+next_padding)*1.0/out_height;
pi2_x=-1.0+((c_width+2*next_padding)*xi+next_padding)*1.0/out_width;
pi2_y=-1.0+((c_height+2*next_padding)*yi+ next_padding+c_height)*1.0/out_height;
pi3_x=-1.0+((c_width+2*next_padding)*xi+next_padding+ c_width)*1.0/out_width;
pi3_y=-1.0+((c_height+2*next_padding)*yi+ next_padding+c_height)*1.0/out_height;
顶点顺序为012123
iii)计算shader变量:定义attribute类型变量textureCoordinate,textureCoordinate.xy为当前输出的像素坐标对应于输入纹理在通道内的卷积计算起始坐标,textureCoordinat.z为当前像素所在的输出通道。对应于每个通道的 4个顶点,textureCoordinate的值为:
ci0_x=0.0;
ci0_y=0/0;
ci0_z=(yi*c_x_count+xi)*4;
ci1_x=c_width*1.0/out_width;
ci1_y=0.0;
ci1_z=(yi*c_x_count+xi)*4;
ci2_x=0.0;
ci2_y=c_height*1.0/out_height;
ci2_z=(yi*c_x_count+xi)*4;
ci3_x=c_width*1.0/out_width;
ci3_y=c_height*1.0/out_height;
ci3_z=(yi*c_x_count+xi)*4;
iv)卷积计算在fragment shader中的实现:
(1)定义以下uniform类型变量:
uniform intchannel_size[2]输入纹理的每个通道长宽(已经加上了padding);
uniform intchannel_count[2]:输入纹理在x方向和y方向上的通道数;
uniform highp float texture_step[2]:输入纹理的每个像素归一化长度,为1.0/out_widht和1.0/out_height;
uniform highp float kernel_step[2]:卷积核纹理的每个像素归一化长度;
uniform highp sampler2D inputImageTexture[2]:0为输入纹理,1为卷积核纹理;
uniform intkernel_size:卷积核大小,如3或者5;
uniform highp float bias[%d]:每个卷积核需要叠加的偏移;
(2)循环遍历输入纹理的通道,在(wi,hi)通道中,用于卷积计算的起始点坐标:
highp float x=float(wi*channel_size[0])*texture_step[0]+textureCoordinate.x;
highp float y=float(hi*channel_size[1])*texture_step[1]+textureCoordinate.y;
然后计算右侧kernel_size-1个点以及下侧kernel_size-1个点共 kernel_size*kernel_size个点的坐标,在inputImageTexture[0]中进行采样,得到其颜色值。定义其颜色值分别为color_00-color_kk。
(3)计算color_00-color_kk对应的卷积核。卷积核的起始坐标为:
intci=hi*channel_count[0]+wi;
float w_x=kernelCoordinate.x+float(ci*kernel_size)*kernel_step[0]+kernel_step[0]/2.0;
float x_y=kernelCoordinate.z*kernel_size*kernel_step[1];
同样对右侧kernel_size-1个点以及下侧kernel_size-1个点共 kernel_size*kernel_size个点计算坐标,在inputImageTexture[1]进行采样,得到其颜色值conv0_00-conv0_kk,即为卷积核。
(4)∑dot(color_ii,conv_ii)即为当前位置的卷积计算结果。由于每个像素有rgba4个通道,所以重复过程(3)获取kernelCoordinate.z+1、kernelCoordinate.z+2、kernelCoordinate.z+3的卷积核,分别定义为conv1、conv2、conv3,则当前像素的输出即为out_color=vec4(∑dot(color_ii,conv0_ii),∑dot(color_ii,conv1_ii),∑dot(color_ii,conv2_ii),∑dot(color_ii,conv3_ii));
至此fragment shader计算完毕,渲染完成后输出纹理即为卷积计算的结果,分布如图3。
2、池化运算单元设计如下:
1)池化的输入一般为上一次卷积运算的输出。定义池化的尺寸为pool_size,那么池化的输出纹理尺寸为out_width/pool_size,out_height/pool_size;
2)顶点坐标和attribute类型变量textureCoordinate的计算和卷积运算中的顶点计算方法相同。
3)池化运算单元在fragment shader中的实现:
i)从当前点开始遍历输入纹理中右侧及下侧共pool_size*pool_size个点,进行纹理采样,得到像素颜色color_00-color_pp;
ii)分别计算color_00-color_pp在r、g、b、a4个通道上的最大值,记为max_r、max_g、max_b、max_a;
iii)当前像素的输出即为out_color=vec4(max_r、max_g、max_b、max_a);
3、全连接运算单元设计:
1)通过PBO将最后一个卷积层或者池化层的输出从gpu内存拷贝到cpu 内存中;
2)借住neon指令对全连接层进行计算,即为当前全连接层的输出;
3)如果有多层全连接层,后面的全连接层的输入为上一层全连接层的输出,此时不再需要PBO传输;
4)最后一层全连接层的输出即为整个神经网络的输出。
本发明的纹理全部使用了RGBA32位浮点纹理,在OpenGL ES2.0中不支持浮点纹理,可以使用RGBA 8位纹理中的rgba4个字节来拼一个浮点数,在每次卷积层计算的输出中,将计算好的浮点数拆解为4个字节分别存储到rgba上,在卷积计算的输入中,将上层卷积输出的rgba再拼接成一个浮点数,进行卷积计算。对于精度要求不太高的场景,本发明中所有32位浮点数都可以替换成16 位浮点数,对于RGBA32位纹理,每个像素通道区域就可以存储8个通道。而对于RGBA8位纹理,每个像素通道区域可以存储2个通道。对于卷积层输出的存储,本发明将一个通道中所有元素放在纹理中的相近区域存放,也可以将不同通道的相同位置的元素放在一起。
在上述实施例中,可以全部或部分地通过软件、硬件、固件或者其任意组合来实现。当使用全部或部分地以计算机程序产品的形式实现,所述计算机程序产品包括一个或多个计算机指令。在计算机上加载或执行所述计算机程序指令时,全部或部分地产生按照本发明实施例所述的流程或功能。所述计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程装置。所述计算机指令可以存储在计算机可读存储介质中,或者从一个计算机可读存储介质向另一个计算机可读存储介质传输,例如,所述计算机指令可以从一个网站站点、计算机、服务器或数据中心通过有线(例如同轴电缆、光纤、数字用户线(DSL)或无线(例如红外、无线、微波等)方式向另一个网站站点、计算机、服务器或数据中心进行传输)。所述计算机可读取存储介质可以是计算机能够存取的任何可用介质或者是包含一个或多个可用介质集成的服务器、数据中心等数据存储设备。所述可用介质可以是磁性介质,(例如,软盘、硬盘、磁带)、光介质(例如,DVD)、或者半导体介质(例如固态硬盘SolidState Disk(SSD))等。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。