【深度学习】后向传播(BP)算法
分类:
文章
•
2024-11-12 08:29:22
一、神经网络学习算法的本质
- 当我们搭建好一个神经网络后,无论在什么应用场合,我们的目标都是:将网络的权值和偏置都变成一个最好的值,这个值可以让我们的输入得到理想的输出。
- 可能大家会觉的神经网络架构很非常神秘和复杂,其实任何一个神经网络架构都是一个多层复合的复合函数,我们可以将它们表示为:f(x,w,b),其中x是输入,w是权值,b为偏置。
- 我们的目标就变成了尝试不同的w,b值,使得最后的f(x,w,b)最接近我们的标签y。
- 现在我们需要一个指标来描述接近这个概念,于是产生了损失函数,这里我们将损失函数令为:(f(x,w,b)−y)2=C(w,b),现在问题变成:将最小C(w,b)化。
- 将最小C(w,b)化这个问题,我们能够马上想到使用梯度下降算法。即:
-
第一步:求解梯度 [∂w1∂C(w,b),(∂b1)∂C(w,b),∂w2∂C(w,b),∂b2∂C(w,b)…,(∂wn)∂C(w,b),∂bn∂C(w,b)]=∂[W,b]∂C(w,b)
-
第二步:更新参数:[W,b]=[W,b]−η∂[W,b]∂C(w,b)其中η为步长。
- 不断迭代上面两步直到函数C(w,b)不能再减少
- 这里解释以下梯度的含义:
- 对于任意一个多元函数f(x1,x2,…,xn),它的梯度为: ∇f=[∂x1∂f,∂x2∂f,…,∂xn∂f]
- 梯度的维度与函数变量维度是一样的,它表示如果自变量沿着梯度方向运动,函数f的函数值将增长最快。当然反过来,如果沿着梯度的反方向函数值将减少最快,这也是为啥上面用减号。
- 其中∂xi∂f为函数f对变量xi的偏导数,它的含义是其他变量不变的情况下xi增加1函数值的改变量,即函数相对xi的的变化率。
-
上面推导的过程的总结:网络权值和偏置更新问题⇒f(x,w,b)的结果逼近y⇒C(w,b)=(f(x,w,b)−y)2取极小值问题 ⇒C(w,b)按梯度下降问题⇒取到极小值,网络达到最优
- 一切都是那么顺利,但是我们忘记了上面推导都是基于一个前提:我们已经提前知道损失函数在当前点的梯度。然而事实并非如此
- 这个问题困扰了NN研究者多年,1969年M.Minsky和S.Papert所著的《感知机》一书出版,它对单层神经网络进行了深入分析,并且从数学上证明了这种网络功能有限,甚至不能解决象"异或"这样的简单逻辑运算问题。同时,他们还发现有许多模式是不能用单层网络训练的,而对于多层网络则没有行之有效的低复杂度算法,最后他们甚至认为神经元网络无法处理非线性问题。然而于1974年,Paul Werbos首次给出了如何训练一般网络的学习算法—back propagation(BP)算法。这个算法可以高效的计算每一次迭代过程中的梯度,让以上我们的推导得以实现。不巧的是,在当时整个人工神经网络社群中无人知晓Paul所提出的学习算法。直到80年代中期,BP算法才重新被David Rumelhart、Geoffrey Hinton及Ronald Williams、David Parker和Yann LeCun独立发现,并获得了广泛的注意,引起了神经网络领域研究的第二次热潮。
二、梯度求解的链式法则
- 上面我们已经已经知道了梯度求解的公式: ∇f=[∂x1∂f,∂x2∂f,…,∂xn∂f],并且我们也知道了中间的每个元素是函数对相应变量的偏导数∂xi∂f。我们也知道了偏导数的含义就是:函数相对xi的的变化率。
- 那么我们只要求出函数f对每个变量的变化率,我们就可以求出函数f的梯度,我们使用下面一个例子来说明这个问题。
- 假设有这样一个运算图:可以将其理解为一个简单的神经网络,e为输出层,a,b为输入层,c,d为隐藏层。该网络可以表示为函数:e=f(a,b)=(a+b)∗(b+1)
- 假设输入a=2,b=1,在这种情况下,如果只考虑相邻层的偏导关系,可以得到下图:
- 根据偏导的含义和上图可知:
- 如果如果其他变量不变,a改变1,那么c就会改变1,而c改变1,e就会改变2,所有最后得到:a改变1,e就会改变2,即e相对a的变化率为2,即∂a∂e=2
- 如果如果其他变量不变,b改变1,那么c就会改变1并且d也会改变1,而c改变1,e就会改变2,d改变1,e就会改变3,所有最后得到:b改变1,e就会改变5,即e相对a的变化率为5,∂b∂e=5
- 上面这个过程就是链式法则,最后总结的公式为: ∂a∂e=∂c∂e∗∂a∂c∂b∂e=∂c∂e∗∂b∂c+∂d∂∗∂a∂d由此可知∂a∂e的值等于从a到e的路径上的偏导值的乘积,而∂be的值等于从b到e的路径1(b−c−e)上的偏导值的乘积加上路径2(b−d−e)上的偏导值的乘积。
- 为啥要这样分析呢?最主要的原因是一般的神经网络的深度是较深的,我们直接去求去求某个损失函数对某个参数的偏导是比较困难的,但是求临近层变量之间的偏导数是非常容易的,通过链式法则,我们可以用临近层的偏导数来求解出损失函数对所有参数的偏导数。
三、前向神经网络中链式法则求解梯度
- 图是一个典型的前向神经网络或者叫全链接神经网络:Layer L1是输入层,Layer L2是隐含层,Layer L3是隐含层
- 这一部分使用一个简单例子,来说明一下神经网络中梯度的求解过程,使用下面简单的网络:
- 输入层包含两个神经元i1,i2,和截距项b1;隐含层包含两个神经元h1,h2和截距项b2,输出层包含两个神经元o1,o2,每的权重我为wi,**函为sigmoid函数:sigmoid(x)=1+e−x1导数为:sigmoid(x)=sigmoid(x)(1−sigmoid(x))
- 每个节点的运算关系用o1做为一个例子进行说明一下:
-
o1输入(neto1)为:neto1=outh1∗w5+outh2∗w6+b21
-
o1输出(outo1)为:outo1=sigmoid(neto1)
- 定义损失函数: Etotal=∑21(target−output)2
- 我们需要更新的是权重w和偏置项b来最小化损失函数Etotal,所有我们需要求出的是损失函数对w和b的梯度,即损失函数对每个权重wi和每个偏置项bi的变化率(偏导数)。
- 求损失函数对于隐藏层到输出层的权重和偏置项的偏导数,我们用w5和b21来作为一个例子:
- 求损失函数Etotal相对w5的变化率的思路为:Etotal相对o1输出(outo1)的变化率⇒o1输出相对o1输人(neto1)的变化率⇒o1输人相对w5的变化率。
- 得到链式法则:∂w5∂Etotal=∂outo1∂Etotal∗∂neto1∂outo1∗∂w5∂neto1
- 过程图如下:
- 具体求导(根据每个量的表达式):∂outo1∂Etotal=(targeto1−outo1)∂neto1∂outo1=sigmoid(neto1)(1−sigmoid(neto1))=outo1(1−outo1)∂w5∂neto1=outh1
- 整理公式:∂w5∂Etotal)=(targeto1−outo1)∗outo1(1−outo1)∗outh1将前两项记为:δo1=∂outo1∂Etotal∗∂neto1∂outo1=∂neto1∂Etotal=(targeto1−outo1)∗outo1(1−outo1)δo1表示的是:误差Etotal相对于输入层o1(neto1)的变化率
- 最后公式变为:∂w5∂Etotal=δo1∗outh1
- 我们用同样的方法来分析b21: b_2的改变会影响o1的输入,即neto1,同时neto1的变化必将影响outo1,进一步outo1的变化会影响损失函数Etotal,于是可以得到链式法则:∂b21∂Etotal=∂outo1∂Etotal∗∂neto1∂outo1∗∂b21∂neto1
- 并且:∂b21∂neto1=1
- 所以有:∂b21∂Etotal=∂outo1∂Etotal∗∂neto1∂outo1∗∂b21∂neto1=δo1
- 求损失函数对于输出层到隐藏层的权重和偏置项的偏导数,我们用w1和b11来作为一个例子:
- 方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算损失函数对w5的偏导时,导数传递的路径是:Etotal→outo1→neto1→w5
- 但是计算损失函数对w1的偏导时,导数传递的路径有多条:Etotal→outo1→neto1→outh1→neth1→w1Etotal→outo2→neto2→outh1→neth1→w1
- 如下图所示:
- 由上面的推导可知:Etotal→outo1→neto1=δo1Etotal→outo2→neto2=δo2
- 所以链式法则为:∂w1∂Etotal=(δo1∗∂outh1∂neto1+δo2∗∂outh1∂neto2)∗∂neth1∂outh1∗∂w1∂neth1
- 现在一项一项求:∂outh1∂neto1=w5∂outh1∂neto1=w7∂neth1∂outh1=sigmoid(neth1)(1−sigmoid(neth1))=outh1(1−outh1)∂w1∂neth1)=i1
- 简化公式:δh1=∂neth1∂Etotal=(δo1∗∂outh1∂neto1+δo2∗∂outh1∂neto2)∗∂neth1∂outh1=(δo1∗w5+δo2∗w7)∗outh1(1−outh1)
- 所以最后公式为:∂w1∂Etotal=δh1i1
- 我们用同样的方法来分析b11得到链式法则:∂b1∂Etotal=δh1
- 根据上面的分析我们能求出神经网络上所有权重和偏置项的偏导数,即求出损失函数对整个网络参数的梯度。然后使用梯度下降法就能最小化损失函数,求出最佳网络。这就是神经网络的后向传播算法
四、后向传播算法
- 这一步主要是讲BP算法推广到一般的前向网络(全链接神经网络)当中去,并将公式进行了进一步简化。
- 前向神经网络的一般结构如下:)
- 一些变量:
- 权重wjkl:表示第l−1层的第k个神经元连接到第l层的第j个神经元的权重;
- 偏置项bjl:表示第层l的第个j神经元的偏置;
- 输入zjl:表示第l层的第j个神经元的输入:zjl=k∑wjklakl−1+bjl
- 输出ajl:表示第l层的第j个神经元的输出:ajl=σ(zjl)其中σ为**函数。
- 损失函数:C(w,b)
- 损失函数对对某一层某个神经元输入的偏导δjl:δjl=∂zjl∂C
- 神经网络的最大层数:L
- 后向传播算法的公式:
-
δjL=∂zjL∂C=∂ajl∂C∗σ′(zjL)其中∂ajl∂C是由损失函数的具体形式给出的。
- δjl=(i∑wijl+1δil+1)∗σ′(zjl)
- ∂wjkl∂C=δjl∗ajl−1
- ∂bjl∂C=δjl
- 最后使用梯度下降算法更新权重和偏置项,直到损失函数不能下降,得到最优网络。