tutorial of CNN 笔记
Vanilla BP Through Fully Connected Networks
这里只考虑二维CNN的情况
Feedforward Pass
这里使用平方误差Loss Function,对于一个c类N个sample的分类器,设
tnk
为第n个图像在k-th维度上对应的label,
ynk
为CNN的输出层对于第n个输入的pattern在第k个维度上的输出,则error为:
多分类器的label大多采用one-hot code(e.g:[0,0,1,0,0])
由于整个dataset的error只是N张输入的error的加和,这里为了简便假定input只有一张图,那么
为了将权值W引入计算,设 ℓ 表示当前层号,输入层为1层,输出层为L层,定义这一层的输出为:
f(.)为激活函数(sigmoid或tanh), f(x)=atanh(bx) ,但是把数据正则化(normalizing)为期望为0方差为1的数据会改善梯度下降中改善收敛的性能,所以tanh较好一点.LeCun推荐 a=1.7159 并且 b=2/3 ,so that the point of maximum nonlinearity occurs at f(±1)=±1 and will thus avoid saturation during training if the desired training targets are normalized to take on the values ±1.
Backpropagation Pass
这里的error可以视为每一个神经元对bias(b)上的扰动的敏感度(大雾),公式为
而 ∂u∂b=1 ,也就是说
那么有
得到反向传播的最重要的公式:
对输出层,公式变为
那么对每一个给定的神经元,更新权值W只需要知道输入和对应的delta(delta法则)
实际应用中对每一个 Wi,j 都对应一个学习率 ηi,j
Convolutional Neural Networks
Convolution Layers
导出convolution layers 的bp更新公式,在convolution layer,前一层的特征图和一个可以学习的kernel进行卷积并且在最后加上一个activation function,每一个convolution layer的output map可能由多个输入卷积之后叠加而成,设
Mj
为选中的input map(a selection of input map),公式为:
对于input map selection的设置,一般选择每两个一组或者每三个一组。
Computing the Gradients
我们假定每一个卷积层
ℓ
的后面都有一个降采样层(pooling?)
ℓ+1
。和全连接的BP网络不同,在CNN中一个卷积层后面是一个降采样层,那么下一层的图像上的一个像素点在上一层中对应一个block的像素点,也就是这一像素点对应的
δ
在上一层中对应一个block的像素点,因为有降采样层的存在,
ℓ
层中的每一个unit只对应
ℓ+1
层中的一个unit。为了有效率地计算
ℓ
层的
δ
,我们可以upsample
ℓ+1
层的
δ
组成的map,使得这一个map和上一个卷积层的大小一致,然后和上一层的
f′(uℓj)
进行元素相乘。在降采样层的map定义的权值全部都等于
β
(constent),所以我们只需要把上一步操作的结果乘上
β
来结束
ℓ
层的
δ
的计算,所以对convolutional层的每一个map j,都有:
up(.)表示upsampling操作,即将每一个像素点横向和纵向地重复n次(假设降采样层是以n*n的大小降采样的),一个有效的计算这个过程的方法是使用Kronecker product
如果A是一个 m x n 的矩阵,而B是一个 p x q 的矩阵,克罗内克积则是一个 mp x nq 的矩阵
A⊗B=⎛⎝⎜⎜a11B⋮am1B⋯⋱⋯a1nB⋮amnB⎞⎠⎟⎟
那么
那么我们很快就可以计算出bias的梯度:
最后,卷积核权值的梯度可以用BP得出,因为权值共享,只需要把所有涉及到给定权值的连接的梯度相加即可
(Pℓ−1i)uv 是 xℓ−1i 中的一个patch,在卷积的过程中和 kℓi,j 进行对应元素相乘以得到在output map xℓj 的第(u,v)个元素, kℓi,j 是从input map i 到output map j过程中使用的卷积核
上式可以在MATLAB中用一行写出,我们先对delta灵敏度map进行旋转,这样就可以进行互相关计算,而不是卷积(在卷积的数学定义中,特征矩阵(卷积核)在传递给conv2时需要先翻转(flipped)一下。也就是颠倒下特征矩阵的行和列)。然后把输出反旋转回来,这样我们在前向传播进行卷积的时候,卷积核才是我们想要的方向。
Sub-sampling Layers
降采样层提供了对input map的降采样的视角,如果有N个input map,那么就有N个output map,但是output map 要比input map小,或者
down(.)表示降采样方程,一般采用n x n的区域计算(取最大或者取平均),所以output map 的大小要比input map的大小在两个空间维度上(x轴,y轴)小n倍, β 为乘性bias,b 为加性bias
Computing the Gradients
这里的难点在于计算 δ maps,一旦我们得到了 δ maps,需要学习的变量就只有 β 和b,我们假设降采样层被卷积层上下包围。如果紧跟着降采样层的是全连接层,那么 δ map可以直接用Vanilla BP公式算出
当我们计算section2.1.1的卷积核的梯度的时候,我们需要算出input中的哪一个patch对应output map中的给定的pixel,而在这里我们需要算出当前层的
δ
map对应下一层的
δ
map的pixel,因为需要使用形如
δℓ=(Wℓ+1)Tδℓ+1⊙f′(uℓ)
的
δ
迭代公式。另外,需要乘以输入patch与输出像素之间连接的权值,这个权值实际上就是卷积核的权值(已旋转的)。
像之前一样,我们先旋转卷积核来让卷积函数进行互相关计算,这里需要使用’full convolution’来处理边界情况,在边界补0,以免input中的一个patch无法被nxn的区域铺满
这时就可以开始计算
β
和b了,对于加性bias,同样只是把
δ
map中的所有元素加起来:
对于乘性bias,不可避免地要涉及到原来的在feedforward过程中的当前层的down-sampled的map,所以最好把这些map先保存起来,避免重复计算,定义:
那么 β 的梯度:
Learning Combinations of Feature Maps
一般来说,使用多个input的卷积相加得出一个output map是有好处的。在一些著作中,这样的一些input map是手动选择的,但是我们可以尝试让CNN自己学习如何选择input maps,令
αij
表示input map i的权重,那么output map j可以表示为:
并且
为了满足上式可以把 αij 设置为由一组无限制的隐含权值通过softmax得到的值
因为上式的j是固定的,为了简便,我们去掉j,只考虑一个输出的情况,那么上面的那个softmax的函数的导数为:
这里的 δ 为Kronecker delta
Kronecker delta: δi,j=0ifi≠jδi,j=1ifi=j
c那么
α
关于E的梯度:
这里 δℓ 是输入为u的output map对应的 δ map,并且这里的卷积为“vaild convolution”,使得结果的尺寸和 δ map 的尺寸一致,现在可以用chain rule来计算E关于c的梯度:
Enforcing Space Combinations(加强稀疏性组合)
为了使得
α
的分布是稀疏的(e.g:(0.1,0,0…,0,0.9)),也就是使得一个output map不至于和很多的input map相关联,可以在最后的Loss Function中加入regularization penalty(稀疏约束项)
Ω(α)
,这样可以使得一部分权值朝着0方向变化,给出对一张图的error:
只考虑一个输出的情况时:
因为
那么总体上