Transformer
Posted 三つ叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Transformer相关的知识,希望对你有一定的参考价值。
Sequence-to-sequence(Seq2seq)
Transformer就是一个,Sequence-to-sequence的model,他的缩写,我们会写做Seq2seq,那Sequence-to-sequence的model,又是什麼呢
我们之前在讲input a sequence的,case的时候,我们说input是一个sequence,那output有几种可能
- 一种是input跟output的长度一样,这个是在作业二的时候做的
- 有一个case是output指,output一个东西,这个是在作业四的时候做的
- 还有一种就是我们不知道应该要output多长,由机器自己决定output的长度,即Seq2seq
Encoder-Decoder
我们现在就是要来学,怎麼做seq2seq这件事,一般的seq2seq’s model,它裡面会分成两块 一块是Encoder,另外一块是Decoder
今天讲到seq2seq’s model的时候,大家第一个会浮现在脑中的,可能都是我们今天的主角,也就是transformer
它有一个Encoder架构,有一个Decoder架构,它裡面有很多花花绿绿的block,等一下就会讲一下,这裡面每一个花花绿绿的block,分别在做的事情是什麼
Encoder
seq2seq model Encoder要做的事情,就是给一排向量,输出另外一排向量
在transformer裡面,transformer的Encoder,用的就是self-attention,这边看起来有点复杂,我们用另外一张图,来仔细地解释一下,这个Encoder的架构,等一下再来跟原始的transformer的,论文裡面的图进行比对
现在的Encoder裡面,会分成很多很多的block, 每一个block裡面做的事情,是好几个layer在做的事情,在transformer的Encoder裡面,每一个block做的事情,大概是这样子的
- 先做一个self-attention,input一排vector以后,做self-attention,考虑整个sequence的资讯,Output另外一排vector.
- 接下来这一排vector,会再丢到fully connected的feed forward network裡面,再output另外一排vector,这一排vector就是block的输出
事实上在原来的transformer裡面,它做的事情是更复杂的
在之前self-attention的时候,我们说 输入一排vector,就输出一排vector,这边的每一个vector,它是考虑了 所有的input以后,所得到的结果
在transformer裡面,它加入了一个设计,我们不只是输出这个vector,我们还要把这个vector加上它的input,它要把input拉过来 直接加给输出,得到新的output
这样子的network架构,叫做residual connection,那其实这种residual connection,在deep learning的领域用的是非常的广泛,之后如果我们有时间的话,再来详细介绍,為什麼要用residual connection
得到residual的结果以后,再把它做一件事情叫做normalization,这边用的不是batch normalization,这边用的叫做layer normalization
layer normalization它是对同一个example, 不同的dimension, 去计算 mean 跟 standard deviation
batch normalization是对不同example, 同一个dimension, 去计算 mean 跟 standard deviation
得到layer normalization的输出以后,它的这个输出 才是FC network的输入
而FC network这边,也有residual的架构,所以 我们会把FC network的input,跟它的output加起来 做一下residual,得到新的输出
这个FC network做完residual以后,还不是结束 你要把residual的结果,再做一次layer normalization,得到的输出,才是residual network裡面,一个block的输出,所以这个是挺复杂的
Encoder总结整个流程
- 首先 你有self-attention,其实在input的地方,还有加上positional encoding(位置资讯)
- Multi-Head Attention,这个就是self-attention的block,这边有特别强调说,它是Multi-Head的self-attention
- Add&norm,就是residual加layer normalization,我们刚才有说self-attention,有加上residual的connection,加下来还要过layer normalization,这边这个图上的Add&norm,就是residual加layer norm的意思
- 接下来,要过feed forward network
- fc的feed forward network以后再做一次Add&norm,再做一次residual加layer norm,才是一个block的输出,
- 然后这个block会重复n次,这个复杂的block,其实在之后会讲到的,一个非常重要的模型BERT裡面,会再用到 BERT,它其实就是transformer的encoder
to learn more
on layer normalization in the transformer architecture,这篇paper它问的问题就是 為什麼,layer normalization是放在那个地方呢
再来还有一个问题就是,為什麼是layer norm 為什麼是别的,不是别的,為什麼不做batch normalization,也许这篇paper可以回答你的问题,这篇paper是Power Norm:,Rethinking Batch Normalization In Transformers
Decoder - Autoregressive(AT)
Decoder其实有两种,接下来会花比较多时间介绍,比较常见的 Autoregressive Decoder,这个 Autoregressive 的 Decoder,是怎麼运作的
Encoder 做的事情,就是输入一个 Vector Sequence,输出另外一个 Vector Sequence
接下来,就轮到 Decoder 运作了,Decoder 要做的事情就是产生输出,也就是产生语音辨识的结果, Decoder 怎麼产生这个语音辨识的结果
首先,你要先给它一个特殊的符号,这个特殊的符号,代表开始,在助教的投影片裡面,是写 Begin Of Sentence,缩写是 BOS
在这个机器学习裡面,假设你要处理 NLP 的问题,每一个 Token,你都可以把它用一个 One-Hot 的 Vector 来表示,One-Hot Vector 就其中一维是 1,其他都是 0,所以 BEGIN 也是用 One-Hot Vector 来表示,其中一维是 1,其他是 0
接下来Decoder 会吐出一个向量,这个 Vector 的长度很长,跟你的 Vocabulary 的 Size 是一样的
每一个中文的字,都会对应到一个数值,因為在產生这个向量之前,你通常会先跑一个 Softmax,就跟做分类一样,所以这一个向量裡面的分数,它是一个 Distribution,也就是,它这个向量裡面的值,它全部加起来,总和 会是 1
分数最高的一个中文字,它就是最终的输出
然后接下来,你把“机”当做是 Decoder 新的 Input,原来 Decoder 的 Input,只有 BEGIN 这个特别的符号,现在它除了 BEGIN 以外,它还有“机”作為它的 Input
所以 Decoder 现在它有两个输入
- 一个是 BEGIN 这个符号
- 一个是“机”
然后这个 Process ,就反覆持续下去
我们来看一下这个 Decoder内部的结构长什麼样子
那我们这边,把 Encoder 的部分先暂时省略掉,那在 Transformer 裡面,Decoder 的结构,长得是这个样子的,看起来有点复杂,比 Encoder 还稍微复杂一点,
那我们现在先把 Encoder 跟 Decoder 放在一起
稍微比较一下它们之间的差异,那你会发现说,如果我们把 Decoder 中间这一块,中间这一块把它盖起来,其实 Encoder 跟 Decoder,并没有那麼大的差别
那只是最后,我们可能会再做一个 Softmax,使得它的输出变成一个机率,那这边有一个稍微不一样的地方是,在 Decoder 这边,Multi-Head Attention 这一个 Block 上面,还加了一个 Masked
这个 Masked 的意思是这样子的,这是我们原来的 Self-Attention
当我们把 Self-Attention,转成 Masked Attention 的时候,它的不同点是,现在我们不能再看右边的部分,也就是产生
b
1
b^1
b1 的时候,我们只能考虑
a
1
a^1
a1 的资讯,你不能够再考虑
a
2
,
a
3
,
a
4
a^2, a^3, a^4
a2,a3,a4
产生 b 2 b^2 b2 的时候,你只能考虑 a 1 , a 2 a^1,a^2 a1,a2 的资讯,不能再考虑 a 3 , a 4 a^3,a^4 a3,a4 的资讯
讲得更具体一点,就是像下图显示的这样
那么为什么要加Masked,其实结合我们刚刚举的例子就容易理解,我们在推演“机器学习”的过程本身就是一步步进行在,先有“机”,再有”器“,然后”学“,最后”习“这样子,它输出的东西是一个一个產生的,所以它只能考虑它左边的东西,它没有办法考虑它右边的东西
讲了 Decoder 的运作方式,但是这边,还有一个非常关键的问题,Decoder 必须自己决定,输出的 Sequence 的长度
可是到底输出的 Sequence 的长度应该是多少,我们不知道
所以我们要让 Decoder 做的事情,也是一样,要让它可以输出一个断,所以你要特别準备一个特别的符号,这个符号,就叫做断,我们这边,用 END 来表示这个特殊的符号
它產生出来的向量END,就是断的那个符号,它的机率必须要是最大的,然后你就输出断这个符号,那整个运作的过程,整个 Decoder 產生 Sequence 的过程,就结束了
Decoder - Non-autoregressive(NAT)
NAT 的 Decoder可能吃的是一整排的 BEGIN 的 Token,你就把一堆一排 BEGIN 的 Token 都丢给它,让它一次產生一排 Token 就结束了
这边你可能会问一个问题:刚才不是说不知道输出的长度应该是多少吗,那我们这边怎麼知道 BEGIN 要放多少个,当做 NAT Decoder 的收入?
- 一个做法是,你另外learn一个 Classifier,这个 Classifier ,它吃 Encoder 的 Input,然后输出是一个数字,这个数字代表 Decoder 应该要输出的长度,这是一种可能的做法
- 另一种可能做法就是,你就不管三七二十一,给它一堆 BEGIN 的 Token,你就假设说,你现在输出的句子的长度,绝对不会超过 300 个字,你就假设一个句子长度的上限,然后 BEGIN ,你就给它 300 个 BEGIN,然后就会输出 300 个字嘛,然后,你再看看什麼地方输出 END,输出 END 右边的,就当做它没有输出,就结束了,这是另外一种处理 NAT 的这个 Decoder,它应该输出的长度的方法
所以发现有很多很多的研究试图让,NAT 的 Decoder 的 Performance 越来越好,试图去逼近 AT 的 Decoder,不过今天你要让 NAT 的 Decoder,跟 AT 的 Decoder Performance 一样好,你必须要用非常多的 Trick 才能够办到,就 AT 的 Decoder 随便 Train 一下,NAT 的 Decoder 你要花很多力气,才有可能跟 AT 的 Performance 差不多
为什么 NAT 的 Decoder Performance 不好,有一个问题我们今天就不细讲了,叫做 Multi-Modality 的问题
Encoder-Decoder
接下来就要讲Encoder 跟 Decoder它们中间是怎么传递资讯的了,也就是我们要讲,刚才我们刻意把它遮起来的那一块
这块叫做 Cross Attention,它是连接 Encoder 跟 Decoder 之间的桥樑,那这一块裡面啊,会发现有两个输入来自於 Encoder,Encoder 提供两个箭头,然后 Decoder 提供了一个箭头,所以从左边这两个箭头,Decoder 可以读到 Encoder 的输出
其实现流程如下
所以其实这个Cross Attention它还是一个类似self-attention的步骤,只不过这个步骤就是 q 来自於 Decoder,k 跟 v 来自于 Encoder,这个步骤就叫做 Cross Attention
Training
在训练的时候,每一个输出都会有一个 Cross Entropy,每一个输出跟 One-Hot Vector,跟它对应的正确答案都有一个 Cross Entropy,我们要希望所有的 Cross Entropy 的总和最小,越小越好
那这边有一件值得我们注意的事情,在训练的时候我们会给 Decoder 看正确答案,也就是我们会告诉它说
- 在已经有 “BEGIN”,在有"机"的情况下你就要输出"器"
- 有 “BEGIN” 有"机" 有"器"的情况下输出"学"
- 有 “BEGIN” 有"机" 有"器" 有"学"的情况下输出"习"
- 有 “BEGIN” 有"机" 有"器" 有"学" 有"习"的情况下,你就要输出"断"
在 Decoder 训练的时候,我们会在输入的时候给它正确的答案,那这件事情叫做 Teacher Forcing
Optimizing Evaluation Metrics?
我们评估的标準用的是BLEU Score这么个东西,BLEU Score 是你的 Decoder,先產生一个完整的句子以后,再去跟正确的答案一整句做比较,我们是拿两个句子之间做比较,才算出 BLEU Score
但我们在训练的时候显然不是这样,训练的时候,每一个词汇是分开考虑的,训练的时候,我们 Minimize 的是 Cross Entropy,Minimize Cross Entropy,真的可以 Maximize BLEU Score 吗
不一定,因為这两个根本就是,它们可能有一点点的关联,但它们又没有那麼直接相关,它们根本就是两个不同的数值,所以我们 Minimize Cross Entropy,不见得可以让 BLEU Score 比较大
在做 Validation 的时候,并不是拿 Cross Entropy 来挑最好的 Model,而是挑 BLEU Score 最高的那一个 Model,所以我们训练的时候,是看 Cross Entropy,但是我们实际上你作业真正评估的时候,看的是 BLEU Score,所以你 Validation Set,其实应该考虑用 BLEU Score
那接下来有人就会想说,那我们能不能在 Training 的时候,就考虑 BLEU Score 呢,我们能不能够训练的时候就说,我的 Loss 就是,BLEU Score 乘一个负号,那我们要 Minimize 那个 Loss,假设你的 Loss 是,BLEU Score乘一个负号,它也等於就是 Maximize BLEU Score. 但事实我们会发现BLUE Score这个东西不是一个convex的,所以对其Optimization是一件难的问题
Scheduled Sampling
那我们要讲到,我们刚才反覆提到的问题了,就是训练跟测试居然是不一致的
测试的时候,Decoder 看到的是自己的输出,所以测试的时候,Decoder 会看到一些错误的东西,但是在训练的时候,Decoder 看到的是完全正确的,那这个不一致的现象叫做Exposure Bias
所以要怎么解决这个问题呢
有一个可以的思考的方向是,给 Decoder 的输入加一些错误的东西,就这麼直觉,你不要给 Decoder 都是正确的答案,偶尔给它一些错的东西,它反而会学得更好,这一招叫做,Scheduled Sampling
以上是关于Transformer的主要内容,如果未能解决你的问题,请参考以下文章
日常Transformer要点记录及实现demo(PyTorch与Tensorflow)
NSPopupButton 与 Value Transformer 的绑定