在caffe中卷基层是通过矩阵相乘来实现的实现,直接计算卷积可以由下面的程序表示:
可以看到,这段程序循环嵌套多,时间复杂度高,而使用矩阵相乘的形式:很多现成的矩阵运算库,不重复“造轮子” 。
我们来看代码:
在conv_layer 中卷记的操作主要由上面两个带红框的操作组成,其中bias是为卷积操作后的结果加入偏差项,这个简单暂不分析。关键在于gemm,卷积操作的核心所在。如下图:
在做矩阵相乘之前首先要将图片转化成向量的形式,调用的函数就是im2col。然后就是矩阵相乘gemm。Im2col 是一个用于图像到向量转换的函数,你大多数情况下不需要了解他,他的作用就是用在caffe原生的卷积运算中,将卷积运算变成矩阵相乘的运算。具体分析im2col_layer.cpp代码:
如下为参数设定的一些代码:
SetUp kernelShape
SetUp stride
SetUp pad
其中,pad的含义可以由下图所示:
SetUp dilation(膨胀系数)
通过reshape为im2col分配空间:
以及计算生成的卷记feature map的尺寸:
最关键的核心在于如下代码:
这段代码看上去特别复杂,但整体上可以分成两个部分,一个是红框的,一个是绿的。其中input_row:在原图中的行数input_col:在原图中的列数
通过这段代码,卷记的kernel就能转化成如下的矩阵:
这样,feature map 就转换成了对应的矩阵的形式,因此,卷积的操作也就能对应的用矩阵相乘的形式实现了。
77695@中国科学技术大学多媒体计算与通信教育部-微软重点实验室
MultiMedia Computing Group