深度学习——反向传播(BP)算法

深度学习——反向传播(BP)算法

1、BP算法引入

1.1 网络基本结构

在之前的文章深度学习——神经网络前向传播与反向求导过程中,我们简单的构建了一个简单的神经网络,描述了其前向传播过程和反向求导的过程。之前的描述的网络结构十分简单,仅仅包含一层的输入层,一层的隐藏层和一层的输出层,并且输出层是一个标量的输出。通常情况下,一个完整的神经网络是要包含多层隐藏层的。下面,我们就具体来展示一下。
在这里插入图片描述
上图是具有两层隐藏层的神经网络结构。

提示:在神经网络中,一般情况下,隐藏层的节点数量是不固定的,下面给出一个经验公式来确定隐藏层节点的数量:
h = m + n + a h = \sqrt{m+n}+a h=m+n +a
其中h是隐藏层节点的数量,m是输入节点的数量,n是输出节点的数量,a是一个1~10之间的一个常数。

1.2 网络参数

训练样本集合:
D = { ( X 1 , Y 1 ) , ( X 2 , Y 2 ) , . . . . . . ( X N , Y N ) } D=\{(X_1,Y_1),(X_2,Y_2),......(X_N,Y_N)\} D={(X1,Y1),(X2,Y2),......(XN,YN)}
其中每一个样本 X i X_i Xi包含两个属性,表示为
X i = x 1 x 2 X_i= \begin{matrix} x_1\\ x_2 \end{matrix} Xi=x1x2
其中每一个样本的标签 Y i Y_i Yi包含两个属性,表示为
Y i = y 1 y 2 Y_i= \begin{matrix} y_1\\ y_2 \end{matrix} Yi=y1y2
权重矩阵包括三个,第一个是输入层向第一层隐藏层输入的权重矩阵W,第二个是第一层隐藏层向第二层隐藏层输入的权重矩阵V,第三个是第二层隐藏层向输出层的权重矩阵U。分别表示为:
W = w 11 w 12 w 13 w 21 w 22 w 23 W= \begin{matrix} w_{11} & w_{12} & w_{13} \\ w_{21} & w_{22} & w_{23} \end{matrix} W=w11w21w12w22w13w23
V = v 11 v 12 v 13 v 21 v 22 v 23 v 31 v 32 v 33 V= \begin{matrix} v_{11} & v_{12} & v_{13} \\ v_{21} & v_{22} & v_{23} \\ v_{31} & v_{32} & v_{33} \end{matrix} V=v11v21v31v12v22v32v13v23v33
U = u 11 u 12 u 21 u 22 u 31 u 32 U= \begin{matrix} u_{11} & u_{12}\\ u_{21} & u_{22} \\ u_{31} & u_{32} \end{matrix} U=u11u21u31u12u22u32

1.3 前向传播过程

具体的传播过程,我们已经在之前的文章中提到过,所以,我们在这里仅仅出代码的实现过程。

#encoding=utf-8
import numpy as np
def sigmoid(x):
    return 1/(1+np.exp(-x))
class NetWork:
    def __init__(self,input_dim,hidden1_dim,hidden2_dim,output_dim):
        self.input_dim = input_dim
        self.hidden1_dim = hidden1_dim
        self.hidden2_dim = hidden2_dim
        self.output_dim = output_dim
        self.W = np.random.rand(input_dim,hidden1_dim)
        self.B1 = np.random.rand(hidden1_dim,1)
        self.V = np.random.rand(hidden1_dim,hidden2_dim)
        self.B2 = np.random.rand(hidden2_dim,1)
        self.U = np.random.rand(hidden2_dim,output_dim)
        self.B3 = np.random.rand(output_dim,1)
    def forward(self,X):
        '''注意,这里我们先采用的逐个样本的计算方式,激活方式采用的是sigmoid激活函数'''
        net1 = np.dot(self.W.T,X) + self.B1
        H1 = sigmoid(net1)
        net2 = np.dot(self.V.T,H1) + self.B2
        H2 = sigmoid(net2)
        Y = np.dot(self.U.T,H2) + self.B3
        return net1,net2,H1,H2,Y

其计算的基本公式为:
n e t 1 = W T X + B 1 net_1 = W^TX+B1 net1=WTX+B1
h 1 = s i g m o i d ( n e t 1 ) h_1 = sigmoid(net_1) h1=sigmoid(net1)
n e t 2 = V T h 1 + B 2 net_2 = V^Th_1+B2 net2=VTh1+B2
h 2 = s i g m o i d ( n e t 2 ) h_2 = sigmoid(net_2) h2=sigmoid(net2)
Y = U T h 2 + B 3 Y=U^Th2+B3 Y=UTh2+B3

2 反向传播(BP)算法

2.1 反向传播算法概述

对于一般的前馈神经网络而言,其训练的过程及时不断的调节网络中的权重和偏置项两类参数,前馈型神经网络。前馈神经网络的训练方法主要是反向传播算法,反向传播算法包括正向的输出过程和反向的误差传播过程。正向过程就是我们上面的描述的从输入到输出的前向传播过程。反向误差传播过程则是根据输出值反向逐层调整网络的权重和偏置项。

2.2反向传播算法的过程计算
2.2.1 误差函数的选择

这里我们依然采用的是MSE的误差计算函数,其基本公式为:
J = 1 2 ∗ ∑ i = 1 b ( y r i − y i ) 2 J=\frac{1}{2}*∑_{i=1}^{b}(y_{ri}-y_i)^2 J=21i=1b(yriyi)2
其中labelY共有b个属性, y r i y_{ri} yri表示y的第i个属性的真实值。 y i y_i yi表示第i个属性的预测值。

2.2.2 对于net求导

为了方便展示,我们再次将网络结构图进行展示。
在这里插入图片描述

上面,我们提到了反向传播是一个逐层进行的过程。我首先计算出输出层的误差为:
J = 1 2 ∗ ∑ i = 1 2 ( y r i − y i ) 2 J =\frac{1}{2}*∑_{i=1}^{2}(y_{ri}-y_i)^2 J=21i=12(yriyi)2

  1. 我们先对输出层求导。计算过程为:
    ∂ J ∂ y 1 ∂ J ∂ y 2 = ∂ 1 2 ( y r 1 − y 1 ) + ( y r 2 − y 2 ) δ y 1 δ 1 2 ( y r 1 − y 1 ) + ( y r 2 − y 2 ) δ y 2 = y 1 − y r 1 y 2 − y r 2 \begin{matrix} \frac{∂J}{∂y_{1}}\\ \\ \frac{∂J}{∂y_{2}} \end{matrix}= \begin{matrix} \frac{∂\frac{1}{2}(y_{r1}-y_1)+(y_{r2}-y_2)}{δy_{1}}\\ \\ \frac{δ\frac{1}{2}(y_{r1}-y_1)+(y_{r2}-y_2)}{δy_{2}} \end{matrix}= \begin{matrix} y_1-y_{r1}\\ \\ y_2-y_{r2} \end{matrix} y1Jy2J=δy121(yr1y1)+(yr2y2)δy2δ21(yr1y1)+(yr2y2)=y1yr1y2yr2
    我们将J关于Y的偏导数记为:
    δ y = Y − Y r δ_y=Y-Y_r δy=YYr

  2. 下面我们要计算的是对于 n e t 2 net_2 net2的偏导数, n e t 2 net_2 net2表示的是对于输入到第二隐藏的各个神经单元未激活时的数据。一共包含三个单元, n e t 21 , n e t 22 , n e t 23 net_{21},net_{22},net_{23} net21,net22,net23
    首先计算对于 n e t 21 net_{21} net21的导数值。
    ∂ J ∂ n e t 21 = ∂ J ∂ y 1 ∂ y 1 ∂ h 21 ∂ h 21 ∂ n e t 21 + ∂ J ∂ y 2 ∂ y 2 ∂ h 21 ∂ h 21 ∂ n e t 21 = ∑ i = 1 L ∂ J ∂ y i ∗ U 1 i ∗ h 21 ∗ ( 1 − h 21 ) \frac{∂J}{∂net_{21}}=\frac{∂J}{∂y_{1}}\frac{∂y_1}{∂h_{21}}\frac{∂h_{21}}{∂net_{21}}+\frac{∂J}{∂y_{2}}\frac{∂y_2}{∂h_{21}}\frac{∂h_{21}}{∂net_{21}}=∑_{i=1}^L\frac{∂J}{∂y_{i}}*U_{1i}*h_{21}*(1-h_{21}) net21J=y1Jh21y1net21h21+y2Jh21y2net21h21=i=1LyiJU1ih21(1h21)
    同理可以计算另外两个神经单元:
    ∂ J ∂ n e t 22 = ∂ J ∂ y 1 ∂ y 1 ∂ h 22 ∂ h 22 ∂ n e t 22 + ∂ J ∂ y 2 ∂ y 2 ∂ h 22 ∂ h 22 ∂ n e t 22 = ∑ i = 1 L ∂ J ∂ y i ∗ U 2 i ∗ h 22 ∗ ( 1 − h 22 ) \frac{∂J}{∂net_{22}}=\frac{∂J}{∂y_{1}}\frac{∂y_1}∂{h_{22}}\frac{∂h_{22}}{∂net_{22}}+\frac{∂J}{∂y_{2}}\frac{∂y_2}{∂h_{22}}\frac{∂h_{22}}{∂net_{22}}=∑_{i=1}^L\frac{∂J}{∂y_{i}}*U_{2i}*h_{22}*(1-h_{22}) net22J=y1Jy1h22net22h22+y2Jh22y2net22h22=i=1LyiJU2ih22(1h22)
    ∂ J ∂ n e t 23 = ∂ J ∂ y 1 ∂ y 1 ∂ h 23 ∂ h 21 ∂ n e t 23 + ∂ J ∂ y 2 ∂ y 2 ∂ h 23 ∂ h 23 ∂ n e t 23 = ∑ i = 1 L ∂ J ∂ y i ∗ U 3 i ∗ h 23 ∗ ( 1 − h 23 ) \frac{∂J}{∂net_{23}}=\frac{∂J}{∂y_{1}}\frac{∂y_1}{∂h_{23}}\frac{∂h_{21}}{∂net_{23}}+\frac{∂J}{∂y_{2}}\frac{∂y_2}{∂h_{23}}\frac{∂h_{23}}{∂net_{23}}=∑_{i=1}^L\frac{∂J}{∂y_{i}}*U_{3i}*h_{23}*(1-h_{23}) net23J=y1Jh23y1net23h21+y2Jh23y2net23h23=i=1LyiJU3ih23(1h23)

整理成向量的形式为:
δ n e t 2 = δ J δ n e t 2 = δ J δ n e t 21 δ J δ n e t 22 δ J δ n e t 23 = U T δ Y ∗ h 2 ∗ ( 1 − h 2 ) δ_{net_2}=\frac{δJ}{δnet_2}= \begin{matrix} \frac{δJ}{δnet_{21}}\\ \\ \frac{δJ}{δnet_{22}}\\ \\ \frac{δJ}{δnet_{23}}\\ \\ \end{matrix}= U^Tδ_Y*h_2*(1-h_2) δnet2=δnet2δJ=δnet21δJδnet22δJδnet23δJ=UTδYh2(1h2)
3. 最后我们要计算的是关于 n e t 1 net_1 net1的偏导数。
首先计算对于 n e t 11 net_{11} net11的导数值。
我首先对 n e t 11 net_{11} net11向上的传递过程进行分析。 n e t 11 net_{11} net11通过激活函数生成 h 11 h_{11} h11,然后 h 11 h_{11} h11j将值分别传递给了 h 21 , h 22 , h 23 h_{21},h_{22},h_{23} h21,h22,h23,最后 h 21 , h 22 , h 23 h_{21},h_{22},h_{23} h21,h22,h23又分别将信息传递给了 y 1 , y 2 y_1,y_2 y1,y2。则通过链式法则,我们不难发现有以下几个步骤:

a). 总误差J对 y 1 , y 2 y_1,y_2 y1,y2求导形成误差δY。
b). h 2 h_2 h2层的每个单元分别从 y 1 , y 2 y_1,y_2 y1,y2处获得误差和,求导之后形成 n e t 2 net_2 net2的误差
c}. h 11 h_{11} h11分别从 h 2 h_2 h2层的每一个单元获得误差,求和,计算出总的误差值。
d). 根据 h 11 h_{11} h11获得的误差值,求导,确定了 n e t 11 net_{11} net11的误差值。

我们采用数学方式进行表示:
a) 总误差J对Y求导表示为:
δ y = δ y 1 δ y 2 δy= \begin{matrix} δy_1\\ δy_2 \end{matrix} δy=δy1δy2
b) 形成 Y 到 n e t 2 Y到net_2 Ynet2的误差
δ n e t 2 = δ Y δ n e t 2 δ_{net_2}=\frac{δY}{δnet_2} δnet2=δnet2δY
c) 形成从 n e t 2 net_2 net2 h 11 h_{11} h11的误差:
∑ i = 1 3 n e t 2 i h 11 = V 11 + V 12 + V 13 ∑_{i=1}^3\frac{net_{2i}}{h_{11}}=V_{11}+V_{12}+V_{13} i=13h11net2i=V11+V12+V13
d). 形成从 h 11 h_{11} h11的到 n e t 11 net_{11} net11的误差:
∂ h 11 ∂ n e t 11 = h 11 ∗ ( 1 − h 11 ) \frac{∂h_{11}}{∂net_{11}}=h_{11}*(1-h_{11}) net11h11=h11(1h11)

n e t 12 , n e t 13 net_{12},net_{13} net12,net13的误差传递过程与 n e t 11 net_{11} net11类似,只不过是从 h 12 , h 13 h_{12},h_{13} h12,h13处获取误差值。

我们利用链式法则对于上述的误差传递过程进行总结得到:
δ n e t 1 = ∂ J ∂ n e t 1 = V T δ 2 ∗ h 1 ∗ ( 1 − h 1 ) = ∂ J ∂ n e t 11 ∂ J ∂ n e t 12 ∂ J ∂ n e t 13 δ_{net_1}=\frac{∂J}{∂net_{1}}=V^Tδ_2*h_1*(1-h_1)= \begin{matrix} \frac{∂J}{∂net_{11}}\\ \\ \frac{∂J}{∂net_{12}}\\ \\ \frac{∂J}{∂net_{13}}\\ \end{matrix} δnet1=net1J=VTδ2h1(1h1)=net11Jnet12Jnet13J

其中”*“表示对位相乘,其他表示矩阵相乘。

2.3 总结

我们发现了,对于BP算法的核心,就是对于各个net进行求导计算误差,在这过程中,我们可以发现,对于底层的net的导数,根据链式法则,可以复用高层次的net的导数。那么,为什么要对net求导呢?
我们根据前向传播的公式可以看出,参数W,V,U是和net直接相关的,也就是说,我们在确定了net的导数之后,可以直接确定参数权重的导数。

3、反向传播的权重更新

3.1 计算相关权重的最终梯度
3.1.1 关于U的梯度

[ ∂ J ∂ u 11 , ∂ J ∂ u 12 ] = [ ∂ J ∂ y 1 ∗ ∂ y 1 ∂ u 11 , ∂ J ∂ y 2 ∗ ∂ y 2 ∂ u 12 ] [\frac{∂J}{∂u_{11}},\frac{∂J}{∂u_{12}}]=[\frac{∂J}{∂y_{1}}*\frac{∂y_1}{∂u_{11}},\frac{∂J}{∂y_{2}}*\frac{∂y_2}{∂u_{12}}] [u11J,u12J]=[y1Ju11y1,y2Ju12y2]
[ ∂ J ∂ u 21 , ∂ J ∂ u 22 ] = [ ∂ J ∂ y 1 ∗ ∂ y 1 ∂ u 21 , ∂ J ∂ y 2 ∗ ∂ y 2 ∂ u 22 ] [\frac{∂J}{∂u_{21}},\frac{∂J}{∂u_{22}}]=[\frac{∂J}{∂y_{1}}*\frac{∂y_1}{∂u_{21}},\frac{∂J}{∂y_{2}}*\frac{∂y_2}{∂u_{22}}] [u21J,u22J]=[y1Ju21y1,y2Ju22y2]
[ ∂ J ∂ u 31 , ∂ J ∂ u 32 ] = [ ∂ J ∂ y 1 ∗ ∂ y 1 ∂ u 31 , ∂ J ∂ y 2 ∗ ∂ y 2 ∂ u 32 ] [\frac{∂J}{∂u_{31}},\frac{∂J}{∂u_{32}}]=[\frac{∂J}{∂y_{1}}*\frac{∂y_1}{∂u_{31}},\frac{∂J}{∂y_{2}}*\frac{∂y_2}{∂u_{32}}] [u31J,u32J]=[y1Ju31y1,y2Ju32y2]

整理一下,误差对于权重U的梯度为
∂ J ∂ U = ∂ J ∂ u 11 ∂ J ∂ u 12 ∂ J ∂ u 11 ∂ J ∂ u 12 ∂ J ∂ u 11 ∂ J ∂ u 12 = ∂ J ∂ Y ∗ [ h 2 ∣ ∣ h 2 ] = δ Y ∗ [ h 2 ∣ ∣ h 2 ] \frac{∂J}{∂U}= \begin{matrix} \frac{∂J}{∂u_{11}} & \frac{∂J}{∂u_{12}} \\ \frac{}{} & \frac{}{}\\ \frac{∂J}{∂u_{11}} & \frac{∂J}{∂u_{12}}\\ \frac{}{} & \frac{}{}\\ \frac{∂J}{∂u_{11}} & \frac{∂J}{∂u_{12}} \end{matrix}= \frac{∂J}{∂Y} * [h_2||h_2]=δ_Y*[h2||h2] UJ=u11Ju11Ju11Ju12Ju12Ju12J=YJ[h2h2]=δY[h2h2]
其中 h 2 h_2 h2表示第二个隐藏层的神经单元,具体为:
h 21 h 22 h 23 \begin{matrix} h_{21} \\ h_{22} \\ h_{23} \end{matrix} h21h22h23
下面的 h 1 , X h1,X h1,X类似。

3.1.2 关于V的梯度

根据输入
n e t 2 = V T h 1 + B 2 net_2 = V^Th_1+B2 net2=VTh1+B2

∂ n e t 2 ∂ V 11 = ∂ n e t 21 ∂ V 11 = h 11 ∂ n e t 2 ∂ V 12 = ∂ n e t 22 ∂ V 12 = h 11 ∂ n e t 2 ∂ V 13 = ∂ n e t 23 ∂ V 12 = h 11 \frac{∂net_2}{∂V_{11}}=\frac{∂net_{21}}{∂V_{11}}=h_{11}\\ \frac{}{}\\ \frac{∂net_2}{∂V_{12}}=\frac{∂net_{22}}{∂V_{12}}=h_{11}\\ \frac{}{}\\ \frac{∂net_2}{∂V_{13}}=\frac{∂net_{23}}{∂V_{12}}=h_{11} V11net2=V11net21=h11V12net2=V12net22=h11V13net2=V12net23=h11
同理可以计算 n e t 2 net_2 net2关于V中其他单元的导数。则总误差J对于V的各个元素的偏导数为
∂ J ∂ V = δ n e t 2 ∗ [ h 1 ∣ h 1 ∣ h 1 ] \frac{∂J}{∂V}=δ_{net_2}*[h1|h1|h1] VJ=δnet2[h1h1h1]

3.1.3 关于W的梯度

根据输入:
n e t 1 = W T X + B 1 net_1 = W^TX+B1 net1=WTX+B1
有:
∂ n e t 1 ∂ W 11 = ∂ n e t 11 ∂ W 11 = X 1 ∂ n e t 1 ∂ W 12 = ∂ n e t 12 ∂ W 12 = X 1 ∂ n e t 1 ∂ W 13 = ∂ n e t 13 ∂ W 13 = X 1 \frac{∂net_1}{∂W_{11}}=\frac{∂net_{11}}{∂W_{11}}=X_{1}\\ \frac{}{}\\ \frac{∂net_1}{∂W_{12}}=\frac{∂net_{12}}{∂W_{12}}=X_{1}\\ \frac{}{}\\ \frac{∂net_1}{∂W_{13}}=\frac{∂net_{13}}{∂W_{13}}=X_{1}\\ W11net1=W11net11=X1W12net1=W12net12=X1W13net1=W13net13=X1
同理,可以计算其他W元素的偏导数,则总的误差对于整个W的偏导数为:
∂ J ∂ W = δ n e t 1 T ∗ [ X ∣ X ∣ X ] T \frac{∂J}{∂W}=δ_{net_1}^T*[X|X|X]^T WJ=δnet1T[XXX]T

3.1.4 关于B1,B2,B3的梯度

根据输入 Y = U T h 2 + B 3 Y=U^Th2+B3 Y=UTh2+B3
可以确定:
∂ y 1 ∂ B 31 = 1 ∂ y 2 ∂ B 32 = 1 \begin{matrix} \frac{∂y_1}{∂B_{31}}=1\\ \frac{}{} \\ \frac{∂y_2}{∂B_{32}}=1\\ \end{matrix} B31y1=1B32y2=1
则有:
∂ J B 3 = δ Y \frac{∂J}{B_3}=δ_Y B3J=δY
同理可以计算出关于B2,B1的梯度为 δ n e t 2 , δ n e t 1 δ_{net_2},δ_{net_1} δnet2δnet1

3.2 梯度更新

W n e w = W − α ∂ J ∂ W , B 1 n e w = B 1 − α ∂ J ∂ B 1 W_{new}=W-α\frac{∂J}{∂W},B1_{new}=B1-α\frac{∂J}{∂B1} Wnew=WαWJB1new=B1αB1J
V n e w = V − α ∂ J ∂ V , B 2 n e w = B 2 − α ∂ J ∂ B 2 V_{new}=V-α\frac{∂J}{∂V},B2_{new}=B2-α\frac{∂J}{∂B2} Vnew=VαVJB2new=B2αB2J
U n e w = U − α ∂ J ∂ U , B 3 n e w = B 3 − α ∂ J ∂ B 3 U_{new}=U-α\frac{∂J}{∂U},B3_{new}=B3-α\frac{∂J}{∂B3} Unew=UαUJB3new=B3αB3J
其中α是学习率。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值