循环神经网络 (neural network) (RNN)逐步处理序列信息,同时保持内部记忆。实现此功能的基本构件是简单RNN单元。
可将RNN单元视为在序列中每个时间步运行的计算引擎。对于输入序列中的每个元素 xt(在时间步 t),该单元接收两个输入:
- 当前输入元素 xt。
- 来自上一时间步的隐藏状态 ht−1。
利用这些输入,该单元执行计算以生成两个输出:
- 新的隐藏状态 ht。此状态捕获当前输入 xt 的信息,以及来自所有先前步骤的相关上下文 (context)(概括于 ht−1 中)。它作为网络的记忆,并传递给下一时间步。
- 可选输出 yt。这是网络专门为当前时间步 t 生成的预测或结果。是否在每一步都产生输出取决于具体任务(例如,预测下一个单词每步需要一个输出,而情感分类可能只需要在整个序列处理完后得到一个输出)。
RNN单元内部
简单RNN单元内的核心计算包含结合当前输入和先前隐藏状态,使用学习到的权重 (weight)和激活函数 (activation function)。本章引言展示了基本方程:
ht=f(Whhht−1+Wxhxt+bh)
yt=g(Whyht+by)
我们来逐一分析:
- Wxh: 一个将输入 xt 进行转换的权重矩阵。
- Whh: 一个将先前隐藏状态 ht−1 进行转换的权重矩阵。这是循环权重矩阵,捕获过去信息的影响。
- bh: 一个添加到隐藏状态计算中的偏置 (bias)向量 (vector)。
- f: 隐藏状态的激活函数。这里的常见选择是双曲正切 (
tanh),它将值压缩到 [-1, 1] 的范围。这有助于调节信息流并减轻一些梯度问题(尽管不能完全解决,正如我们稍后将了解的)。
- Why: 一个将当前隐藏状态 ht 进行转换以产生输出 yt 的权重矩阵。
- by: 一个添加到输出计算中的偏置向量。
- g: 输出 yt 的激活函数。g 的选择取决于任务(例如,分类使用
softmax,回归使用线性函数)。
此架构的一个重要特点是权重共享。相同的权重矩阵 (Wxh, Whh, Why) 和偏置 (bh, by) 在每个时间步都使用。这意味着网络学习一套参数 (parameter)来明确如何处理输入元素并更新其记忆,无论该元素在序列中的位置如何。这使得RNN在参数上具有高效性,并且能够泛化处理不同长度的序列。
单元和循环的可视化
我们可以可视化单个RNN单元及其连接:
单个RNN单元处理输入 xt 和先前状态 ht−1,以计算得到新状态 ht 和输出 yt。权重 (weight)矩阵 (Wxh, Whh, Why) 在这些转换过程中应用。
真正的作用体现在将这些单元链接起来,形成循环连接。在时间步 t 计算得到的隐藏状态 ht 成为时间步 t+1 单元的输入 ht−1。这种时间上的“展开”使得信息能够流经序列:
一个RNN在三个时间步上展开。每个时间步由单元计算得到的隐藏状态 (ht) 作为输入传递给下一时间步 (t+1) 的单元。每个时间步都使用相同的单元参数 (parameter)(权重 W 和偏置 (bias) b)。
这种展开视图很有帮助,尤其是在思考梯度在训练期间如何反向流动(时间反向传播 (backpropagation))时,我们将在接下来讨论这个。然而,请记住,在实际应用中,是相同的单元结构(具有相同的权重)被重复应用,而不是每个时间步都有不同的副本。这种结构使得RNN能够使用固定数量的参数处理任意长度的序列。