反向传播
有关……
- 计算机科学>
反向传播,是“误差反向传播”的缩写,是一种用于监督学习的算法<一个href="//www.parkandroid.com/wiki/artificial-neural-network/" class="wiki_link" title="人工神经网络"t一个rget="_blank">人工神经网络一个>使用<一个href="//www.parkandroid.com/wiki/gradient-descent/" class="wiki_link" title="梯度下降法"t一个rget="_blank">梯度下降法一个>.给定一个人工神经网络和一个<一个href="//www.parkandroid.com/wiki/artificial-neural-network/" class="wiki_link" title="误差函数"t一个rget="_blank">误差函数一个>,该方法计算误差函数相对于神经网络权重的梯度。它将感知器的delta规则推广到多层前馈神经网络。
名称中的“向后”部分源于这样一个事实,即梯度的计算在网络中向后进行,首先计算最后一层权重的梯度,最后计算第一层权重的梯度。一层梯度的部分计算在前一层的梯度计算中被重用。这种误差信息的反向流动允许有效地计算每一层的梯度,而不是单独计算每一层梯度的简单方法。
由于深度神经网络在图像识别和语音识别方面的广泛采用,反向传播的受欢迎程度最近有所回升。它被认为是一种高效的算法,现代实现利用专门的gpu来进一步提高性能。
历史
反向传播是在20世纪70年代发明的,作为一种执行复杂嵌套函数自动微分的通用优化方法。然而,直到1986年,Rumelhart、Hinton和Williams发表了一篇题为《反向传播误差的学习表示》(Learning representation by backward - propagating Errors)的论文,该算法的重要性才得到机器学习社区的普遍认可。
长期以来,研究人员一直对寻找一种方法来训练多层人工神经网络感兴趣,这种网络可以自动发现良好的“内部表征”,即使学习更容易、更准确的特征。特征可以被认为是特定节点的典型输入,激活该节点(即使其输出接近1的正值)。由于节点的激活依赖于其传入权重和偏差,研究人员说,如果节点的权重和偏差导致该节点在其输入中出现时激活该特征,则该节点已经学习了该特征。
到20世纪80年代,手工设计的特征已经成为许多领域事实上的标准,特别是在计算机视觉领域,因为专家们从实验中知道哪些特征(例如计算机视觉中的线、圆、边、斑点)可以使学习更简单。然而,手工设计成功的特性需要大量的知识和实践。更重要的是,由于它不是自动的,所以通常很慢。
反向传播是第一个能够证明人工神经网络可以学习良好的内部表示的方法之一,即它们的隐藏层学习非平凡的特征。研究使用反向传播训练的多层前馈网络的专家实际上发现,许多节点学习的特征类似于人类专家设计的特征,以及研究哺乳动物大脑生物神经网络的神经科学家发现的特征(例如,某些节点学习检测边缘,而其他节点计算Gabor滤波器)。更重要的是,由于算法的效率以及不再需要领域专家来发现适当的特征,反向传播使得人工神经网络可以应用于更广泛的问题领域,这些问题以前由于时间和成本的限制而被禁止。
正式的定义
反向传播类似于计算多层前馈网络的增量规则。因此,像增量规则一样,反向传播需要三个条件:
1)
数据集 由输入-输出对组成( x我 ,y我 ),在那里x 我 是输入y 我 网络的期望输出是否在输入上x 我 .大小的输入-输出对的集合N 来标示X ={(x1 ,y1 ),...,(xN ,yN )}.2)一个
.在反向传播中,主要感兴趣的参数是前馈神经网络 的正式定义<一个href="//www.parkandroid.com/wiki/feedforward-neural-networks/" class="wiki_link" title="前馈神经网络"t一个rget="_blank">前馈神经网络一个>,其参数为集合表示θ w 我jk,节点间的权值j 在层l k和节点我 在层l k−1,b 我k,节点的偏置我 在层l k.同一层的节点之间不存在连接,各层完全连通。3)一个
误差函数 ,E (X,θ),它定义了所需输出之间的误差y 我 以及计算输出y 我 ^神经网络的输入x 我 对于一组输入-输出对( x我 ,y我 )∈X和一个特定的参数值θ .
用梯度下降训练神经网络需要计算误差函数的梯度
θt+1=θt−α∂θ∂E(X,θt),
在哪里
目标是什么?
如前一节所述,训练多层前馈神经网络的一个主要问题是决定如何学习良好的内部表示,即隐藏层节点的权重和偏差应该是什么。与感知器不同,感知器具有近似定义良好的目标输出的delta规则,隐藏层节点没有目标输出,因为它们被用作计算中的中间步骤。
由于隐藏层节点没有目标输出,因此不能简单地定义一个特定于该节点的错误函数。相反,该节点的任何错误函数都将依赖于前一层中的参数值(因为前一层决定了该节点的输入)和下面的层 正式的定义 下面的公式适用于只有一个输出的神经网络,但是通过一致应用链式法则和幂法则,该算法可以应用于有任意数量输出的网络。因此,对于下面的所有示例,输入-输出对将是这样的形式 记住前馈神经网络的一般公式,
w我jk:节点权值
对于输入节点
b我k:节点偏置
一个我k:节点的产品和加上偏差(激活)
o我k:节点的输出
rk:层中节点数
g:隐层节点的激活函数
经典反向传播中的误差函数是均方误差
E(X,θ)=2N1我=1∑N(y我^−y我)2,
在哪里
梯度的推导
反向传播算法的推导是相当简单的。它源于微分学中的链式法则和乘积法则。这些规则的应用依赖于激活函数的微分,这是不使用heaviside step函数的原因之一(因为不连续,因此不可微)。
预赛
在本节的其余部分,函数的导数
为了进一步简化数学,偏差
w0我k=b我k.
要看出这与原来的公式是等价的,请注意
一个我k=b我k+j=1∑rk−1wj我kojk−1=j=0∑rk−1wj我kojk−1,
左边是原来的公式右边是新的公式。
使用上面的符号,反向传播尝试最小化以下关于神经网络权重的误差函数:
E(X,θ)=2N1我=1∑N(y我^−y我)2
通过计算,每个权重
∂w我jk∂E(X,θ)=N1d=1∑N∂w我jk∂(21(yd^−yd)2)=N1d=1∑N∂w我jk∂Ed.
因此,为了推导的目的,反向传播算法将只关注一个输入-输出对。一旦导出了这个,中所有输入-输出对的一般形式
E=21(y^−y)2,
下标在这里
误差函数导数
反向传播算法的推导首先将链式法则应用于误差函数的偏导数
∂w我jk∂E=∂一个jk∂E∂w我jk∂一个jk,
在哪里
第一项通常称为
δjk≡∂一个jk∂E.
第二项可以由方程计算
∂w我jk∂一个jk=∂w我jk∂(l=0∑rk−1wljkolk−1)=o我k−1.
因此,误差函数的偏导数
∂w我jk∂E=δjko我k−1.
因此,权重的偏导数是误差项的乘积
值得注意的是,上述偏导数都是在没有考虑特定误差函数或激活函数的情况下计算出来的。但是,由于误差项
误差的计算
输出层
从最后一层开始,反向传播尝试定义值
E=21(y^−y)2=21(go(一个1米)−y)2,
在哪里
因此,应用偏导数和链式法则给出
δ1米=(g0(一个1米)−y)go”(一个1米)=(y^−y)go”(一个1米).
把它们放在一起,就是误差函数的偏导数
∂w我1米∂E=δ1米o我米−1=(y^−y)go”(一个1米)o我米−1.
隐藏层
现在的问题是如何计算输出层以外的其他层的偏导数。幸运的是,多元函数的链式法则又来帮忙了。观察下面的误差项方程
δjk=∂一个jk∂E=l=1∑rk+1∂一个lk+1∂E∂一个jk∂一个lk+1,
在哪里
代入误差项
δjk=l=1∑rk+1δlk+1∂一个jk∂一个lk+1.
还记得
一个lk+1=j=1∑rkwjlk+1g(一个jk),
在哪里
∂一个jk∂一个lk+1=wjlk+1g”(一个jk).
把这个代入上面的方程就得到了误差项的最终方程
δjk=l=1∑rk+1δlk+1wjlk+1g”(一个jk)=g”(一个jk)l=1∑rk+1wjlk+1δlk+1.
把它们放在一起,就是误差函数的偏导数
∂w我jk∂E=δjko我k−1=g”(一个jk)o我k−1l=1∑rk+1wjlk+1δlk+1. 反向传播作为向后计算 这个方程就是反向传播得名的原因。也就是误差 这种误差的反向传播与计算神经网络输出的正向计算非常相似。因此,计算输出通常被称为 此外,由于反相的计算依赖于激活
反向传播算法
使用“形式定义”一节中定义的术语和“推导梯度”一节中导出的方程,反向传播算法依赖于以下五个方程:
对于偏导,
∂w我jk∂Ed=δjko我k−1.
对于最后一层的误差项,
δ1米=go”(一个1米)(yd^−yd).
对于隐层的误差项,
δjk=g”(一个jk)l=1∑rk+1wjlk+1δlk+1.
为了组合每个输入-输出对的偏导数,
∂w我jk∂E(X,θ)=N1d=1∑N∂w我jk∂(21(yd^−yd)2)=N1d=1∑N∂w我jk∂Ed.
为了更新权重,
Δw我jk=−α∂w我jk∂E(X,θ).
通用算法
反向传播算法按照以下步骤进行,假设有一个合适的学习率
1)
计算正向相位 对于每个输入-输出对( xd ,yd)并存储结果y d^,一个 jk,o jk对于每个节点j 在层k 从一层开始0 ,输入层,到层米 ,即输出层。2)
计算反向相位 对于每个输入-输出对( xd ,yd)并存储结果∂ w我jk∂Ed对于每个权重w 我jk连接节点我 在层k −1到节点j 在层k 从一层开始米 ,输出层,到层1 ,即输入层。a)计算最后一层的误差项
δ 1米用第二个方程。b)反向传播隐层的误差项 k,从最后的隐藏层向后工作δ jk =米−1,通过重复使用第三个方程。c)求个别误差的偏导数 E d关于w 我jk用第一个方程。3)
组合各个渐变 对于每个输入-输出对∂ w我jk∂Ed得到总的梯度∂ w我jk∂E(X,θ)对于整个输入-输出对集合X ={(x1 ,y1),...,(xN ,yN)}通过使用第四个方程(单个梯度的简单平均值)。4)
和总梯度更新权重 根据学习率α ∂ w我jk∂E(X,θ)通过使用第五个方程(沿负梯度方向移动)。
Sigmoidal神经网络中的反向传播
经典的反向传播算法是为具有s型激活单元的回归问题设计的。虽然反向传播可以应用于分类问题以及具有非sigmoidal激活函数的网络,但sigmoid函数具有方便的数学性质,当与适当的输出激活函数结合时,极大地简化了算法的理解。因此,在经典公式中,隐藏节点的激活函数是s型的 反向传播实际上是历史上使用sigmoid激活函数的主要激励因素,因为它的导数很方便:
g”(x)=∂x∂σ(x)=σ(x)(1−σ(x)). 因此,计算sigmoid函数的导数只需要记住输出 此外,输出激活函数的导数也非常简单:
go”(x)=∂x∂go(x)=∂x∂x=1. 因此,使用这两个激活函数就不需要记住激活值 因此,对于具有s型隐单元和单位输出单元的前馈神经网络,误差项方程为:
对于最后一层的误差项,
δ1米=yd^−yd. 对于隐层的误差项,
δjk=ojk(1−ojk)l=1∑rk+1wjlk+1δlk+1. 代码示例 下面的代码示例是前面小节中描述的sigmoidal神经网络。它有一个隐藏层和输出层中的一个输出节点。代码是用Python3编写的,并大量使用NumPy库来执行矩阵数学。因为单独的输入输出对的梯度计算
12 34 56 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
进口numpy作为np#定义sigmoid函数def乙状结肠(x,导数=假):如果(导数= =真正的):返回乙状结肠(x,导数=假)*(1-乙状结肠(x,导数=假))其他的:返回1/(1+np.经验值(-x))#选择一个随机的种子以获得可重复的结果np.随机.种子(1)#学习率α=.1#隐藏层的节点数num_hidden=3.#输入X=np.数组([[0,0,1),[0,1,1),[1,0,0),[1,1,0),[1,0,1),[1,1,1),])#输出# x.T是x的转置,使它成为列向量y=np.数组([[0,1,0,1,1,0]]).T#随机初始化权重,均值为0,范围为[- 1,1]权重矩阵第1维中的+1是偏置权重hidden_weights=2*np.随机.随机((X.形状[1]+1,num_hidden))-1output_weights=2*np.随机.随机((num_hidden+1,y.形状[1)))-1#梯度下降的迭代次数num_iterations=10000#用于梯度下降的每次迭代为我在范围(num_iterations):#正向阶段# np.hstack((np.ones(…),X)为偏差权重添加一个固定的输入1input_layer_outputs=np.hstack((np.的((X.形状[0),