GPGPU-简单卷积神经网络的并行加速优化
4
2) 网络层在 SdlfLayer.h 中被继承,层类型包括卷积层、池化层、全连接层、
SoftMax 层,网络层中定义了各层的构建、参数初始化、执行和梯度传
递等方法,在 SdlfLayer.cpp 中被具体实现。其中卷积核等参数的结构体
和其操作方法被定义实现在 KernelCPU.h 和 KernelCUDA.h 中。SdlfLayer
的相关方法会被 SdlfModel 所调用,用于构建模型;
3) 网络计算类在 SdlfCalculator.h 中被定义,一些属性被定义,包括卷积、
池化、全连接和 SoftMax 的计算方法被声明。在 SdlfCalculatorCPU.h 和
SdlfCalculatorCUDA.h 对 SdlfCalculator.h 进行了继承,分别负责串行计
算和并行计算过程,其方法也在 SdlfCalcutorCPU.cpp 和
SdlfCalculatorCUDA.cpp 中进行了实现,SdlfCalcutor.cpp 仅实现了基础
的共用方法。SdlfCalculator 相关的方法会被 SdlfLayer 所调用,用于各
层的计算;
4) 函数计算类在 SdlfFunction.h 和 SdlfFunctionCUDA.h 中被分别声明,同
时在 SdlfFunction.cpp 和 SdlfFunctionCUDA.cpp 中被分别实现。
SdlfFunction 主要集中了项目计算中可能会用到的数学计算的具体实现,
被 SdlfModel, SdlfLayer 和 SdlfCalcutor 所调用,即真正的计算代码是被
写在 SdlfFuntion 中,其与 SdlfCalcutor 共同完成了各个计算过程。此外,
CUDA 的具体所有真正计算过程被写在 Kernel.cu 中。
2.2. 串行运算
卷积神经网络的实现除了上述到的数据结构、函数等服务于运算的过程,最
令人关注的是其具体网络层的前向传播和反向传播,由于时间关系,在实现时仅
对前向传播过程进行了并行加速,因此本文的串并行算法介绍主要集中在各层的
前向计算,反向传播过程仅有串行实现。
2.2.1. 卷积层
在进行卷积运算时,原项目[2]采用先加载数据并匹配卷积核,后卷积运算
的两步卷积,而非数据加载和运算同时进行的方式。这种两步方式理解起来较为
简单,但占用内存较大,本项目在实现时沿用了这种传统。
对于输入数据 InData[BatchSize*InChannel*ImgHeight*ImgWidth](InData 表
示数据名称,[]内表示其组织形式及大小,单位为 sizeof(float)字节),卷积核的
大小为 W[OutChannel*InChannel*ConvHeight*ConvWidth],B[OutChannel],表示
有 OutChannel 个长度为 ConvLen=InChannel*ConvHeight*ConvWidth 的卷积核。
其中卷积核大小选择为 3 ,即卷积前后图像大小不变。则输出数据为
OutData[BatchSize*OutChannel*ImgHeight*ImgWidth]。
如图 2-1 所示,对于 OutData 中的每一个输出,都是由 OutChannel 个卷积核