《深度学习系列》反向传播算法的公式推导

反向传播算法及其梯度扩散

前言

最近开始认真学习了下反向传播算法和梯度传递的问题,其本质是导数的链式法则的应用,由此可以分析出为什么sigmoid激活函数不适合用于做多层网络的激活函数,可以考虑联系我的另一篇关于激活函数的文章。如有谬误,请联系指正。转载请注明出处。
联系方式:
e-mail: FesianXu@163.com
QQ: 973926198
github: https://github.com/FesianXu
完整代码开源: click me || 其中的sigmoid_base_BP.py


神经网络

要知道什么是反向传播算法,我们还是要从神经网络开始将起。神经网络如图所示。
network

图中所示的是一个具有一个输入层(input layer),一个隐藏层(hidden layer),一个输出层(output layer)的三层神经网络。我们都知道,在神经网络的训练过程中,其权值是通过梯度的变化大小来更新的,我们这里先进行符号规定,以便于接下来的分析。
w j k l w^l_{jk} wjkll-1层的第k个神经元与l层的第j个神经元的连接权值

b j l b^l_{j} bjll层的第j个神经元的偏置。

z j l z^l_{j} zjll层的第j神经元的输入。

a j l a^l_{j} ajll层的第j神经元的激活输出。

用公式表达即是:
(1.1) z j l = ∑ k ( w j k l ∗ a k l − 1 + b j l ) z^l_{j} = \sum_{k} (w^l_{jk}*a^{l-1}_{k}+b^l_j) \tag{1.1} zjl=k(wjklakl1+bjl)(1.1)

(1.2) a j l = σ ( z j l ) = σ ( ∑ k ( w j k l ∗ a k l − 1 + b j l ) ) a^l_j = \sigma(z^l_j) = \sigma(\sum_k (w^l_{jk}*a^{l-1}_k+b^l_j) ) \tag{1.2} ajl=σ(zjl)=σ(k(wjklakl1+bjl))(1.2)

其中的 σ ( x ) \sigma(x) σ(x)为激活函数。多采用sigmoid,ReLU,tanh等。
C = 1 2 n ∗ ∑ x ∣ ∣ y − a L ∣ ∣ 2 C = \frac{1}{2n}*\sum_x||y-a^L||^2 C=2n1xyaL2 代价函数,其中L是神经网络的层数。


我们知道,进行权值更新的时候,我们采用的是梯度下降法更新(Gradient Descent), 公式如下:
(1.3) w j k l : = w j k l − η ∗ ∂ C ∂ w j k l w^l_{jk} := w^l_{jk}-\eta*\frac{\partial{C}}{\partial{w^l_{jk}}} \tag{1.3} wjkl:=wjklηwjklC(1.3)
这里最重要的便是需要求得 ∂ C ∂ w j k l \frac{\partial{C}}{\partial{w^l_{jk}}} wjklC,为了求得这个导数,我们现在有几个公式需要推导,这些公式大多都有链式法则推导而出。


δ L = ∇ a C ⨀ σ ′ ( z L ) \delta^L = \nabla_a{C}\bigodot \sigma^\prime(z^L) δL=aCσ(zL) (对L层的误差)

其中我们要注意的是,对于某层的误差 δ l \delta^l δl定义为 δ l = ∂ C ∂ z l \delta^l = \frac{\partial{C}}{\partial{z^l}} δl=zlC,其中具体到某一个神经元j的误差为 δ j l = ∂ C ∂ z j l \delta^l_j = \frac{\partial{C}}{\partial{z^l_j}} δjl=zjlC

推导:
(2.1) δ j L = ∂ C ∂ z j L = ∂ C ∂ a j L ∗ ∂ a j L ∂ z j L = ∂ C ∂ a j L ∗ σ ′ ( z j L ) \delta^L_j = \frac{\partial{C}}{\partial{z^L_j}} = \frac{\partial{C}}{\partial{a^L_j}}*\frac{\partial{a^L_j}}{\partial{z^L_j}} = \frac{\partial{C}}{\partial{a^L_j}}*\sigma^\prime(z^L_j) \tag{2.1} δjL=zjLC=ajLCzjLajL=ajLCσ(zjL)(2.1)

所以当扩展到对于所有的第L层的神经元时,我们为了方便用一个矩阵去代表我们的结果:
(2.2) δ L = ( δ 1 L δ 2 L ) \delta^L = \left(\begin{array}{c} \delta^L_1 \\ \delta^L_2 \end{array}\right) \tag{2.2} δL=(δ1Lδ2L)(2.2)
需要注意的是,所有的误差矩阵都可以这样定义,如:

(2.3) δ l = ( δ 1 l , δ 2 l , ⋯   , δ n l ) T \delta^l = (\delta^l_1, \delta^l_2, \cdots,\delta^l_n)^T \tag{2.3} δl=(δ1l,δ2l,,δnl)T(2.3)
其中n是l层神经元的数量,类似的,可以得出:

(2.4) σ ′ ( z l ) = ( σ ′ ( z 1 l ) , σ ′ ( z 2 l ) , ⋯   , σ ′ ( z n l ) ) \sigma^\prime(z^l) = (\sigma^\prime(z^l_1),\sigma^\prime(z^l_2),\cdots,\sigma^\prime(z^l_n)) \tag{2.4} σ(zl)=(σ(z1l),σ(z2l),,σ(znl))(2.4)
其中n是第l层的神经元数量
由此可以得出结论:
(2.5) δ L = ∇ a C ⨀ σ ′ ( z L ) \delta^L = \nabla_a{C}\bigodot \sigma^\prime(z^L) \tag{2.5} δL=aCσ(zL)(2.5)
其中, ∇ ( ⋅ ) \nabla(·) ()算子代表了梯度,具体为 ∇ x f ( x ) \nabla_xf(x) xf(x)代表 f ( x ) f(x) f(x) x x x的所有偏导数的矩阵,类似于:
(2.6) ∇ x f ( x ) = ( ∂ f ( x ) ∂ x 1 , ∂ f ( x ) ∂ x 2 , ⋯   , ∂ f ( x ) ∂ x n ) , x ∈ R n \nabla_xf(x) = (\frac{\partial{f(x)}}{\partial{x_1}}, \frac{\partial{f(x)}}{\partial{x_2}}, \cdots, \frac{\partial{f(x)}}{\partial{x_n}}), x \in R^n \tag{2.6} xf(x)=(x1f(x),x2f(x),,xnf(x)),xRn(2.6)
⨀ \bigodot 点乘,表示了两个操作数的各个元素的分别相乘,前提是两个操作数的维度统一。


δ j l = ∑ k ( δ k l + 1 ∗ w k j l + 1 ∗ σ ′ ( z j l ) ) \delta^l_j = \sum_k(\delta^{l+1}_k*w^{l+1}_{kj}*\sigma^\prime(z^l_j)) δjl=k(δkl+1wkjl+1σ(zjl)) 第l层第j个神经元的误差

(3.1) δ j l = ∂ C ∂ z j l = ∑ k ∂ C ∂ z k l + 1 ∗ ∂ z k l + 1 ∂ a j l ∗ ∂ a j l ∂ z j l = ∑ k δ k l + 1 ∗ ∂ ( w k j l + 1 ∗ a j l + b k l + 1 ) ∂ a j l ∗ σ ′ ( z j l ) = ∑ k ( δ k l + 1 ∗ w k j l + 1 ∗ σ ′ ( z j l ) ) \delta^l_j = \frac{\partial{C}}{\partial{z^l_j}} = \sum_k \frac{\partial C}{ \partial z^{l+1}_k} * \frac{ \partial{z^{l+1}_k} }{ \partial{a^l_j} } * \frac{ \partial{a^l_j} }{ \partial{z^l_j} } \\ = \sum_k \delta^{l+1}_k * \frac{ \partial({w^{l+1}_{kj}} * a^l_j+b^{l+1}_k )}{ \partial{a^l_j} } * \sigma^\prime(z^l_j) = \sum_k(\delta^{l+1}_k*w^{l+1}_{kj}*\sigma^\prime(z^l_j)) \tag{3.1} δjl=zjlC=kzkl+1Cajlzkl+1zjlajl=kδkl+1ajl(wkjl+1ajl+bkl+1)σ(zjl)=k(δkl+1wkjl+1σ(zjl))(3.1)

同样的,为了表示方便,也多用矩阵形式表示,有:

(3.2) δ 1 l = δ 1 l + 1 ∗ w 11 l + 1 ∗ σ ′ ( z 1 l ) + δ 2 l + 1 ∗ w 21 l + 1 ∗ σ ′ ( z 1 l ) \delta^l_1 = \delta^{l+1}_1*w^{l+1}_{11}*\sigma^\prime(z^l_1)+ \delta^{l+1}_2*w^{l+1}_{21}*\sigma^\prime(z^l_1) \tag{3.2} δ1l=δ1l+1w11l+1σ(z1l)+δ2l+1w21l+1σ(z1l)(3.2)

(3.3) δ 2 l = δ 1 l + 1 ∗ w 12 l + 1 ∗ σ ′ ( z 2 l ) + δ 2 l + 1 ∗ w 22 l + 1 ∗ σ ′ ( z 2 l ) \delta^l_2 = \delta^{l+1}_1*w^{l+1}_{12}*\sigma^\prime(z^l_2)+ \delta^{l+1}_2*w^{l+1}_{22}*\sigma^\prime(z^l_2) \tag{3.3} δ2l=δ1l+1w12l+1σ(z2l)+δ2l+1w22l+1σ(z2l)(3.3)

(3.4) δ 3 l = δ 1 l + 1 ∗ w 13 l + 1 ∗ σ ′ ( z 3 l ) + δ 2 l + 1 ∗ w 23 l + 1 ∗ σ ′ ( z 3 l ) \delta^l_3 = \delta^{l+1}_1*w^{l+1}_{13}*\sigma^\prime(z^l_3)+ \delta^{l+1}_2*w^{l+1}_{23}*\sigma^\prime(z^l_3) \tag{3.4} δ3l=δ1l+1w13l+1σ(z3l)+δ2l+1w23l+1σ(z3l)(3.4)

(3.5) δ 4 l = δ 1 l + 1 ∗ w 14 l + 1 ∗ σ ′ ( z 4 l ) + δ 2 l + 1 ∗ w 24 l + 1 ∗ σ ′ ( z 4 l ) \delta^l_4 = \delta^{l+1}_1*w^{l+1}_{14}*\sigma^\prime(z^l_4)+ \delta^{l+1}_2*w^{l+1}_{24}*\sigma^\prime(z^l_4) \tag{3.5} δ4l=δ1l+1w14l+1σ(z4l)+δ2l+1w24l+1σ(z4l)(3.5)

(3.6) W l + 1 = ( w 11 l + 1 w 12 l + 1 w 13 l + 1 w 14 l + 1 w 21 l + 1 w 22 l + 1 w 23 l + 1 w 24 l + 1 ) W^{l+1} = \left(\begin{array}{ccc} w^{l+1}_{11} & w^{l+1}_{12} & w^{l+1}_{13} & w^{l+1}_{14}\\ w^{l+1}_{21} & w^{l+1}_{22} & w^{l+1}_{23} & w^{l+1}_{24} \end{array}\right) \tag{3.6} Wl+1=(w11l+1w21l+1w12l+1w22l+1w13l+1w23l+1w14l+1w24l+1)(3.6)

所以,有:
(3.7) δ l = ( ( W l + 1 ) T ∗ δ l + 1 ) ⨀ σ ′ ( z l ) \delta^l = ((W^{l+1})^T * \delta^{l+1}) \bigodot \sigma^\prime(z^l) \tag{3.7} δl=((Wl+1)Tδl+1)σ(zl)(3.7)


∂ C ∂ w j k l = a k l − 1 ∗ δ j l \frac{\partial{C}}{\partial{w^l_{jk}}} = a^{l-1}_k*\delta^l_j wjklC=akl1δjl 误差具体到对某个边权重的偏导数

(4.1) ∂ C ∂ w j k l = ∂ C ∂ z j l ∗ ∂ z j l ∂ w j k l = a k l − 1 ∗ δ j l = a k l − 1 ∗ ∑ k ( δ k l + 1 ∗ w k j l + 1 ∗ σ ′ ( z j l ) ) \frac{\partial{C}}{\partial{w^l_{jk}}} = \frac{\partial{C}}{\partial{z^l_{j}}} * \frac{\partial{z^l_j}}{\partial{w^l_{jk}}} = a^{l-1}_k*\delta^l_j=a^{l-1}_k * \sum_k(\delta^{l+1}_k*w^{l+1}_{kj}*\sigma^\prime(z^l_j)) \tag{4.1} wjklC=zjlCwjklzjl=akl1δjl=akl1k(δkl+1wkjl+1σ(zjl))(4.1)

由此可以看出, ∂ C ∂ w j k l \frac{\partial{C}}{\partial{w^l_{jk}}} wjklC σ ′ ( z j l ) \sigma^\prime(z^l_j) σ(zjl)呈正相关的关系,当激活函数采用了sigmoid函数时,由于x越大,其导数呈现指数衰减,所以在层数太大而且输出值范围太大的时候, ∂ C ∂ w j k l \frac{\partial{C}}{\partial{w^l_{jk}}} wjklC就会变得很小,从而使得参数的更新速率变得很慢,因此会出现梯度消散的问题(The problem of gradient vanishing)。
此时,可以考虑替换代价函数或者激活函数,对于更换激活函数,可以更换为ReLU(Rectified Linear Units)函数, R e L U = m a x ( 0 , x ) ReLU = max(0, x) ReLU=max(0,x)其导数为分段导数,在激活区 x > 0 x > 0 x>0时,其导数恒为1,不会存在梯度消散的问题。


∂ C ∂ b j l = δ j l \frac{\partial{C}}{\partial{b^l_j}} = \delta^l_j bjlC=δjl 误差对偏置的导数

(5.1) ∂ C ∂ b j l = ∂ C ∂ z j l ∗ ∂ z j l ∂ b j l = δ j l ∗ 1 = δ j l \frac{\partial{C}}{\partial{b^l_j}} = \frac{\partial{C}}{\partial{z^l_j}} * \frac{\partial{z^l_j}}{\partial{b^l_j}} = \delta^l_j*1 = \delta^l_j \tag{5.1} bjlC=zjlCbjlzjl=δjl1=δjl(5.1)


总的更新公式

(6.1) w l : = w l − η ∗ δ l ∗ ( a l − 1 ) T w^l := w^l-\eta*\delta^l*(a^{l-1})^T \tag{6.1} wl:=wlηδl(al1)T(6.1)

(6.2) b l : = b l − η ∗ δ l b^l := b^l-\eta*\delta^l \tag{6.2} bl:=blηδl(6.2)


我们在这篇文章中推导了BP算法的公式,我们接下来将在下一篇文章《基于numpy和python的反向传播算法的实现与分析》中利用numpy和python实现BP算法,有兴趣的朋友请移步。

引用

  1. 《基于numpy和python的反向传播算法的实现与分析》
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FesianXu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值