序列模型与注意力机制

文章目录
  1. 1. Seq2Seq 模型
    1. 1.1. 选择最可能的句子
  2. 2. 集束搜索
    1. 2.1. 优化:长度标准化
    2. 2.2. 误差分析
  3. 3. Bleu 得分
  4. 4. 注意力模型
  5. 5. 语音识别
  6. 6. 触发词检测
  7. 7. 代码示例

Seq2Seq 模型

Seq2Seq(Sequence-to-Sequence)模型能够应用于机器翻译、语音识别等各种序列到序列的转换问题。一个 Seq2Seq 模型包含编码器(Encoder)解码器(Decoder)两部分,它们通常是两个不同的 RNN。如下图所示,将编码器的输出作为解码器的输入,由解码器负责输出正确的翻译结果。

提出 Seq2Seq 模型的相关论文:

这种编码器-解码器的结构也可以用于图像描述(Image captioning)。将 AlexNet 作为编码器,最后一层的 Softmax 换成一个 RNN 作为解码器,网络的输出序列就是对图像的一个描述。

图像描述的相关论文:

选择最可能的句子

机器翻译用到的模型与语言模型相似,只是用编码器的输出作为解码器第一个时间步的输入(而非 0)。因此机器翻译的过程其实相当于建立一个条件语言模型。

由于解码器进行随机采样过程,输出的翻译结果可能有好有坏。因此需要找到能使条件概率最大化的翻译,即

$$arg \ max_{y^{⟨1⟩}, …, y^{⟨T_y⟩}}P(y^{⟨1⟩}, …, y^{⟨T_y⟩} | x)$$

鉴于贪心搜索算法得到的结果显然难以不符合上述要求,解决此问题最常使用的算法是 集束搜索(Beam Search)


集束搜索

集束搜索会考虑每个时间步多个可能的选择。设定一个 集束宽(Bean Width)B,代表了解码器中每个时间步的预选单词数量。例如 B=3,则将第一个时间步最可能的三个预选单词及其概率值 $P(\hat y^{⟨1⟩}|x)$ 保存到计算机内存,以待后续使用。

第二步中,分别将三个预选词作为第二个时间步的输入,得到 $P(\hat y^{⟨2⟩}|x, \hat y^{⟨1⟩})$。

因为我们需要的其实是第一个和第二个单词对(而非只有第二个单词)有着最大概率,因此根据条件概率公式,有:

$P(\hat y^{⟨1⟩}, \hat y^{⟨2⟩}|x) = P(\hat y^{⟨1⟩}|x) P(\hat y^{⟨2⟩}|x, \hat y^{⟨1⟩})$

设词典中有 $N$ 个词,则当 $B=3$ 时,有 $3*N$ 个 $P(\hat y^{⟨1⟩}, \hat y^{⟨2⟩}|x)$。仍然取其中概率值最大的 3 个,作为对应第一个词条件下的第二个词的预选词。以此类推,最后输出一个最优的结果,即结果符合公式:

$$arg \ max \prod^{T_y}_{t=1} P(\hat y^{⟨t⟩} | x, \hat y^{⟨1⟩}, …, \hat y^{⟨t-1⟩})$$

可以看到,当 $B=1$ 时,集束搜索就变为贪心搜索。

优化:长度标准化

长度标准化(Length Normalization)是对集束搜索算法的优化方式。对于公式

$$arg \ max \prod^{T_y}_{t=1} P(\hat y^{⟨t⟩} | x, \hat y^{⟨1⟩}, …, \hat y^{⟨t-1⟩})$$

当多个小于 1 的概率值相乘后,会造成 数值下溢(Numerical Underflow),即得到的结果将会是一个电脑不能精确表示的极小浮点数。因此,我们会取 log 值,并进行标准化:

$$arg \ max \frac{1}{T_y^{\alpha}} \sum^{T_y}_{t=1} logP(\hat y^{⟨t⟩} | x, \hat y^{⟨1⟩}, …, \hat y^{⟨t-1⟩})$$

其中,$T_y$ 是翻译结果的单词数量,$α$ 是一个需要根据实际情况进行调节的超参数。标准化用于减少对输出长的结果的惩罚(因为翻译结果一般没有长度限制)。

关于集束宽 B 的取值,较大的 B 值意味着可能更好的结果和巨大的计算成本;而较小的 B 值代表较小的计算成本和可能表现较差的结果。通常来说,B 可以取一个 10 以下的值。

和 BFS、DFS 等精确的查找算法相比,集束搜索算法运行速度更快,但是不能保证一定找到 arg max 准确的最大值。

误差分析

集束搜索是一种启发式搜索算法,其输出结果不总为最优。当结合 Seq2Seq 模型和集束搜索算法所构建的系统出错(没有输出最佳翻译结果)时,我们通过误差分析来分析错误出现在 RNN 模型还是集束搜索算法中。

例如,对于下述两个由人工和算法得到的翻译结果:

Human: Jane visits Africa in September. (y∗)
Algorithm: Jane visited Africa last September. (y∗)

将翻译中没有太大差别的前三个单词作为解码器前三个时间步的输入,得到第四个时间步的条件概率 $P(y^* | x)$ 和 $P(\hat y | x)$,比较其大小并分析:

如果 $P(y^ | x) > P(\hat y | x)$,说明是集束搜索算法出现错误,没有选择到概率最大的词;
如果 $P(y^
| x) \le P(\hat y | x)$,说明是 RNN 模型的效果不佳,预测的第四个词为“in”的概率小于“last”。
建立一个如下图所示的表格,记录对每一个错误的分析,有助于判断错误出现在 RNN 模型还是集束搜索算法中。如果错误出现在集束搜索算法中,可以考虑增大集束宽 B;否则,需要进一步分析,看是需要正则化、更多数据或是尝试一个不同的网络结构。


Bleu 得分

Bleu(Bilingual Evaluation Understudy) 得分用于评估机器翻译的质量,其思想是机器翻译的结果越接近于人工翻译,则评分越高。

最原始的 Bleu 将机器翻译结果中每个单词在人工翻译中出现的次数作为分子,机器翻译结果总词数作为分母得到。但是容易出现错误,例如,机器翻译结果单纯为某个在人工翻译结果中出现的单词的重复,则按照上述方法得到的 Bleu 为 1,显然有误。改进的方法是将每个单词在人工翻译结果中出现的次数作为分子,在机器翻译结果中出现的次数作为分母。

上述方法是以单个词为单位进行统计,以单个词为单位的集合称为unigram(一元组)。而以成对的词为单位的集合称为bigram(二元组)。对每个二元组,可以统计其在机器翻译结果($count$)和人工翻译结果($count_{clip}$)出现的次数,计算 Bleu 得分。

以此类推,以 n 个单词为单位的集合称为n-gram(多元组),对应的 Blue(即翻译精确度)得分计算公式为:

$$p_n = \frac{\sum_{\text{n-gram} \in \hat y}count_{clip}(\text{n-gram})}{\sum_{\text{n-gram} \in \hat y}count(\text{n-gram})}$$

对 N 个 pn 进行几何加权平均得到:

$$p_{ave} = exp(\frac{1}{N}\sum^N_{i=1}log^{p_n})$$

有一个问题是,当机器翻译结果短于人工翻译结果时,比较容易能得到更大的精确度分值,因为输出的大部分词可能都出现在人工翻译结果中。改进的方法是设置一个最佳匹配长度(Best Match Length),如果机器翻译的结果短于该最佳匹配长度,则需要接受 简短惩罚(Brevity Penalty,BP)

$$
BP =
\begin{cases}
1, &MT_length \ge BM_length \\
exp(1 - \frac{MT_length}{BM_length}), &MT_length \lt BM_length
\end{cases}
$$
因此,最后得到的 Bleu 得分为:

$$Blue = BP \times exp(\frac{1}{N}\sum^N_{i=1}log^{p_n})$$

Bleu 得分的贡献是提出了一个表现不错的单一实数评估指标,因此加快了整个机器翻译领域以及其他文本生成领域的进程。

相关论文:neni et. al., 2002. A method for automatic evaluation of machine translation


注意力模型

对于一大段文字,人工翻译一般每次阅读并翻译一小部分。因为难以记忆,很难每次将一大段文字一口气翻译完。同理,用 Seq2Seq 模型建立的翻译系统,对于长句子,Blue 得分会随着输入序列长度的增加而降低。

实际上,我们也并不希望神经网络每次去“记忆”很长一段文字,而是想让它像人工翻译一样工作。因此,注意力模型(Attention Model)被提出。目前,其思想已经成为深度学习领域中最有影响力的思想之一。

注意力模型的一个示例网络结构如上图所示。其中,底层是一个双向循环神经网络(BRNN),该网络中每个时间步的激活都包含前向传播和反向传播产生的激活:

$$a^{\langle t’ \rangle} = ({\overrightarrow a}^{\langle t’ \rangle}, {\overleftarrow a}^{\langle t’ \rangle})$$

顶层是一个“多对多”结构的循环神经网络,第 t 个时间步的输入包含该网络中前一个时间步的激活 $s^{\langle t-1 \rangle}$、输出 $y^{\langle t-1 \rangle}$ 以及底层的 BRNN 中多个时间步的激活 c,其中 c 有(注意分辨 α 和 a):

$$c^{\langle t \rangle} = \sum_{t’}\alpha^{\langle t,t’ \rangle}a^{\langle t’ \rangle}$$

其中,参数 $\alpha^{\langle t,t’ \rangle}$ 即代表着 $y^{\langle t \rangle}$ 对 $a^{\langle t’ \rangle}$ 的“注意力”,总有:

$$\sum_{t’}\alpha^{\langle t,t’ \rangle} = 1$$

我们使用 Softmax 来确保上式成立,因此有:

$$\alpha^{\langle t,t’ \rangle} = \frac{exp(e^{\langle t,t’ \rangle})}{\sum^{T_x}_{t’=1}exp(e^{\langle t,t’ \rangle})}$$

而对于 $e^{\langle t,t’ \rangle}$,我们通过神经网络学习得到。输入为 $s^{\langle t-1 \rangle}$ 和 $a^{\langle t’ \rangle}$,如下图所示:

注意力模型的一个缺点是时间复杂度为 $O(n^3)$。

相关文章:带Attention机制的Seq2Seq框架梳理

相关论文:


语音识别

在语音识别任务中,输入是一段以时间为横轴的音频片段,输出是文本。

音频数据的常见预处理步骤是运行音频片段来生成一个声谱图,并将其作为特征。以前的语音识别系统通过语言学家人工设计的音素(Phonemes)来构建,音素 指的是一种语言中能区别两个词的最小语音单位。现在的端到端系统中,用深度学习就可以实现输入音频,直接输出文本。

对于训练基于深度学习的语音识别系统,大规模的数据集是必要的。学术研究中通常使用 3000 小时长度的音频数据,而商业应用则需要超过一万小时的数据。

语音识别系统可以用注意力模型来构建,一个简单的图例如下:

用 CTC(Connectionist Temporal Classification)损失函数来做语音识别的效果也不错。由于输入是音频数据,使用 RNN 所建立的系统含有很多个时间步,且输出数量往往小于输入。因此,不是每一个时间步都有对应的输出。CTC 允许 RNN 生成下图红字所示的输出,并将两个空白符(blank)中重复的字符折叠起来,再将空白符去掉,得到最终的输出文本。

相关论文:Graves et al., 2006. Connectionist Temporal Classification: Labeling unsegmented sequence data with recurrent neural networks


触发词检测

触发词检测(Trigger Word Detection)常用于各种智能设备,通过约定的触发词可以语音唤醒设备。

使用 RNN 来实现触发词检测时,可以将触发词对应的序列的标签设置为“1”,而将其他的标签设置为“0”。


代码示例

序列模型和注意力机制