04-Transformer(Attention Is All
本文是观看B站视频(传送门:https://www.bilibili.com/video/av48285039/?p=92
)后做的笔记,一方面加深理解,另一方面方便日后复习的时候不用重头再来。
transformer有一个非常出色的应用叫做BERT,下一篇将会说明BERT,我会在学习后做好笔记并把它上传。
1.引入
在讲transformer之前,我想提一下RNN,我们都知道RNN非常擅长处理这些input是sequence,但是它有个问题,不容易被平行化(单向信息流),也就是说每个word Embedding都不能同时计算,而需要按照顺序执行。
那么现在就有人提出用CNN来代替RNN。
但是单层的CNN相比RNN考虑的序列有限,如上图中它只考虑了4个vector。为了考虑更长的序列,这就需要增加CNN的层数,那么第二层的filter卷积核会将第一层的输出Output当成它的Input。
CNN的优势在于可以不需要等待第一个filter卷积核计算完成,自己才能进行计算,它达到了平行的状态,也就是说所有的filter卷积核能够同时进行计算。
而伴随二楼的CNN的缺点就是必须要叠加很多层,以便为了得到上下文的更多信息,反之只能得到很少的范围。
2.Self-Attention
那么为了解决这个问题,self-attention应运而生,它取代了RNN可以做的事情(Input是sequence,output也是sequence),它特别的地方是相比于RNN(需要按顺序执行),如下图b1到b4它是可以同时进行计算的。
下面将对self-attention以及multi-head attention的原理进行介绍,进而引出transformer模型
2.1Self-Attention从输入到输出到底发生了什么?(含详细计算过程)
Self-attention出现在google发表的一篇论文名为Attention is all you need中(原文地址:https://arxiv.org/abs/1706.03762).
2.1.1q,v,k分别是什么,怎么产生的?
首先,这里的input是到,然后通过Word Embedding再乘上matrix W变成到,然后把它们丢进self-attention 层中,这时候每一个input都分别乘上3个不同的matrix产生3个不同的vector,分别把它们命名为。
代表的是查询向量,query (to match others用来去匹配其它的向量)
代表的是地址向量,key (to be matched用来去被query匹配的向量)
代表的是内容向量,value(information to be extracted用来被抽取的信息的向量)
2.1.2用q和k做attention,得到α向量
现在要做的工作就是用每个query 去对每个 key 做attention(吃2个向量,输出就是告诉你这2个向量有多么匹配或者可以说输入两个向量输出一个分数(而怎么去吃2个向量output一个分数,有很多不同的做法))。
这里的公式被称为 Scaled Dot-Product Attention 被缩放的点积 注意力,它是由向量与向量做点积然后除以,这里的指的是和向量的维度。
至于为什么要除以,一种直观的解释是和的点积会随着它们维度的增加,点积中相加的子项就越多,所以除以(论文有注解。)(思考:如果这里的点积换成其他的方式,效果会不会更好?)
这里普及下点乘的几何意义:
可以用来表征或计算两个向量之间的夹角,以及在$b$向量在$a$向量方向上的投影
a·b>0 方向基本相同,夹角在0°到90°之间
a·b=0 正交,相互垂直
a·b<0 方向基本相反,夹角在90°到180°之间
2.1.3soft-max
接下来要做的是Soft-max,会将到通过Soft-max层得到biaozheng到 。
2.1.4得到输出
我们用和每一个v相乘,和相乘加上和相乘。以此类推并相加,最终得到。
刚才说self-attention就是输入一个sequence输出一个sequence,现在我们已经得到了要输出的sequence的第一个vector ,这时候的,根据它的计算过程使得它考虑到了全部的sequence。
这里考虑一下得到的其他情况:
- 如果我们只想让它考虑局部的信息,只要让和得到值为0就可以实现。
- 如果我们只想让它考虑最远的信息,只让和计算出值,其他没有即可。
这就做到了想截取input哪部分的sequence,self-attention都可以实现它。
因为self-attention是可以同时进行计算的,那么self-attention可以在计算b1的时候同时计算、、,计算过程与相同,他们这些表征向量是可以平行的计算出来。
2.1.5整体架构
如果以黑盒的角度看,self-attention的机制就是这样的。
2.2self-attention进阶版
下面根据2.1的内容,更详细的说明self-attention每一步是怎么进行计算的。
2.2.1分别是什么,怎么产生的?
整体思路:输入信息,通过线性变换得到为查询向量序列,键向量序列和值向量序列。
首先看第一行:
- 乘以matrix得到;
- 乘以matrix得到;
- 乘以matrix得到;
- 乘以matrix得到;
这时候我们可以把到拼接起来作为一个matrix。概括一下将到整合为,将到整合为,整体为=,代表每个位置的query。
同理,对于向量的计算同向量。将到整体概括为。整体为。
对于向量的计算也同向量。将到整体概括为。整体为。
2.2.2用q和k做attention,得到α向量;soft-max得到
之前说我们用每一个向量去和做attention,其实是做点积。
这里将做转置与点积,可以将省去,让式子更加简化。
那么,,, ,在这个过程中我们发现所有式子都用到了,那么这时候我们将提取出来,将到叠放在一起成为一个matrix矩阵,那么这时候乘以这个matrix矩阵,得到的结果是到的matrix矩阵。
同理,到的计算过程和一样,和到组成矩阵相乘得到到,依此类推。
我们将到组成的向量叫做,到组成的向量转置叫做,他们之间相乘的结果为,经过softmax得到。
2.1.3得到输出
现在按照之前的步骤,我们要得到,此时按照线性代数的公式,用到组成的矩阵乘以矩阵,即的行去相乘相加矩阵的每一列,第一次计算得到,以此类推直到。将到的向量组成矩阵(也是整个self-attention层的输出)。
2.1.4回顾
现在我们再将刚才的运算回顾一下,我们将到组成的输入叫做(以下用来指代),输出到叫做。下面我们梳理下从到这个过程之中,self-attention层做了哪些事情。
1.首先,我们将分别和三个不同的matrix相乘,,和。我们得到了到向量组成的矩阵,到向量组成的矩阵,到组成的矩阵。
2.然后,我们用矩阵和的转置相乘(为了省去,让式子简化),得到了矩阵(attention矩阵),每个元素α代表的是input输入的的sequence每个位置上的两两之间的attention(即概率分布)。
3.然后矩阵经过softmax计算,成为了矩阵
4.最后,矩阵与矩阵相乘就得到了输出矩阵。
Tips:我们发现self-attention中做的就是一连串的矩阵乘法,我们可以使用GPU进行加速计算。
3.Multi-head Self-attention 多头自注意力机制
除了self-attention,现在还有多头自注意力机制 Multi-head Self-attention。下面以2头注意力机制作为说明。
多头的关键之处就在于,分别将向量继续细分为。
这里的只和位置在1的进行相乘,如乘以和,得到,然后经过soft-max的,再和,相乘相加,最终得到。
同理,同上,最终得到。
进行到这一步,这时候我们拥有了和,如果不想要和组成的矩阵的维度(这里是2),我们可以进行降维,得到。
这样多头的机制有什么好处呢?在论文中,不同的head它们关注的部分不同,这样每个head会各司其职注意力集中于各自的区域,
(换句话说,多头注意力(multi-head attention)是利用多个查询Q = [],来平行地计算从输入信息中选取多个信息。每个注意力关注输入信息的不同部分,然后再进行拼接)
在模型中head的个数也是超参数,可以进行调优。
4.Transformer在此前的基础上改进了什么?
我们这里有个问题,对于self-attention来说,它的Input的sequence是没有顺序的,这显然不是我们想要的。
在Transformer的论文中,我们手动设定了位置编码向量,它代表了位置信息,我们就可以知道某个现在在哪个位置。
那么这里可能会有疑问,直接将位置向量和输入向量相加会不会导致向量混乱影响结果,这里对的产生有一种解释(与原论文不同,但是最后的公式一致):
在输入的时候,每个输入的再加入一个用one-hot编码的向量pi用来代表位置信息。
1.将和进行拼接;
2.然后与(分为和)相乘得到Embedding,
3.根据线性代数公式和相乘,和相乘然后相加。
对比上面的式子,和相乘就得到,和相乘然后相加就得到。
而在原论文中比较匪夷所思的是,是人工设置的。
右边的图形就是的样子。
4.1什么是Transformer?
Transformer就是seq2seq model with Attention。
4.2从Input到output发生了什么?
Encoding的时候所有输入的序列的词,两两进行attention,这些attention是平行的,有三层所以做三次。
Decoding的时候,不仅会attend之前已经输入的部分还有已经输出的部分。
4.3Transformer内部原理
一个seq2seq的model,左边是encoder,右边是decoder,希望输入中文输出是英文。
比如输入的是机器学习
首先decoder给一个BOS的token,decoder输出machine,然后将machine作为输入,输出learning,然后知道输出句点,就结束了。
下面解释下transformer内部发生了什么?
左半部分:
1.input通过一个input Embedding层变为vector;
2.vector会加上位置编码进入block,这个block会重复N次;
3.block的第一层是multi-head attention,通过它会得到另一个sequence;
4.然后是add&norm,其中add是:将multi-head attention的输出b和输入a加起来b';norm是:将b'经过layer norm做layer normalization(详情见https://www.jianshu.com/p/c357c5717a60);
5.经过add&norm,vector会进入feed forward进行处理(简单的全连接网络,对每个position的向量分别进行相同的操作,包括两个线性变换和一个ReLU激活输出),然后再进行add&norm;
右半部分:
1.decoder的底部的output是由前一个向量计算产生的结果作为输入;
2..同理。vector会加上位置编码进入block,这个block会重复N次;
3.进入第一层,block的第一层是masked multi-head attention。这里的masked是attend on the generated sequence,意思就是decoder只会参加到已经产生出的sequence中(由于是序列生成过程,所以在时刻 i 的时候,大于 i 的时刻都没有结果,只有小于 i 的时刻有结果,所以没有产生出来的向量是不存在的,无法进行attention),然后进行add&norm;
4.之后进入一层 multi-head attention,它的输入是之前encoder部分的输出;
5.然后再与3.的输出进行add&norm,之后进入feed forward进行处理,进入add&norm,然后是linear层(Linear层就是一个全连接网络,作用是把decoder输出的向量映射到一个大很多的logits 向量上。)
6.经过softmax计算后输出分数最高的那个词就是这一步的输出。
4.4Transformer的应用场景
transformer的应用场景:
只要是可以用seq2seq,就可以用transformer