Bootstrap

从RNN讲起(RNN、LSTM、GRU、BiGRU)——序列数据处理网络

RNN(Recurrent Neural Network,循环神经网络)

1. 什么是RNN?

循环神经网络是一类用于处理序列数据的神经网络,它一般以序列数据作为输入,通过网络内部的结构设计有效地捕捉序列之间的关系,以序列的形式输出。与传统的前馈神经网络不同,RNN具有"记忆"能力,通过在网络中引入循环连接,使得其可以利用先前的输入信息来影响当前的输出。这使得RNN非常适合处理具有时间依赖性或顺序性的任务


2. 经典RNN的结构

在介绍RNN之前,需要先了解最基本的单层网络,结构如图所示: 在这里插入图片描述

其含义是:输入 x x x,经过变换 W x + b Wx+b Wx+b 和激活函数 f f f,得到输出 y y y
常用激活函数主要有:在这里插入图片描述

在实际应用中,我们会遇到很多序列型的数据:在这里插入图片描述

以自言语言处理问题为例,简单来说,这可以看成是一句话, x 1 x_1 x1可以看做是第一个单词, x 2 x_2 x2可以看做是第二个单词,以此类推。


为了建模这种序列问题,RNN引入了 隐藏状态(hidden state) h h h 的概念。隐状态 h h h可以对序列类型的数据提取特征,然后再转换为输出。

h 1 h_1 h1 的计算为例:在这里插入图片描述
其中:圆圈或方框表示的是向量一个箭头就表示对该向量做一次变换 (例如上图中表示对 h 0 h_0 h0 x 1 x_1 x1 各做了一次变换)。

具体来说, h 1 h_1 h1 是基于上一个隐藏层的状态 h 0 h_0 h0 和当前的输入 x 1 x_1 x1 计算得到来的。泛化到任意时刻就是 h t = f ( W h t − 1 + U x t + b t ) h_t = f(Wh_{t-1}+Ux_t+b_t) ht=f(Wht1+Uxt+bt),这里激活函数 f f f 一般是tanh、sigmoid、ReLU等非线性激活函数。在实践中, h t h_t ht 一般只包含前面若干步而不是所有步的隐藏状态。

h 2 h_2 h2 的计算与 h 1 h_1 h1 相似:在这里插入图片描述

计算时,每一步使用的参数U、W、b都是一样的,也就是说每个步骤的参数是共享的,这是RNN的重要特点。 而在LSTM中权重是不共享的。
那为什么RNN的权值是共享的呢?是因为RNN的权值是在同一个向量中,只是不同的时刻而已。【进一步解释权重共享,指的是 x i x_i xi 在不同的时刻 i i i 乘的一直都是 U h i h_i hi 在不同的时刻 i i i 乘的一直都是 W。在 LSTM 中因为多出了门的概念,每个门对应的 W是不同的(即不同的门权重不共享),但是相同的门之间的 W 是共享的。】


依次计算剩下的(使用相同的参数U、W和b):在这里插入图片描述

到此,我们得到了所有的隐藏状态 h 1 h_1 h1 h 2 h_2 h2 h 3 h_3 h3 h 4 h_4 h4

RNN的输出通过隐藏状态进行计算:在这里插入图片描述

正如前面提到的,一个箭头就表示对向量做一次类似于 f ( W x + b ) f(Wx+b) f(Wx+b) 的变换,这里箭头表示对 h 1 h_1 h1 进行一次变换,得到输出 y 1 y_1 y1
剩下的输出可以类似得到(使用相同的参数 V 和 c):在这里插入图片描述

到此为止,得到了所有的输出,这就是经典的RNN结构,输入和输出序列是等长的。


通过上面的描述,我们知道RNN是包含循环的网络,在这个循环的结构中,每个神经网络的模块,读取到某个输入 x t x_t xt,并输出一个值 y t y_t yt,然后不断循环,使得信息可以从当前步传递到下一步。RNN可以被看做是同一神经网络的多次复制,每个神经网络模块会把消息传递给下一个,将这个循环展开:

在这里插入图片描述

链式的特征揭示了RNN本质上是与序列相关的,它们是对这类数据的最自然的神经网络架构。


3. RNN的主要特点

循环连接:RNN的核心在于它的循环连接,即网络的输出会作为下一个时间步的输入,这使得网络能够保持对之前信息的记忆。

参数共享:在RNN中,无论序列的长度如何,使用的权重和参数是共享的。

记忆能力:RNN能够记住序列中的信息,这使得它在处理时间序列数据、自然语言处理等领域表现出色。


4. RNN存在问题——长期依赖(Long-TermDependencies)问题

有时候,我们仅仅需要知道先前的信息来执行当前的任务。例如,我们有一个语言模型用来基于先前的词来预测下一个词。如果我们试着预测这句话中 “the clouds are in the sky” 最后的这个词 “sky”,我们并不再需要其他的信息,因为很显然下一个词应该是sky。在这样的场景中,相关的信息和预测的词位置之间的间隔是非常小的,RNN可以学会使用先前的信息
在这里插入图片描述

但是同样会有一些更加复杂的场景。比如我们试着去预测 “I grew up in France…I speak fluent French” 最后的词 “French”。当前的信息建议下一个词可能是一种语言的名字,但是如果我们需要弄清楚是什么语言,我们是需要先前提到的离当前位置很远的 “French” 的上下文。这说明相关信息和当前预测位置之间的间隔就肯定变得相当的大。不幸的是,在这个间隔不断增大时,RNN会丧失学习到连接如此远的信息的能力。
在这里插入图片描述

换句话说, RNN 会受到短时记忆的影响。如果一条序列足够长,那它们将很难将信息从较早的时间步传送到后面的时间步。

因此,如果你正在尝试处理一段文本进行预测,RNN 可能从一开始就会遗漏重要信息。在反向传播期间(反向传播本质是通过不断缩小误差去更新权值,从而不断去修正拟合的函数),RNN 会面临梯度消失的问题。

因为梯度是用于更新神经网络的权重值(新的权值 = 旧权值 - 学习率*梯度),梯度会随着时间的推移不断下降减少,而当梯度值变得非常小时,就不会继续学习。

在这里插入图片描述

换言之,在递归神经网络中,获得小梯度更新的层会停止学习—— 那些通常是较早的层。 由于这些层不学习,RNN会忘记它在较长序列中以前看到的内容,因此RNN只具有短时记忆

而梯度爆炸则是因为计算的难度越来越复杂导致。

然而,幸运的是,有个RNN的变体——LSTM,可以在一定程度上解决梯度消失和梯度爆炸这两个问题!



LSTM(Long Short-Term Memory,长短期记忆网络)

1. 什么是LSTM?

长短期记忆网络(LSTM, Long Short-Term Memory)是一种特殊的循环神经网络RNN,设计用来解决传统RNN在处理长序列数据时遇到的梯度消失和梯度爆炸问题。

LSTM 网络的核心是三个门的机制:遗忘门(forget gate)输入门(input gate)输出门(output gate)。这些门通过自适应的方式控制信息的流动,从而实现对长期依赖信息的捕捉。

2. LSTM的网络结构

2.1 与RNN的不同之处

所有的RNN都具有一种重复神经网络模块的链式的形式。在标准的RNN中,这个重复的模块只有一个非常简单的结构,例如一个tanh层。

激活函数tanh的作用在于帮助调节流经网络的值,使得数值始终限制在-1到1之间。在这里插入图片描述

在这里插入图片描述

LSTM也同样是这种结构,但是重复的模块有一个不同的结构。具体来说,RNN重复单一的神经网络层,LSTM中的重复模块则包含四个交互的层,三个Sigmoid和一个tanh层,并以一种非常特殊的方式进行交互。

图中,每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入。粉色的圈代表pointwise的操作,诸如向量的和,而黄色的矩阵就是学习到的神经网络层。合在一起的线表示向量的连接,分开的线表示内容被复制,然后分发到不同的位置。
在这里插入图片描述

在这里插入图片描述

上图中,σ表示Sigmoid 激活函数,与tanh不同,sigmoid把值压缩到0到1之间。在这里插入图片描述

这样的设置有助于更新或忘记信息:

  • 因为任何数乘以 0 都得 0,这部分信息就会剔除掉;
  • 同样的,任何数乘以 1 都得到它本身,这部分信息就会完美地保存下来

相当于要么是1则记住,要么是0则忘掉,所以还是这个原则:因记忆能力有限,记住重要的,忘记无关紧要的。

2.2 LSTM核心

记忆细胞(Memory Cell) 是LSTM网络的核心,负责在整个序列处理过程中保持和更新长期依赖信息。记忆单元的结构相对简单,主要由一个或多个神经元组成,其状态通过时间步传递,仅通过线性方式更新。

在这里插入图片描述
LSTM有通过精心设计的称作为“门”的结构来去除或者增加信息到记忆细胞状态的能力。门是一种让信息选择式通过的方法。他们包含一个sigmoid神经网络层和一个pointwise乘法的非线性操作。

0代表“不许任何量通过”,1就指“允许任意量通过”!从而使得网络就能了解哪些数据是需要遗忘,哪些数据是需要保存。在这里插入图片描述


2.3 遗忘门(Forget Gate)

LSTM第一步是决定我们会从细胞状态中丢弃什么信息,这个决定通过一个称为 “遗忘门” 的结构完成。

遗忘门会读取上一个输出 h t − 1 h_{t-1} ht1 和当前输入 x t x_t xt,做一个sigmoid的非线性映射,然后输出一个向量 f t f_t ft(该向量每一个维度的值都在0到1之间,1表示完全保留,0表示完全舍弃,相当于记住了重要的,忘记了无关紧要的),最后与细胞状态 C t − 1 C_{t-1} Ct1 相乘。

在这里插入图片描述

  • W f W_f Wf 权值是不共享的: f t = σ ( W f h h t − 1 + W f x x t + b f ) f_t = \sigma(W_{fh}h_{t-1}+W_{fx}x_t+b_f) ft=σ(Wfhht1+Wfxxt+bf)

2.4 输入门(Input Gate)

这一步是确定什么样的新信息被存放在细胞状态中。包含两个部分:

  • sigmoid层决定哪些值将要更新
  • tanh层创建一个新的候选值向量 C ~ t \tilde C_t C~t,该向量被加入状态中。

在这里插入图片描述

  • i t = σ ( W i h h t − 1 + W i x x t + b i ) i_t = \sigma(W_{ih}h_{t-1}+W_{ix}x_t+b_i) it=σ(Wihht1+Wixxt+bi)
  • C ~ t = t a n h ( W C h h t − 1 + W C x x t + b C ) \tilde C_t=tanh(W_{Ch}h_{t-1}+W_{Cx}x_t+b_C) C~t=tanh(WChht1+WCxxt+bC)

2.5 细胞状态

更新旧细胞状态, C t − 1 C_{t-1} Ct1 更新为 C t C_t Ct

我们把旧状态与 f t f_t ft 相乘,丢弃掉我们确定需要丢弃的信息,接着加上 i t ∗ C ~ t i_t * \tilde C_t itC~t,这就是新的候选值。

在这里插入图片描述

2.6 输出门(Output Gate)

最终,输出门负责决定记忆单元状态的哪一部分将被输出到隐藏状态。包含两个操作:

  • sigmoid层确定细胞状态的哪个部分将输出
  • tanh层处理细胞状态(得到一个-1到1之间的值),并将其与sigmoid门的输出相乘

在这里插入图片描述

  • o t = σ ( W o h h t − 1 + W o x x t + b o ) o_t=\sigma(W_{oh}h_{t-1}+W_{ox}x_t+b_o) ot=σ(Wohht1+Woxxt+bo)

3. LSTM网络结构总结

在这里插入图片描述

  • 遗忘门:决定从单元状态中丢弃哪些信息 f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) f_t=\sigma\left(W_f\cdot[h_{t-1},x_t] + b_f\right) ft=σ(Wf[ht1,xt]+bf)
  • 输入门:两部分组成:sigmoid层决定哪些值将被更新,tanh层创建一个新的候选值向量 i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) C ~ t = tanh ⁡ ( W C ⋅ [ h t − 1 , x t ] + b C ) \begin{aligned}i_{t}&=\sigma\left(W_i\cdot[h_{t-1},x_t] + b_i\right)\\\tilde{C}_{t}&=\tanh(W_C\cdot[h_{t-1},x_t] + b_C)\end{aligned} itC~t=σ(Wi[ht1,xt]+bi)=tanh(WC[ht1,xt]+bC)
  • 细胞状态:更新结合了遗忘门和输入门的信息 C t = f t ∗ C t − 1 + i t ∗ C ~ t C_t=f_t*C_{t-1}+i_t*\tilde{C}_t Ct=ftCt1+itC~t
  • 输出门:决定输出哪些信息,同时输出的值通过tanh函数进行缩放 o t = σ ( W o [ h t − 1 , x t ] + b o ) h t = o t ∗ tanh ⁡ ( C t ) \begin{aligned}&o_{t}=\sigma\left(W_o [ h_{t-1},x_t] + b_o\right)\\&h_{t}=o_t*\tanh\left(C_t\right)\end{aligned} ot=σ(Wo[ht1,xt]+bo)ht=ottanh(Ct)

4. 梯度消失与爆炸问题

在标准的RNN中,梯度消失或爆炸问题是一个常见的问题,这会导致网络难以学习长期依赖关系。LSTM通过引入门控机制来解决这个问题。

梯度消失意味着随着时间的推移,梯度值逐渐减小,导致网络权重更新非常缓慢。梯度爆炸则是指梯度值随着时间的推移而变得非常大,导致权重更新过于剧烈,从而影响学习过程。

LSTM通过以下方式缓解这些问题:

  • 遗忘门允许网络有选择性地保留或遗忘信息,这有助于防止无关信息的积累。
  • 输入门允许网络更新单元状态,但仅当新输入与单元状态相关时。

通过这种方式,LSTM可以维持梯度在一个合理的范围内,避免消失或爆炸。

此外,现代的优化算法,如Adam或RMSprop,也可以有效缓解这些问题,它们通过调整学习率来适应每个参数的更新需求。



GRU(Gate Recurrent Unit,门控循环单元)

1. 什么是GRU?

GRU(Gate Recurrent Unit)门控循环单元,是循环神经网络(RNN)的变体,与LSTM类似,通过门控单元解决RNN中不能长期记忆和反向传播中的梯度等问题。

简单来说,GRU简化了LSTM的结构,将遗忘门和输入门合并为一个单一的 “更新门”,并且合并了细胞状态和隐藏状态。

GRU的核心思想是减少模型参数,同时保持对长短期依赖的记忆能力。


2. GRU的网络结构

在这里插入图片描述

更新门 z t z_t zt 和重置门 r t r_t rt 都是对 h t − 1 h_{t-1} ht1 x t x_t xt 做的sigmoid非线性映射,区别在哪?

更新门控制信息的流动,而重置门则决定了之前的记忆有多少应该被保留。

2.1 重置门(Reset Gate)

重置门记为 r t r_t rt,这个门决定了之前的记忆有多少应该被保留(或者理解为控制以往状态的影响程度)。也就是说,重置门控制着前一状态的信息 h t − 1 h_{t-1} ht1 传入候选状态 h t h_t ht 的比例,重置门 r t r_t rt 的值越小,则与 h t − 1 h_{t-1} ht1 的乘积越小, h t − 1 h_{t-1} ht1 的信息添加到 h t h_t ht 的越少。

计算时会结合前一时间步的隐藏状态 h t − 1 h_{t-1} ht1 和当前输入 x t x_t xt,输出是一个0到1之间的值。值越接近1表示越多地保留之前的状态,越接近0表示遗忘更多旧状态。对应的数学表达如下:
r t = σ ( W r ⋅ [ h t − 1 , x t ] ) r_t=\sigma (W_r\cdot[h_{t-1},x_t]) rt=σ(Wr[ht1,xt])

2.2 更新门(Update Gate)

更新门记为 z t z_t zt,这个门决定了上一时间步的记忆状态有多少需要传递到当前步,以及当前的输入信息有多少需要加到这个新的记忆状态中。也就是说,更新门用于控制前一状态的信息 h t − 1 h_{t-1} ht1 有多少保留到新状态 h t h_t ht 中,当 1 − z t 1-z_t 1zt越大,保留的信息越多。

同样,它也是基于 h t − 1 h_{t-1} ht1 x t x_t xt计算得到的。
z t = σ ( W z ⋅ [ h t − 1 , x t ] ) z_t=\sigma (W_z\cdot[h_{t-1},x_t]) zt=σ(Wz[ht1,xt])

2.3 候选记忆状态(candidate memory)

新的候选记忆 h ~ t \tilde h_t h~t 是基于当前输入 x t x_t xt、上一时间步的隐藏状态 h t − 1 h_{t-1} ht1 以及重置门的输出 r t r_t rt 三者得到的。其中重置门决定了如何重置旧的记忆状态,以便更好地整合新信息。
h ~ t = t a n h ( W ⋅ [ r t ∗ h t − 1 , x t ] ) \tilde h_t = tanh(W\cdot[r_t*h_{t-1},x_t]) h~t=tanh(W[rtht1,xt])

2.4 最终记忆状态(hidden state)

更新后的隐藏状态 h t h_t ht 为最终记忆状态,通过结合更新门的输出 z t z_t zt、候选记忆状态 h ~ t \tilde h_t h~t 以及上一时间步的记忆状态 h t − 1 h_{t-1} ht1 计算得出的。其中更新门决定了新旧记忆的混合比例。
h t = ( 1 − z t ) ∗ h t − 1 + z t ∗ h ~ t h_t=(1-z_t)*h_{t-1}+z_t*\tilde h_t ht=(1zt)ht1+zth~t

3. GRU网络结构总结

在这里插入图片描述

  • 重置门:控制前一个状态在当前时间步骤的计算中保留多少历史信息,帮助模型决定忽略多少之前的信息。
    • r t = σ ( W r ⋅ [ h t − 1 , x t ] ) r_t=\sigma (W_r\cdot[h_{t-1},x_t]) rt=σ(Wr[ht1,xt])
    • 输出接近于0:表示较多地忽略前一个隐状态的信息
    • 输出接近于1:表示较多地保留前一个隐状态的信息
  • 更新门:控制当前时间步的候选隐状态对最终隐状态更新的贡献程度,有助于模型决定在每一步保留多少之前时刻的信息。
    • z t = σ ( W z ⋅ [ h t − 1 , x t ] ) z_t=\sigma (W_z\cdot[h_{t-1},x_t]) zt=σ(Wz[ht1,xt])
    • 输出接近于0:表示较少地更新当前时间步的隐状态
    • 输出接近于1:表示较多地更新当前时间步的隐状态
  • 候选隐藏状态: h ~ t = t a n h ( W ⋅ [ r t ∗ h t − 1 , x t ] ) \tilde h_t = tanh(W\cdot[r_t*h_{t-1},x_t]) h~t=tanh(W[rtht1,xt])
  • 最终隐藏状态: h t = ( 1 − z t ) ∗ h t − 1 + z t ∗ h ~ t h_t=(1-z_t)*h_{t-1}+z_t*\tilde h_t ht=(1zt)ht1+zth~t

GRU通过这种方式,实现了对信息的动态过滤和更新,同时减少了模型的复杂性。由于其结构的简化,GRU在某些任务上能够更快地训练,并且在某些情况下能够与LSTM相媲美或甚至更优。

4. GRU为何能够缓解梯度消失?

在传统的RNN中,由于长时间依赖问题,反向传播过程中梯度可能会因连续乘以小于1的数而变得非常小,导致早期时间步的权重几乎不更新,这就是梯度消失问题。

而GRU通过其独特的门控机制,特别是更新门和重置门的设计,能够更加灵活地控制信息流,可以更好地捕获时间步距离很长的序列上的依赖关系。

  • 重置门有助于捕获序列中的短期依赖关系。
    • 重置门帮助模型决定忽略多少之前的信息。重置门可以用来减少那些不太相关信息的影响,从而保护模型不会把注意力放在不相关的长期依赖上。当选择忽略一些不相关的信息时,梯度将不会在这部分信息上进行传递,这有助于集中于更相关的信息,并有助于梯度完整地在其他相关部分传递。
  • 更新门有助于捕获序列中的长期依赖关系。
    • 更新门有助于模型决定在每一步中应该保留多少之前时刻的信息。它可以让模型在需要的时候保持激活状态,这样有助于后续的梯度传递而不会随时间迅速减小。如果更新门接近1,那么梯度可以在很多时间步内传递而不衰减,使得长期依赖的信息得到保留。
  • 重置门打开时,门控循环单元包含基本循环神经网络;更新门打开时,门控循环单元可以跳过子序列。

因为有了这样的机制,GRU能够在每次更新中将梯度既不是完全传递也不是完全阻断,而是能够在相关的部分进行传递。这样在优化过程中,即使对于较长的序列,也能够更加稳定地保留梯度,防止了梯度极端消失,这对于学习长期依赖至关重要。因此,GRU往往在处理长序列数据时比传统RNN更加有效。



BiGRU(双向GRU)

BiGRU(双向门控循环单元)是一种改进的循环神经网络(RNN)结构,它由两个独立的GRU层组成,一个沿正向处理序列,另一个沿反向处理序列。这种双向结构使得BiGRU能够捕捉到序列中的长距离依赖关系,从而提高模型的性能。

在这里插入图片描述

首先,对于一个输入序列 X = x 1 , x 2 , … , x T X = x_1,x_2,\dots,x_T X=x1,x2,,xT,BiGRU模型的前向计算可以表示为:
h t → = G R U ( h t − 1 → , x t ) h t ← = G R U ( h t + 1 ← , x t ) \overrightarrow{h_t}=\mathrm{GRU}(\overrightarrow{h_{t-1}},x_t)\\\\\overleftarrow{h_t}=\mathrm{GRU}(\overleftarrow{h_{t+1}},x_t) ht =GRU(ht1 ,xt)ht =GRU(ht+1 ,xt)

其中, h t → \overrightarrow{h_t} ht h t ← \overleftarrow{h_t} ht 分别表示从左到右和从右到左的隐藏状态, G R U GRU GRU 表示GRU单元, x t x_t xt 表示输入序列中的第 t t t 个元素。

然后,将两个方向的隐藏状态拼接在一起,得到最终的隐藏状态 h t h_t ht
h t = [ h t → ; h t ← ] h_t=[\overrightarrow{h_t};\overleftarrow{h_t}] ht=[ht ;ht ]
其中, [ ⋅ ; ⋅ ] [\cdot;\cdot] [;] 表示向量的拼接操作。

最后,将隐藏状态 h t h_t ht 传递给一个全连接层,得到输出 y t y_t yt
y t = s o f t m a x ( W h t + b ) y_t=\mathrm{softmax}(Wh_t+b) yt=softmax(Wht+b)



参考文献

  1. 循环神经网络(Recurrent Neural Networks)
  2. 如何从RNN起步,一步一步通俗理解LSTM
  3. 【深度学习:Recurrent Neural Networks】循环神经网络(RNN)的简要概述
  4. 神经网络之lstm
  5. 循环神经网络 RNN、LSTM、GRU
  6. 人工智能(pytorch)搭建模型12-pytorch搭建BiGRU模型
;