2.4 误差反向传播算法的本质
误差反向传播(error BackPropagation)的提出主要就是用来解决神经网络中参数偏导的计算。
它主要分为两个步骤:
(1)计算所有参数的偏导,这是反向传播主要解决的问题。
(2)利用偏导信息(梯度)或者更高阶的信息(如海森矩阵)更新参数。既然浅层参数的偏导依赖于深层参数的结果,那么我们不再对参数偏导的计算做独立的估计。一个典型的前馈神经网络如图2.4,{1,2,3,i}表示输入层,{4,5,6,j}表示隐层,{7,8,9,k}表示输出层,见图2.4。
图2.4 简单神经网络示意
当使用输入获得输出时,就是信息前向传播。我们用I表示输入向量,Ii表示输入层的第i个神经元,H表示隐层向量,Hj表示隐层的第j个神经元,连接权重wij就是输入层的第i个神经元到隐层第j个神经元的权重,连接权重wjk就是隐层的第i个神经元到输出层第j个神经元的权重,我们可以将两种权重收缩到两个矩阵中,矩阵W的元素为wij,矩阵M的元素为wjk,先假设不使用激活函数,就有关系:
其中,我们用来bH表示加到隐层上的偏置,同理,输出层的第k个神经元表示为Ok,它与隐层的关系也有:
当我们获得了输出之后,损失就是输出向量O与实际向量t的函数:
此时我们在使用输入信息获得输出,这一过程被称为信息的前向传播。我们首先来求矩阵M的参数偏导,因为损失函数作为输出值和真实值的函数,其中输出值又是权重系数的函数,根据式(2.17),偏导可以写作:
它由两部分组成,我们把损失对输出的偏导这一项做一个简单的记号,表示输出层O的误差(error):
误差其实就代表着这一层神经元对于损失的贡献程度,它是一个包含k个元素的向量表示第k个神经元的误差。输出层的误差只与损失函数的形式有关,在神经网络的历史上,我们曾经将分类任务的损失函数由均方误差替换为交叉熵,就是出于误差的考虑,我们会在第4章详细讨论。同时,我们也可以将输出层对于参数矩阵的偏导,它属于向量对矩阵求导,结果是一个三阶张量,见定义2.4,注意到M是一个j行k列的矩阵,但我们可以固定矩阵M的第j行来直观观察第k个输出单元偏导:
在上式中,其他权重均不与Ok相连,均为零。只有处于对角元上,它等于:
这说明了,第k个输出单元对于权重系数ωij的偏导就是隐层第j个单元的输出。同理,我们可以依次求出不同的隐藏单元下的第k个输出单元的偏导:
定义2.4(向量对矩阵求导) 假设向量A由矩阵M和向量B相乘得到:
向量A的每一个元素ai都是矩阵M每一个元素mij的函数,那么就可以定义向量A对于矩阵M的导数矩阵:
它本质上是一个三阶张量,之所以只讲解向量对矩阵的求导,这样对于初学者更容易拓展,如果是矩阵对矩阵求导,那么我们会得到一个四阶张量,如果是向量对向量求导,就会得到一个二阶张量,也是平常的矩阵。
同时,我们也可以求出不同的输出单元对于权重的偏导:
所以,我们同时变换j和k,将上述两项乘起来,最终的结果就可以写为一个矩阵:
上述的矩阵的每一个元素都对应着每一个ωjk的偏导,上式的含义是,损失函数对隐层到输出层的权重(ωjk)的偏导等于所有与输出(Ok)单元相关联的隐层的输出(Hj)与该输出单元提供的误差的乘积。
我们完成了误差反向传播算法中对于初学者最难的部分,但此时我们还未接触到误差反向传播的本质。如果我们对输入到隐层的参数W进行更新,根据式(2.17),就会得到:
其中,第一项在上面已经计算过,就是输出层的误差。而第二项是输出层向量对于隐层向量的偏导,根据定义2.4,结果是一个二阶张量,实际上就是我们的参数矩阵M:
同样的,我们定义隐层的误差为:
此时我们得到了误差反向传播的真正含义,浅层的误差通过深层的误差传递过来,并参与到该层的权重偏导求解中。基于反向传播的神经网络的训练就是围绕如何最大可能的传递该误差这一问题来进行的。它的高效性就体现在,我们利用链式法则需要计算复合函数嵌套的每一步的链,而不少的链是重复的,反向传播算法传递了误差到每一层上,我们只需要看与该层误差直接相关的参数。
式(2.26)的第3项隐层对输入层的偏导,可以类比于上述的输出层对隐层的求导得出,最终我们对参数W的偏导为:
当我们得到参数偏导之后,就代表着误差反向传播算法的第一阶段完成,接着,第二阶段就是使用偏导来更新参数,例如梯度下降:
我们也可以利用基于梯度的优化算法来进行更新参数,见第3章。
在完整的理解误差反向传播算法之后,我们来使用激活函数f,此时,隐层上激活函数的添加更为容易理解,只是在计算参数偏导上多嵌套了一层复合函数的求导,从而区分了隐层的输入H和输出f(H):
其中就是激活函数对于输入的一阶导,记为f',误差传递也变为了:
上式是前馈神经难以训练的一个重要原因,参数的更新依赖于参数偏导的计算,偏导的计算需要得到每一层的误差,但是在误差传递的过程中,激活函数的一阶导小于1(f'<1),那么误差会在传递过程中逐渐减小,浅层的参数就无法得到更新,甚至激活函数的一阶导数趋于零,使得浅层传递而来的误差直接为零,我们称这一现象为梯度消失,将会在第4章详细讨论。