c5w3_序列模型和注意力机制

发布时间 2023-11-18 13:49:21作者: newbe3three

序列模型和注意力机制

Seq2Seq模型

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

image

和上述模型的似的结构,被应用于图像描述(image captioning)。图像描述的模型编码器可以是AlexNet结构,然后去掉最后一层的softmax单元,将AlexNet输出的特征向量输入作为解码器的RNN,RNN的输出序列就是对图像的一个描述。

image

对于上述的两个Seq2Seq模型,和之前讨论的使用语言模型产生新文本还有差别,主要在于,我们不希望模型输出的结果是随机的翻译或图片描述,而是选择可能性最大的结果输出。

选择可能的句子

Seq2Seq机器翻译和之前讨论的语言模型有一些相似,但是在输出结果这块有很大的不同。我们可以把机器翻译看作是构建一个条件语言模型(condition language model)

下图是两个模型的对比,可以看出机器翻译模型的解码器部分和语言模型是类似的,差别在于,机器翻译模型解码器的第一个输入来自于解码器,而语言模型固定地输入\(a^{<0>}\)这个0向量。

所以机器翻译模型可以看作是在输入为编码器的输出的条件下,求语言模型的输出。

image

机器翻译模型计算的是条件概率,

\[P(y^{<1>},...,y^{<T_y>}|x^{<1>},...,x^{<T_x>}) \]

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

\[argmax_{y^{1},...,y^{T_{y}}}P(y^{<1>},...,y^{<T_y>}|x) \]

解决此问题最常使用的算法是集束搜索(Beam Search)

为什么不用贪心搜索(greedy search),贪心搜索(Greedy Search),贪心搜索得到的是当前时间步的条件概率最大的词,然后再下一步挑出这一步对应的最好的词,而我们希望的是整个语句的条件概率最大。

集束搜索(Beam Search)会考虑每个时间步多个可能的选择。每个时间步中解码器预选单词的数量设为集束宽(Beam Width)*\(B\)

继续以法语翻译为例,当\(B=3\)时,

第一个时间步选择概率最大的三个单词作为预选词,条件概率为\(P(\hat y^{<1>} |x)\)。可能选到的单词是:in、jane、september

image

第二步中,分别将三个预选词作为第二个时间步的输入,得到 \(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⟩}) \]

设词汇表中有10000个单词,则当\(B=3\)时,有3*10000 个 \(P(\hat y^{⟨1⟩}, \hat y^{⟨2⟩}|x)\),还是从中选择概率最大的3个,作为对应第一个词条件下的第二个词的预选词。

最终可能的候选是:in september, jane is, jane visits(第一个单词是september的情况已经被剔除了)。我们将30000的搜索范围,收缩为3个候选。

image

第3步和第2步类似,可能继续得到3个候选:in september jane, jane is visiting, jane visits africa

image

以此类推,最后输出一个符合如下公式的最优的结果:

\[arg\, max\prod_{t=1}^{T_y}P(\hat y^{(t)}|x,\hat y^{(1)},...,\hat y^{t-1}) \]

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

改进集束搜索

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

\[arg\, max\prod_{t=1}^{T_y}P(\hat y^{(t)}|x,\hat y^{(1)},...,\hat y^{t-1}) \]

当多个小于1的概率值相乘后,数字变得非常小以至于计算机的浮点数不能精确表达,会造成数值下溢(Numerical Underflow)。因此,我们会取\(log\)值,

\[arg\, max\sum_{t=1}^{T_y}logP(\hat y^{(t)}|x,\hat y^{(1)},...,\hat y^{t-1}) \]

因为每个条件概率都小于1,当如果一上面的公式作为最优化方案,尽管已经从求乘积变成了求和,模型总是会选择那些短的句子作为翻译的结果,因为句子越短上面的公式值越大,所以我们还要进行标准化,增加对语句太短的惩罚,则有:

\[arg\, \frac{1}{T^{a}_y}max\sum_{t=1}^{T_y}logP(\hat y^{(t)}|x,\hat y^{(1)},...,\hat y^{t-1}) \]

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

对于集束宽\(B\)的取值,较大的\(B\)值意味着可能更好的结果但是更大的计算成本;较小的\(B\)值意味着可能较差的计算结果和较小的计算成本。\(B\)的大小取决于应用场景,比如论文中可能为了榨取全部性能\(B=1000--3000\)。通常来说\(B\)可以取10以下的值。

另外,需要明白的是beam search和计算机中的其他搜索算法,如广度优先搜索(BFS)、深度优先搜索(DFS)不一样,它们都是精确的搜索算法。而beam search是一个近似搜索算法,并不保证搜索到实际的最大值。

误差分析

集束搜索时一种启发式搜索算法,其输出的结果不总为最优值。当结合Seq2Seq模型和集束搜索算法所构建出的系统出错(比如没有输出最佳的翻译结果甚至是错误的结果)时,我们可以通过误差分析来弄清楚错误产生于RNN网络模型还是集束搜索算法中。

例如,对于下图中人工和机器的翻译结果

image

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

  • 如果 \(P(y^* | x) > P(\hat y | x)\),说明是集束搜索算法出现错误,没有选择到概率最大的词;
  • 如果 \(P(y^* | x) \le P(\hat y | x)\),说明是 RNN 模型的效果不佳,\(y^*\)是更好的翻译结果,但是预测的第四个词为“in”的概率小于“last”。

所以错误分析的做法是,建立一个如下的表格,记录每一对错误的分析,有助于判断错误出现在RNN模型还是集束搜索算法中。如果很多错误都出现子集束搜索算法中,可以考虑增大集束宽\(B\);否则,需要进一步分析RNN,看是需要正则化、更多训练数据还是尝试构建的新的RNN结构。

image

Bleu得分

注意力模型

对于一大段文字,将句子完整记下来再翻译是比较困难的,所以人工翻译一般每次阅读并翻译一段内容,然后再重复这个过程。同理,对于Seq2Seq模型建立的机器翻译系统,对于比较常的句子,Bleu得分会随着输入句子的序列边长而降低得分。

image

所以,我们也并不希望神经网络每次去“记忆”很长一段文字再去翻译,而是希望能够像人工翻译一样,一部分一部分去翻译。因此注意力模型(Attention Model)被提出。目前,注意力模型已经称为深度学习领域最具有影响力的思想之一。

image

注意力模型的结构如上图所示。其中,底层是一个双向循环的神经网络(BRNN)作为编码器。该BRNN中每个时间步都的激活都包含向前传播和向后传播两部分产生的激活,在这里把这两部分合起来,即:

\[a^{(t^{'})}=(\overrightarrow a^{<t^{'}>},\overleftarrow a^{<t^{'}>}) \]

其中\(t^{'}\)是用来描述BRNN的中时间步数。

顶层是一个”多对多“的结构的循环神经网络,对于这个RNN我们用\(s\)来表述其激活函数,主要是为了和BRNN做出区别。

在这个RNN中第 \(t\) 个时间步的输入包含该网络中前一个时间步的激活 \(s^{\langle t-1 \rangle}\)、输出 \(y^{\langle t-1 \rangle}\) 以及底层的 BRNN 中所有时间步的输出\(a^{(t^{'})}\)乘以对应的注意力权重(attention weights)参数 \(\alpha^{<t,t^{'}>}\)构成的\(c^{t}\),即(注意分辨 \(\alpha\)\(a\)):

\[c^{<t>} = \sum_{t’}\alpha^{<t,t^{'}>}a^{(t^{'})} \]

其中\(t^{}\)是用来描述顶层RNN的中时间步数。

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

\[\sum_{t{'}}\alpha^{<t,t^{'}>}=1 \]

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

\[a^{\langle t,t'\rangle} = \frac{\text{exp}(e^{\langle t,t'\rangle})}{\sum^{T_x}_{t'=1} \text{exp}(e^{\langle t,t'\rangle})} \]

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

image

注意力模型的一个缺点是时间复杂度为 \(O(n^2d)\)\(d\)代表输入序列的嵌入维度。

语音识别

在语音识别任务中,输入的是一段以时间为横轴的音频序列数据,输出的是文本序列数据。Seq2Seq模型可以应用于此。

音频数据的常见预处理步骤是运行音频片段来生成声谱图,并将其作为特征。以前的语音识别系统是通过语音专家人工设计的音位(Phonemes)来构建的,音位指的是一种语言中能区别两个词的最小语音单位。

现在端到端的系统中,通过深度学习网络模型,就可以实现输入一段音频输出对应的文本。

对于训练基于深度学习的语音识别系统,大规模的数据集是有必要的。学术研究中通常使用300小时长度的音频数据,而商业应用甚至操过了一万小时的音频数据来训练模型。

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

image

用了CTC(Connectionist Temporal Classification)损失函数来做语音识别的效果也不错。

在这种方法下,将构建非常深的RNN模型(这里使用单向RNN说明,实践中会用基于GRU 的BRNN)。由于输入的是音频数据,使用RNN所建立的系统包含有很多个时间步,且输出量通常小于输入量。

因此,不是每一个时间步都有对应的输出。CTC 允许 RNN 生成下图红字所示的输出,并将两个空白符(blank)中重复的字符折叠起来,再将空白符去掉,得到最终的输出文本。

image

这样就允许整个网络有1000个有重复的字母的输出,但最终仍能得到短得多的文本输出。

触发词检测

触发词检测(Trigger Word Detection)常用于各种智能设备,通过约定的触发词可以语音唤醒设备。相比通用的语音识别系统需要大量训练数据,触发词检测要简单得多,使用较小的数据量即可训练。

使用 RNN 来实现触发词检测时,我们要做的就是把一个音频片段计算出它的声谱图特征(spectrogram features),得到的特征向量\(x^{<1>},x^{<2>},x^{<3>},...x^{<n>}\)输入到RNN中。将触发词对应的序列的标签设置为“1”,而将其他的标签设置为“0”

image

上面的算法有一个明显的缺点是,构建了一个很不平衡的训练集,即0比1要多得多。但有一个简单粗暴的办法可以解决,是的训练更容易。我们在一个时间步上输出1后,在变回0之前多输出几次1,或者在固定的一段时间内输出多个1。