目录
5-7忽略激活函数,分析卷积网络中卷积层的前向计算和反向传播是一种转置关系。
习题5-2 证明宽卷积具有交换性,即公式(5.13)
证明:
首先给定一个二维图像:和一个二维卷积核
因为要对图像X进行卷积,但是上面定义中提到了是宽卷积,所以先对他进行填充,两端各补U-1和V-1个零,得到全填充图像
为了方便我们先设一下
和
因为我们要证明交换性,所以要对W也填充,就是W两端各补M-1和N-1个零,得到全填充图像
从我们设的X和W很容易可以看出来U=N=2,M=N=3。
那么填充完的
然后把W和X旋转180°
然后就方便计算
可以看出来我们得到的结果是一样的。所以交换律成立
习题5-3 分析卷积神经网络中用1×1的卷积核的作用
1 跨通道的特征整合
如果当前层和下一层都只有一个通道那么1×1卷积核确实没什么作用,但是如果它们分别为m层和n层的话,1×1卷积核可以起到一个跨通道聚合的作用,所以进一步可以起到降维(或者升维)的作用,起到减少参数的目的。
这里通过一个例子来直观地介绍1x1卷积。输入6x6x1的矩阵,这里的1x1卷积形式为1x1x1,即为元素2,输出也是6x6x1的矩阵。但输出矩阵中的每个元素值是输入矩阵中每个元素值x2的结果。
上述情况,并没有显示1x1卷积的特殊之处,那是因为上面输入的矩阵channel为1,所以1x1卷积的channel也为1。这时候只能起到升维的作用。这并不是1x1卷积的魅力所在。
让我们看一下真正work的示例。当输入为6x6x32时,1x1卷积的形式是1x1x32,当只有一个1x1卷积核的时候,此时输出为6x6x1。此时便可以体会到1x1卷积的实质作用:降维。当1x1卷积核的个数小于输入channels数量时,即降维[3]。
注意,下图中第二行左起第二幅图像中的黄色立方体即为1x1x32卷积核,而第二行左起第一幅图像中的黄色立方体即是要与1x1x32卷积核进行叠加运算的区域。
其实1x1卷积,可以看成一种全连接(full connection)。
第一层有6个神经元,分别是a1—a6,通过全连接之后变成5个,分别是b1—b5,第一层的六个神经元要和后面五个实现全连接,本图中只画了a1—a6连接到b1的示意,可以看到,在全连接层b1其实是前面6个神经元的加权和,权对应的就是w1—w6,到这里就很清晰了:
第一层的6个神经元其实就相当于输入特征里面那个通道数:6,而第二层的5个神经元相当于1*1卷积之后的新的特征通道数:5。w1—w6是一个卷积核的权系数,若要计算b2—b5,显然还需要4个同样尺寸的卷积核[4]。
上述列举的全连接例子不是很严谨,因为图像的一层相比于神经元还是有区别的,图像是2D矩阵,而神经元就是一个数字,但是即便是一个2D矩阵(可以看成很多个神经元)的话也还是只需要一个参数(1*1的核),这就是因为参数的权值共享。
注:1x1卷积一般只改变输出通道数(channels),而不改变输出的宽度和高度
2 降维/升维
由于 1×1 并不会改变 height 和 width,改变通道的第一个最直观的结果,就是可以将原本的数据量进行增加或者减少。这里看其他文章或者博客中都称之为升维、降维。但我觉得维度并没有改变,改变的只是 height × width × channels 中的 channels 这一个维度的大小而已[5]。
图像来自知乎ID: YJango[6]
3 加非线性
1*1卷积核,可以在保持feature map尺度不变的(即不损失分辨率)的前提下大幅增加非线性特性(利用后接的非线性激活函数),把网络做的很deep。
备注:一个filter对应卷积后得到一个feature map,不同的filter(不同的weight和bias),卷积以后得到不同的feature map,提取不同的特征,得到对应的specialized neuron[7]。
4 跨通道信息交互(channal 的变换)
例子:使用1x1卷积核,实现降维和升维的操作其实就是channel间信息的线性组合变化,3x3,64channels的卷积核后面添加一个1x1,28channels的卷积核,就变成了3x3,28channels的卷积核,原来的64个channels就可以理解为跨通道线性组合变成了28channels,这就是通道间的信息交互[7]。
注意:只是在channel维度上做线性组合,W和H上是共享权值的sliding window
5 减少计算量
以下图为例,我们可以看到,计算量明显减少。
6 1x1卷积核应用
Inception
-
这一点孙琳钧童鞋讲的很清楚。1×1的卷积层(可能)引起人们的重视是在NIN的结构中,论文中林敏师兄的想法是利用MLP代替传统的线性卷积核,从而提高网络的表达能力。文中同时利用了跨通道pooling的角度解释,认为文中提出的MLP其实等价于在传统卷积核后面接cccp层,从而实现多个feature map的线性组合,实现跨通道的信息整合。而cccp层是等价于1×1卷积的,因此细看NIN的caffe实现,就是在每个传统卷积层后面接了两个cccp层(其实就是接了两个1×1的卷积层)。
-
进行降维和升维引起人们重视的(可能)是在GoogLeNet里。对于每一个Inception模块(如下图),原始模块是左图,右图中是加入了1×1卷积进行降维的。虽然左图的卷积核都比较小,但是当输入和输出的通道数很大时,乘起来也会使得卷积核参数变的很大,而右图加入1×1卷积后可以降低输入的通道数,卷积核参数、运算复杂度也就跟着降下来了。
以GoogLeNet的3a模块为例,输入的feature map是28×28×192,3a模块中1×1卷积通道为64,3×3卷积通道为128,5×5卷积通道为32,如果是左图结构,那么卷积核参数为1×1×192×64+3×3×192×128+5×5×192×32,而右图对3×3和5×5卷积层前分别加入了通道数为96和16的1×1卷积层,这样卷积核参数就变成了1×1×192×64+(1×1×192×96+3×3×96×128)+(1×1×192×16+5×5×16×32),参数大约减少到原来的三分之一。
同时在并行pooling层后面加入1×1卷积层后也可以降低输出的feature map数量,左图pooling后feature map是不变的,再加卷积层得到的feature map,会使输出的feature map扩大到416,如果每个模块都这样,网络的输出会越来越大。
而右图在pooling后面加了通道为32的1×1卷积,使得输出的feature map数降到了256。GoogLeNet利用1×1的卷积降维后,得到了更为紧凑的网络结构,虽然总共有22层,但是参数数量却只是8层的AlexNet的十二分之一(当然也有很大一部分原因是去掉了全连接层)[8]。
5-4对于一个输入为100×100×256的特征映射组,使用3×3的卷积核,输出为100×100×256的特征映射组的卷积层,求其时间和空间复杂度。如果引入一个1×1的卷积核,先得到100×100×64的特征映射,再进行3×3的卷积,得到100×100×256的特征映射组,求其时间和空间复杂度。
时间复杂度:时间复杂度即模型的运行次数。
单个卷积层的时间复杂度:Time~O(M^2 * K^2 * Cin * Cout)
- M:输出特征图(Feature Map)的尺寸。
- K:卷积核(Kernel)的尺寸。
- Cin:输入通道数。
- Cout:输出通道数。
注:
- 为了简化表达式变量个数,统一假设输入和卷积核的形状是正方形,实际中如果不是,则将M ^2替换成特征图的长宽相乘即可;
- 每一层卷积都包含一个偏置参数(bias),这里也给忽略了。加上的话时间复杂度则为:O(M^2 * K^2 * Cin *
Cout+Cout)。
空间复杂度:空间复杂度即模型的参数数量。
单个卷积的空间复杂度:Space~O(K^2 * Cin * Cout+M^2*Cout)
注:空间复杂度只与卷积核的尺寸K、通道数C相关。而与输入图片尺寸无关。当我们需要裁剪模型时,由于卷积核的尺寸通常已经很小,而网络的深度又与模型的能力紧密相关,不宜过多削减,因此模型裁剪通常最先下手的地方就是通道数。
解题:
-
时间复杂度=100×100×3×3^256×256=5898240000
空间复杂度=3×3^256×256+100×100×256=3149824
-
时间复杂度=100×100×1×1×256×64+100×100×3×3×64×256=1638400000
空间复杂度=1×1×256×64+100×100×64+3×3×64×256+100×100×256=3363840
5-7忽略激活函数,分析卷积网络中卷积层的前向计算和反向传播是一种转置关系。
以一个3×3的卷积核为例,输入为X输出为Y
将4×4的输入特征展开为16×1的矩阵,y展开为4×1的矩阵,将卷积计算转化为矩阵相乘
由 而
即
所以
再看一下上面的Y=CX可以发现忽略激活函数时卷积网络中卷积层的前向计算和反向传播是一种转置关系。
推导CNN反向传播算法
在前向传播时,池化层我们会用MAX或者Average对输入进行池化,池化的区域大小已知。现在我们反过来,要从缩小后区域的误差,还原前一层较大区域的误差。这个过程叫做upsample。假设我们的池化区域大小是2x2。第l层误差的第k个子矩阵为:
如果池化区域表示为a*a大小,那么我们把上述矩阵上下左右各扩展a-1行和列进行还原:
如果是MAX,假设我们之前在前向传播时记录的最大值位置分别是左上,右下,右上,左下,则转换后的矩阵为:
如果是Average,则进行平均,转换后的矩阵为:
上边这个矩阵就是误差矩阵经过upsample之后的矩阵,那么,由后一层误差推导出前一层误差的公式为:
上式和普通网络的反向推导误差很类似:
可以看到,只有第一项不同。
2、已知卷积层的误差,反向推导上一隐藏层的误差
公式如下:
我们再看一次普通网络的反向推导误差的公式:
可以看到区别在于,下一层的权重w的转置操作,变成了旋转180度的操作,也就是上下翻转一次,左右再翻转一次,这其实就是“卷积”一词的意义(我们可简单理解为数学上的trick),可参考下图,Q是下一层的误差,周围补0方便计算,W是180度翻转后的卷积核,P是W和Q做卷积的结果:
3、已知卷积层的误差,推导该层的W,b的梯度
经过以上各步骤,我们已经算出每一层的误差了,那么:
a)对于全连接层,可以按照普通网络的反向传播算法求该层W,b的梯度。
b)对于池化层,它并没有W,b,也不用求W,b的梯度。
c)只有卷积层的W,b需要求出,先看w:
再对比一下普通网络的求w梯度的公式,发现区别在于,对前一层的输出做翻转180度的操作:
而对于b,则稍微有些特殊,因为在CNN中,误差δ是三维张量,而b只是一个向量,不能像普通网络中那样直接和误差δ相等。通常的做法是将误差δ的各个子矩阵的项分别求和,得到一个误差向量,即为b的梯度: