系列博客是博主学习神经网络中相关的笔记和一些个人理解,仅为作者记录笔记之用,不免有很多细节不对之处。
DNN基本计算流程
1、 首先计算输出层的 δL δ L :
δL=∂C∂aL⊙σ′(zL)(BP1) (BP1) δ L = ∂ C ∂ a L ⊙ σ ′ ( z L )
注:若输出函数采用 softmax 函数
aLj=ezLj/∑kezLk a j L = e z j L / ∑ k e z k L ,则对应的交叉熵函数选择
C=−∑kykln(aLk) C = − ∑ k y k ln ( a k L )
若输出函数采用 sigmoid 函数 aLj=1/(1+e−zLj) a j L = 1 / ( 1 + e − z j L ) ,则对应的交叉熵函数选择 C=−∑k[ykln(aLk)+(1−yk)ln(1−aLk)] C = − ∑ k [ y k ln ( a k L ) + ( 1 − y k ) ln ( 1 − a k L ) ]
2、 利用链式法则,由 δl+1 δ l + 1 可一步一步推出 δl δ l ,其表达式为
δl=(Wl+1)Tδl+1⊙σ′(zl)(BP2) (BP2) δ l = ( W l + 1 ) T δ l + 1 ⊙ σ ′ ( z l )
注:解决梯度弥散问题:ReLU激活函数,
σ(z)=max(0,z) σ ( z ) = max ( 0 , z ) ,其导数为
σ(z)=max(0,z)/z σ ( z ) = max ( 0 , z ) / z
3、 由 δl δ l 计算出 W W 和 b b 的梯度表达式
∂C∂W=δl(al−1)T(BP3) (BP3) ∂ C ∂ W = δ l ( a l − 1 ) T
∂C∂b=δl(BP4) (BP4) ∂ C ∂ b = δ l
4、 模型更新:
W←W−η∂C∂W W ← W − η ∂ C ∂ W
b←b−η∂C∂b b ← b − η ∂ C ∂ b
注:M小批量随机梯度下降法+L2规则化缓解过拟合
W←(1−ηλn)W−ηm∑x∂Cx∂W,b←b−ηm∑x∂Cx∂b W ← ( 1 − η λ n ) W − η m ∑ x ∂ C x ∂ W , b ← b − η m ∑ x ∂ C x ∂ b
卷积神经网络的反向传播算法
1、全连接到池化层的反向传播
池化层是没有激活函数的,但是我们可以令池化层的激活函数 σ(z)=z σ ( z ) = z , 那么它的导数为 1。现假设 δl+1 δ l + 1 为全连接层的误差敏感项, δl δ l 是池化层的误差敏感项,由公式(BP2)有
δl=(Wl+1)Tδl+1 δ l = ( W l + 1 ) T δ l + 1
2、池化层到卷积层的反向传播
池化层对输入数据进行了一定的压缩处理(这里假设每个小区域不重复,即输入矩阵 N×N N × N , 池化矩阵大小 k×k k × k ,则输出矩阵为 (N/k)×(N/k) ( N / k ) × ( N / k ) ),池化的两种常见方式如下图所示
Mean-pooling将每个小区域内的平均值作为池化结果;Max-pooling将每个小区域内的最大值作为池化结果
在误差反向传播过程中要对数据做逆向降采样。现假设 δl+1 δ l + 1 为池化层的误差敏感项, δl δ l 是卷积层的误差敏感项,那么有
δl=upsample(δl+1)⊙σ′(zl) δ l = u p s a m p l e ( δ l + 1 ) ⊙ σ ′ ( z l )
对于mean-pooling, upsample 函数将池化层的结果平均分配至原有小区域内;对于max-pooling, upsample 函数将池化层的结果放置于原最大值的位置,其余位置为0 (在池化的正向计算过程中需记录每个小区域内最大值的位置)。下面是一个upsample的例子:
3、卷积层到上一层的反向传播
卷积层向上一层的误差反传方式与BP神经网络是不一样的,但是其思路仍旧是一样的。咱们先从正向传播开始,逐步推导出其反向传播算法(为简单起见,卷积核的移动步幅stride设置为1)。
假设 al a l 是第 l l 层的输出, zl+1 z l + 1 是第 l+1 l + 1 层的输入,则卷积层的输入为,有
⎛⎝⎜⎜al11al21al31al12al22al32al13al23al33⎞⎠⎟⎟∗(wl+111wl+121wl+112wl+122)=(zl+111zl+121zl+112zl+122) ( a 11 l a 12 l a 13 l a 21 l a 22 l a 23 l a 31 l a 32 l a 33 l ) ∗ ( w 11 l + 1 w 12 l + 1 w 21 l + 1 w 22 l + 1 ) = ( z 11 l + 1 z 12 l + 1 z 21 l + 1 z 22 l + 1 )
利用卷积的定义(
W W 先进行左右和上下翻转,再相乘求和),很容易得出:
zl+111=al11wl+122+al12wl+121+al21wl+112+al22wl+111zl+112=al12wl+122+al13wl+121+al22wl+112+al23wl+111zl+121=al21wl+122+al22wl+121+al31wl+112+al32wl+111zl+122=al22wl+122+al23wl+121+al32wl+112+al33wl+111 z 11 l + 1 = a 11 l w 22 l + 1 + a 12 l w 21 l + 1 + a 21 l w 12 l + 1 + a 22 l w 11 l + 1 z 12 l + 1 = a 12 l w 22 l + 1 + a 13 l w 21 l + 1 + a 22 l w 12 l + 1 + a 23 l w 11 l + 1 z 21 l + 1 = a 21 l w 22 l + 1 + a 22 l w 21 l + 1 + a 31 l w 12 l + 1 + a 32 l w 11 l + 1 z 22 l + 1 = a 22 l w 22 l + 1 + a 23 l w 21 l + 1 + a 32 l w 12 l + 1 + a 33 l w 11 l + 1
上式可由MATLAB中卷积函数的’valid’模式计算得出:
zl+1=conv2(al,Wl+1,′valid′) z l + 1 = c o n v 2 ( a l , W l + 1 , ′ v a l i d ′ ) 。为了方便推导,我们希望借助MATLAB的符号计算功能,但是 conv (conv2,convn)函数并不适用于符号计算。咱们自己先写一个可以进行符号计算的卷积函数 symconv
function z = symconv(a,k)
syms zero real
k = rot90(k,2);
[hw,ww] = size(k);
[ha,wa] = size(a);
h = ha - hw + 1;
w = wa - ww + 1;
for in = 1:h
for im = 1:w
z(in,im) = zero;
for jn = 1:hw
for jm = 1:ww
z(in,im) = z(in,im)+a(in+jn-1,im+jm-1)*k(jn,jm);
end
end
end
end
z = z - zero;
end
下面是计算 z z 的脚本:
syms a11 a12 a13 a21 a22 a23 a31 a32 a33 real
syms w11 w12 w21 w22 real
syms z11 z12 z21 z22 real
syms d11 d12 d21 d22 real
a = [a11 a12 a13; a21 a22 a23; a31 a32 a33];
d = [d11 d12; d21 d22];
w = [w11 w12; w21 w22];
z = symconv(a,w);
这样,我们就可以随意对 aij a i j 或者 wij w i j 进行求导了(本节大部分推导利用了这些代码),如下
diff(z,a11);
diff(z,w11);
接着卷积层的误差敏感项 δl δ l ,由链式法则
δlij=∂C∂zlij=(∑mn∂C∂zl+1mn∂zl+1mn∂alij)∂alij∂zlij δ i j l = ∂ C ∂ z i j l = ( ∑ m n ∂ C ∂ z m n l + 1 ∂ z m n l + 1 ∂ a i j l ) ∂ a i j l ∂ z i j l
对于这个例子,可以把上式改写为
δlij=∂C∂zlij=(δl+1⊙∂zl+1∂alij)∗[1111]σ′(zlij) δ i j l = ∂ C ∂ z i j l = ( δ l + 1 ⊙ ∂ z l + 1 ∂ a i j l ) ∗ [ 1 1 1 1 ] σ ′ ( z i j l )
那么
δl11=(δl+111wl+122000)∗[1111]σ′(zl11)=(000δl+111)∗(wl+122000)σ′(zl11) δ 11 l = ( δ 11 l + 1 w 22 l + 1 0 0 0 ) ∗ [ 1 1 1 1 ] σ ′ ( z 11 l ) = ( 0 0 0 δ 11 l + 1 ) ∗ ( w 22 l + 1 0 0 0 ) σ ′ ( z 11 l )
δl12=(δl+111wl+1210δl+112wl+1220)∗[1111]σ′(zl12)=(0δl+1110δl+112)∗(wl+1220wl+1210)σ′(zl12) δ 12 l = ( δ 11 l + 1 w 21 l + 1 δ 12 l + 1 w 22 l + 1 0 0 ) ∗ [ 1 1 1 1 ] σ ′ ( z 12 l ) = ( 0 0 δ 11 l + 1 δ 12 l + 1 ) ∗ ( w 22 l + 1 w 21 l + 1 0 0 ) σ ′ ( z 12 l )
δl13=(00δl+112wl+1210)∗[1111]σ′(zl13)=(0δl+11200)∗(00wl+1210)σ′(zl13) δ 13 l = ( 0 δ 12 l + 1 w 21 l + 1 0 0 ) ∗ [ 1 1 1 1 ] σ ′ ( z 13 l ) = ( 0 0 δ 12 l + 1 0 ) ∗ ( 0 w 21 l + 1 0 0 ) σ ′ ( z 13 l )
δl22=(δl+111wl+111δl+121wl+121δl+112wl+112δl+122wl+122)∗[1111]σ′(zl13)=(δl+111δl+112δl+112δl+122)∗(wl+122wl+112wl+121wl+111)σ′(zl22) δ 22 l = ( δ 11 l + 1 w 11 l + 1 δ 12 l + 1 w 12 l + 1 δ 21 l + 1 w 21 l + 1 δ 22 l + 1 w 22 l + 1 ) ∗ [ 1 1 1 1 ] σ ′ ( z 13 l ) = ( δ 11 l + 1 δ 12 l + 1 δ 12 l + 1 δ 22 l + 1 ) ∗ ( w 22 l + 1 w 21 l + 1 w 12 l + 1 w 11 l + 1 ) σ ′ ( z 22 l )
其他几个不再列举了,仔细观察,可以发现
δl11 δ 11 l 中的
(wl+122000) ( w 22 l + 1 0 0 0 ) 可以写为
(wl+122wl+112wl+121wl+111) ( w 22 l + 1 w 21 l + 1 w 12 l + 1 w 11 l + 1 ) ,
δl12,δl13 δ 12 l , δ 13 l 也可以这么处理,那么
δl=⎛⎝⎜⎜⎜⎜00000δl+111δl+11200δl+112δl+12200000⎞⎠⎟⎟⎟⎟∗(wl+122wl+112wl+121wl+111)σ‘(zl)=padding(δl+1)∗rot90(Wl+1,2) δ l = ( 0 0 0 0 0 δ 11 l + 1 δ 12 l + 1 0 0 δ 12 l + 1 δ 22 l + 1 0 0 0 0 0 ) ∗ ( w 22 l + 1 w 21 l + 1 w 12 l + 1 w 11 l + 1 ) σ ‘ ( z l ) = p a d d i n g ( δ l + 1 ) ∗ r o t 90 ( W l + 1 , 2 )
在MATLAB中,上式可以用卷积函数的’full’模式计算:
δl=conv2(δl+1,rot90(W,2),′full′) δ l = c o n v 2 ( δ l + 1 , r o t 90 ( W , 2 ) , ′ f u l l ′ )
4、卷积层 W W 和 b b 的梯度
下面看看 W W 的梯度表达式
∂C∂Wlij=∑mn∂C∂zlmn∂zlmn∂Wlij ∂ C ∂ W i j l = ∑ m n ∂ C ∂ z m n l ∂ z m n l ∂ W i j l
那么有:
∂C∂Wl11=(al−133al−123al−132al−122)∗(δl11δl21δl12δl22),∂C∂Wl12=(al−132al−122al−131al−121)∗(δl11δl21δl12δl22) ∂ C ∂ W 11 l = ( a 33 l − 1 a 32 l − 1 a 23 l − 1 a 22 l − 1 ) ∗ ( δ 11 l δ 12 l δ 21 l δ 22 l ) , ∂ C ∂ W 12 l = ( a 32 l − 1 a 31 l − 1 a 22 l − 1 a 21 l − 1 ) ∗ ( δ 11 l δ 12 l δ 21 l δ 22 l )
∂C∂Wl21=(al−123al−113al−122al−112)∗(δl11δl21δl12δl22),∂C∂Wl22=(al−122al−112al−121al−111)∗(δl11δl21δl12δl22) ∂ C ∂ W 21 l = ( a 23 l − 1 a 22 l − 1 a 13 l − 1 a 12 l − 1 ) ∗ ( δ 11 l δ 12 l δ 21 l δ 22 l ) , ∂ C ∂ W 22 l = ( a 22 l − 1 a 21 l − 1 a 12 l − 1 a 11 l − 1 ) ∗ ( δ 11 l δ 12 l δ 21 l δ 22 l )
如果,我们把上面四个式子的
al−1ij a i j l − 1 ,排列起来并去掉重复的元素,得到的刚好是
rot90(al−1,2) r o t 90 ( a l − 1 , 2 ) ,那么有
∂C∂Wl=δl∗rot90(al−1,2) ∂ C ∂ W l = δ l ∗ r o t 90 ( a l − 1 , 2 )
在MATLAB中的实现为
∂C∂Wl=conv2(δl,rot90(al−1,2),′valid′) ∂ C ∂ W l = c o n v 2 ( δ l , r o t 90 ( a l − 1 , 2 ) , ′ v a l i d ′ )
对于偏执 b b 的梯度表达式,由于 δ δ 是张量,而 b b 只是一个标量(如果 δ δ 是三维张量, 则 b b 是一个向量),不能像DNN那样, b b 直接与 δ δ 相同。通常的做法(UFLDL Tutorial)是将 δ δ 的各个子矩阵的项分别求和,得到一个误差向量,即 b b 的梯度为:
∂C∂bl=∑mnδlmn ∂ C ∂ b l = ∑ m n δ m n l
但是,为什么是和,而不是平均值呢? 一般的解释是,因为
b b 影响了所有的输出神经元,所以把所有的误差加起来。但是我认为平均值更合理些(个人愚见):
∂C∂bl=mean(∑mnδlmn) ∂ C ∂ b l = m e a n ( ∑ m n δ m n l )
在常规BP网络,
∂C∂bl=(∂C∂bl1∂C∂bl2…∂C∂bln)T=(δl1δl2…δln)T ∂ C ∂ b l = ( ∂ C ∂ b 1 l ∂ C ∂ b 2 l … ∂ C ∂ b n l ) T = ( δ 1 l δ 2 l … δ n l ) T ,假如,我们也共享偏置,那么应该有
∂C∂bl=(∂C∂bl∂C∂bl…∂C∂bl)T=(δl1δl2…δln)T ∂ C ∂ b l = ( ∂ C ∂ b l ∂ C ∂ b l … ∂ C ∂ b l ) T = ( δ 1 l δ 2 l … δ n l ) T ,显然
∂C∂bl=mean(δl) ∂ C ∂ b l = m e a n ( δ l ) 会更合理。
5、卷积神经网络反向传播算法总结
下面,我们以最基本的批量随机梯度下降法对卷积神经网络的的反向传播算法做一个简单的总结:
需要确定参数有:
- 小批量数据的大小 m m
- CNN模型的层数 L L 和所有隐藏层的类型
- 对于卷积层,要定义卷积核的大小 k k ,卷积核子矩阵的维度 d d ,填充大小 p p ,步幅 s s
- 对于池化层,要定义池化区域大小 h h 和池化标准(max 或者 mean)
- 对于全连接层,要定义全连接层的激活函数和各层的神经元个数
- 对于输出层,要定义输出函数和代价函数,多分类任务一般采用 softmax 函数和交叉熵代价函数
- 超参数:学习速率 η η , 最大迭代次数 max_iter, 和停止条件 ϵ ϵ
- ……
计算步骤
1. 初始化每个隐含层的 W,b W , b 的值为随机数
2. 正向传播
2.1).将输入数据 x x 赋值于输入神经元 a1,a1=x a 1 , a 1 = x
2.2).从第二层开始,根据下面3种情况进行前向传播计算:
- 如果当前是全连接层:则有 al=σ(zl)=σ(Wlal−1+bl) a l = σ ( z l ) = σ ( W l a l − 1 + b l )
- 如果当前是卷积层:则有 al=σ(zl)=σ(Wl∗al−1+bl) a l = σ ( z l ) = σ ( W l ∗ a l − 1 + b l )
- 如果当前是池化层:则有 al=pool(al−1) a l = pool ( a l − 1 )
2.3).对于输出层第
L L 层,计算输出
aL=softmax(zl)=softmax(Wlal−1+bl) a L = softmax ( z l ) = softmax ( W l a l − 1 + b l )
3. 反向传播
3.1).通过损失函数计算输出层的 δL δ L
3.2).从倒数第二层开始,根据下面3种情况逐层进行反向传播计算:
- 如果当前是全连接层:则有 δl=(Wl+1)Tδl+1⊙σ′(zl) δ l = ( W l + 1 ) T δ l + 1 ⊙ σ ′ ( z l )
- 如果上层是卷积层:则有 δl=δl+1∗rot180(Wl+1)⊙σ′(zl) δ l = δ l + 1 ∗ rot180 ( W l + 1 ) ⊙ σ ′ ( z l )
- 如果上层是池化层:则有 δl=upsample(δl+1) δ l = upsample ( δ l + 1 ) 。
4. 根据以下两种情况进行模型更新:
4.1).如果当前是全连接层:
Wl=Wl−ηm∑[δl(al−1)T] W l = W l − η m ∑ [ δ l ( a l − 1 ) T ]
bl=bl−ηm∑(δl) b l = b l − η m ∑ ( δ l )
4.2).如果当前是卷积层,对于每一个卷积核有:
Wl=Wl−ηm∑[δl∗rot90(al−1,2)] W l = W l − η m ∑ [ δ l ∗ rot90 ( a l − 1 , 2 ) ]
bl=bl−ηm∑[mean(δl)] b l = b l − η m ∑ [ mean ( δ l ) ]