0
点赞
收藏
分享

微信扫一扫

【李宏毅深度学习CP13】Transformer(part2)


学习总结

(1)上一小节主要是先讲Encoder,这次是学习Decoder(根据并行性分为AT和NAT两种)、Encoder和Decoder之间的关系(通过Cross Attention机制)还有训练的一些tips(好多tips呜呜)。

【李宏毅深度学习CP13】Transformer(part2)_语音合成


(2)Cross Attention:比如在Decoder输入 BEGIN 输入“机”,产生一个向量,该向量一样乘上一个 Linear 的 Transform 后得到 q’(得到一个 Query),这个 Query 一样跟 去计算 Attention 的分数(得到),attention再跟 做 Weighted Sum 做加权,然后加起来得到 v’,交给接下来 Fully-Connected Network 做处理。

ps:QKV三个矩阵都是来源于词向量矩阵。(3)在(2)中是计算完attention即(即对应各个向量value的权重)后还要乘这些value加权求和。就像一张图,attention只是告诉你你的注意力要注意在左上角,但是没告诉你左上角是什么你还是不知道这张图表达了什么——【关系程度】最后要和【上下文】结合,也即将向量再编码下

附:秋阳大佬画的图哈哈哈:

【李宏毅深度学习CP13】Transformer(part2)_语音合成_06

文章目录

  • ​​学习总结​​
  • ​​一、Decoder – Autoregressive (AT)​​
  • ​​Decoder内部结构​​
  • ​​1)带Masked的MHA​​
  • ​​2)特殊符号END​​
  • ​​二、Decoder – Non-autoregressive (NAT)​​
  • ​​2.1 AT v.s. NAT​​
  • ​​2.2 begin要放几个​​
  • ​​2.3 NAT的Decoder的好处​​
  • ​​三、Encoder-Decoder​​
  • ​​3.1 Cross Attention的运作流程​​
  • ​​3.2 其他的Cross Attension 方式​​
  • ​​四、Training​​
  • ​​五、训练的Tips​​
  • ​​5.1 Copy Mechanism​​
  • ​​5.2 Summarization摘要​​
  • ​​5.3 Guided Attention​​
  • ​​5.4 Beam Search​​
  • ​​5.5 Optimizing Evaluation Metrics?​​
  • ​​5.6 Scheduled Sampling​​

一、Decoder – Autoregressive (AT)

Decoder有两种,比较常见的是Autoregressive Decoder。我们上小节说了Encoder是做了输入一个vector sequence,输出另外一个vector sequence。接下来轮到Decoder产生输出,如产生语音识别的结果。

【李宏毅深度学习CP13】Transformer(part2)_语音识别_07


Decoder做的事情是把Encoder的输出先读进去。那Decoder是怎么产生一段文字的:

(1)先给它一个特殊的符号——代表开始,在开始的ppt里写Begin Of Sentence(缩写是BOS),这是一个special的token。就是在你的Lexicon(字典)里面,即Decoder可能产生的文字里面多加一个特殊的字——该字代表begin(开始)。

假设你要处理NLP问题,每一个Token都可以用一个One-Hot的Vector来表示(就其中一维是1,其他是0),所以begin也是用One-Hot Vector来表示。

(2)接着Decoder会吐出一个很长的vector(和vocabulary的size一样)

【李宏毅深度学习CP13】Transformer(part2)_语音识别_08

vocabulary size是什么意思?
先想好Decoder输出的单位是什么,如果做得是中文的语音识别则我们Decoder输出的是中文,那么vocabulary size可能就是中文方块字的数目
不同的字典size可能是不同的,常用的中文方块字大约三千,一半人可能人的四五千,那么这个Decoder能够输出常见的3000个方块字就好(这个取决于你对该语言的理解)。
再举栗子:可以选择输出字母A到Z输出英文的字母,而如果觉得字母这个单位太小了,可以用英文单词的“词根”作为单位。

每一个中文的字对应到一个数值,因为在产生这个向量之前,通常会先跑一个softmax(和分类一样),所以这个向量里面的分数积一个Distribution,即该向量里面的值全部加起来等于1。分数最高的一个中文字,它就是最终的输出

【李宏毅深度学习CP13】Transformer(part2)_语音合成_09

而在上面例子中“机”字的分数最高,所以就是这个Decoder第一个输出的东东,然后把“机”字当做是Decoder新的input(原来Decoder的input只有begin这个特别的符号,现在它除了begin外还有“机”作为其input)。

【李宏毅深度学习CP13】Transformer(part2)_语音识别_10

同理:根据这两个输入,它输出一个蓝色的向量,根据这个蓝色的向量里面,给每一个中文的字的分数,我们会决定第二个输出,哪一个字的分数最高,它就是输出,假设"器"的分数最高,"器"就是输出

最后,现在 Decode:

  • 看到了 BEGIN
  • 看到了"机"
  • 看到了"器"
  • 还有"学"

Encoder 这边其实也有输入,等一下再讲 Encoder 的输入,Decoder 是怎麼处理的,所以 Decoder 看到 Encoder 这边的输入,看到"机" 看到"器" 看到"学",决定接下来输出一个向量,这个向量里面"习"这个中文字的分数最高的,所以它就输出"习"

【李宏毅深度学习CP13】Transformer(part2)_ide_11


【李宏毅深度学习CP13】Transformer(part2)_语音合成_12

上面这个过程反复持续,其中有个关键之处(上图红色虚线),Decoder看到的输入起始是它在前一个时间点自己的输出。而如果Decoer看到错误的输入后,让Decoer看到自己错误的输入再被Decoder自己吃进去后,会不会造成Error Propagation(一步错步步错)问题?——是有可能的(后面会讲)。

Decoder内部结构

【李宏毅深度学习CP13】Transformer(part2)_ide_13

先省略Encoder部分,在transformer里面的Decoder结构如下图所示,比Encoder稍微复杂点:

【李宏毅深度学习CP13】Transformer(part2)_语音识别_14

但是我们现在把Decoder中间的一块先盖起来,会发现Encoder和Decoder是差不多的(如下图)。两者都是先Multi-Head Attention,然后Add & Norm,再Feed Forward,Add & Norm,重复N次。只是最后可能会再做一个softmax,使得输出变成一个概率。

ps:注意有个地方不同,在Decoder的Multi-Head Attention这个Block上面还加了一个Masked

【李宏毅深度学习CP13】Transformer(part2)_语音合成_15

1)带Masked的MHA

这个 Masked 的意思是这样子的,首先这是我们原来的 Self-Attention

【李宏毅深度学习CP13】Transformer(part2)_ide_16


Input 一排 Vector,Output 另外一排 Vector,这一排 Vector

每一个输出

,都要看过完整的 Input 以后,才做决定,所以输出

的时候,其实是根据

所有的资讯,去输出

当我们把 Self-Attention,转成 Masked Attention 的时候,它的不同点是,现在我们不能再看右边的部分,也就是產生

的时候,我们只能考虑

的资讯,你不能够再考虑

【李宏毅深度学习CP13】Transformer(part2)_语音识别_26


產生

的时候,你只能考虑

的资讯,不能再考虑

的资讯


【李宏毅深度学习CP13】Transformer(part2)_语音合成_32


產生

的时候,你就不能考虑

的资讯,


【李宏毅深度学习CP13】Transformer(part2)_语音合成_35


產生

的时候,你可以用整个 Input Sequence 的资讯,这个就是 Masked 的 Self-Attention,


讲得更具体一点,你做的事情是,

当我们要產生 的时候,我们只拿第二个位置的 Query ,去跟第一个位置的 Key,和第二个位置的 Key,去计算 Attention,第三个位置跟第四个位置,就不管它,不去计算 Attention

【李宏毅深度学习CP13】Transformer(part2)_ide_39


我们这样子不去管这个

右边的地方,只考虑

,只考虑

,只考虑

,

只跟

去计算 Attention,然后最后只计算

的 Weighted Sum


然后当我们输出这个

的时候,

就只考虑了

,就没有考虑到


为什么需要加 Masked

【李宏毅深度学习CP13】Transformer(part2)_语音合成_58


这件事情其实非常地直觉:我们一开始 Decoder 的运作方式,它是

一个一个输出

,所以是先有

再有

,再有

再有


这跟原来的 Self-Attention 不一样

,原来的 Self-Attention,

是一次整个输进去你的 Model 裡面的,在我们讲 Encoder 的时候,Encoder 是一次把

,都整个都读进去


但是

对 Decoder 而言,先有 才有 ,才有 才有

,所以实际上,当你有

,你要计算

的时候,你是没有

的,所以你根本就没有办法把

考虑进来


所以这就是為什麼,在那个 Decoder 的那个图上面,Transformer 原始的 Paper 特别跟你强调说,

那不是一个一般的 Attention,这是一个 Masked 的 Self-Attention

,意思只是想要告诉你说,Decoder 它的 Token,

它输出的东西是一个一个產生的,所以它只能考虑它左边的东西,它没有办法考虑它右边的东西

2)特殊符号END

Decoder 必须自己决定,输出的 Sequence 的长度。你没有办法轻易的从输入的 Sequence 的长度,就知道输出的 Sequence 的长度是多少,因为并不是说输入是 4 个向量,输出一定就是 4 个向量。按照我们介绍的流程不断重复,可能会一直像“推文接龙”游戏一样推出每个字然后不会停止。所以让Decoder可以输出一个“断”END特殊符号(ps:在作业的助教代码里是将begin和end用同一个符号表示,也没毛病)。

所以我们现在,当把"习"当作输入以后,就 Decoder 看到 Encoder 输出的这个 Embedding,看到了 “BEGIN”,然后"机" “器” “学” "习"以后,看到这些资讯以后知道这个语音识别的结果已经结束了(它产生出来的向量END的几率是最大的,然后输出断符号,最后整个Decoder产生Sequence的过程就结束了)。

【李宏毅深度学习CP13】Transformer(part2)_语音识别_77

二、Decoder – Non-autoregressive (NAT)

【李宏毅深度学习CP13】Transformer(part2)_语音识别_78

2.1 AT v.s. NAT

这个 Autoregressive 的 Model 是先输入 BEGIN,然后出现 w1,然后把 w1 当做输入,输出 w2,直到输出 END 为止。那 NAT 是这样,它不是依次产生

【李宏毅深度学习CP13】Transformer(part2)_ide_79

像上图的例子如果是产生中文的句子,NAT不是依次产生一个字,而是一次把整个句子都产生出来。NAT的Decoder可能吃的是一整排的begin的token,如上图就是丢进4个begin后就产生4个中文字,变成一个句子后即完成。

2.2 begin要放几个

刚才说了不知道输出的长度是多少,为了解决NAT Decoder的输入问题,有以下几个方法:

(1)另外learn一个classifier——吃Encoder的input,然后输出是一个数字(代表Decoder应该要输出的长度)

(2)给一堆begin的token,就是假设现在输出的句子长度不超过300个字,那么给定300个begin然后输出300个字。然后看什么地方输出END,输出的END的右边就忽略掉(代表结束)

【李宏毅深度学习CP13】Transformer(part2)_ide_80

2.3 NAT的Decoder的好处


(1)并行化:NAT比一个一个字产生的AT更快。NAT Decoder是在transformer、self-attention的Decoder以后才有的,因为以前如果你是用按个LSTM或者RNN,就算给它一排begin,它也没有办法同时产生所有的输出(它的输出还是一个一个产生的)。自从有个self-attention后,NAT的Decoder现在算是一个热门的研究主题了。

(2)能够控制输出的长度,如语音合成今天你都可以用Sequence To Sequence 的模型来做,那最知名的是一个叫做 Tacotron 的模型(是 AT 的 Decoder)

那有另外一个模型叫 FastSpeech,那它是 NAT 的 Decoder,那 NAT 的 Decoder 有一个好处,就是你可以控制你输出的长度。

你可能有一个 Classifier,决定 NAT 的 Decoder 应该输出的长度,那如果在做语音合成的时候,假设你现在突然想要让你的系统讲快一点,加速,那你就把那个 Classifier 的 Output 除以二,它讲话速度就变两倍快,然后如果你想要这个讲话放慢速度,那你就把那个 Classifier 输出的那个长度,它 Predict 出来的长度乘两倍,那你的这个 Decoder ,说话的速度就变两倍慢。
所以你可以如果有这种 NAT 的 Decoder,那你有 Explicit 去 Model,Output 长度应该是多少的话,你就比较有机会去控制,你的 Decoder 输出的长度应该是多少,你就可以做种种的变化。

(3)注意虽然平行化是NAT的Decoder的最大优势,但其performance往往不如AT的Decoder。现在很多研究提升其performance,但往往需要很多trick。NAT的Decoder performance不好的原因是有个Multi-Modality的问题,如果想要深入了解NAT可参考之前助教课程:https://youtu.be/jvyKmU4OM3c

三、Encoder-Decoder

Encoder和Decoder是通过【cross attention】传递信息,刚才遮住的那块就是【cross attention】。会发现有2个输入来自Encoder,Encoder提供2个箭头(Decoder可以读到Encoder的输出),然后Decoder提供了一个箭头。

【李宏毅深度学习CP13】Transformer(part2)_语音识别_81

3.1 Cross Attention的运作流程

【李宏毅深度学习CP13】Transformer(part2)_ide_82

(1)上图左边是Encoder,输入一排向量,输出一排向量,我们叫它 ;接着是Decoder,它会先吃begin这个special的token,经过有做mask的self-attention后得到一个向量(即使是有做mask,越是输入多少长度的向量就输出多少向量)。所以输入一个向量输出以向量后,把这个向量乘一个矩阵做一个transform,得到一个Query(叫做q)

(2)然后像下图一样,左边的 产生 Key——Key1 Key2 Key3,那把这个 q 跟 去计算 Attention 的分数,得到 ,当然你可能一样会做 Softmax,把它稍微做一下 Normalization,所以下图这边加一个 ​​​'​​代表它可能是做过 Normalization。

【李宏毅深度学习CP13】Transformer(part2)_语音识别_87

(3)将就乘上 ,再把它 Weighted Sum 加起来会得到 v

【李宏毅深度学习CP13】Transformer(part2)_语音合成_90

(4)最后就是将V丢进Fully-Connected 的Network 做接下来的处理,那这个步骤就是 q 来自于 Decoder,k 跟 v 来自于 Encoder,这个步骤就叫做 Cross Attention。

所以 Decoder 就是凭借着产生一个 q,去 Encoder 这边抽取资讯出来,当做接下来的 Decoder 的 Fully-Connected 的 Network 的 Input。现在假设产生第二个,第一个这个中文的字产生一个“机”,接下来的运作也是一模一样的。

【李宏毅深度学习CP13】Transformer(part2)_语音合成_91

输入 BEGIN 输入“机”,产生一个向量(该向量后面的操作和上面描述的1-4步骤相同),该向量一样乘上一个 Linear 的 Transform 后得到 q’(得到一个 Query),这个 Query 一样跟 去计算 Attention 的分数,一样跟

3.2 其他的Cross Attension 方式

【李宏毅深度学习CP13】Transformer(part2)_ide_94

Encoder 这边有很多层,Decoder 这边有很多层,为什么 Decoder 这边每一层都一定要看Encoder 的最后一层输出呢,能不能够有各式各样不同的连接方式,这完全可以当做一个研究的问题来 Study,可以参考上图的paper链接(有人就尝试了不同的Cross Attension 方式)。

四、Training

【李宏毅深度学习CP13】Transformer(part2)_语音合成_95


上面讲的都是假设模型训练好后怎么运作的,即怎么做testing(即inference),接下来说如何training的:

如果是做语音识别,需要有大量的声音讯号的训练资料,听到“机器学习”四个字后,人工标签该对应的中文字。而要让机器学到这件事:我们先把begin丢给Encoder时,期待它第一个输出应该跟“机”越接近越好。而“机”这个字会被表示成一个One-Hot的Vector(只有机字对应的那个维度是1,其他都是0),而Decoder的输出是一个distribution(一个概率的分布)。所以你会去计算Ground Truth和这个distribution之间的cross Entropy,并且希望这个值越小越好。

【李宏毅深度学习CP13】Transformer(part2)_语音识别_96

上面的步骤和分类很像,可以想成每一次在产生一个中文文字就是做了一次分类的问题,希望第一二三四次输出的字分别是机、器、学、习四个文字,和四个字的One-Hot Vector越接近越好(每一个输出跟 One-Hot Vector,跟它对应的正确答案都有一个 Cross Entropy,我们要希望所有的 Cross Entropy 的总和最小,越小越好,注意还有END符号)。

【李宏毅深度学习CP13】Transformer(part2)_ide_97


那这个就是 Decoder 的训练:把 Ground Truth ,正确答案给它,希望 Decoder 的输出跟正确答案越接近越好。在训练的时候我们会给 Decoder 看正确答案,也就是我们会告诉它说:

  • 在已经有 “BEGIN”,在有"机"的情况下你就要输出"器"
  • 有 “BEGIN” 有"机" 有"器"的情况下输出"学"
  • 有 “BEGIN” 有"机" 有"器" 有"学"的情况下输出"习"
  • 有 “BEGIN” 有"机" 有"器" 有"学" 有"习"的情况下,你就要输出"断"

在 Decoder 训练的时候,我们会在输入的时候给它正确的答案,那这件事情叫做 Teacher Forcing

那这个时候你马上就会有一个问题——训练的时候,Decoder 有偷看到正确答案了;但是测试的时候,显然没有正确答案可以给 Decoder 看。刚才也有强调说在真正使用这个模型,在 Inference 的时候,Decoder 看到的是自己的输入,这中间显然有一个 Mismatch,后面会提到解决方案。

五、训练的Tips

不局限与Transformer,以下是训练这种Seq2Seq model的tips

5.1 Copy Mechanism

【李宏毅深度学习CP13】Transformer(part2)_ide_98

如上图中对话的例子,复制“库洛洛”的能力是需要的,而没必要创造出来(训练结果)。

5.2 Summarization摘要

【李宏毅深度学习CP13】Transformer(part2)_ide_99

最早有从输入复制东西的能力的模型叫做Pointer Network,后来还有一个变形Copy Network。生成摘要是需要训练大量(百万篇文章)得到的模型,需要从文章里面赋值一些信息出来,Seq2Seq是能做到这样的。
过去视频:(https://youtu.be/VdOyqNQ9aww)

5.3 Guided Attention

语音合成TTS有时会训练出的模型有点怪,李老师举的栗子是机器读 发财发财发财 没问题,但是读 发财 就只读出一个财字,即机器漏字了,想让机器一定把输入的每个东西通通看过,可以用Guided Attention

Guiding Attention 要做的事情就是,要求机器它在做 Attention 的时候,是有固定的方式的,举例来说,对语音合成或者是语音辨识来说,我们想像中的 Attention,应该就是由左向右

【李宏毅深度学习CP13】Transformer(part2)_语音识别_100

在这个例子裡面,我们用红色的这个曲线,来代表 Attention 的分数,这个越高就代表 Attention 的值越大
我们以语音合成為例,那你的输入就是一串文字,那你在合成声音的时候,显然是由左念到右,所以机器应该是,先看最左边输入的词汇產生声音,再看中间的词汇產生声音,再看右边的词汇產生声音。如果你今天在做语音合成的时候,你发现机器的 Attention,是颠三倒四的,它先看最后面,接下来再看前面,那再胡乱看整个句子,那显然有些是做错了,显然有些是,Something is wrong,有些是做错了,

所以 Guiding Attention 要做的事情就是,强迫 Attention 有一个固定的样貌,那如果你对这个问题,本身就已经有理解知道说,语音合成 TTS 这样的问题,你的 Attention 的分数,Attention 的位置都应该由左向右,那不如就直接把这个限制,放进你的 Training 裡面,要求机器学到 Attention,就应该要由左向右
那这件事怎麼做呢,有一些关键词汇我就放在这边,让大家自己 Google 了,比如说某某 Mnotonic Attention,或 Location-Aware 的 Attention,那这个部分也是大坑,也不细讲,那就留给大家自己研究

5.4 Beam Search

Greedy Decoding用来找到类似下图的分数最高的那个token,橙色的数字为路径分数,有的路一开始虽然低分(0.4),但后面的路径最后加起来的score更高。也就是说Greedy Decoding不一定是最好的方法,可以使用Beam Search——能够找一个估测的solution。

【李宏毅深度学习CP13】Transformer(part2)_ide_101


Beam Search也不一定牛逼,有篇paper《The Curious Case Of Neural Text Degeneration》在做Sentence Completion(让机器先读一段句子,然后让机器发挥想象力完成后半部分),但是用Beam Search后机器不断讲重复的话(效果不好),所以不见得分数最高的路是最好的——取决于任务的特性

(1)如果任务的答案非常明确,Beam Search通常效果好

(2)如果任务需要机器发挥一点创造力时,Beam Search效果就一般,如刚才说的Sentence Completion要机器完成后半段的创造,答案不唯一,往往需要在Decoder里面加入随机性。语音合成TTS也需要加入一定随机性。

【李宏毅深度学习CP13】Transformer(part2)_语音识别_102

5.5 Optimizing Evaluation Metrics?

【李宏毅深度学习CP13】Transformer(part2)_语音识别_103


在李宏毅课程作业里评估用的是BLEU Score,是你的Decoder先产生一个完整的句子后再和答案一整句作比较计算score;但是在训练时不时这样,训练时每一个词汇是分开考虑的——我们是Minimize的是Cross Entropy。注意如果想在Training时就考虑BLEU Score(假设loss是BLEU Score乘一个负号),但这样不好搞,因为BLEU Score本身很复杂(不能微分的)

Minimize Cross Entropy不一定可以Maximize BLEU Score:因为两者可能只有一点联系,但没有直接关系。所以在课程助教代码里,助教在做validation时并不是拿Cross Entropy来挑最好的model。

如果在Optimization遇到无法解决的问题,就用RL硬train一发,这样即使遇到BLEU Score不能微分,即无法optimize的loss function时,把它当做是RL的reward,把Decoer当做是Agent,就当做强化学习任务硬做是可以完成的(但是做法比较难)。

5.6 Scheduled Sampling

【李宏毅深度学习CP13】Transformer(part2)_语音合成_104


训练的时候Decoder看到的是自己的输出,所以测试的时候Decoder会看到一些错误的东西;但是在训练的时候,Decoder看到的是完全正确的。这个不一致的现象叫做Exposure Bias

为了解决一个问题:因为Decoder在训练时只看到过正确的东西,那在测试时可能只要有一个错就步步错,对Decoder来说从来没看过错的东西。
可以参考的方向:给Decoder的输入加入一些错误的东西,即不要给Decoder全部正确的答案(偶尔给一些错误的东西),反而会学得更好点——这招叫做Scheduled Sampling,不是那个Schedule learning rate。

Scheduled Sampling 其实很早就有了,下图的这个是 15 年的 Paper,很早就有 Scheduled Sampling,在还没有 Transformer,只有 LSTM 的时候就已经有 Scheduled Sampling,但是 Scheduled Sampling 这一招,它其实会伤害到Transformer 的平行化的能力,那细节可以再自己去了解一下,所以对 Transformer 来说,它的 Scheduled Sampling,另有招数跟传统的招数,跟原来最早提在,这个 LSTM上被提出来的招数也不太一样。

【李宏毅深度学习CP13】Transformer(part2)_语音合成_105


举报

相关推荐

0 条评论