1. 语言模型

语⾔模型(language model)是⾃然语⾔处理的重要技术。⾃然语⾔处理中最常⻅的数据是⽂本数据。我们可以把⼀段⾃然语⾔⽂本看作⼀段离散的时间序列。 假设⼀段⻓度为 $T$ 的⽂本中的词依次为 $w_1,w_2,\cdots,w_T$,那么在离散的时间序列中,$w_t(1\le  t \le T)$可看作在时间步(time step)$t$的输出或标签。给定⼀个⻓度为$T$的词的序列$w_1,w_2,\cdots,w_T$,语⾔模型将计算该序列的概率:

$$P(w_1,w_2,\cdots,w_T)$$

1.1 语⾔模型的计算

假设序列$w_1,w_2,\cdots,w_T$中的每个词是依次⽣成的,我们有
$$P(w_1,w_2,\cdots,w_T)=\prod^{T}_{t=1}P(w_t | w_1,\cdots,w_{t-1}).$$

例如,⼀段含有4个词的⽂本序列的概率

$$P(w_1,w_2,w_3,w_4)=P(w_1)P(w_2|w_1)P(w_3|w_1,w_2)P(w_4|w_1,w_2,w_3).$$

1.2 n元语法

当序列⻓度增加时,计算和存储多个词共同出现的概率的复杂度会呈指数级增加。$n$ 元语法通过⻢尔可夫假设(虽然并不⼀定成⽴)简化了语⾔模型的计算。这⾥的⻢尔可夫假设是指⼀个词的出现只与前⾯ $n$ 个词相关,即 $n$ 阶⻢尔可夫链(Markov chain of ordern)。如果 $n=1$,那么有$P(w_3|w_1,w_2)=P(w_3|w_2)$。如果基于 $n-1$ 阶⻢尔可夫链,我们可以将语⾔模型改写为

$$P(w_1,w_2,\cdots,w_T) \approx \prod^{T}_{t=1}P(w_t | w_{t-(n-1)},\cdots,w_{t-1}).$$

以上也叫 $n$ 元语法(n-grams)。它是基于 $n-1$ 阶⻢尔可夫链的概率语⾔模型。

2. 循环神经⽹络

上⼀节介绍的 $n$ 元语法中,时间步 $t$ 的词 $w_t$ 基于前⾯所有词的条件概率只考虑了最近时间步的 $n-1$ 个词。如果要考虑⽐ $t-(n-1)$ 更早时间步的词对 $w_t$ 的可能影响,我们需要增⼤ $n$。但这样模型参数的数量将随之呈指数级增⻓。

本节将介绍循环神经⽹络。它并⾮刚性地记忆所有固定⻓度的序列,而是通过隐藏状态来存储之前时间步的信息。

2.1 不含隐藏状态的神经⽹络

让我们考虑⼀个含单隐藏层的多层感知机。给定样本数为 $n$、输⼊个数(特征数或特征向量维度)为 $d$ 的小批量数据样本$X\in R^{n\times d}$。设隐藏层的激活函数为$\phi$,那么隐藏层的输出 $H\in R^{n\times h}$计算为

$$H=\phi(XW_{xh}+b_h).$$

其中隐藏层权重参数 $W_{xh}\in R^{d\times h}$,隐藏层偏差参数 $b_h \in R^{1\times h}$ ,$h$ 为隐藏单元个数。 把隐藏变量 $H$ 作为输出层的输⼊,且设输出个数为 $q$(如分类问题中的类别数),输出层的输出为

$$O = HW_{hq} +b_q.$$

其中输出变量 $O \in R^{h\times q}$, 输出层权重参数 $W_{hq}\in R^{h \times q}$, 输出层偏差参数 $b_q \in R^{1\times q}$

2.2 含隐藏状态的循环神经⽹络

现在我们考虑输⼊数据存在时间相关性的情况。假设 $X_t \in R^{n\times d}$ 是序列中时间步 $t$ 的小批量输⼊,$H_t \in R^{n\times h}$是该时间步的隐藏变量。与多层感知机不同的是,这⾥我们保存上⼀时间步的隐藏变量$H_{t-1}$,并引⼊⼀个新的权重参数 $W_{hh}\in R^{h\times h}$,该参数⽤来描述在当前时间步如何使⽤上⼀时间步的隐藏变量。具体来说,时间步t的隐藏变量的计算由当前时间步的输⼊和上⼀时间步的隐藏变量共同决定:

$$H_t = \phi(X_tW_{xh}+H_{t-1}W_{hh}+b_H).$$

与多层感知机相比, 我们在这里添加了 $\boldsymbol{H}_{t-1} \boldsymbol{W}_{h h}$ 一项。由上式中相邻时间步的隐藏变量 $\boldsymbol{H}_{t}$ 和 $\boldsymbol{H}_{t-1}$ 之间的关系可 知, 这里的隐藏变量能够捕捉截至当前时间步的序列的历史信息, 就像是神经网络当前时间步的状态或记忆一样。因 此,该隐藏变量也称为隐藏状态。由于隐藏状态在当前时间步的定义使用了上一时间步的隐藏状态,上式的计算是循 环的。使用循环计算的网络即循环神经网络(recurrent neural network)。

循环神经网络有很多种不同的构造方法。含上式所定义的隐藏状态的循环神经网络是极为常见的一种。若无特别说明,本章中的循环神经网络均基于上式中隐藏状态的循环计算。在时间步 $t$,输出层的输出和多层感知机中的计算类似:\[\boldsymbol{O}_t = \boldsymbol{H}_t \boldsymbol{W}_{hq} + \boldsymbol{b}_q.\]

循环神经网络的参数包括隐藏层的权重 $\boldsymbol{W}_{xh} \in \mathbb{R}^{d \times h}$、$\boldsymbol{W}_{hh} \in \mathbb{R}^{h \times h}$ 和偏差 $\boldsymbol{b}_h \in \mathbb{R}^{1 \times h}$,以及输出层的权重$\boldsymbol{W}_{hq} \in \mathbb{R}^{h \times q}$ 和偏差 $\boldsymbol{b}_q \in \mathbb{R}^{1 \times q}$。值得一提的是,即便在不同时间步,循环神经网络也始终使用这些模型参数。因此,循环神经网络模型参数的数量不随时间步的增加而增长。

下图展示了循环神经网络在 3 个相邻时间步的计算逻辑。在时间步 $t$, 隐藏状态的计算可以看成是将输入 $\boldsymbol{X}_{t}$ 和前一时 间步隐藏状态 $\boldsymbol{H}_{t-1}$ 连结后输入一个激活函数为 $\phi$ 的全连接层。该全连接层的输出就是当前时间步的隐藏状态 $\boldsymbol{H}_{t}$, 且模型参数为 $\boldsymbol{W}_{x h}$ 与 $\boldsymbol{W}_{h h}$ 的连结, 偏差为 $\boldsymbol{b}_{h}$ 。当前时间步 $t$ 的隐藏状态 $\boldsymbol{H}_{t}$ 将参与下一个时间步 $t+1$ 的隐藏状态 $\boldsymbol{H}_{t+1}$ 的计算,并输入到当前时间步的全连接输出层。

含隐藏状态的循环神经网络

3. 门控循环单元(GRU)

门控循环神经网络(gated recurrent neural network)的提出,正是为了更好地捕捉时间序列中时间步距离较大的依赖关系。它通过可以学习的门来控制信息的流动。其中,门控循环单元(gated recurrent unit,GRU)是一种常用的门控循环神经网络。它引入了重置门(reset gate)和更新门(update gate)的概念,从而修改了循环神经网络中隐藏状态的计算方式。

3.1 重置门和更新门

门控循环单元中的重置门和更新门的输入均为当前时间步输入 $X_t$ 与上一时间步隐藏状态 $H_{t-1}$,输出由激活函数为sigmoid函数的全连接层计算得到。

门控循环单元中重置门和更新门的计算

具体来说, 假设隐藏单元个数为 $h$, 给定时间步 $t$ 的小批量输入 $\boldsymbol{X}_{t} \in \mathbb{R}^{n \times d}$ (样本数为 $n$, 输入个数为 $d$ ) 和上一时 间步隐藏状态 $\boldsymbol{H}_{t-1} \in \mathbb{R}^{n \times h}$ 。重置门 $\boldsymbol{R}_{t} \in \mathbb{R}^{n \times h}$ 和更新门 $\boldsymbol{Z}_{t} \in \mathbb{R}^{n \times h}$ 的计算如下:
$$
\begin{aligned}
\boldsymbol{R}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x r}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h r}+\boldsymbol{b}_{r}\right) \\
\boldsymbol{Z}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x z}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h z}+\boldsymbol{b}_{z}\right)
\end{aligned}
$$
其中 $\boldsymbol{W}_{x r}, \boldsymbol{W}_{x z} \in \mathbb{R}^{d \times h}$ 和 $\boldsymbol{W}_{h r}, \boldsymbol{W}_{h z} \in \mathbb{R}^{h \times h}$ 是权重参数, $\boldsymbol{b}_{r}, \boldsymbol{b}_{z} \in \mathbb{R}^{1 \times h}$ 是偏差参数。 sigmoid函数可以将元素的值变换到0和 1 之间。因此, 重置门 $\boldsymbol{R}_{t}$ 和更新门 $\boldsymbol{Z}_{t}$ 中每个元素的值域都是 [0,1] 。

3.2 候选隐藏状态

最后, 时间步 $t$ 的隐藏状态 $\boldsymbol{H}_{t} \in \mathbb{R}^{n \times h}$ 的计算使用当前时间步的更新门 $\boldsymbol{Z}_{t}$ 来对上一时间步的隐藏状态 $\boldsymbol{H}_{t-1}$ 和当前 时间步的候选隐藏状态 $\tilde{\boldsymbol{H}}_{t}$ 做组合:
$$
\boldsymbol{H}_{t}=\boldsymbol{Z}_{t} \odot \boldsymbol{H}_{t-1}+\left(1-\boldsymbol{Z}_{t}\right) \odot \tilde{\boldsymbol{H}}_{t}
$$

门控循环单元中隐藏状态的计算。这里的 ⊙ 是按元素乘法

值得注意的是, 更新门可以控制隐藏状态应该如何被包含当前时间步信息的候选隐藏状态所更新, 如上图所示。假设更新门在时间步 $t^{\prime}$ 到 $t\left(t^{\prime}<t\right)$ 之间一直近似 1 。那么, 在时间步 $t^{\prime}$ 到 $t$ 之间的输入信息几乎没有流入时间步 $t$ 的隐藏状态 $\boldsymbol{H}_{t}$ 。实际上,这可以看作是较早时刻的隐藏状态 $\boldsymbol{H}_{t^{\prime}-1}$ 一直通过时间保存并传递至当前时间步 $t$。 这个设计可以应对循环神经网络中的梯度衰减问题, 并更好地捕捉时间序列中时间步距离较大的依赖关系。

我们对门控循环单元的设计稍作总结:

  • 重置门有助于捕捉时间序列里短期的依赖关系;
  • 更新门有助于捕捉时间序列里长期的依赖关系。

4. 长短期记忆(LSTM)

LSTM 中引入了3个门,即输入门(input gate)、遗忘门(forget gate)和输出门(output gate),以及与隐藏状态形状相同的记忆细胞(某些文献把记忆细胞当成一种特殊的隐藏状态),从而记录额外的信息。

4.1 输入门、遗忘门和输出门

与门控循环单元中的重置门和更新门一样, 如下图所示, 长短期记忆的门的输入均为当前时间步输入 $\boldsymbol{X}_{t}$ 与上一时间 步隐藏状态 $\boldsymbol{H}_{t-1}$, 输出由激活函数为 sigmoid函数的全连接层计算得到。如此一来, 这3个门元素的值域均为 [0,1]。

长短期记忆中输入门、遗忘门和输出门的计算

具体来说, 假设隐藏单元个数为 $h$, 给定时间步 $t$ 的小批量输入 $\boldsymbol{X}_{t} \in \mathbb{R}^{n \times d}$ (样本数为 $n$, 输入个数为 $d$ ) 和上一时 间步隐藏状态 $\boldsymbol{H}_{t-1} \in \mathbb{R}^{n \times h}$ 。时间步 $t$ 的输入门 $\boldsymbol{I}_{t} \in \mathbb{R}^{n \times h}$ 、遗忘门 $\boldsymbol{F}_{t} \in \mathbb{R}^{n \times h}$ 和输出门 $\boldsymbol{O}_{t} \in \mathbb{R}^{n \times h}$ 分别计算如 下:
$$
\begin{aligned}
\boldsymbol{I}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x i}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h i}+\boldsymbol{b}_{i}\right) \\
\boldsymbol{F}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x f}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h f}+\boldsymbol{b}_{f}\right) \\
\boldsymbol{O}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x o}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h o}+\boldsymbol{b}_{o}\right)
\end{aligned}
$$
其中的 $\boldsymbol{W}_{x i}, \boldsymbol{W}_{x f}, \boldsymbol{W}_{x o} \in \mathbb{R}^{d \times h}$ 和 $\boldsymbol{W}_{h i}, \boldsymbol{W}_{h f}, \boldsymbol{W}_{h o} \in \mathbb{R}^{h \times h}$ 是权重参数, $\boldsymbol{b}_i, \boldsymbol{b}_f, \boldsymbol{b}_o \in \mathbb{R}^{1 \times h}$是偏差参数。

4.2 候选记忆细胞

接下来,长短期记忆需要计算候选记忆细胞 $\tilde{\boldsymbol{C}}_{t}$。它的计算与上面介绍的3个门类似,但使用了值域在 [−1,1] 的 tanh 函数作为激活函数,如下图所示。

长短期记忆中候选记忆细胞的计算

具体来说, 时间步 $t$ 的候选记忆细胞 $\tilde{\boldsymbol{C}}_{t} \in \mathbb{R}^{n \times h}$ 的计算为

\[\tilde{\boldsymbol{C}}_{t}=\tanh \left(\boldsymbol{X}_{t} \boldsymbol{W}_{x c}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h c}+\boldsymbol{b}_{c}\right)\]

其中 $\boldsymbol{W}_{x c} \in \mathbb{R}^{d \times h}$ 和 $\boldsymbol{W}_{h c} \in \mathbb{R}^{h \times h}$ 是权重参数,  $\boldsymbol{b}_{c} \in \mathbb{R}^{1 \times h}$ 是偏差参数。

4.3 记忆细胞

我们可以通过元素值域在 [0,1] 的输入门、遗忘门和输出门来控制隐藏状态中信息的流动, 这一般也是通过使用按元素乘法 (符号为 $\odot$ ) 来实现的。当前时间步记忆细胞 $\boldsymbol{C}_{t} \in \mathbb{R}^{n \times h}$ 的计算组合了上一时间步记忆细胞和当前时间步候选记忆细胞的信息,并通过遗忘门和输入门来控制信息的流动:

$$
\boldsymbol{C}_{t}=\boldsymbol{F}_{t} \odot \boldsymbol{C}_{t-1}+\boldsymbol{I}_{t} \odot \tilde{\boldsymbol{C}}_{t}
$$

如下图所示, 遗忘门控制上一时间步的记忆细胞 $C_{t-1}$ 中的信息是否传递到当前时间步, 而输入门则控制当前时间步 的输入 $\boldsymbol{X}_{t}$ 通过候选记忆细胞 $\tilde{\boldsymbol{C}}_{t}$ 如何流入当前时间步的记忆细胞。如果遗忘门一直近似1且输入门一直近似 0 , 过去的记忆细胞将一直通过时间保存并传递至当前时间步。这个设计可以应对循环神经网络中的梯度衰减问题, 并更好地 捕捉时间序列中时间步距离较大的依赖关系。

长短期记忆中记忆细胞的计算。这里的 ⊙ 是按元素乘法

4.4 隐藏状态

有了记忆细胞以后, 接下来我化管:可以通过输出门来控制从记忆细胞到隐藏状态 $\boldsymbol{H}_{t} \in \mathbb{R}^{n \times h}$ 的信息的流动:

$$
\boldsymbol{H}_{t}=\boldsymbol{O}_{t} \odot \tanh \left(\boldsymbol{C}_{t}\right)
$$

这里的 tanh 函数确保隐藏状态元素值在-1到1之间。需要注意的是, 当输出门近似 1 时, 记忆细胞信息将传递到隐藏状 态供输出层使用; 当输出门近似 0 时, 记忆细胞信息只自己保留。下图展示了长短期记忆中隐藏状态的计算。

长短期记忆中隐藏状态的计算。这里的 ⊙ 是按元素乘法

5. 深度循环神经网络

在深度学习应用里,我们通常会用到含有多个隐藏层的循环神经网络,也称作深度循环神经网络。下图演示了一个有 L 个隐藏层的深度循环神经网络,每个隐藏状态不断传递至当前层的下一时间步和当前时间步的下一层。

深度循环神经网络的架构

具体来说, 在时间步 $t$ 里, 设小批量输入 $\boldsymbol{X}_{t} \in \mathbb{R}^{n \times d}$ (样本数为 $n$, 输入个数为 $d$ ), 第 $l$ 隐藏层 $(l=1, \ldots, L)$ 的隐藏状态为 $\boldsymbol{H}_{t}^{(l)} \in \mathbb{R}^{n \times h}$ (隐藏单元个数为 $h$ ) , 输出层变量为 $\boldsymbol{O}_{t} \in \mathbb{R}^{n \times q}$ (输出个数为 $q$ ) , 且隐藏层的激活函数为 $\phi_{\circ}$ 第 1 隐藏层的隐藏状态和之前的计算一样:
$$
\boldsymbol{H}_{t}^{(1)}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(1)}+\boldsymbol{H}_{t-1}^{(1)} \boldsymbol{W}_{h h}^{(1)}+\boldsymbol{b}_{h}^{(1)}\right)
$$
其中权重 $\boldsymbol{W}_{x h}^{(1)} \in \mathbb{R}^{d \times h} 、 \boldsymbol{W}_{h h}^{(1)} \in \mathbb{R}^{h \times h}$ 和偏差 $\boldsymbol{b}_{h}^{(1)} \in \mathbb{R}^{1 \times h}$ 分别为第1隐藏层的模型参数。 当 $1<l \leq L$ 时, 第 $l$ 隐藏层的隐藏状态的表达式为

$$
\boldsymbol{H}_{t}^{(l)}=\phi\left(\boldsymbol{H}_{t}^{(l-1)} \boldsymbol{W}_{x h}^{(l)}+\boldsymbol{H}_{t-1}^{(l)} \boldsymbol{W}_{h h}^{(l)}+\boldsymbol{b}_{h}^{(l)}\right)
$$

其中权重 $\boldsymbol{W}_{x h}^{(l)} \in \mathbb{R}^{h \times h} 、 \boldsymbol{W}_{h h}^{(l)} \in \mathbb{R}^{h \times h}$ 和偏差 $\boldsymbol{b}_{h}^{(l)} \in \mathbb{R}^{1 \times h}$ 分别为第 $l$ 隐藏层的模型参数。 最终, 输出层的输出只需基于第 $L$ 隐藏层的隐藏状态:

$$
\boldsymbol{O}_{t}=\boldsymbol{H}_{t}^{(L)} \boldsymbol{W}_{h q}+\boldsymbol{b}_{q}
$$

其中权重 $\boldsymbol{W}_{h q} \in \mathbb{R}^{h \times q}$ 和偏差 $\boldsymbol{b}_{q} \in \mathbb{R}^{1 \times q}$ 为输出层的模型参数。

同多层感知机一样, 隐藏层个数 $L$ 和隐藏单元个数 $h$ 都是超参数。此外, 如果将隐藏状态的计算换成门控循环单元或 者长短期记忆的计算,我们可以得到深度门控循环神经网络。

6. 双向循环神经网络

之前介绍的循环神经网络模型都是假设当前时间步是由前面的较早时间步的序列决定的,因此它们都将信息通过隐藏状态从前往后传递。有时候,当前时间步也可能由后面时间步决定。例如,当我们写下一个句子时,可能会根据句子后面的词来修改句子前面的用词。双向循环神经网络通过增加从后往前传递信息的隐藏层来更灵活地处理这类信息。下图演示了一个含单隐藏层的双向循环神经网络的架构。

双向循环神经网络的架构

下面我们来介绍具体的定义。 给定时间步 $t$ 的小批量输入 $\boldsymbol{X}_{t} \in \mathbb{R}^{n \times d}$ (样本数为 $n$, 输入个数为 $d$ ) 和隐藏层激活函 数为 $\phi_{\circ}$ 在双向循环神经网络的架构中, 设该时间步正向隐藏状态为 $\overrightarrow{\boldsymbol{H}}_{t} \in \mathbb{R}^{n \times h}$ (正向隐藏单元个数为 $h$ ) , 反向 隐藏状态为 $\overleftarrow{\boldsymbol{H}}_{t} \in \mathbb{R}^{n \times h}$ (反向隐藏单元个数为 $h$ ) 。我们可以分别计算正向隐藏状态和反向隐藏状态:

$$
\begin{aligned}
&\overrightarrow{\boldsymbol{H}}_{t}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(f)}+\overrightarrow{\boldsymbol{H}}_{t-1} \boldsymbol{W}_{h h}^{(f)}+\boldsymbol{b}_{h}^{(f)}\right) \\
&\overleftarrow{\boldsymbol{H}}_{t}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(b)}+\overleftarrow{\boldsymbol{H}}_{t+1} \boldsymbol{W}_{h h}^{(b)}+\boldsymbol{b}_{h}^{(b)}\right)
\end{aligned}
$$

其中权重 $\boldsymbol{W}_{x h}^{(f)} \in \mathbb{R}^{d \times h} 、 \boldsymbol{W}_{h h}^{(f)} \in \mathbb{R}^{h \times h} 、 \boldsymbol{W}_{x h}^{(b)} \in \mathbb{R}^{d \times h} 、 \boldsymbol{W}_{h h}^{(b)} \in \mathbb{R}^{h \times h}$ 和偏差 $\boldsymbol{b}_{h}^{(f)} \in \mathbb{R}^{1 \times h}, \boldsymbol{b}_{h}^{(b)} \in \mathbb{R}^{1 \times h}$ 均为模型参数。
然后我们连结两个方向的隐藏状态 $\overrightarrow{\boldsymbol{H}}_{t}$ 和 $\overleftarrow{\boldsymbol{H}}_{t}$ 来得到隐藏状态 $\boldsymbol{H}_{t} \in \mathbb{R}^{n \times 2 h}$, 并将其输入到输出层。输出层计算输出 $\boldsymbol{O}_{t} \in \mathbb{R}^{n \times q}$ (输出个数为 $q$ ) :

$$
\boldsymbol{O}_{t}=\boldsymbol{H}_{t} \boldsymbol{W}_{h q}+\boldsymbol{b}_{q}
$$

其中权重 $\boldsymbol{W}_{h q} \in \mathbb{R}^{2 h \times q}$ 和偏差 $\boldsymbol{b}_{q} \in \mathbb{R}^{1 \times q}$ 为输出层的模型参数。不同方向上的隐藏单元个数也可以不同。

References

  1. Long short-term memory. [PDF]
  2. On the properties of neural machine translation: Encoder-decoder approaches. [PDF]
  3. Empirical evaluation of gated recurrent neural networks on sequence modeling. [PDF]
  4. Bidirectional recurrent neural networks. [PDF]
  5. Recurrent Neural Networks.