GRU循环神经网络 - Python中预测序列的智能方法

2025年1月5日 | 阅读6分钟

Cho 等人 (2014) 提出了门控循环单元 (GRU),一种循环神经网络 (RNN) 的类型,作为长短期记忆 (LSTM) 网络的更简单替代方案。GRU 能够处理序列数据,包括音频、文本和时间序列数据,正如 LSTM 一样。

GRU 的基本原理是使用门控方法仅在选定的时间步子集上更新网络的隐藏状态。进入和离开网络的信息由门控机制管理。重置门和更新门是 GRU 的两个门控机制。

更新门定义了应该使用多少新输入来更新隐藏状态,而重置门指示应该忽略多少先前的隐藏状态。更新后的隐藏状态作为计算 GRU 输出的基础。

以下公式用于确定 GRU 的重置门、更新门和隐藏状态

总而言之,GRU 网络是一种 RNN,它们通过使用门控技术在每个时间步选择性地更新隐藏状态,从而能够有效地表示序列数据。在许多自然语言处理任务中,包括语音识别、机器翻译和语言建模,都已证明其有效性。

许多改进被创建以解决在基本循环神经网络的运行过程中经常遇到的梯度消失-爆炸问题。长短期记忆网络 (LSTM) 是最著名的变体之一。门控循环单元网络是一个鲜为人知但同样有效的变体 (GRU)。

它只有三个门,并且不像 LSTM 那样保留内部单元状态。门控循环单元的隐藏状态包含了 LSTM 循环单元的内部单元状态中存储的信息。下面的门控循环单元接收此聚合数据。下面是 GRU 各个门的描述

  1. 更新门 (z):它确定了需要传输到未来的历史信息量。它类似于 LSTM 循环单元的输出门。
  2. 重置门 (r):它决定了应该遗忘多少过去的信息。它类似于 LSTM 循环单元中的输入门和遗忘门如何协同工作。
  3. 当前记忆门 (\overline{h}_{t} ):在正常的门控循环单元网络讨论中,它经常被忽略。它用于添加一些非线性和使输入均值为零,并且它像输入调制门是输入门的一个子部分一样集成到重置门中。减少过去知识对当前传输到未来的信息的影响是将其包含为重置门子组件的另一个原因。

当描绘时,门控循环单元网络和基本循环神经网络的基本工作流程是相似的。两者之间的主要区别在于每个循环单元内部的功能,因为门控循环单元网络由门组成,这些门调制当前输入和先前的隐藏状态。

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

门控循环单元的工作原理

  • 假设有两个向量作为输入:当前输入和先前的隐藏状态。
  • 利用下述程序,确定三个不同门的值
    1. 通过对每个门的权重执行元素乘法 (Hadamard 积),可以将参数化的当前输入和先前的隐藏状态向量与相关向量相乘。
    2. 在参数化向量上,逐个元素地应用每个门适当的激活函数。下面是门列表以及需要为每个门使用的激活函数。
  • 计算当前记忆门的方法略有不同。首先,计算先前的隐藏状态向量和重置门的 Hadamard 积。然后,将此向量参数化并添加到已参数化的现有输入向量中。
    GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python
  • 为了确定当前生效的隐藏状态,必须首先创建一个与输入维度相同的向量。该向量在数学上称为“全 1”向量,表示为 1。首先,找到更新门和先前的隐藏状态向量的 Hadamard 积。从全 1 向量中减去更新门以创建一个新向量,然后将所得向量的 Hadamard 积乘以记忆门的当前值。最后将两个向量相加即可得到当前隐藏的状态向量。
GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

上述工作表述如下:

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

请注意,元素乘法由蓝色圆圈表示。向量减法 (负值向量加法) 由圆圈中的负号表示,而向量加法由圆圈中的正号表示。对于每个门,权重矩阵 W 为先前的隐藏状态和当前输入向量分配了不同的权重。

GRU 网络在每个时间步都会产生一个输出,就像循环神经网络一样,并使用梯度下降来训练网络。

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

需要注意的是,与工作流程类似,GRU 网络的训练过程在图上与简单循环神经网络的训练过程相似,只是每个循环单元内部的功能有所不同。

门控循环单元网络与长短期记忆网络的时间反向传播算法之间的主要区别在于微分链的构建。

设每个时间步的实际输出为 y_{t} ,期望输出为 \overline{y}_{t} 。那么,每个时间步的误差由下式给出:

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

因此,所有时间步的误差之和即为总误差。

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

同样,\frac{\partial E}{\partial W} 的值可以计算为每个时间步的梯度之和。

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

利用链式法则,并利用 \overline{y}_{t} 是 h_{t} 的函数,而 h_{t} 又是 \overline{h}_{t} 的函数这一事实,得出以下表达式:

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

因此,总误差梯度如下:-

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

需要注意的是,尽管梯度方程的 \partial {h}_{t} 链与简单循环神经网络的相似,但由于 h_{t} 的导数内部结构方式不同,其功能也不同。

门控循环单元如何解决梯度消失问题?

从 \frac{\partial h_{t}}{\partial h_{t-1}} 开始的导数链控制着梯度的值。请记住 h_{t} 的以下公式:-

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

使用上述表达式,\frac{\partial {h}_{t}}{\partial {h}_{t-1}} 的值为:-

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

请记住 \overline{h}_{t} 的以下公式:-

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

使用上述表达式计算 \frac{\partial \overline{h_{t}}}{\partial h_{t-1}} 的值:-

GRU Recurrent Neural Networks - A Smart Way to Predict Sequences in Python

由于 Sigmoid 函数用作更新门和重置门的激活函数,因此它们的值只能是 0 或 1。

情况 1 (z = 1)

在这种情况下,无论 r 的值是多少,\frac{\partial \overline{h_{t}}}{\partial h_{t-1}} 项都等于 z,而 z 又等于 1。

情况 2A (z=0 且 r=0)

在这种情况下,\frac{\partial \overline{h_{t}}}{\partial h_{t-1}} 项等于 0。

情况 2B (z=0 且 r=1)

在这种情况下,(1-\overline{h}_{t}^{2})(W) 是 \frac{\partial \overline{h_{t}}}{\partial h_{t-1}} 表达式的值。网络学习修改权重以使 \frac{\partial \overline{h_{t}}}{\partial h_{t-1}} 项接近 1。该值由可训练的权重矩阵确定。

因此,时间反向传播算法修改相应权重以使导数链的值尽可能接近 1。