深度学习3:循环神经网络Recurrent Neural Network(基于Python MXNet.Gluon框架)

2023-11-07

循环神经网络概述

  在前馈神经网络中,信息的传递是单向的,这种限制虽然使得网络变得更容易学习,但在一定程度上也减弱了神经网络模型的能力1

  在生物神经网络中,神经元之间的连接关系要复杂得多。前馈神经网络不能解决的两个问题:

  1. 前馈神经网络每次输入都是独立的,但是在很多现实任务中,网络的输入不仅和当前时刻的输入相关,也和其过去一段时间的输出相关

  2. 前馈网络难以处理时序数据(比如视频、语音、文本等)。时序数据的长度一般是不固定的,而前馈神经网络要求输入和输出的维数都是固定的,不能任意改变。

  因此,当处理这一类和时序数据相关的问题时,就需要一种能力更强的模型。

  循环神经网络(Recurrent Neural Network,RNN)是一类具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其他神经元的信息,也可以接受自身的信息,形成具有环路的网络结构。

  循环神经网络的参数学习可以通过随时间反向传播算法来学习。随时间反向传播算法即按照时间的逆序将错误信息一步步地往前传递。当输入序列比较长时,会存在梯度爆炸和消失问题 ,也称为长程依赖问题。为了解决这个问题,人们对循环神经网络进行了很多的改进,其中最有效的改进方式引入门控机制(Gating Mechanism)。

  此外,循环神经网络可以很容易地扩展到两种更广义的记忆网络模型:递归神经网络图网络

给网络增加记忆能力

  为了处理这些时序数据并利用其历史信息,我们需要让网络具有短期记忆能力。而前馈网络是一种静态网络,不具备这种记忆能力。

  一般来讲,我们可以通过以下三种方法来给网络增加短期记忆能力。

延时神经网络

  一种简单的利用历史信息的方法是建立一个额外的延时单元,用来存储网络的历史信息(可以包括输入、输出、隐状态等)。比较有代表性的模型是延时神经网络(Time Delay Neural Network,TDNN)。

  延时神经网络是在前馈网络中的非输出层都添加一个延时器,记录神经元的最近几次活性值。在第 t t t 个时刻,第 l l l 层神经元的活性值依赖于第 l − 1 l-1 l1 层神经元的最近 K K K 个时刻的活性值,即

h t ( l ) = f ( h t ( l − 1 ) , h t − 1 ( l − 1 ) , ⋯   , h t − K ( l − 1 ) ) , h_t^{(l)}=f(h_t^{(l-1)},h_{t-1}^{(l-1)},\cdots,h_{t-K}^{(l-1)}), ht(l)=f(ht(l1),ht1(l1),,htK(l1)),

其中 h t ( l ) ∈ R M l h_t^{(l)}\in\mathbb{R}^{M_l} ht(l)RMl 表示第 l l l 层神经元在时刻 t t t 的活性值, M l M_l Ml 为第 l l l 层神经元的数量。通过延时器,前馈网络就具有了短期记忆的能力。

有外部输入的非线性自回归模型

  自回归模型(AutoRegressive Model,AR)是统计学上常用的一类时间序列模型,用一个变量 y t y_t yt 的历史信息来预测自己。

y t = ω 0 + ∑ k = 1 K ω k y t − k + ϵ t , y_t=\omega_0+\sum_{k=1}^K\omega_k\textbf{y}_{t-k}+\epsilon_t, yt=ω0+k=1Kωkytk+ϵt,

其中 K K K 为超参数, ω 0 , ⋯   , ω K \omega_0,\cdots,\omega_K ω0,,ωK 为可学习参数, ϵ t ∼ N ( 0 , σ 2 ) \epsilon_t\sim N(0,\sigma^2) ϵtN(0,σ2) 为第 t t t 个时刻的噪声,方差 σ 2 \sigma^2 σ2 和时间无关。

  有外部输入的非线性自回归模型(Nonlinear AutoRegressive with Exoge-nous Inputs Model,NARX)是自回归模型的扩展,在每个时刻 t t t 都有一个外部输入 x t x_t xt ,产生一个输出 y t y_t yt 。NARX 通过一个延时器记录最近 K x K_x Kx 次的外部输入和最近 K y K_y Ky 次的输出,第 t t t 个时刻的输出 y t y_t yt

y t = f ( x t , x t − 1 , ⋯   , x t − K x , y t − 1 , y t − 2 , ⋯   , y t − K y ) , y_t=f(x_t,x_{t-1},\cdots,x_{t-K_x},y_{t-1},y_{t-2},\cdots,y_{t-K_y}), yt=f(xt,xt1,,xtKx,yt1,yt2,,ytKy),

其中 f ( ⋅ ) f(\cdot) f() 表示非线性函数,可以是一个前馈网络, K x K_x Kx K y K_y Ky 为超参数。

循环神经网络

  循环神经网络(Recurrent Neural Network,RNN)通过使用带自反馈的神经元,能够处理任意长度的时序数据

  给定一个输入序列 x 1 : T = ( x 1 , x 2 , ⋯   , x t , ⋯   , x T ) \textbf{x}_{1:T}=(\textbf{x}_1,\textbf{x}_2,\cdots,\textbf{x}_t,\cdots,\textbf{x}_T) x1:T=(x1,x2,,xt,,xT),循环神经网络通过下面公式更新带反馈边的隐藏层的活性值 h t \textbf{h}_t ht

h t = f ( h t − 1 , x t ) \textbf{h}_t=f(\textbf{h}_{t-1},\textbf{x}_t) ht=f(ht1,xt)

其中 h 0 = 0 , f ( ⋅ ) \textbf{h}_0=0,f(\cdot) h0=0,f() 为一个非线性函数,可以是一个前馈网络。

  从数学上讲,公式 h t = f ( h t − 1 , x t ) \textbf{h}_t=f(\textbf{h}_{t-1},\textbf{x}_t) ht=f(ht1,xt) 可以看成一个动力系统。因此,隐藏层的活性值 h t \textbf{h}_t ht 在很多文献上也称为状态(State)或隐状态(Hidden State)。理论上,循环神经网络可以近似任意的非线性动力系统。

简单循环网络

  简单循环网络(Simple Recurrent Network,SRN)是一个非常简单的循环神经网络,只有一个隐藏层的神经网络。在一个两层的前馈神经网络中,连接存在相邻的层与层之间,隐藏层的节点之间是无连接的。而简单循环网络增加了从隐藏层到隐藏层的反馈连接。

  令向量 x t ∈ R M \textbf{x}_t\in\mathbb{R}^M xtRM 表示在时刻 t t t 时网络的输入, h t ∈ R D \textbf{h}_t\in\mathbb{R}^D htRD 表示隐藏层的状态(即隐藏层神经元活性值),则 h t \textbf{h}_t ht 不仅和当前时刻的输入 x t \textbf{x}_t xt 相关,也和上一个时刻的隐藏层状态 h t − 1 \textbf{h}_{t-1} ht1 相关。 简单循环网络在时刻 t t t 的状态更新公式为

z t =   U h t − 1 + W x t + b h t =   f ( z t ) \begin{aligned} \textbf{z}_t=&\ \textbf{U}\textbf{h}_{t-1}+\textbf{W}\textbf{x}_t+\textbf{b}\\ \textbf{h}_t=&\ f(\textbf{z}_t) \end{aligned} zt=ht= Uht1+Wxt+b f(zt)

其中 z t \textbf{z}_t zt 为隐藏层的净输入, U ∈ R D × D \textbf{U}\in\mathbb{R}^{D\times D} URD×D状态-状态权重矩阵 W ∈ R D × M \textbf{W}\in\mathbb{R}^{D\times M} WRD×M状态-输入权重矩阵 b ∈ R D \textbf{b}\in\mathbb{R}^D bRD偏置向量 f ( ⋅ ) f(\cdot) f()非线性激活函数,通常为 L o g i s t i c Logistic Logistic 函数或 T a n h Tanh Tanh 函数。

在这里插入图片描述
  上面两个公式也经常直接写为

h t = f ( U h t − 1 + W x t + b ) \textbf{h}_t=f(\textbf{U}\textbf{h}_{t-1}+\textbf{W}\textbf{x}_t+\textbf{b}) ht=f(Uht1+Wxt+b)

  如果我们把每个时刻的状态都看作是前馈神经网络的一层,循环神经网络可以看作是在时间维度上权值共享的神经网络。下图给出了按时间展开的循环神经网络。

解释:

循环神经网络的计算能力

  由于循环神经网络具有短期记忆能力,相当于存储装置,因此其计算能力十分强大。前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序

  我们先定义一个完全连接的循环神经网络,其输入为 x t \textbf{x}_t xt ,输出为 y t \textbf{y}_t yt

h t =   f ( U h t − 1 + W x t + b ) y t =   V h t \begin{aligned} \textbf{h}_t=&\ f(\textbf{U}\textbf{h}_{t-1}+\textbf{W}\textbf{x}_t+\textbf{b})\\ \textbf{y}_t=&\ \textbf{V}\textbf{h}_t \end{aligned} ht=yt= f(Uht1+Wxt+b) Vht

其中 h \textbf{h} h 为隐状态, f ( ⋅ ) f(\cdot) f()为非线性激活函数, U , W , b \textbf{U},\textbf{W},\textbf{b} U,W,b V \textbf{V} V 为网络参数。

循环神经网络的通用近似定理

  循环神经网络的拟合能力也十分强大。一个完全连接的循环网络是任何非线性动力系统的近似器。

图灵完备

  图灵完备(Turing Completeness)是指一种数据操作规则,比如一种计算机编程语言,可以实现图灵机(Turing Machine)的所有功能,解决所有的可计算问题。

  目前主流的编程语言(比如 C++、Java、Python 等)都是图灵完备的。

应用到机器学习

  循环神经网络可以应用到很多不同类型的机器学习任务。根据这些任务的特点可以分为以下几种模式:序列到类别模式、同步的序列到序列模式、异步的序列到序列模式。

序列到类别模式

  序列到类别模式主要用于序列数据的分类问题:输入为序列,输出为类别。

  比如在文本分类中,输入数据为单词的序列,输出为该文本的类别。

  假设一个样本 x 1 : T = ( x 1 , x 2 , ⋯   , x t , ⋯   , x T ) \textbf{x}_{1:T}=(\textbf{x}_1,\textbf{x}_2,\cdots,\textbf{x}_t,\cdots,\textbf{x}_T) x1:T=(x1,x2,,xt,,xT) 为一个长度为 T T T 的序列,输出为一个类别 y ∈ { 1 , 2 , ⋯   , C } y\in\{1,2,\cdots,C\} y{1,2,,C}。我们可以将样本 x \textbf{x} x 按不同时刻输入到循环神经网络中,并得到不同时刻的隐藏状态 h 1 , ⋯   , h T \textbf{h}_1,\cdots,\textbf{h}_T h1,,hT。我们可以将 h T \textbf{h}_T hT 看作整个序列的最终表示(或特征),并输入给分类器 g ( ⋅ ) g(\cdot) g() 进行分类。

y ^ = g ( h T ) \hat{y}=g(\textbf{h}_T) y^=g(hT)

其中 g ( ⋅ ) g(\cdot) g() 可以是简单的线性分类器(比如 Logistic 回归)或复杂的分类器(比如多层前馈神经网络)。

  除了将最后时刻的状态作为整个序列的表示之外,我们还可以对整个序列的所有状态进行平均,并用这个平均状态来作为整个序列的表示

y ^ = g ( 1 T ∑ t = 1 T h t ) \hat{y}=g(\frac{1}{T}\sum_{t=1}^T\textbf{h}_t) y^=g(T1t=1Tht)

同步的序列到序列模式

  同步的序列到序列模式主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入和输出,输入序列和输出序列的长度相同。比如在词性标注(Part-of-Speech Tagging)中,每一个单词都需要标注其对应的词性标签。

  在同步的序列到序列模式(如图6.4所示)中,输入为一个长度为 T T T 的序列 x 1 : T = ( x 1 , x 2 , ⋯   , x t , ⋯   , x T ) \textbf{x}_{1:T}=(\textbf{x}_1,\textbf{x}_2,\cdots,\textbf{x}_t,\cdots,\textbf{x}_T) x1:T=(x1,x2,,xt,,xT),输出为序列 y 1 : T = ( y 1 , y 2 , ⋯   , y t , ⋯   , y T ) y_{1:T}=(y_1,y_2,\cdots,y_t,\cdots,y_T) y1:T=(y1,y2,,yt,,yT)。样本 x \textbf{x} x 按不同时刻输入到循环神经网络中,并得到不同时刻的隐状态 h 1 , ⋯   , h T \textbf{h}_1,\cdots,\textbf{h}_T h1,,hT 每个时刻的隐状态 h t \textbf{h}_t ht 代表了当前时刻和历史的信息,并输入给分类器 g ( ⋅ ) g(\cdot) g() 得到当前时刻的标签 y ^ \hat{y} y^

y ^ t = g ( h t ) , t ∈ [ 1 , T ] \hat{y}_t=g(\textbf{h}_t),t\in[1,T] y^t=g(ht),t[1,T]

异步的序列到序列模式

  异步的序列到序列模式也称为编码器-解码器(Encoder-Decoder)模型,即输入序列和输出序列不需要有严格的对应关系,也不需要保持相同的长度

  比如在机器翻译中,输入为源语言的单词序列,输出为目标语言的单词序列。

  出为长度为 M M M 的序列 y 1 : M = ( y 1 , y 2 , ⋯   , y t , ⋯   , y M ) y_{1:M}=(y_1,y_2,\cdots,y_t,\cdots,y_M) y1:M=(y1,y2,,yt,,yM)。异步的序列到序列模式一般通过先编码后解码的方式来实现。先将样本 x \textbf{x} x 按不同时刻输入到一个循环神经网络(编码器)中,并得到其编码 h T \textbf{h}_T hT。然后再使用另一个循环神经网络(解码器),得到输出序列 y ^ 1 : M \hat{y}_{1:M} y^1:M。为了建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型

h t =   f 1 ( h t − 1 , x t ) , t ∈ [ 1 , T ] h T + t =   f 2 ( h T + t − 1 , y ^ t − 1 ) , t ∈ [ 1 , M ] y ^ t =   g ( h T + t ) , t ∈ [ 1 , M ] \begin{aligned} \textbf{h}_t=&\ f_1(\textbf{h}_{t-1},\textbf{x}_t),t\in[1,T] \\ \textbf{h}_{T+t}=&\ f_2(\textbf{h}_{T+t-1},\hat{y}_{t-1}) ,t\in[1,M]\\ \hat{y}_t=&\ g(\textbf{h}_{T+t}),t\in[1,M] \end{aligned} ht=hT+t=y^t= f1(ht1,xt),t[1,T] f2(hT+t1,y^t1),t[1,M] g(hT+t),t[1,M]

其中 f 1 ( ⋅ ) f_1(\cdot) f1() f 2 ( ⋅ ) f_2(\cdot) f2() 分别为用作编码器和解码器的循环神经网络, g ( ⋅ ) g(\cdot) g() 为分类器, y ^ t \hat{y}_t y^t 为预测输出 y ^ t \hat{y}_t y^t 的向量表示.

参数学习

  循环神经网络的参数可以通过梯度下降方法来进行学习。

  以随机梯度下降为例,给定一个训练样本 ( x , y ) (\textbf{x},\textbf{y}) (x,y),其中 x 1 : T = ( x 1 , x 2 , ⋯   , x t , ⋯   , x T ) \textbf{x}_{1:T}=(\textbf{x}_1,\textbf{x}_2,\cdots,\textbf{x}_t,\cdots,\textbf{x}_T) x1:T=(x1,x2,,xt,,xT) 为长度是 T T T 的输入序列, y 1 : T = ( y 1 , y 2 , ⋯   , y t , ⋯   , y T ) y_{1:T}=(y_1,y_2,\cdots,y_t,\cdots,y_T) y1:T=(y1,y2,,yt,,yT) 是长度为 T T T 的标签序列。即在每个时刻 t t t,都有一个监督信息 y t y_t yt ,我们定义时刻 t t t 的损失函数为

L t = L ( y t , g ( h t ) ) \mathcal{L}_t=\mathcal{L}(y_t,g(\textbf{h}_t)) Lt=L(yt,g(ht))

其中 g ( h t ) g(\textbf{h}_t) g(ht) t t t 时刻的输出, L \mathcal{L} L 为可微分的损失函数,比如交叉熵。那么整个序列的损失函数为

L = ∑ t = 1 T L t \mathcal{L}=\sum_{t=1}^T\mathcal{L}_t L=t=1TLt

  整个序列的损失函数 L \mathcal{L} L 关于参数 U \textbf{U} U 的梯度为

∂ L ∂ U = ∑ t = 1 T ∂ L t ∂ U \frac{\partial{\mathcal{L}}}{\partial{\textbf{U}}}=\sum_{t=1}^T\frac{\partial{\mathcal{L}_t}}{\partial{\textbf{U}}} UL=t=1TULt

即每个时刻损失 L t \mathcal{L}_t Lt 为参数 U \textbf{U} U 的偏导数之和。

  循环神经网络中存在一个递归调用的函数 f ( ⋅ ) f(\cdot) f(),因此其计算参数梯度的方式和前馈神经网络不太相同。在循环神经网络中主要有两种计算梯度的方式:随时间反向传播(BPTT)算法和实时循环学习(RTRL)算法。

随时间反向传播算法

  随时间反向传播(BackPropagation Through Time,BPTT)算法的主要思想是通过类似前馈神经网络的错误反向传播算法来计算梯度。

  BPTT 算法将循环神经网络看作是一个展开的多层前馈网络,其中“每一层”对应循环网络中的“每个时刻”这样,如下图所示

循环神经网络就可以按照前馈网络中的反向传播算法计算参数梯度。在“展开”的前馈网络中,所有层的参数是共享的,因此参数的真实梯度是所有“展开层”的参数梯度之和。

  介绍一个手动算的例子2

实时循环学习算法

  与反向传播的 BPTT 算法不同的是,实时循环学习(Real-Time Recurrent Learning,RTRL)是通过前向传播的方式来计算梯度。

两种算法的比较

  两种算法比较 RTRL 算法和 BPTT 算法都是基于梯度下降的算法,分别通过前向模式和反向模式应用链式法则来计算梯度。在循环神经网络中,一般网络输出维度远低于输入维度,因此 BPTT 算法的计算量会更小,但是 BPTT 算法需要保存所有时刻的中间梯度,空间复杂度较高。RTRL 算法不需要梯度回传,因此非常适合用于需要在线学习或无限序列的任务中。

RTRL 算法和 BPTT 算法比较
BPTT 算法 RTRL 算法
反向模式应用链式法则来计算梯度 前向模式应用链式法则来计算梯度
BPTT 算法的计算量会更小,但是 BPTT 算法需要保存所有时刻的中间梯度,空间复杂度较高 RTRL 算法不需要梯度回传,因此非常适合用于需要在线学习或无限序列的任务中

手动计算的例子

z 1 =   U h 0 + W x 1 + b =   [ − 1 0 2 1 ] ⋅ [ 1 2 ] + [ 1 2 3 4 5 6 ] ⋅ [ 1 0 0 ] + [ − 2 2 ] =   [ − 2 10 ] \begin{aligned} z_1=&\ Uh_0+Wx_1+b \\ =&\ \begin{bmatrix}-1 & 0\\2 & 1\end{bmatrix}\cdot\begin{bmatrix}1\\2\end{bmatrix}+\begin{bmatrix}1 & 2 & 3\\4 & 5 & 6\end{bmatrix}\cdot\begin{bmatrix}1\\0\\0\end{bmatrix}+\begin{bmatrix}-2\\2\end{bmatrix}\\ =&\ \begin{bmatrix}-2\\10\end{bmatrix} \end{aligned} z1=== Uh0+Wx1+b [1201][12]+[142536]100+[22] [210]

h 1 = R e l u ( z 1 ) =   [ 0 10 ] h_1=Relu(z_1)=\ \begin{bmatrix}0\\10\end{bmatrix} h1=Relu(z1)= [010]

y 1 = V h 1 = [ 1 0 2 − 1 3 1 ] ⋅ [ 0 10 ] = [ 0 − 10 10 ] y_1=Vh_1=\begin{bmatrix}1 & 0\\2 & -1\\3 & 1\end{bmatrix}\cdot\begin{bmatrix}0\\10\end{bmatrix}=\begin{bmatrix}0\\-10\\10\end{bmatrix} y1=Vh1=123011[010]=01010

z 2 =   U h 1 + W x 2 + b =   [ − 1 0 2 1 ] ⋅ [ 0 10 ] + [ 1 2 3 4 5 6 ] ⋅ [ 0 1 0 ] + [ − 2 2 ] =   [ 0 17 ] \begin{aligned}z_2=&\ Uh_1+Wx_2+b \\=&\ \begin{bmatrix}-1 & 0\\2 & 1\end{bmatrix}\cdot\begin{bmatrix}0\\10\end{bmatrix}+\begin{bmatrix}1 & 2 & 3\\4 & 5 & 6\end{bmatrix}\cdot\begin{bmatrix}0\\1\\0\end{bmatrix}+\begin{bmatrix}-2\\2\end{bmatrix}\\=&\ \begin{bmatrix}0\\17\end{bmatrix}\end{aligned} z2=== Uh1+Wx2+b [1201][010]+[142536]010+[22] [017]

h 2 = R e l u ( z 2 ) =   [ 0 17 ] h_2=Relu(z_2)=\ \begin{bmatrix}0\\17\end{bmatrix} h2=Relu(z2)= [017]

y 2 = V h 2 = [ 1 0 2 − 1 3 1 ] ⋅ [ 0 17 ] = [ 0 − 17 17 ] y_2=Vh_2=\begin{bmatrix}1 & 0\\2 & -1\\3 & 1\end{bmatrix}\cdot\begin{bmatrix}0\\17\end{bmatrix}=\begin{bmatrix}0\\-17\\17\end{bmatrix} y2=Vh2=123011[017]=01717

在这里插入图片描述

在这里插入图片描述

长程依赖问题

  循环神经网络在学习过程中的主要问题是由于梯度消失或爆炸问题,很难建模长时间间隔(Long Range)的状态之间的依赖关系。

  虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系。这样,如果时刻 t t t 的输出 y t y_t yt 依赖于时刻 k k k 的输入 x k \textbf{x}_k xk,当间隔 t − k t-k tk 比较大时,简单神经网络很难建模这种长距离的依赖关系,称为长程依赖问题(Long-Term Dependencies Problem)。

改进方案

  为了避免梯度爆炸或消失问题,一种最直接的方式就是选取合适的参数,同时使用非饱和的激活函数,尽量使得 d i a g ( f ′ ( z ) ) U T ≈ 1 diag(f'(\textbf{z}))\textbf{U}^T\approx1 diag(f(z))UT1,这种方式需要足够的人工调参经验,限制了模型的广泛应用。比较有效的方式是通过改进模型或优化方法来缓解循环网络的梯度爆炸和梯度消失问题。

梯度爆炸

  一般而言,循环网络的梯度爆炸问题比较容易解决,一般通过权重衰减梯度截断来避免。

  权重衰减是通过给参数增加 l 1 l_1 l1 l 2 l_2 l2 范数的正则化项来限制参数的取值范围,从而使得 γ ≤ 1 \gamma\leq1 γ1

  梯度截断是另一种有效的启发式方法,当梯度的模大于一定阈值时,就将它截断成为一个较小的数。

梯度消失

  梯度消失是循环网络的主要问题。除了使用一些优化技巧外,更有效的方式就是改变模型,比如让 U = I \textbf{U}=\textbf{I} U=I,同时令 ∂ h t ∂ h t − 1 = I \frac{\partial{\textbf{h}_t}}{\partial{\textbf{h}_{t-1}}}=\textbf{I} ht1ht=I 为单位矩阵,即

h t = h t − 1 + g ( x t ; θ ) \textbf{h}_t=\textbf{h}_{t-1}+g(\textbf{x}_t;\theta) ht=ht1+g(xt;θ)

其中 g ( ⋅ ) g(\cdot) g() 是一个非线性函数, θ \theta θ 为参数。

  上式中, h t \textbf{h}_t ht h t − 1 \textbf{h}_{t-1} ht1 之间为线性依赖关系,且权重系数为 1,这样就不存在梯度爆炸或消失问题。但是,这种改变也丢失了神经元在反馈边上的非线性激 活的性质,因此也降低了模型的表示能力。

  为了避免这个缺点,我们可以采用一种更加有效的改进策略:

h t = h t − 1 + g ( x t , h t − 1 ; θ ) \textbf{h}_t=\textbf{h}_{t-1}+g(\textbf{x}_t,\textbf{h}_{t-1};\theta) ht=ht1+g(xt,ht1;θ)

这样 h t \textbf{h}_t ht h t − 1 \textbf{h}_{t-1} ht1 之间为线性依赖关系,也有非线性关系,并且可以缓解梯度消失问题。但这种改进依然存在两个问题:

参考资料


  1. 邱锡鹏. 神经网络与深度学习[M]:13-14
    https://nndl.github.io/. ↩︎

  2. 博客园博主:Determined22. 机器学习 —— 基础整理(八)循环神经网络的BPTT算法步骤整理;梯度消失与梯度爆炸
    https://www.cnblogs.com/Determined22/p/6562555.html. ↩︎

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度学习3:循环神经网络Recurrent Neural Network(基于Python MXNet.Gluon框架) 的相关文章

随机推荐

  • XNA是什么?

    Software will be the single most important force in digital entertainment over the next decade XNA underscores Microsoft
  • 虚幻4学习笔记(9)基础概念、常用快捷键汇总、蓝图概念

    虚幻4学习笔记 基础概念 常用快捷键汇总 中英文命名注意事项 帧和秒的概念 带星号文件的意思 编译的作用 实例和原素材 情景关联 蓝图概念 函数概念 宏的概念 宏与蓝图的区别 函数 事件的区别 变量的概念 面向对象思想 B站UP谌嘉诚课程
  • springMVC @ModelAttribute学习

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 转自 http hbiao68 iteye com blog 1948380 ModelAttribute 绑定请求参数到命令对象 ModelAttribute一个具有如下
  • 前后端分离部署方式

    转自https www cnblogs com moveofgod p 12363544 html 写得简洁明了 例如 vue 这种前后端分离的框架如何部署 1 前后端一起部署 前端打包成静态文件后 copy 到后端项目中 然后部署后端项目
  • GO语言实战要点摘录

    1 变量的声明与定义 1 var t T 通常用于零值初始化 非零值初始化通常采用短变量声明 初始化的方式 type user struct name string age int 用右侧的指定的类型初始化变量 每行初始化一个变量 以逗号结
  • numpy和pandas简单快速入门

    由于部分代码需要和数据文件配合 将项目和文件个人的GitHub 地址 https github com 1769172502 machine learning 关于numpy参考菜鸟地址 http www runoob com numpy
  • 使用QProcess调用外部程序

    在实际的项目开发中往往会有调用外部程序的需求 例如 主程序中添加调用记事本的快捷方式等 QProcess调用接口介绍 QProcess是Qt专门用于外部程序启动并与之通信的类 启动外部程序主要分为两种方式 一体式 将随主程序的退出而退出 v
  • 如何解决Dev-c++无法调试或者无法性能分析的问题

    无法调试 1 打开Dev c 2 点击屏幕顶部的 工具 3 点击 编译选项 4 点击 代码生成 优化 5 点击 连接器 6 将 产生调试信息 改为 yes 7 点击 确定 无法性能分析 1 打开Dev c 2 点击屏幕顶部的 工具 3 点击
  • uniapp调试 手机上没有信任本计算机的授权,请在手机上信任该授权

    真机运行失败 失败原因 手机上没有信任本计算机的授权 请在手机上信任该授权 HBUILDER 手机调试 提示没有授权 其实就是usb调试权限 刷这样才能用pc操作手机进行安装app等操作 这个时候可以 断开手机和电脑的连接 然后重新连接 跳
  • SQLyog ERROR 1045 : Access denied for user ‘root’@‘localhost’ (using password: YES)

    Linux和MySQL小白遇到的一些问题 在window中使用SQLyog远程连接虚拟机中Linux CentOs7 中的MySQL数据库 问题描述及解决方法1 连接时报错ERROR 1045 Access denied for user
  • uniapp实现用户登录

    store js文件 login vue页面
  • html语言左对齐是什么,html - 如何左对齐标签?

    我试图左对齐标签保持输入字段右对齐没有成功 我能够对齐标签或输入字段 但不能同时使用它们 我已经尝试了很多东西 但没有奏效html 如何左对齐标签 HTML Info Cod Name Phone Address CSS form styl
  • halcon识别斜着的车牌

    对于倾斜的车牌 我们必须用仿射变换 将车牌弄正 再进行识别 如图 halcon代码 read image Image666 C Users Administrator Desktop 666 jpg decompose3 Image666
  • C/C++经典项目:用C++制作在线考试系统(附源码)

    在线考试是指通过操作计算机在网络上进行考试整个过程的一种考试形式 脱离了纸质媒体 也可以说成是通过网络媒体进行的考试 是现如今比较常用的一种考试形式 用C 编写的在线考试系统 Access MSSQL数据库可选 从权限操作来看 包含学生 教
  • java如何使用代码求两个list集合的差集呢?

    转自 java如何使用代码求两个list集合的差集呢 下文笔者讲述求list集合的差集的方法简介说明 如下所示 差集 用一个集合减去一个集合得到的集合 我们称之为 差集 实现思路 使用stream流中的filter方法对集合 进行 不包含关
  • C#编程,字符串与字符、字符串与字节的转化方法

    1 string 转换成 Char string ss abcdefg char cc ss ToCharArray 2 Char 转换成string string s new string cc 3 byte 与 string 之间的装换
  • 字典树(Trie树) Java实现源码参考

    定义 字典树 又称为单词查找树 Tire数 是一种树形结构 它是一种哈希树的变种 用于保存大量的字符串 它的优点是 利用字符串的公共前缀来节约存储空间 字典树结构对应的Java源码 public class Trie char val bo
  • mysql-基础篇

    Mysql 基础篇 MySQL概述 数据库相关概念 名称 全称 简称 数据库 存储数据的仓库 数据是有组织的进行存储 DataBase DB 数据库管理系统 操纵和管理数据库的大型软件 DataBase Management System
  • 详解Spring的CreateBean方法

    在AbstractBeanFactory类的doGetBean 中 都是调用AbstractAutowireCapableBeanFactory类的createBean 来创建Bean实例 该方法参数如下 protected Object
  • 深度学习3:循环神经网络Recurrent Neural Network(基于Python MXNet.Gluon框架)

    循环神经网络 循环神经网络概述 给网络增加记忆能力 延时神经网络 有外部输入的非线性自回归模型 循环神经网络 简单循环网络 循环神经网络的计算能力 循环神经网络的通用近似定理 图灵完备 应用到机器学习 序列到类别模式 同步的序列到序列模式