首页 > 编程知识 正文

BP神经网络算法,简述bp神经网络及其算法流程

时间:2023-05-06 10:50:06 阅读:22328 作者:573

前文:循环神经网络——初学rnn https://blog.csdn.net/weixin _ 38522681/article/details/109129490

循环神经网络——RNN训练算法: BPTT基本步长前向计算误差项计算权重梯度计算RNN梯度爆发和消失问题基本步长

BTT算法是一种循环层训练算法,其基本原理与BP算法相同,包括三个类似的步骤:

1 .向前计算每个神经元的输出值

2 .反向计算各神经元的误差项j(Delta_jj的值。 这是误差函数e相对于神经元j的加权输入n e t j net_j netj的偏导数。

3 .计算各权重的梯度。

最后用随机梯度下降算法更新权重。

循环图层如下图所示。

前向计算ST=f(uxtwst1) s_t=f ) UX_tws_{t-1} ) ST=f(uxtwst1) ) ) ) ) ) ) )

上面的s t s_t st、x t x_t xt、st1s_{t-1}ST1都是向量,用黑体字母表示; u、v是矩阵,用大写字母表示。 的下标表示时刻,例如,s t s_t st表示时刻t时的向量s的值。

假设输入向量x的维数为m,输出向量s的维数为n,则矩阵u的维数为n m ntimes m nm,矩阵w的维数为n n ntimes n nn。 下面是上式展开为矩阵的样子,看起来更直观:

这里,用手写字符表示向量的一个要素,其下标表示该向量的第几个要素,其上标表示第几个时刻。 例如,

s j t s^t_j sjt​表示向量s的第j个元素在t时刻的值。 u j i u_{ji} uji​表示输入层第i个神经元到循环层第j个神经元的权重。 w j i w_{ji} wji​表示循环层第t-1时刻的第i个神经元到循环层第t个时刻的第j个神经元的权重。

误差项的计算

BTPP算法将第l层t时刻的误差项值 δ j l delta^l_j δjl​沿两个方向传播,一个方向是其传递到上一层网络,得到 δ j l − 1 delta^{l-1}_j δjl−1​,这部分只和权重矩阵U有关;另一个是方向是将其沿时间线传递到初始时刻 t 1 t_1 t1​,得到 δ j 1 delta^1_j δj1​,这部分只和权重矩阵W有关。
我们用向量 n e t t net_t nett​表示神经元在t时刻的加权输入,因为:


我们用a表示列向量,用 a T a^T aT表示行向量。两项结果为Jacobian矩阵:


其中,diag[a]表示根据向量a创建一个对角矩阵,即

两项结合,得

上式描述了将 δ delta δ沿时间往前传递一个时刻的规律,有了这个规律,我们就可以求得任意时刻k的误差项 δ k delta_k δk​

式3就是将误差项沿时间反向传播的算法。
循环层将误差项反向传递到上一层网络,与普通的全连接层是完全一样的
循环层的加权输入 n e t l net^l netl与上一层 n e t l − 1 net^{l-1} netl−1的加权输入关系如下:

所以,

式4就是将误差项传递到上一层算法。

权重梯度的计算

现在,我们终于来到了BPTT算法的最后一步:计算每个权重的梯度。

首先,我们计算误差函数E对权重矩阵W的梯度 ∂ E ∂ W frac{partial E}{partial W} ∂W∂E​。

只要知道了任意一个时刻的误差项 δ t delta_t δt​,以及上一个时刻循环层的输出值 s t − 1 s_{t-1} st−1​,就可以按照下面的公式求出权重矩阵在t时刻的梯度 ∇ W t E nabla _{W_t}E ∇Wt​​E:

式5推导如下

因为对W求导与 U x t Ux_t Uxt​无关,我们不再考虑。现在,我们考虑对权重项 w j i w_{ji} wji​求导。通过观察上式我们可以看到 w j i w_{ji} wji​只与 n e t j t net^t_j netjt​有关,所以:

我们已经求得了权重矩阵W在t时刻的梯度 ∇ W t E nabla _{W_t}E ∇Wt​​E,最终的梯度 ∇ W E nabla _WE ∇W​E是各个时刻的梯度之和,详解见参考

式6就是计算循环层权重矩阵W的梯度的公式。

RNN的梯度爆炸和消失问题

实践中前面介绍的几种RNNs并不能很好的处理较长的序列。一个主要的原因是,RNN在训练中很容易发生梯度爆炸和梯度消失,这导致训练时梯度不能在较长序列中一直传递下去,从而使RNN无法捕捉到长距离的影响。

根据式3可得

上式的 β beta β定义为矩阵的模的上界。因为上式是一个指数函数,如果t-k很大的话(也就是向前看很远的时候),会导致对应的误差项的值增长或缩小的非常快,这样就会导致相应的梯度爆炸梯度消失问题(取决于 β beta β大于1还是小于1)。

通常来说,梯度爆炸更容易处理一些。因为梯度爆炸的时候,我们的程序会收到NaN错误。我们也可以设置一个梯度阈值,当梯度超过这个阈值的时候可以直接截取。

梯度消失更难检测,而且也更难处理一些。总的来说,我们有三种方法应对梯度消失问题:

合理的初始化权重值。初始化权重,使每个神经元尽可能不要取极大或极小值,以躲开梯度消失的区域。使用relu代替sigmoid和tanh作为激活函数。使用其他结构的RNNs,比如长短时记忆网络(LTSM)和Gated Recurrent Unit(GRU),这是最流行的做法。

参考: https://zybuluo.com/hanbingtao/note/541458

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。