给定一个卷积层 C in * C out * H k * W k, 以及输入 feature map C in * H * W,我们希望将该卷积操作转化为一次矩阵乘,以便使用一些矩阵计算优化策略,请设计转换方法。
img2col
Mat A: (H * W) * (Cin * Hk * Wk )
Mat B: (Cin * Hk * Wk )* (Cout )
MATLAB中函数image2col可以实现这个功能,具体的原理如下
上图为3D卷积的传统计算方式与矩阵乘法计算方式的对比,传统卷积运算是将卷积核以滑动窗口的方式在输入图上滑动,当前窗口内对应元素相乘然后求和得到结果,一个窗口一个结果。相乘然后求和恰好也是向量内积的计算方式,所以可以将每个窗口内的元素拉成向量,通过向量内积进行运算,多个窗口的向量放在一起就成了矩阵,每个卷积核也拉成向量,多个卷积核的向量排在一起也成了矩阵,于是,卷积运算转化成了矩阵运算。
下图为转化后的矩阵尺寸,padding为0:
优缺点分析
将卷积运算转化为矩阵乘法,从乘法和加法的运算次数上看,两者没什么差别,但是转化成矩阵后,运算时需要的数据被存在连续的内存上,这样访问速度大大提升(cache),同时,矩阵乘法有很多库提供了高效的实现方法,像BLAS、MKL等,转化成矩阵运算后可以通过这些库进行加速。
缺点呢?这是一种空间换时间的方法,消耗了更多的内存——转化的过程中数据被冗余存储。