深度神经网络之反向传播算法

1.DNN反向传播算法简介

回顾我们前面学到的监督问题,通常会遇到这种情况,假如有 m m m个训练样本,分别为 { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) , . . . , ( x m , y m ) } \{(x_1,y_1),(x_2,y_2),(x_3,y_3),...,(x_m,y_m) \} {(x1,y1),(x2,y2),(x3,y3),...,(xm,ym)},其中 x x x为输入变量,特征维度为n_in,y为输出向量,特征维度为n_out。现在我们利用这m个训练样本来训练模型,当有测试样本 ( x t e s t , ? ) (x_{test},?) (xtest,?)时,需要我们能够预测出 y t e s t y_{test} ytest向量的输出。

现在对应到我们的DNN模型之中,即输入层有n_in个神经元,输出层有n_out个神经元,再加上一些含有若干个神经元的隐含层。此时我们需要找到所有隐含层和输出层所对应的线性系数矩阵W、偏倚向量b,希望通过DNN对所有的训练样本计算后,计算结果能够等于或很接近样本输出,当有新的测试样本数据时,能够有效预测样本输出。但怎样找到合适的线形系数矩阵W和偏倚变量b呢?

回顾我们前面学习的机器学习之Logistic回归、机器学习之SVM支持向量机等机器学习算法,很容易联想到,我们可以用一个合适的损失函数来度量训练样本的输出损失。然后对损失函数优化,求损失函数最小化的极值,此时对应的线性系数矩阵W,偏倚变量b便是我们希望得到的结果。深度神经网络中,损失函数优化极值求解的过程,通常是利用梯度下降法迭代完成的。当然也可以利用其他的迭代方法,比如牛顿法或拟牛顿法。梯度下降算法以前在机器学习之线形回归中有过详细介绍,有兴趣可以回顾一下。

对DNN损失函数用梯度下降法进行迭代优化求极小值的过程,便是我们的反向传播算法(Back Propagation,BP)

2.DNN反向传播算法数学推导

进行DNN反向传播算法之前,我们需要选择一个损失函数,来度量计算样本的输出和真实样本之间的损失。但训练时的计算样本输出怎么得到呢?

初始时,我们会随机选择一系列W,b,然后利用神经网络之前向传播算法中介绍到的 a l = σ ( z l ) = σ ( W l a l − 1 + b l ) a^l=\sigma(z^l)=\sigma(W^la^{l-1}+b^l) al=σ(zl)=σ(Wlal1+bl),计算输出层所对应的 a L a^L aL,此时的 a L a^L aL便是DNN计算样本的输出。为专注DNN反向传播算法的推导,我们选择较为简单的损失函数,为此我们使用最常见的均方差来度量损失。

即对于每个样本,我们期望能够最小化下式,其中 a L a^L aL y y y为特征维度的n_out的向量, ∣ ∣ S ∣ ∣ 2 ||S||_2 S2为S的L2范数。
J ( W , b , x , y ) = 1 2 ∣ ∣ a L − y ∣ ∣ 2 2 J(W,b,x,y)=\frac{1}{2}||a^L-y||_{2}^{2} J(W,b,x,y)=21aLy22
通过损失函数,我们能够用梯度下降法来迭代求解每一层的W,b。首先计算的是输出层,其中输出层的W,b满足下式
a L = σ ( z L ) = σ ( W L a L − 1 + b L ) a^L=\sigma(z^L)=\sigma(W^La^{L-1}+b^L) aL=σ(zL)=σ(WLaL1+bL)

J ( W , b , x , y ) = 1 2 ∣ ∣ a L − y ∣ ∣ 2 2 = 1 2 ∣ ∣ σ ( W L a L − 1 + b L ) − y ∣ ∣ 2 2 J(W,b,x,y)=\frac{1}{2}||a^L-y||_{2}^{2}=\frac{1}{2}||\sigma(W^La^{L-1}+b^L)-y||_2^2 J(W,b,x,y)=21aLy22=21σ(WLaL1+bL)y22

然后对 W L , b L W^L,b^L WL,bL分别求偏导,其中符号 ⊙ \odot 表示Hadamard积,对于两个维度的向量 A ( a 1 , a 2 , a 3 , . . . , a n ) T A(a_1,a_2,a_3,...,a_n)^T A(a1,a2,a3,...,an)T B ( b 1 , b 2 , b 3 , . . . , b n ) T B(b_1,b_2,b_3,...,b_n)^T B(b1,b2,b3,...,bn)T,那么 A ⊙ B = ( a 1 b 1 , a 2 b 2 , a 3 b 3 , . . . , a n b n ) T A\odot B=(a_1b_1,a_2b_2,a_3b_3,...,a_nb_n)^T AB=(a1b1,a2b2,a3b3,...,anbn)T。之所以使用Hadamard积,是因为我们不了解激活函数的形式,所以用Hadamard积来乘激活函数的导数。另外补充矩阵求导的知识点,其中 ∂ A B ∂ B = A T \frac{\partial AB}{\partial B}=A^T BAB=AT
∂ J ( W , b , x , y ) ∂ W L = ∂ J ( W , b , x , y ) ∂ z L ∂ z L ∂ W L = ( a L − y ) ⊙ σ ′ ( z L ) ( a L − 1 ) T \frac{\partial J(W,b,x,y)}{\partial W^L}=\frac{\partial J(W,b,x,y)}{\partial z^L}\frac{\partial z^L}{\partial W^L}=(a^L-y)\odot {\sigma}' (z^L)(a^{L-1})^T WLJ(W,b,x,y)=zLJ(W,b,x,y)WLzL=(aLy)σ(zL)(aL1)T

∂ J ( W , b , x , y ) ∂ b L = ∂ J ( W , b , x , y ) ∂ z L ∂ z L ) ∂ b L = ( a L − y ) ⊙ σ ′ ( z L ) \frac{\partial J(W,b,x,y)}{\partial b^L}=\frac{\partial J(W,b,x,y)}{\partial z^L}\frac{\partial z^L)}{\partial b^L}=(a^L-y)\odot {\sigma}' (z^L) bLJ(W,b,x,y)=zLJ(W,b,x,y)bLzL)=(aLy)σ(zL)

注意到在求解输出层W,b的时候,有公共部分 ∂ J ( W , b , x , y ) ∂ z L \frac{\partial J(W,b,x,y)}{\partial z^L} zLJ(W,b,x,y),因此我们可以把公共部分先算出来,记为
δ L = ∂ J ( W , b , x , y ) ∂ z L = ( a L − y ) ⊙ σ ′ ( z L ) \delta^L=\frac{\partial J(W,b,x,y)}{\partial z^L}=(a^L-y)\odot {\sigma}' (z^L) δL=zLJ(W,b,x,y)=(aLy)σ(zL)
现在我们已经把输出层的梯度算出来了,那么如何求解L-1、L-2…层的梯度呢?这里我们需要进一步递推,对于第 l l l层的 δ l \delta^l δl可以表示为
δ l = ∂ J ( W , b , x , y ) ∂ z l = ∂ J ( W , b , x , y ) ∂ z L ∂ z L ∂ z L − 1 ∂ z L − 1 ∂ z L − 2 . . . ∂ z l + 1 ∂ z l \delta^l=\frac{\partial J(W,b,x,y)}{\partial z^l}=\frac{\partial J(W,b,x,y)}{\partial z^L}\frac{\partial z^L}{\partial z^{L-1}} \frac{\partial z^{L-1}}{\partial z^{L-2}}...\frac{\partial z^{l+1}}{\partial z^{l}} δl=zlJ(W,b,x,y)=zLJ(W,b,x,y)zL1zLzL2zL1...zlzl+1
如果我们能够计算出第 l l l层的 δ l \delta^l δl,那么对于该层的 W l , b l W^l,b^l Wl,bl也会很容易计算。为什么呢?注意到前向传播算法,我们有
z l = W l a l − 1 + b l z^l=W^l a^{l-1}+b^l zl=Wlal1+bl
所以根据上式我们可以很方便的计算第 l l l层的 W l , b l W^l,b^l Wl,bl
∂ J ( W , b , x , y ) ∂ W l = ∂ J ( W , b , x , y ) ∂ z l ∂ z l ∂ W l = δ l ( a l − 1 ) T \frac{\partial J(W,b,x,y)}{\partial W^l}=\frac{\partial J(W,b,x,y)}{\partial z^l}\frac{\partial z^l}{\partial W^l}=\delta^l (a^{l-1})^T WlJ(W,b,x,y)=zlJ(W,b,x,y)Wlzl=δl(al1)T

∂ J ( W , b , x , y ) ∂ b l = ∂ J ( W , b , x , y ) ∂ z l ∂ z l ) ∂ b l = δ l \frac{\partial J(W,b,x,y)}{\partial b^l}=\frac{\partial J(W,b,x,y)}{\partial z^l}\frac{\partial z^l)}{\partial b^l}=\delta ^l blJ(W,b,x,y)=zlJ(W,b,x,y)blzl)=δl

现在问题关键便是如何求解 δ l \delta^l δl。假设我们已经得到第 l + 1 l+1 l+1层的 δ l + 1 \delta^{l+1} δl+1,那么如何得到第 l l l层的 δ l \delta^l δl呢?我们注意到
δ l = ∂ J ( W , b , x , y ) ∂ z l = ∂ J ( W , b , x , y ) ∂ z l + 1 ∂ z l + 1 ∂ z l = δ l + 1 ∂ z l + 1 ∂ z l = \delta^l=\frac{\partial J(W,b,x,y)}{\partial z^l}=\frac{\partial J(W,b,x,y)}{\partial z^{l+1}}\frac{\partial z^{l+1}}{\partial z^{l}} =\delta^{l+1} \frac{\partial z^{l+1}}{\partial z^l}= δl=zlJ(W,b,x,y)=zl+1J(W,b,x,y)zlzl+1=δl+1zlzl+1=

∂ ( δ l + 1 ) T z l + 1 ∂ z l = ∂ ( δ l + 1 ) T ( W l + 1 σ ( z l ) + b l + 1 ) ∂ z l = ∂ ( δ l + 1 ) T W l + 1 σ ( z l ) ∂ z l = \frac{\partial (\delta^{l+1})^T z^{l+1}}{\partial z^l}=\frac{\partial (\delta^{l+1})^T (W^{l+1}\sigma(z^l)+ b^{l+1})}{\partial z^l}=\frac{\partial (\delta^{l+1})^T W^{l+1}\sigma(z^l)}{\partial z^l}= zl(δl+1)Tzl+1=zl(δl+1)T(Wl+1σ(zl)+bl+1)=zl(δl+1)TWl+1σ(zl)=

( ( δ l + 1 ) T W l + 1 ) T ⊙ σ ′ ( z l ) = ( W l + 1 ) T δ l + 1 ⊙ σ ′ ( z l ) ((\delta^{l+1})^TW^{l+1})^T\odot {\sigma}' (z^l)=(W^{l+1})^T\delta ^{l+1}\odot {\sigma}' (z^l) ((δl+1)TWl+1)Tσ(zl)=(Wl+1)Tδl+1σ(zl)

现在我们已经得到 δ l \delta^l δl的递推式,只要我们求出当前隐含层的 δ l \delta^l δl,便能够得到 W l , b l W^l,b^l Wl,bl

3.DNN反向传播算法过程

梯度下降算法有批量(Batch),小批量(Mini-Batch),随机三种方式,采用哪种方式取决于我们的问题而定。为简化描述,这里采用最基本的批量梯度下降法来描述反向传播算法。

输入:总层数L、各隐含层与输出层的神经元个数、激活函数、损失函数、迭代步长α、最大迭代次数Max、停止迭代阈值ϵ、输入的m个训练样本 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) {(x_1,y_1),(x_2,y_2),...,(x_m,y_m)} (x1,y1),(x2,y2),...,(xm,ym)

输出:各隐含层与输出层的线性关系系数W和偏倚变量b。

  • 初始化各隐藏层与输出层的线性关系系数矩阵W和偏倚向量b为随机值。
  • f o r   i t e r = 1   t o   M a x for \ iter = 1 \ to\ Max for iter=1 to Max
    • f o r   i   = 1   t o   m for\ i\ = 1 \ to \ m for i =1 to m
      • a 1 a^1 a1输入值设置为 x i x_i xi
      • f o r   l = 2   t o   L for\ l=2 \ to \ L for l=2 to L,进行前向传播算法,计算 a i , l = σ ( z i , l ) = σ ( W l a i , l − 1 + b l ) a^{i,l}=\sigma(z^{i,l})=\sigma(W^l a^{i,l-1}+b^l) ai,l=σ(zi,l)=σ(Wlai,l1+bl)
      • 通过损失函数计算输出层 δ i , L \delta^{i,L} δi,L
      • f o r   l = L   t o   2 for\ l = L\ to\ 2 for l=L to 2,进行反向传播算法,计算 δ i , l = ( W l + 1 ) T δ i , l + 1 ⊙ σ ′ ( z i , l ) \delta^{i,l}=(W^{l+1})^T\delta ^{i,l+1}\odot {\sigma}' (z^{i,l}) δi,l=(Wl+1)Tδi,l+1σ(zi,l)
    • f o r   l = 2   t o   L for \ l =2 \ to\ L for l=2 to L,更新第 l l l层的 W l , b l W^l,b^l Wl,bl
      • W l = W l − α ∑ i = 1 m δ i , l ( a i , l − 1 ) T W^l=W^l-\alpha\sum_{i=1}^{m}\delta^{i,l}(a^{i,l-1})^T Wl=Wlαi=1mδi,l(ai,l1)T
      • b l = b l − α ∑ i = 1 m δ i , l b^l=b^l-\alpha\sum_{i=1}^{m}\delta^{i,l} bl=blαi=1mδi,l
    • 如果所有的W,b的变化值都小于停止迭代阈值ϵ,跳出循环。
  • 输出各隐含层和输出层的线形关系系数矩阵W和偏倚向量b。

通过深度神经网络之中的前向传播算法和反向传播算法的结合,我们能够利用DNN模型去解决各种分类或回归问题,但对于不同问题,效果如何呢?是否会过拟合呢?我们将在下次文章中详细介绍损失函数和激活函数的选择、正则化方面的知识点,来让深度神经网络能更精确的解决我们的问题。

参考

刘建平Pinard_深度神经网络(DNN)反向传播算法(BP)

4.推广

更多内容请关注公众号谓之小一,若有疑问可在公众号后台提问,随时回答,欢迎关注,内容转载请注明出处。
深度神经网络之反向传播算法_第1张图片

你可能感兴趣的:(深度学习)