## inner_product_layer理论研究 ##
对于全连接来说,神经网络里的全连接是在全连接层实现的,实际实现的本质是两个向量的内积,即:两个行向量:x=(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9),w=(w0,w1,w2,w3,w4,w5,w6,w7,w8,w9),w*x=x0*w0+x1*w1+x2*w2+x3*w3+x4*w4+x5*w5+x6*w6+x7*w7+x8*w8+x9*w9;
若x为N*1,w为M*N,内积w*x为M维.实际上内积实现的全连接层实际上就是一个参数矩阵W与输入的N维向量X之间做矩阵想乘。
可是全连接层的实现形式可不仅仅就这一种,当然,caffe里的实现形式是内积实现的全连接,但是还有一种更普遍的实现形式,那就是卷积实现全连接。
谈到卷积实现全连接可能有点生疏,起码我是生疏的,所以做总结如下,为了自己回头翻看的时候可以更容易想起来。实际上,内积是卷积的一种特例,为什么这么说呢?上述提到的内积形式:x=(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9),w=(w0,w1,w2,w3,w4,w5,w6,w7,w8,w9),w*x=x0*w0+x1*w1+x2*w2+x3*w3+x4*w4+x5*w5+x6*w6+x7*w7+x8*w8+x9*w9;
由加法的结合律,得:w*x=(x0*w0+x1*w1+x2*w2)+(x3*w3+x4*w4+x5*w5)+(x6*w6+x7*w7+x8*w8+x9*w9);写成了三个小的内积之和,然后这不就是
输入X= x0 x1 x2 和 卷积核W= w0 w1 w2 之间
x3 x4 x5 w3 w4 w5
x6 x7 x8 w6 w7 w8
的卷积吗?
将上面两种方式之间的障碍转换一下,比如一个25*3*3的输入,卷积核为M*25*3*3,则输出为M*1*1,现在我们将输入flatten一下,特征个数没变还是25*3*3,没个卷积核flatten一行,则内积之后是M*1。注意:卷积核的长和宽一定要和输入的长和宽保持一致。
实际上,这两种实现形式的区别在于应用场景不同,举个例子:
比如输入x为:3*100*100,pad=1,经过卷积核25*3*3*3,pad=1,则经过卷积的特征图大小为:25*100*100,后再经过一个内积实现的全连接,全连接的输出为2,则全连接层的参数维度为25*100*100*2,如果输入此时变成3*200*200呢?第一层的卷积还可以算,卷积核为25*3*3*3,pad=1,输出:25*200*200,但是接下来的全连接层呢?此时由于输入维度和参数维度不一样,不能实现内积,所以由内积实现的全连接层,输入是不允许发生改变的。但如果此时用卷积实现全连接层呢?情况如何?则情况发生了改变,输入变为25*200*200,经过2*25*100*100,pad=0,则2*101*101。
应用场景:滑动窗口检测:
比如一幅图像大小:3*200*200,图像里有一个西瓜,西瓜直径为100个像素,那么如何检测西瓜的位置?
思路:在200*200的图像里抠出一个100*100的图像块,那么有多少个位置需要判断呢?当然抠出的可能性有101*101种,也就是说需要做101*101次判断此处是不是西瓜,每次都是一个3*100*100的块。显然,3*200*200是图像,100*100是卷积核,则输出为101*101个位置,若卷积核大小为2*25*100*100,那么输出2*101*101,但是问题来了,这样在卷积核的滑动过程中,会出现大量的重复计算,若卷积核在(0,1)位置上进行卷积,下一次滑动到(0,2)位置上进行卷积,那么由于卷积核大小为100*100,则第二次运算和第一次运算有100*99是重复的,那么就会造成大量的冗余计算,那为什么不一次卷积实现此过程呢?即输入3*200*200,直接先卷积一次,经过卷积核25*3*3*3,输出为 25*200*200,在此基础上进行取块,25*100*100,是一样的,但是还是存在一个计算次数冗的问题,那么何不用卷积层去实现全连接层一次分类呢。此时的全连接层输入是25*200*200,直接用卷积核2*25*100*100,即输出2*101*101,一次完成所有计算。就是这么神奇。