2021斯坦福CS224N课程笔记~7

7. 机器翻译,序列到序列、注意力机制

参考文献:

https://zhuanlan.zhihu.com/p/430709084

https://zhuanlan.zhihu.com/p/147310766 【简易】

https://zhuanlan.zhihu.com/p/47063917 【注意力系列】

https://www.showmeai.tech/article-detail/242

https://zhuanlan.zhihu.com/p/111974764

https://zhuanlan.zhihu.com/p/61928885

讲座计划

今天我们将:

1.引入一个新任务:机器翻译 [15 分钟]

2.一种新的神经架构:序列到序列[45 分钟]

3.一种新的神经技术:注意力 [20 分钟]

7.1.机器翻译的历史

机器翻译(MT)是将一种语言(源语言)的句子 x 翻译成另一种语言(目标语言)的句子 y 的任务。

image-20230315183152212

MT 由军方大量资助,但基本上只是简单的基于规则的系统进行单词替换

7.1.1. 基于规则的方法

​ 基于规则的方法主要有三种。机器翻译的实际系统倾向于将这三种不同方法中的部件进行组合,因此,每一种方法可以看成是一种算法设计空间,而不是确定的算法。

直接(direct)翻译:源语言的单词是一个接着一个地进行形态分析处理,然后利用目标语言的形态,生成目标语言的单词。直接翻译方法使用一部较大的双语词典,词典中的每一个条目相当于翻译每一个词的小程序**(规则)**

转换(transfer)翻译:首先对输入文本进行句法和语义分析,得到句法和语义结构,然后利用规则将这些结构转换到目标语言的句法和语义结构,再利用这些结构生成目标语言。

中间语言(interlingua)翻译:首先对源语言文本进行概念分析,得到抽象的意义表示,这种表示形式称为中间语言,然后根据这种中间表示的概念,生成目标语言。

通常可以利用**沃夸三角形(Vauquois tiangle)**来形象地表示这三种方法,见图 7.2:

image-20230315183917765

​ 从这个三角形可以看出,随着从直接翻译方法、转换方法到中间语言方法的变化,在源语言分析端和目标语言生成端所需要的语言分析程度在不断加深。此外,从这个三角形还可以看出随三角形向上行进,所需要的转换知识的数量在不断递减。在直接方法中,需要大量的转换知识(对每个词来说几乎所有的翻译知识都是转换知识)。在转换方法中,转换规则仅用于句法分析树或是语义角色。在中间语言方法中,不需要特定的转换知识。

​ 2013 年,Recurrent Continuous Translation Models 发表,Nal Kalchbrenner 和 Phil Blunsom 等人在文章中提出了一种用于机器翻译的新型端到端编码器-解码器架构。该模型使用卷积神经网络(CNN)将给定的源文本编码为连续向量,然后使用循环神经网络(RNN)作为解码器将状态向量转换为目标语言。他们的研究为神经机器翻译(NMT)提供了的思想灵感。

​ 2014 年,Bengio 等人提出 Sequence to sequence learning with neural networks,基于 encoder-decoder架构,其中 encoder 和 decoder 都是 RNN 结构,使用的是 LSTM。这个架构也上线到 Google 的翻译中,翻译的质量有些可以超越人类。

​ 2017 年,Ashish Vaswani 等人发表 Attention Is All You Need 论文,提出了著名的 Transformer 模型架构,抛弃了传统的 CNN 和 RNN,整个网络结构完全是由 Attention 机制组成。Transformer 的主要创新点在于multi-head、self-Attenion,基于此,Transformer 可以并行操作,大大加快了训练过程。

​ 2018 年,Jacob Devlin 等人发表 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 论文,引入了一种称为 BERT 的新语言表示模型,它代表来自 Transformers 的双向编码器表示。

7.2.机器翻译 ★

7.2.1. 传统机器翻译(SMT)

  • 早期的(1950s)机器翻译的思路十分简单,通过设置大量的翻译规则,构建一个大型的双语对照表,来将源语言翻译成目标语言。这个固然简单,也自然效果很一般。因此我们不展开描述。

  • 后来(1990s-2010s)我们有了更为先进复杂的机器翻译技术——「统计机器翻译」(Statistical Machine Translation, SMT)。

    • SMT的主要思想就是从大量的数据中学习一个概率模型P(y|x),其中x是源语言(source language),y是目标语言(target language),即x翻译成y的概率有多大。在翻译时,我们只需要通过求argmaxyP(y|x)就行了,即找到概率最大的那个y,就是x的最佳翻译了。

    • 这么一想,是不是感觉跟之前介绍过的语言模型(LM)挺像的?LM是根据一句话的前面几个词,给出下一个词的概率。这里的SMT则是根据source文本给出target文本的概率。但不要搞混淆,这里的x和y不是单个词,而是一句话。我们对P(y|x)通过贝叶斯公式进行转换,可以得到:
      P ( y ∣ x ) = P ( y ) P ( x ∣ y ) P ( x ) 则 a r g m a x y P ( y ∣ x ) = a r g m a x y P ( y ) P ( x ∣ y ) P ( x ) = a r g m a x y P ( y ) P ( x ∣ y ) P(y|x)=\frac{P(y)P(x|y)}{P(x)}则 \\ argmax_yP(y|x)=argmax_y\frac{P(y)P(x|y)}{P(x)}=argmax_yP(y)P(x|y) P(yx)=P(x)P(y)P(xy)argmaxyP(yx)=argmaxyP(x)P(y)P(xy)=argmaxyP(y)P(xy)

  • 这里由于我们是要找出使得上式最大的y,因此只跟x相关的分母可以被省去。跟上面这个公式的变换,我们发现**SMT真的跟语言模型LM是有关的**:

  • P(y)就是求y这个句子的概率,这就是一个**「语言模型」(LM)。而后者P(x|y)则被称为「翻译模型」(TM)。LM可以通过目标语言的语料进行训练,==TM则需要通过「平行语料」**==(parallel corpus,即源和目标两种语言的互相对照的语料,比如“罗塞塔石碑”,上面刻有一份古埃及的诏书的三个语言的版本)进行训练。

  • 有人(我)就奇怪了,原本的P(y|x)不就是一个翻译模型吗?经过这么一分解,不仅还有一个翻译模型,还多了一个语言模型!这不是越搞越复杂吗?

    • 其实不是这样的,翻译模型和语言模型,各自有所偏重
      • 翻译模型通过大量的平行语料,学习到的主要是两种语言之间的对应关系
      • 而语言模型则侧重于学习一种语言内部的语法结构,不同词汇是怎么流畅地组合成句子的。
      • 原本的公式只有一个翻译模型,会导致我们训练出来的模型在翻译结果的语言通畅性方面很差。因此,我们经过公式变换,将一个TM任务转化成TM+LM两种任务,可以模型学习的结果更好
  • 对于TM的学习,一般我们会进一步进行分解,考虑两种语言之间的各种对齐方式(alignment),即在原有的翻译模型上,引入一个隐变量a,得到P(x,a|y),可以理解为给定句子y,按照对齐方式a翻译成x的概率。

    • 具体什么是对齐方式alignment呢?它的意思就是在两种语言A和B之间,A的词是跟B的词怎么对应的。很明显,这种对应关系可以是一对一、一对多、多对一、多对多的。比方下图:
      • image-20230315191144110
      • 这里例子展示了一个法语句子和英语句子词语对齐关系,其中法语词entarte,英文翻译是“hit me with a pie”,英文中根本没有一个词可以直接表示这个含义。中英文中这样的例子更加常见了,有些英文单词可以用一个汉字对应,但也有很多单词需要两个甚至多个汉字对应。另外,同一个词,在不同的语境下,对齐的词和数量都有可能不同,比如“牛”可以对应“cow”也可以对应“awesome”,“cool”可以对应“酷”也可以对应“凉快”。因此,对齐,alignment,是一个十分复杂的东西,学习P(x,a|y)也是很麻烦,这里我也不太了解,就不细讲了。
  • 在学习了LM和TM这两个模型之后,是不是就完事儿了呢?

    • 当然没有,别忘了公式里还有一个argmax,我们要找出最佳的翻译是什么。根据LM和TM寻找最佳y的过程,就称为“decoding”,即解码
      • image-20230315191355392 - 一个最直接的方法就是,**遍历所有可能的y,选择概率最大的那个**,当然就是最佳的翻译。明显,这种方式带来的开销是我们无法忍受的。 - 如果学习过CRF或者HMM,我们应该知道对于这种解码的过程,我们一般**使用动态规划、启发式搜索的方法**来处理。在SMT中具体怎么解码,我们这里也暂时不做深入的研究。
  • 统计机器翻译——SMT,在深度学习时代之前,风光无限,一直是机器翻译的巅峰技术。但是,**SMT的门槛也是很高**的,那些表现优异的SMT模型,通常都是极其复杂的,里面涉及到大量的特征工程,海量的专家知识,无数的资源积累,繁多的功能模块,还需要庞大的人力去维护。这也是我根本不想去深入了解这个技术的原因。

  • 幸好,在深度学习时代,我们有了更好的方法:神经机器翻译(Neural Machine Translation,NMT

7.2.2. 神经机器翻译(NMT)

​ 深度学习的“可恨之处”在于,它把那些需要大量人力的工作都吃掉了,导致行业专家和搬砖工人门纷纷下岗。NMT就是这样,企图就是用一个简洁的神经网络结构,就把机器翻译这么大的一个工程给包下来。 我画了一个形象生动的图来示意SMT和NMT的区别:

image-20230315191832137

NMT使用的神经网络结构,是一种被称为sequence-to-sequence的结构,即**seq2seq。它还有另外一个常见的名字:Encoder-Decoder结构。这种结构一般都是由两个RNN组成**。下面我画了一个抽象的示意图:

image-20230315191953151

​ 从这个抽象示意图上看,seq2seq的结构的Encoder部分读取输入文本,在机器翻译中即源语言文本,通过Encoder编码成一个表示向量,即context vector,然后交给Decoder来进行解码,翻译成目标语言。在训练和预测时,我们都可以使用这样的结构,没有其他的花里胡哨的东西,因此总体上看起来比SMT要简洁明了得多。

​ 上面这张图还是太抽象了,下面让我们深入seq2seq结构的内部,看看我们如何使用这个结构来进行训练和预测。

7.3.神经机器翻译(NMT):序列到序列(Seq2Seq)

​ 到目前为止,在这门课中,我们已经处理了预测单个输出的问题:一个词的 NER 标签,给定过去几个句子中最有可能的下一个词,等等。 然而,有一整类 NLP 任务依赖于顺序输出,或者是长度可能变化的序列的输出。 例如,

翻译:将一种语言的一个句子作为输入,然后输出是另外一种语言的相同的意思的句子。

会话:以陈述或问题作为输入并作出回应。

摘要:将大量文本作为输入并输出其摘要。

前面讲过,翻译系统是基于概率(即统计)模型构建的

翻译模型:告诉我们一个源语言中最有可能被翻译成的句子或者短语。

语言模型:告诉我们给定句子或者短语的整体可能性。

这些组成部分用于构建基于单词或短语的翻译系统。

基于单词的翻译系统将**完全不能捕获语言之间的排序差异**(例如,否定词移动,句子中的主语和动词的位置等)。

基于短语的翻译系统可以**根据短语序列考虑输入和输出,相比比基于单词的系统可以处理更复杂的语法。然而,在基于短语的翻译系统仍然难以捕获长距离的信息**。

7.3.1. Seq2Seq 架构:编码器-解码器

​ 在下面的部分,我们将介绍 Seq2Seq 模型,一个用来处理上述问题的深度学习框架。这个框架被证明了是非常有效的,在不到三年的时间里成为了机器翻译的标准方法

​ Seq2Seq 带来很大的优势,尤其是使用 LSTM,现代翻译系统==可以在观测到整个输入后生成任意的输出序列。他们甚至可以自动地专注于输入的特定部分,==以帮助生成有用的翻译。

​ 序列到序列,或者 Seq2Seq,是一个比较新的模型,在 2014 年被提出用英语-法语翻译。在更高的层面上,Seq2Seq 是一个有两个 RNN 组成的端到端模型

编码器:将模型的输入序列作为输入,然后编码固定大小的“上下文向量”

解码器:使用来自编码器生成的上下文向量作为从其生成输出序列的“种子”

​ 因此,Seq2Seq 模型通常被称为“编码器-解码器模型”。接下来我们将分别讨论这两个网络的细节。

7.3.1.1. 编码器

​ 编码器网络的作用是读取输入序列到我们的 Seq2Seq 模型中,然后对该序列生成一个固定维度的上下文向量 C 。为此,编码器使用一个循环神经网络单元——一般使用 LSTM——每个时间步读取一个输入单词。单元的最终隐藏状态就是 C 。然而,因为将一个任意长度序列压缩到一个单一固定大小的向量是很困难的(特别是像翻译这样的困难任务),编码器通常由堆叠的 LSTM 组成:一系列 LSTM“层”,其中每层的输出是下一层的输入序列。LSTM 最后一层的最终隐藏状态就是 C 。

​ Seq2Seq 编码器通常会做一些奇怪的事情:它们将**反向处理输入序列**。实际上这么处理是有目的的。通过这样做,编码器看到的最后的信息(粗略地)对应于模型输出的开始信息;这使得解码器更容易在输出上“开始”,同时解码器也更容易地产生适当的输出句子。在翻译的环境中,我们允许网络在看到输入的前几个单词时就进行翻译;一旦前几个单词被正确地翻译,构建一个正确的句子比从头开始更加容易

​ 一个展示编码器的例子见图 7.9:

image-20230315204718111

7.3.1.2. 解码器

​ 解码器也是一个 LSTM 网络,但是它的使用比编码器网络略微复杂。从本质上讲,我们希望它能作为一个语言模型,可以“知道”到目前为止生成的单词和输入。为此,我们将解码器保持“堆叠”的 LSTM 架构,但是我们将使用编码器生成的上下文向量来初始化第一层的隐藏层;然后解码器将使用输入的上下文向量来逐词地生成输出。

​ 一旦解码器使用其上下文向量设置好,我们将传入一个特殊的字符来表示生成输出的开始。在文献中,一般是附加到输入结尾的 \text{} 标记(在输出的结尾也有这样的标记,表示生成输出完成)。然后我们第一个时间步将一层接一层地运行这个三层的 LSTM,将最后一层的输出放到 softmax 函数中生成一个输出单词。然后我们把这个词传递到下一个时间步的第一层,重复上述的流程生成输出单词。这就是我们如何使 LSTM 像语言模型一样起作用。【一个接着一个后续单词的预测】

​ 一个展示解码器的例子见图 7.10。

​ 一旦我们有了输出序列,我们就像往常一样使用相同的学习策略。我们对预测序列定义一个交叉熵损失函数,然后用梯度下降算法和反向传播算法来最小化损失函数。同时对编码器和解码器进行训练,使得它们都学习到相同的上下文向量表示。

7.3.1. seq2seq结构详解

我们把前面那张抽象图(7.2.2. 神经机器翻译(NMT))展开,可以看到内部的结构是这样的:

image-20230315195310516

这张图,展示了在**「训练时」**,seq2seq内部的详细结构。

  • Encoder端,我们将source文本的词序列(是一个句子或者更多,而不是一个词)先经过embedding嵌入层转化成向量,然后输入到一个RNN结构(可以是普通RNN,LSTM,GRU等等)中。
    • 另外,这里的RNN也可以是多层、双向的。
    • 经过了RNN的一系列计算,最终隐藏层的输入,就作为源文本整体的一个表示向量,称为**「context vector」**。
  • Decoder端的操作就稍微复杂一些了。
    • 首先,Decoder的输入是什么呢?
    • Decoder的输入,训练和测试时是不一样的!
    • 「在训练时,我们使用真实的目标文本,即“标准答案”作为输入」(注意第一步使用一个特殊的<start>字符,表示句子的开头)。每一步根据当前正确的输出词、上一步的隐状态来预测下一步的输出词。

下图则展示了在**「预测时」**,seq2seq的内部结构:

image-20230315195906054

预测时,

  • Encoder端没什么变化
  • 在Decoder端,由于此时没有所谓的“真实输出”或“标准答案”了,所以只能**「自产自销:每一步的预测结果,都送给下一步作为输入」**,直至输出<end>就结束。
    • 如果你对我之前写的笔记很熟悉的话,会发现,这时的Decoder就是一个语言模型(预测下一个单词是啥出现的概率)」
    • 由于这个语言模型是根据context vector来进行文本的生成的,因此这种类型的语言模型,被称为“条件语言模型”:Conditional LM
    • 正因为如此,在训练过程中,我们可以使用一些预训练好的语言模型来对Decoder的参数进行初始化,从而加快迭代过程

7.3.2. 为什么训练和预测时的Decoder不一样?

​ 很多人可能跟我一样,对此感到疑惑:为什么在训练的时候,不能直接使用这种语言模型的模式,使用上一步的预测来作为下一步的输入呢?

image-20230315200422763

我们称这两种模式,根据标准答案来decode的方式为**「teacher forcing」,而根据上一步的输出作为下一步输入的decode方式为「free running」**。

  • 其实,free running的模式真的不能在训练时使用吗?
    • 当然是可以的!从理论上没有任何的问题,又不是不能跑。
    • 但是,在**实践中人们发现,这样训练太南了。因为没有任何的引导,一开始会完全是瞎预测,正所谓“一步错,步步错”,而且越错越离谱,这样会导致训练时的累积损失太大(「误差爆炸」**问题,exposure bias),训练起来就很费劲。
    • 这个时候,如果我们**能够在每一步的预测时,让老师来指导一下,即提示一下上一个词的正确答案,decoder就可以快速步入正轨,训练过程也可以更快收敛**。因此大家把这种方法称为teacher forcing。
    • 所以,这种操作的目的就是为了使得训练过程更容易。
  • 这就好比我们考驾照时,很多教练为了让我们快速通关,会给我们在场地上画上各种标记,告诉我们你看到某个标记就执行某个动作(说白了就是作弊手段)。这种方法很有效,我们在练车的时候,死记住这些作弊技巧,很容易在训练场顺利倒车、侧方停车。但这种方法在我们上考场的时候就会暴露出问题了——考场上可没人给你做标记!因此很多人明明在下面自己练车的时候很顺,以上考场就挂了。这也是**teacher forcing方法的一个弊端预测时我们没有老师给你做标记了!纯靠自己很可能挂掉**。

​ 所以,更好的办法,更常用的办法,是**老师只给适量的引导,学生也积极学习。即我们设置一个概率p,每一步,以概率p靠自己上一步的输入来预测,以概率1-p根据老师的提示来预测,这种方法称为「计划采样」**(scheduled sampling):

image-20230315201127813

​ 这是种什么感觉呢?就拿我们来刷LeetCode来说吧,完全不看答案的话,对于我来说的话就太难了。。。做题的进度会灰常慢,如果我完全看答案写,那也没啥意义,过几天就忘了,所以最好的方式就是自己也思考,遇到太难的时候就看看答案,这样我们又能保证进度,又能有学习效果。

​ 另外有一个小细节:在seq2seq的训练过程中,decoder即使遇到了<end>标识也不会结束,因为训练的时候并不是一个生成的过程 ,我们需要等到“标准答案”都输入完才结束。

7.3.3. seq2seq的损失函数

前面我们详细介绍了seq2seq的内部的结构,明白了内部结构,想知道是怎么训练的就很容易了。

在上面的图中,我们看到decoder的每一步产生隐状态后,会通过一个projection层映射到对应的词。那**怎么去计算每一步的损失呢**?

  • 实际上,这个projection层,通常是一个softmax神经网络层

    • 假设词汇量是V,则会输出一个V维度的向量,每一维代表是某个词的概率。映射的过程就是把最大概率的那个词找出来作为预测出的词
  • 在计算损失的时候,我们使用交叉熵作为损失函数,所以我们要找出这个V维向量中,正确预测对应的词的那一维的概率大小p^,则这一步的损失就是它的负导数−log(p^),将每一步的损失求和,即得到**总体的损失函数**:

    • image-20230315201952846
    • 其中T代表Decoder有多少步,[EOS]代表‘end of sentence’这个特殊标记,本来想打<end>跟前面保持一致的,因为LaTeX里面显示的问题,我替换了一下。

7.3.4. Decoding和Beam search

​ 前面画的几个图展示的预测过程,其实就是最简单的decoding方式——Greedy Decoding,即每一步,都预测出概率最大的那个词,然后输入给下一步

image-20230315202252580
  • 这种Greedy的方式,简单快速,但是既然叫“贪心”,肯定会有问题,那就是**「每一步最优,不一定全局最优」**,这种方式很可能“捡了芝麻,丢了西瓜”。

  • 改进的方法,就是使用**「Beam Search」**方法:每一步,多选几个作为候选,最后综合考虑,选出最优的组合。下面我们来具体看看Beam Search的操作步骤:

    • 首先,我们需要设定一个候选集的大小beam size=k;
    • 每一步的开始,我们从每个当前输入对应的所有可能输出,计算每一条路的“序列得分”
    • 保留**“序列得分”最大的k个**作为下一步的输入;
    • 不断重复上述过程,直至结束,**选择“序列得分”最大的那个序列**作为最终结果。
  • 这里的重点就在于这个**“序列得分”的计算**。

    • 我们使用如下的score函数来定义**「序列得分」**:
    • image-20230315202703088
    • 这个score代表了当前到第t步的输出序列的一个综合得分,越高越好。其中logP(yi|y1,y2,…,yi−1,x)类似于前面我们写的第t步的交叉熵损失的负数。所以这个score越大,就意味着到当前这一步为止,输出序列的累积损失越小
  • 再多描述不如一张图直观,我用下图描绘一个极简的案例(只有3个词的语料,k=2):

image-20230315203156906

​ 在每一步,我们都会去对所有的可能输出,计算一次score,假设beam size为k,词汇量为V,那么每一步就需要分出k×V个分支并逐一计算score。所以在图中我们可以看到除了第一步,后面每一步都是分出来2×3=6支。然后综合这k×V个score的结果,只选择其中最大的k个保留

​ 最后还有一个问题:由于会有多个分支,所以很有可能我们会遇到多个<end>标识,由于分支较多,如果等每一个分支都遇到<end>才停的话,可能耗时太久,因此一般我们会**设定一些规则(结束的规则),比如已经走了T步,或者已经积累了N条已完成的句子,就终止beam search过程**。

在search结束之后,我们需要对已完成的N个序列做一个抉择,挑选出最好的那个,那不就是通过前面定义的score函数来比较吗?

  • 确实可以,但是如果直接使用score来挑选的话,会导致那些很短的句子更容易被选出。

    • 因为score函数的每一项都是负的,序列越长,score往往就越小。
    • 因此我们可以使用长度来对score函数进行细微的调整:
      • 每个序列的得分,除以序列的长度。根据调整后的结果来选择best one。

Beam Search的使用,往往可以得到比Greedy Search更好的结果,道理很容易理解,高手下棋想三步,深思熟虑才能走得远。

7.3.5. NMT的优缺点、评价方式

​ 上面我们花了大量时间基本介绍清楚了神经机器翻译以及seq2seq的结构细节。最后我们对NMT稍作总结,并补充一些小细节。

7.3.5.1 NMT的优缺点

​ NMT相比于SMT,最大的优点当然就如前面所说的——简洁。我们不需要什么人工的特征工程,不需要各种复杂的前后组件,就是一个端到端的神经网络,整个结构一起进行优化

​ 另外,由于使用了深度学习的方法,我们可以引入很多语义特征,比如利用文本的相似度,利用文本内隐含的多层次特征,这些都是统计学方法没有的。

​ 但是,没有什么东西是绝对好或绝对差的,NMT也有其不足。它的不足也是跟深度学习的黑箱本质息息相关。NMT的解释性差,难以调试,难以控制,我们谁也不敢保证遇到一个新的文本它会翻译出什么奇怪的玩意儿,所以NMT在重要场合使用是有明显风险的。

7.3.5.2 NMT的评价

机器翻译的效果如何评价呢?——**「BLEU」**指标。

BLEU,全称是Bilingual Evaluation Understudy,它的主要思想是基于N-gram等特征来比较人工翻译和机器翻译结果的相似程度。详情我不赘述。

7.4.注意力★★★

7.4.1. 动机:Seq2Seq 的瓶颈问题

​ 当你听到句子“the ball is on the fifield”,你不会认为这 6 个单词都一样重要。你首先会注意到单词“ball”,“on” 和 “fifield”,因为这些单词你是觉得最“重要”的。类似的,Bahdanau 等人注意到使用 RNN 的最终状态作为 Seq2Seq 模型的单一“上下文向量”的缺点:一般而言,输入的不同部分具有不同的重要程度。上述提到的缺点,就是这种架构存在的问题:信息瓶颈!见图 7.19:

image-20230315205630476

​ 针对这个问题就引发了如下思考:输出的不同部分甚至可以考虑输入的不同部分“重要性”。例如,在翻译任务中,输出的第一个单词是一般是基于输入的前几个词,输出的最后几个词可能基于输入的几个词。

​ ==注意机制利用这一观察结果,为解码器网络提供了在每个解码步骤查看【整个输入序列】的功能;然后解码器可以在任何时间点决定哪些输入单词是重要的。==有很多类型的编码器机制,但是我们将讨论由Bahdanau 等人提出的机制。

7.4.2. NMT 模型的注意力原理

​ 再回顾一下我们的 Seq2Seq 模型是由两部分组成,一个编码器将一个输入句子编码,以及利用解码器所提取的信息生成翻译句子的解码器。基本上,我们的输入句子是一个我们想要翻译的词序列x1 , x2 , ⋯, xn,我们的翻译过结果(目标句子)是一个词序列y1 , y2 , ⋯, yn。

7.4.2.1. 编码器

​ 令ℎ1 , ℎ2 , ⋯, ℎn输入句子的隐藏向量表示。这些向量是例如 bi-LSTM 的输出,并且捕获句子中每个单词的上下文表示

7.4.2.2. 解码器

image-20230315210316223

7.4.2.3. 注意力

具体参考:(一)——Seq2Seq中的Attention

image-20230316210008672

7.4.2.4. 对齐表

参考 1.2 Attention机制的引入下的图

​ 基于注意力的模型为输出的每个时间步分配对输入的不同部分的显着性(“重要性”)在翻译任务中,注意力可以认为是“对齐”。Bahdanau 等人认为在解码的时间步 i 中的注意力分数ai,j表示源句子中的单词对齐目标句子中的单词 i。注意到这一点,我们可以使用注意力分数来构建一个对齐表——这个表是将源句子中的单词映射到目标句子中的相应单词——基于从我们从 Seq2Seq NMT 系统中学习到的编码器和解码器。一个对齐表的例子见表 7.2:

image-20230316210733949

对齐是翻译句子中特定词语之间的对应关系

注意:有些词没有对应词

image-20230317122852054

对齐可以是多对一的

image-20230317122926877

对齐可以是一对多的

image-20230317122946950

对齐可以是多对多(短语级)

image-20230317123006072

7.4.3. NMT 模型的注意力技术

7.4.3.1. 注意力:计算步骤

参考 :1.2 Attention机制的引入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z97GPT4G-1679027797719)(C:\Users\23972\AppData\Roaming\Typora\typora-user-images\image-20230316211908740.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hRtcMKCE-1679027797720)(C:\Users\23972\AppData\Roaming\Typora\typora-user-images\image-20230316211935574.png)]

image-20230316212011006

然后,通过图解显示注意力的计算公式,见图 7.21。

image-20230316212054039

7.4.3.2. 注意力:计算公式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ghHeu512-1679027797723)(C:\Users\23972\AppData\Roaming\Typora\typora-user-images\image-20230316212404778.png)]

7.4.3.3. 注意力:变化多样

1.2 Attention机制的引入 中的第一张图

image-20230316214520267

image-20230316214447744

7.4.3.4. 注意力:通用万能

image-20230316220130651

7.4.3.5. 注意力:善译长句

​ 基于注意力模型的主要优点是**能够有效地翻译长句**。当句子的输入长度变大时,模型如果只使用最终隐藏状态表示而不使用注意机制,这会丢失信息和降低准确度。注意力机制是一个聪明的方式来解决这个问题,并且现在很多实验也证实了确实如此。一个长句子在不同的 NMT 模型中的表现,见图 7.22:

image-20230316220323890

7.4.4. NMT+注意力的经典模型

值得了解的模型有以下三种:

​ (1) Show, Attend and Tell: Neural Image Caption Generation with Visual Attention.

​ 这篇论文是提出单词/图像对齐的方法。

​ (2) Modeling Coverage for Neural Machine Translation.

​ 他们的模型使用覆盖向量,考虑到使用注意力的历史以帮助计算将来的注意力。

​ (3) Incorporating Structural Alignment Biases into an Attentional Neural Translation Model.

​ 这篇论文通过引入其他传统语言学的思想来提高注意力表现。

重点关注的模型有以下两种。

7.4.4.1. 双注意力 NMT 模型

​ Luong 等人提出了一个注意力机制模型的变体,是由两个不同的注意力机制组成,见图 7.23:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aWhG18IN-1679027797735)(C:\Users\23972\AppData\Roaming\Typora\typora-user-images\image-20230317111310810.png)]

①全局注意力:我们运行简单的 Seq2Seq NMT。

image-20230317111723576

参考:7.4.3.2. 注意力:计算公式

②局部注意力:该模型预测输入序列中的对齐位置。然后,它使用**以此位置为中心的窗口**来计算上下文向量。这个计算耗费的计算资源是恒定的,不会随着句子的长度而暴增。

7.4.4.2. 多语种 GNMT 模型

Google 最近通过提升自己的翻译系统[2016]为 NMT 做出了重大突破,见图 7.24:

image-20230317112032765

图注:左边是编码器网络,右边是解码器网络,中间是注意力模块。

  • 左下底部编码器层是双向的:粉色节点从左到右收集信息,而绿色节点从右到左收集信息。
    • 编码器的其他层是单向的。
  • 残差连接从编码器和解码器底部的第三层开始。
  • 该模型被划分为多个 GPU 以加快训练速度。在我们的设置中,有 8 个编码器 LSTM 层(1 个双向层和 7 个单向层)和 8 个解码器层。使用此设置,一个模型副本被划分为 8 路,并放置在通常属于一台主机的 8 个不同的 GPU 上。
    • 在训练期间,底部的双向编码器层首先并行计算
    • 两者都完成后,单向编码器层可以开始计算,每个层都在单独的 GPU 上。
  • 为了在运行解码器层期间保持尽可能多的并行性,我们使用底部解码器层输出仅用于获取循环注意上下文,该上下文直接发送到所有剩余的解码器层
  • softmax 层也被分区并放置在多个 GPU 上。根据输出词汇量的大小,我们要么让它们在与编码器和解码器网络相同的 GPU 上运行,要么让它们在一组单独的专用 GPU 上运行。
  • 另外,我们的输入还有一个人工标记来指示所需的目标语言。在这个例子中,标记“<2es>”表示目标句是西班牙语,源句作为一个处理步骤进行反转。
  • 对于我们的大多数实验,我们还使用了编码器和解码器之间的直接连接,尽管我们后来发现这些连接的影响可以忽略不计(但是,一旦你用这些连接进行训练,它们也必须存在以进行推理)。

​ 为了提高并行度并因此减少训练时间,我们的注意力机制将解码器的底层连接到编码器的顶层。为了加快最终翻译速度,我们在推理计算过程中采用了低精度算法。为了改善对稀有单词的处理,我们将单词分为有限的一组公共子词单元(wordpieces,词片)集合,用于输入和输出。

​ 不是为他们支持翻译的每一种语言维护一个完整的 Seq2Seq 模型——每种语言不是单独进行训练,而是构建一个单独系统可以翻译任意两种语言,这在数据和计算时间方面都是一个巨大的成就。这是一个Seq2Seq 模型,它接受一个单词序列和一个指定要翻译的语言的符号作为输入。该模型使用共享参数来翻译为任何目标语言。

​ 这个新的的多语言模式不仅改善了他们的翻译表现,还能够“零数据翻译”,即使我们没有翻译的训练数据。我们也可以在两种语言之间进行翻译。例如,我们如果仅有日语-英语的翻译数据和韩语-英语的翻译数据,Google 团队发现多语言 NMT 系统对这些数据进行训练后的实际上可以产生合理的日语-韩语翻译。这个发现的重要意义在于,解码过程的部分并不是特定于语言的,而且该模型实际上维持一个了独立于所涉及的实际语言的输入/输出句子的内部表示。

7.5.处理大的输出词汇

​ 尽管现代的 NMT 系统取得了成功,但是他们很难处理大量的词汇量。特别地,这些 Seq2Seq 模型通过使用 softmax 计算整个词汇表上的目标概率分布来预测序列中的下一个单词。事实证明,使用大量词汇表来计算 softmax 可能相当耗费计算资源,而且时间复杂度也会与词汇大小成正比。我们现在将研究一些解决这个问题的方法。

7.5.1. 缩放 softmax

​ 一个非常自然的想法是问“我们能**找到更有效的方法来计算目标概率分布吗?”答案是可以的!实际上,我们已经学会了两种可以降低“softmax”复杂度的方法**,我们将在下面回顾一下(更多细节请看第一章)。

噪声对比估计(Noise Contrastive Estimation,NCE)的想法是通过随机地从负样本中抽取 K 个单词来近似“softmax”。因此,我们将计算复杂度降低了|V|/K 倍,其中|V|是词汇表的大小。这个方法在 word2vec中证明了非常有效。Zoph 等人6最近的一项工作是应用这种技术来学习 LSTM 语言模型,他们还通过使用每个 mini batch 的相同样本来引入一个技巧,使 GPU 的训练效率更高。

分层 Softmax 是 Morin 等人7提出的,它**引入了一种二叉树结构来更有效地计算“softmax”。目标分布中的每个概率是通过沿着树向下走的路径计算的,该路径只需要 O(loglVl) 步。值得注意的是,即使 分层Softmax 节省了计算,它也不能很容易地并行化以在 GPU 上高效运行**。Kim 等人8使用这种方法来训练基于字符的语言模型。

​ 这两种方法的一个限制是它们**仅在训练阶段中节省计算量(当目标词已知时)**。在测试阶段,我们还需要计算词汇表中的所有单词的概率,然后做出预测。

7.5.2. 减少词汇量

​ 除了优化“softmax”,我们还可以尝试减少有效的词汇量,这将加快训练和测试过程。一种简单的方法是**将词汇量限制在一个很小的数量上,用一个标签替换限制后的词汇表外的单词**。现在,无论是训练和测试时间可以显着地降低了,但这显然是不理想的,因为我们可能会产生很多的输出

​ Jean 等人9提出了一种保持固定词汇大小|V′|的方法,通过将训练数据分成**具有τ个唯一目标单词的子集,其中τ=|V′|。可通过依次扫描原始数据集直到检测τ个唯一的目标词**,从而形成一个子集,见图 7.25:

image-20230317114211504

​ 然后按照上述过程遍历整个数据集,以产生所有的 mini-batch 子集。实际中,我们可以通过这个方法词汇量为|V|=500K 实现了 10 倍以上的节省(|V′|=30K,50K)。

​ 这个概念和 NCE 非常类似,对任意给定的单词,输出的词汇包含目标单词和|V′|−1 个负(噪声)样例。然而,这两个方法主要的不同是,对每个子集|V′|,是从偏置分布|Q|中采样这些负样例,其中:

image-20230317114252575

在测试阶段,也可以从整个词汇表中选择一个子集(称为候选列表)来预测目标单词挑战在于,正确的目标词是未知的,我们必须“猜测”目标词可能是什么。在论文中,作者提出使用 K 个最常用的单词(基于 unigram 概率)和 K′个可能的目标词为每个源句构建一个候选列表。一个 K′=3 的例子见图 7.26:

image-20230317114357193

​ 其中,候选列表由紫色框中的所有单词组成。在实际中,可选择以下参数值:K=15k,30k,50k;K′=10,20。

7.5.3. 处理未知词

​ 当 NMT 系统使用上面提到的方法来以降低有效词汇量**,不可避免地,某些单词将被映射到。例如,当预测词(通常是罕见词)不在候选列表中或当我们在测试阶段遇到未知的单词时,可能会发生这种情况。我们需要新的机制来解决罕见和未知的单词问题**。

7.5.3.1. 指向未知词:PAN

​ Gulcehre 等人10提出了一个想法来处理这些问题:学习从源文本中“复制”。该模型见图 7.27:

image-20230317114546872

​ 该模型应用了注意力分布 lt来决定源文本中的指向何处,并使用解码器的隐藏状态 St来预测二分类变量 Zt,从而决定何时从源文本中复制。最后的预测结果是根据 Zt的值,在候选列表中由前面介绍的方法使用 softmax 选择的词ytw,或者从源文本复制的ytl。他们在论文中的结果表明,该方法提高了机器翻译和文本摘要等任务的表现。

​ 然而可以想到的是,这种方法也是有局限性的。这里要重点指出的是在 Google NMT 论文11中对这个方法的一个评论:“这种做法在规模很大时是不可靠的——当网络是很深的时候,注意力机制是不稳定的——而复制机制可能不是最适合处理罕见单词的策略——有时音译更合适”。

​ 如上所述,“复制”机制在处理罕见或未知词语上仍然存在不足

​ 解决这些问题的另一个思路是在 sub-word 的级别进行操作。

​ 一个趋势是使用相同的 Seq2Seq 架构,但是在更小的单元上操作——基于字符的分词模型。

​ 另一个趋势是对单词和字符采用混合架构。

7.5.3.2. 单词分割:BPE

​ Sennrich 等人12提出了一种通过将罕见和未知的单词作为一个子词单元( subword units)的序列来实现开放词汇翻译的方法。

​ 这通过调整字节对编码(Byte Pair Encoding,BPE)的压缩算法来实现。基本思想是从字符词汇表开始,并且继续扩展数据集中最常见的 n-gram 对。字节对编码得例子见图 7.28:

image-20230317121021269

​ 我们的数据集包含 4 个单词,图中的左边的表示单词频率,例如“low”出现了 5 次。用(p,q,f)来表示一个 n-gram 对 p,q 及其出现的频率 f。如图中所示,我们已经选择的频率最高的的 n-gram 对(e,s,9),然后我们现在增加当前频率最高的的 n-gram 对(es,t,9)。重复此过程,直到所有 n-gram 对被选择过或词汇大小达到某个阈值。

​ 我们可以选择为训练集和测试集构建单独的词汇表,或者共同构建一个词汇表。在构建词汇表之后,一个带有 Seq2Seq 体系结构的 NMT 系统(Bahdanau 等人在论文13中使用的),可以直接训练这些词段。值得注意的是,这种方法赢得了 WMT 2016 的第一名。

7.5.3.3. 基于字符的模型

image-20230317121150160

7.5.3.4. 混合 NMT

​ Luong 等人15提出了一个混合(Hybrid)词字模型来处理未知词,从而实现开放词汇 NMT。系统主要进行单词级翻译,并查阅罕见单词的字符组成。在高层次上,字符级循环神经网络计算源单词词表示,并在需要时重新获得未知目标单词。这种混合方法的双重优点在于,它的训练比基于字符的方法要快得多,而且更容易进行训练;同时,它不会像基于单词的模型,产生未知的单词。

​ 基于单词的翻译作为主干:混合 NMT 的核心是一个单词级翻译的深度 LSTM 编码器—解码器。我们对每种语言维护大小|V|的词汇表和使用来表示 OOV 词汇。

​ 基于字符表示:在常规的基于单词的 NMT,是使用一个通用的词向量来表示全部 OOV 词汇。这是有问题的,因为它丢弃了关于源单词的有价值的信息。相反,我们学习了一个关于罕见单词的字符的深层 LSTM 模型,并使用 LSTM 的最终隐藏状态作为罕见单词的表示,见图 7.29:

image-20230317121427604

​ 目标字符级别生成:一般基于单词的 NMT 允许目标输出生成的。相反,这里的目标是创建一个处理无限输出词汇表的连贯框架。解决方案是,在给定当前单词级别的状态下,使用一个单独的深层LSTM 来进行字符级别的“翻译”。注意,当前单词上下文用于初始化字符级编码器。该系统的训练方法是,每当单词级别的 NMT 产生一个的时候,字符级解码器被要求恢复未知目标词的正确表面形式。

7.6.总结

今天的讲座总结如下:

(1) 我们学习了机器翻译 (MT) 的一些历史;

(2) 自 2014 年以来,NMT 迅速取代了复杂的 SMT;

(3) 序列到序列是 NMT 的架构(使用两个模型:编码器和解码器);

(4) 注意力是关注输入的特定部分的一种方式(大大改进了序列到序列)!

(5) 注意力本身计算有三步:分数、分布、输出,其中计算分数有三种变体:点积、乘法、加法;

(6) 注意力应用计算有三步:向量拼接、预测概率、损失函数

猜你喜欢

转载自blog.csdn.net/mwcxz/article/details/129617920