6. 循环神经网络
6.1 语言模型
语言模型(language model)是自然语言处理的重要技术。自然语言处理中最常见的数据是文本数据。我们可以把一段自然语言文本看作一段离散的时间序列。
假设一段长度为
语言模型可用于提升语音识别和机器翻译的性能。
6.1.1 语言模型的计算
假设序列
我们有
为了计算语言模型,我们需要计算词的概率,以及一个词在给定前几个词的情况下的条件概率,即语言模型参数。设训练数据集为一个大型文本语料库。词的概率可以通过该词在训练数据集中的相对词频来计算。根据条件概率定义,一个词在给定前几个词的情况下的条件概率也可以通过训练数据集中的相对词频计算。
6.1.2 n元语法
当序列长度增加时,计算和存储多个词共同出现的概率的复杂度会呈指数级增加。
如果基于
以上也叫
当
6.2 循环神经网络
循环神经网络并非刚性地记忆所有固定长度的序列,而是通过隐藏状态来存储之前时间步的信息。
6.2.1 不含隐藏状态的神经网络
考虑一个含单隐藏层的多层感知机。样本数为
6.2.2 含隐藏状态的循环神经网络
现在我们考虑输入数据存在时间相关性的情况。我们保存上一时间步的隐藏变量
与多层感知机相比,我们在这里添加了
循环神经网络有很多种不同的构造方法。含上式所定义的隐藏状态的循环神经网络是极为常见的一种。在时间步
循环神经网络的参数包括隐藏层的权重
在时间步ttt,隐藏状态的计算可以看成是将输入
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向量。假设词典中不同字符的数量为 vocab_size
),每个字符已经同一个从0到