从Conv2D的正向传播说起
为了快速计算conv2d,需要将conv2d整理成两个矩阵相乘的形式,例如WX,或者其转置形式。这里以XW为例,X的每一列表示一张feature map的所有方格,也就是将一个feature map的某一个3X3或者5X5区域先展平(flatten)成行向量,再将所有的小区域的行向量纵向拼接起来组成一个大的矩阵,矩阵的维度是((map_s-filter_size+pad)/ filter_size + 1)**2X(filter_size**2)。再将所有feature map得到的列横向组合成一个大矩阵。对于权值矩阵,对应的方法处理,然后进行一次转置即可。当然,由于(AB)的转置等于B的转置乘以A的转置,上述img2col方式不是唯一的。完成img2col后,只需要进行一次矩阵相乘运算即可,矩阵相乘运算可以调用各种BLAS库在CPU或GPU上高速进行。当然,还要额外考虑的一个问题是,神经网络一般使用mini-batch进行训练,所以希望一次性把batch内的所有计算完成。可以这样思考:将batch内的多个样本看作同一个样本,也就是把输入样本全部concatenate在一起,然后就可以套用上面的过程了。再计算完成后再将不同batch的数据分开就可以了。根据上面的分析,WX的输出应该是这样的:每一列都是一个滤波器的全部输出,再回复成二维的形状即可。batch内不同样本的输出是纵向拼接在一起的,因此平均分割开即可。
代码组建思路:总的思路就是遍历,给转换后的矩阵的每一个位置赋值。有两种方式,第一种是对转换后的矩阵遍历,第一个维度是row,第二个维度是col,根据row和col的取值(当然也