transformer理解
本文最后更新于:1 年前
什么是Attention(注意力机制)
在提起Attention之前,因其涉及到encoder-decoder的设计思想,因此先从RNN->Seq2Seq做一个简单介绍,以理解Attention为何如此设计
RNN的一个例子
我们知道,RNN(循环神经网络),是可以帮助我们处理序列数据,如文本,语音
例如,我们需要订票,那么"我去A地"和"我离开A地",这两个A地分别指代的是不同的信息,一个是目的地,一个是始发地.若是用传统的神经网络难以处理此类问题,而RNN则可以很好的进行分类
因为RNN对于处理文本信息时,每一个输入的词是自带了时序信息在里面的,而当前时刻的词,通过hidden layer,可以与前一时刻的词相关联(类似hidden markov model)
对输入的词进行编码,构建RNN,因为"去"和"离开"二词的编码信息不同,则最后计算出来的"A地"的得分也不同,因此便可以进行区分
这是一个N对N的例子,即输入序列的长度==输出序列的长度
RNN亦可以实现1对N 或是 N对1
那如果我们是做文本翻译或是QA系统,那么就会有N对M的情况,则需要用到Seq2Seq
Seq2Seq的一个例子
上面说了,Seq2Seq可以处理N对M的情形,其结构又称为encoder-decoder模型
其本质就是利用了两个RNN(encoder和decoder都是)来做处理,decoder利用encoder生成的语义编码来做解码,有两种(我所知)使用形式:
- 可以将语义编码作为decoder的初始状态
- 可以将语义编码作为decoder每一个token的输入
很明显,若是将语义编码作为decoder每一个token输入的话(较前一个方法好),那么存在一个问题:所有待预测的token它们使用的都是一个语义编码,即没有针对性,没有做到focus each one
因此就有attention注意力机制的出现
Attention
由上述可知,我们在对不同的词做翻译的时候,如"机器学习"->“machine learning”,并不是说"机器","学习"这两个词语对machine的翻译具有相同的贡献,因此不同贡献可以通过如权重的概念来进行体现
那么这个"贡献"要怎么获得,即不同词语的权重影响要怎么实现?
先将这个问题放一边(假设我们有能力做到这一点),那么我们不同的贡献就可以对应不同语义模型,那么"注意力"的思想即得到了体现
回到"贡献"获得的问题,attention中的"贡献":是输入的时候通过计算encoder和decoder对应token的余弦相似度来获得,然后每一个词有不同的值,通过softmax进行归一化,那么这就是一个语义模型.流程见下图:
什么是transformer
transformer是一个NLP任务的一个里程碑模型(刷新了多项任务的SOTA),而后被人运用到CV,如DETR(Detection Transformer),ViT(Vision Transformer,做分类的)
其中ViT在数据量足够大的情况下,可以达到甚至超过当时的SOTA(ViT基本是直接将transformer直接搬到CV上用的,没咋改,除了切图片以使其序列化)
因此可以看出transformer在CV领域也是大有作为.下面将先以NLP的transformer的释义进行模型解释.
此外,transformer在NLP机器翻译中的一大特点是它可以并行处理(存疑:我认为只局限于training阶段),即对单词的翻译不必由一个去预测下一个
原论文链接:Attention Is All You Need
整体结构
由上图可见,我们的transformer整体也是分为encoder-decoder结构的
图中所示为encoder,即表明其内部由多个encoder block组成(原论文是6个),decoder也同理
(也是6个)
输入
在transformer中因其采用了注意力机制,因此导致了位置信息的缺失,而在机器翻译中,如一个not放置的位置若是不同,语句的意义也可能截然相反.因此我们需要对输入进行编码,以保持位置信息
我们要对输入进行词编码和位置编码,以获取输入语句的一个词的表示向量x,而后这些词的表示向量堆叠可以获得词的表示矩阵X,X∈R(nxd~model~)
对于词编码,可以通过如Word2Vec等的方式获取
对于位置编码,transformer采用了正余弦函数来获取(位置编码:偶数位置用正弦,奇数位置用余弦)
pos:表示的是词在句子中的位置;
d:表示的是词编码后的维度,即词编码后的表示向量的列数;
2i:表示的是偶数维度;
2i+1:表示的是奇数维度
词编码和位置编码均完毕后,我们将其对应相加,即可以得到X的表示矩阵,过程图如下图示:
self-attention
self-attention是attention中的一个特例
我们知道attention是找两个句子间的词间关系,而self-attention找的是一个句子间的词间关系(也可以理解为两个相同的句子)
从transformer_arch的图可以看出Multi-Head Attention在整个过程中起了极大作用,是核心模型,图中的Multi-Head Attention,其实里面就是由多个self-attention组成(论文里是8个)
因此我们需要关注self-attention的工作机制
self-attention的工作过程如下图所示:
可以看出,它有三个输入Q,K,V,分别代表的是Query,Key,Value,然后需要经过MatMul(矩阵相乘),Scale(数值放缩),Mask(掩码,Output时需要),Softmax(归一化)这些个过程.
获取Q,K,V
首先,输入到encoder里的是我们上面获得的表示矩阵X
X通过与对应权重(一开始是随机生成的,后面梯度下降更新的)的矩阵:WQ,WK,WV相乘,获取到对应的Q,K,V三个矩阵,其中它们的维度为:n*dQ,n*dK,n*dV,n代表着一个句子中词的数目,每一个行向量,代表的是某一个词的Q或K或V的维度
计算的示例图如下图所示:
self-attention计算公式
根据上面的方法获取了Q,K,V三者的矩阵后,可以对其进行self-attention-process图示的计算,公式如下:
Q与KT相乘,得到的是n*n的矩阵(dK==dQ),那么这个矩阵的每一行代表的是该词语与别的词语的关注强度(相关性),然后为了防止内积过大(不利于梯度更新),则进行放缩,而后通过softmax以使得词语与词语间的关注强度更为明显,而后再乘于V,则得到最终的输出Z(n*dV)
从逻辑上思考,Q与KT乘积后得到的矩阵,存在着一个问题,即模型会过度关注自身的位置,则整体模型的效果会大打折扣,因此作者提出了Multi-Head Attention机制来应对这个问题
我认为Q,K,V三者的关系可以这么理解(知乎看的):
我们要在一个dict上查单词,那么单词肯定是K对应V,若是在dict中刚好有Q==K,则可以立刻找到对应的V;但是现在的情况是,我们的词变成了词向量,则要通过其Q和K相关洗漱,再与V做内积,来找到最有可能的V
Multi-Head Attention
self-attention机制存在一个问题,模型在对当前位置信息进行编码时,会过度的将注意力集中于自身的位置,那么这样出来的模型就会忽略了其他位置的作用.因此作者提出了Multi-Head Attention机制.
在原论文中作者运用了8个头,即h=8.用其去对Q,K,V三者的维度进行划分,即
由上述公式可以看出,我们的dK是经过划分的,若不划分,那么即是在h=1的情况下,dK= dV = dmodel,则经过Scaled Dot-Production Attention后的Z,其主对角线的值总是最大的(就是过于关注自身的问题),因此,通过多头机制,对Q,K,V的列的维度进行划分,以减弱这种影响!公式如下:
我们划分将Q,K,V划分成八个(8个h),对它们可以并行做计算,然后最后会得到八个Zi(i∈[0,7]),对它们进行concat(合并后的维度与X一致),然后与WO矩阵进行相乘即得出对应输出,输出矩阵维度与表示矩阵维度X一致
具体过程见下图:
至此,多头注意力机制介绍完毕
encoder block
我们知道,一个encoder block里面,经过了Multi-Head Attention的洗礼后,要经过一个Add & Norm的东东,而后再将输出经过Feed Forward NN,便完成了一个encoder的工作
Add & Norm
其实Add就是ResNet的shortcut connection,以防止gradient vanish或者说network degradation;
然后Norm其实指的就是Layer Normalization,一个归一化的东东(这是用于RNN里的,与BN不同,是针对每个样本进行的),用于加快收敛(总之就是加快训练速度)
Feed Forward
是一个两层的全连接层,公式如下(这个没细看):
最后输出的维度与X表示矩阵的一致
Encoder
Encoder就是将多个encoder block线性连接了起来,前者的输出作为后者的输入,重复六次,则得出最终的输出编码信息矩阵,其维度与X的一致
过程见图所示:
decoder block
decoder block相较于encoder block,它有如下差别:
- 首个Multi-Head Attention有Masked掩码操作;
- 第二个多头注意力机制,K,V源于encoder的输出的编码信息矩阵,Q则是源于上一个含掩码的输出;
关于Masked Multi-Head Attention
所谓的Masked指的是:翻译的时候是顺推的,即翻译出了第i个单词后,才会进行第i+1个单词的翻译,那么在翻译第i个单词的时候,就需要将第i+1个单词及之后的信息进行遮掩
需注意:
- 在training阶段时,我们采用的是teacher force的策略,就是在每一轮(i)的预测的时候,不采用上一轮(i-1)的输出,而是直接采用正确答案,因为是训练,所以有答案,所以可以做并行;
- 在predict阶段,没有答案,需要类似Seq2Seq的方法,即i轮预测需要i-1轮的输出,无法并行.循环往复,直至预测完毕
Mask操作,是在self-attention里的softmax前执行的
关于第二个Multi-Head Attention
这个其实和普通的差不多,就是K,V来自于encoder的编码信息矩阵
softmax预测
根据最后输出的结果,我们的矩阵是含有掩码的,那么就是说:第0行的输出,只包含词0的信息,第二行,则包括词0,词1的信息.
因此softmax是根据输出矩阵的每一行预测下一个单词.
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!