Skip to content

6. 循环神经网络

6.1 语言模型

语言模型(language model)是自然语言处理的重要技术。自然语言处理中最常见的数据是文本数据。我们可以把一段自然语言文本看作一段离散的时间序列。

假设一段长度为 T 的文本中的词依次为 w1,w2,,wT,那么在离散的时间序列中,wt1tT)可看作在时间步(time step) t 的输出或标签。给定一个长度为 T 的词的序列 w1,w2,,wT,语言模型将计算该序列的概率:

P(w1,w2,,wT)

语言模型可用于提升语音识别和机器翻译的性能。

6.1.1 语言模型的计算

假设序列 w1,w2,,wT 中的每个词是依次生成的,我们有

我们有

P(w1,w2,,wT)=t=1TP(wtw1,,wt1)

为了计算语言模型,我们需要计算词的概率,以及一个词在给定前几个词的情况下的条件概率,即语言模型参数。设训练数据集为一个大型文本语料库。词的概率可以通过该词在训练数据集中的相对词频来计算。根据条件概率定义,一个词在给定前几个词的情况下的条件概率也可以通过训练数据集中的相对词频计算。

6.1.2 n元语法

当序列长度增加时,计算和存储多个词共同出现的概率的复杂度会呈指数级增加。n 元语法通过马尔可夫假设(虽然并不一定成立)简化了语言模型的计算。这里的马尔可夫假设是指一个词的出现只与前面 n 个词相关,即 n 阶马尔可夫链(Markov chain of order n)。

如果基于 n1 阶马尔可夫链,我们可以将语言模型改写为

P(w1,w2,,wT)t=1TP(wtwt(n1),,wt1)

以上也叫 n 元语法(n-grams)。它是基于n−1n - 1n−1阶马尔可夫链的概率语言模型。当n 分别为1、2和3时,我们将其分别称作一元语法(unigram)、二元语法(bigram)和三元语法(trigram)。

n 较小时,n 元语法往往并不准确。然而,当 n 较大时,n 元语法需要计算并存储大量的词频和多词相邻频率。

6.2 循环神经网络

循环神经网络并非刚性地记忆所有固定长度的序列,而是通过隐藏状态来存储之前时间步的信息。

6.2.1 不含隐藏状态的神经网络

考虑一个含单隐藏层的多层感知机。样本数为 n,特征数为 d 的小批量样本 X\Rn×d,隐藏层激活函数为 ϕ,隐藏层输出为 H\Rn×h,输出个数为 q,输出变量 O\Rn×q

H=ϕ(XWxh+bh)O=HWhq+bq

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

现在我们考虑输入数据存在时间相关性的情况。我们保存上一时间步的隐藏变量 Ht1,并引入一个新的权重参数 WhhRh×h,该参数用来描述在当前时间步如何使用上一时间步的隐藏变量。时间步 t 的隐藏变量的计算由当前时间步的输入和上一时间步的隐藏变量共同决定:

Ht=ϕ(XtWxh+Ht1Whh+bh)

与多层感知机相比,我们在这里添加了 Ht1Whh 一项。这里的隐藏变量能够捕捉截至当前时间步的序列的历史信息,就像是神经网络当前时间步的状态或记忆一样。因此,该隐藏变量也称为隐藏状态。由于隐藏状态在当前时间步的定义使用了上一时间步的隐藏状态,上式的计算是循环的。使用循环计算的网络即循环神经网络(recurrent neural network)。

循环神经网络有很多种不同的构造方法。含上式所定义的隐藏状态的循环神经网络是极为常见的一种。在时间步 t,输出层的输出和多层感知机中的计算类似:

Ot=HtWhq+bq

循环神经网络的参数包括隐藏层的权重 WxhRd×hWhhRh×h和偏差 bhR1×h,以及输出层的权重 WhqRh×q 和偏差 bqR1×q。值得一提的是,即便在不同时间步,循环神经网络也始终使用这些模型参数。因此,循环神经网络模型参数的数量不随时间步的增加而增长。

在时间步ttt,隐藏状态的计算可以看成是将输入 Xt 和前一时间步隐藏状态 Ht1 连结后输入一个激活函数为 ϕ 的全连接层。该全连接层的输出就是当前时间步的隐藏状态 Ht,且模型参数为 WxhWhh 的连结,偏差为 bh。当前时间步 t 的隐藏状态 Ht 将参与下一个时间步 t+1 的隐藏状态 Ht+1 的计算,并输入到当前时间步的全连接输出层。

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

6.2.3 应用:基于字符级循环神经网络的语言模型

字符级循环神经网络(character-level recurrent neural network)

6.3 语言模型数据集

6.3.1 读取数据集

6.3.2 建立字符索引

我们将每个字符映射成一个从0开始的连续整数,又称索引,来方便之后的数据处理。之后,将训练数据集中每个字符转化为索引。

6.3.3 时序数据的采样

在训练中我们需要每次随机读取小批量样本和标签。与之前章节的实验数据不同的是,时序数据的一个样本通常包含连续的字符。我们有两种方式对时序数据进行采样,分别是随机采样和相邻采样。

6.3.3.1 随机采样

在随机采样中,每个样本是原始序列上任意截取的一段序列。相邻的两个随机小批量在原始序列上的位置不一定相毗邻。因此,我们无法用一个小批量最终时间步的隐藏状态来初始化下一个小批量的隐藏状态。在训练模型时,每次随机采样前都需要重新初始化隐藏状态。

6.3.3.2 相邻采样

除对原始序列做随机采样之外,我们还可以令相邻的两个随机小批量在原始序列上的位置相毗邻。这时候,我们就可以用一个小批量最终时间步的隐藏状态来初始化下一个小批量的隐藏状态,从而使下一个小批量的输出也取决于当前小批量的输入,并如此循环下去。

这对实现循环神经网络造成了两方面影响:一方面, 在训练模型时,我们只需在每一个迭代周期开始时初始化隐藏状态;另一方面,当多个相邻小批量通过传递隐藏状态串联起来时,模型参数的梯度计算将依赖所有串联起来的小批量序列。同一迭代周期中,随着迭代次数的增加,梯度的计算开销会越来越大。

为了使模型参数的梯度计算只依赖一次迭代读取的小批量序列,我们可以在每次读取小批量前将隐藏状态从计算图中分离出来。我们将在下一节(循环神经网络的从零开始实现)的实现中了解这种处理方式。

6.4 循环神经网络的从零开始实现

6.4.1 one-hot向量

为了将词表示成向量输入到神经网络,一个简单的办法是使用one-hot向量。假设词典中不同字符的数量为 N(即词典大小vocab_size),每个字符已经同一个从0到 N1 的连续整数值索引一一对应。如果一个字符的索引是整数 i, 那么我们创建一个全0的长为 N 的向量,并将其位置为 i 的元素设成1。该向量就是对原字符的one-hot向量。

Released under the MIT License.