本文参考的原始论文地址:https://arxiv.org/abs/1706.03762
概述
传统的序列任务一般通过循环神经网络来解决,但是不管是单向还是双向的循环神经网络都无法实现运行运算,一个单元的运算依赖于其他部分的结果。为了解决并行运算的问题,可以使用CNN模型,对于同一层的卷积操作时,不同的卷积核可以并行的执行。但是在比较浅层的卷积层时,卷积核只能覆盖到很小的一块区域,只有更深的卷积层中的卷积核可以覆盖比较广的数据,因此使用CNN的局限就在于获取输入的信息需要多个卷积层操作,这就导致了网络模型会加深,模型参数会增加等问题。本文作者提出了一种新的简单网络体系结构,即Transformer,其仅仅基于注意力机制,完全的省去了RNN和CNN。实验结果也表明,这些模型的质量更高,可并行运行,并且训练时需要更少的时间。
本文作者的主要贡献就在于提出了一种模型体系结构:Transformer,完全的依赖于注意力机制在输入和输出之间引入了全局依赖性,并且可以显著的并行化运算。
背景
减少序列模型的计算时间也构成了扩展神经GPU的基础,这些模型全部使用CNN作为基本构建块,对所有的输入和输出位置并行的计算隐藏的表达。但在这些模型中,运算的数量随着两个输入和输出的位置增大而增加。这样会使得学习位置之间的关系更加困难。而在Transformer中,这个运算数量并缩减到固定的操作数量,尽管会由于平均注意力加权的位置会导致有效分辨率的降低。
模型结构
像大多数神经序列转义模型一样,Transformer的结构主要也是Encoder-Decoder,通过向Encoder提供输入并生成连续表达的隐藏变量,再通过Decoder产生输出结果,最后通过一层全连接层。Transformer的架构如下图1:
堆栈式编码器和解码器
编码器:编码器由6个相同的层堆叠而成,每一层都有两个子层,第一层是multi-head自注意力机制层,第二层是简单的全连接网络,并且在每两个子层之间应用了残差连接,然后紧接着进行标准化操作。
解码器:解码器也由6个相同的层组成,除了在每一层中的两个子层,解码器还引入了在编码器的输出上执行multi-head注意力操作。和编码器类似,解码器也在没两层之间应用了残差连接,接着紧跟标准化操作。作者还修改了解码器堆栈中的自注意力子层层,以防止位置参加后续位置。这种掩蔽,结合了输出嵌入被一个位置所抵消的事实,可确保对位置i的预测仅取决于小于i的已知的位置。
注意力
自注意力机制:一个注意力功能可以被描述映射查询a到key-value集合上然后输出结果,其中query,keys,values和输出都是向量。输出被作为values的加权和,其中权重是通过query和对应key计算出来的。计算结构如下图:
实际中,同时在多个query上计算注意力函数,具体来说,首先计算Q和K的矩阵相乘,为了避免在softmax梯度平缓的问题,对结果进行放缩操作,然后进行可选的标记操作,最后应用一个softmax操作,得到每一个key的权重,然后将得出的权重与V矩阵进行相乘,得到注意力结果。具体公式如下:
multi-head注意力:作者发现对d维的keys,values和querys,分别用不同的线性投影,然后分别对不同的投影执行注意力操作,产生多个d维的输出,可以将这些值连接起来,获得最终的值,运行结构如下图:
multi-head的计算如下:
在文本提出的Transformer架构中,注意力机制主要应用在三个方面:
编码器-解码器:其中querys来自于前一层的输出层,keys和values来自encoder的输出层。这能够让解码器中每一个位置都注意到输入序列的全部位置信息。
编码器:编码器包含了自注意力机制,在自注意力中,所有的querys,keys和values都来自同一个地方,在这个架构中,就是前一层的编码器的输出。编码器中的每一个位置都可以注意到编码器前一层的所有位置。
解码器:解码器包含了自注意力机制,解码器中的自注意力允许解码器中的每一个位置都可以关注到上一层解码器的全部位置。
位置方面前馈神经网络
除了注意力子层,每一层中还包含全连接前馈神经网络。这一层主要包含了两个线性转换和一个relu激活函数,计算公式如下:
嵌入和softmax
和其他序列转义模型一样,本文也是用已经学好的嵌入层将输入和输出转换为d维的向量。本文也使用了学好的线性转换和softmax函数将解码器的输出转换为预测的下一个token的概率。在本文的模型中,在两层嵌入层和前一层softmax线性层中共享参数。
位置编码
由于本文提出的模型没有使用RNN和CNN,为了充分利用序列的顺序,必须注入一些绝对或相对的位置信息。最后,本文通过向编码器和解码器的栈底部嵌入层添加“位置编码”。位置编码和嵌入层有相同的维度d,所以这两项是可以加和的。在本文中,使用的是不同频率下的sin和cos函数,公式如下:
其中pos是位置(位置是指序列中词的位置),i是维度(一个词是由k维的向量表示)。也就是说明位置编码的每一维都对应一个sin函数。
总结
本文介绍了Transformer,这是完全基于注意力的第一个序列转导模型,使用具有multi-head自注意力的编码器架构取代了序列任务中最常用的RNN层。对于翻译任务,训练Transformer模型可以比基于RNN或CNN的架构更快。在WMT 2014年英语到德国人和WMT 2014年英语翻译任务上,我们取得了最好的结果。
Transformer的优点在于,他完全抛弃了传统的RNN和CNN并且取得了非常不错的效果,实现了模型的创新;Transformer的设计带来的最大的性能提升的关键是将任意两个词的距离变为1;Transformer不仅仅能应用于NLP的翻译领域,还可以应用到其他领域。
Transformer的缺点在于,抛弃了RNN和CNN虽然很好,但是失去了捕获局部特征的能力;Transformer失去的位置信息在NLP中是至关重要的,虽然通过位置编码可以弥补,但是结构上的缺失是固有的。后续的改进可以尝试结合RNN,CNN和Transformer,结构上考虑位置信息。当输入序列N较长时,在计算query向量和key向量点积操作得到注意力矩阵时,计算量可能会特别的大。
后续的改进可以从加速query和key向量的点积运算,比如并行的计算注意力矩阵,加快网络的训练和推理过程
扩展
由于在Transformer中,计算注意力矩阵时,我们假定计算一个元素的注意力权重时需要考虑其他全部元素,但随之带来的就是计算量的增大。为了加快注意力矩阵的运算,对于某些任务我们可以在计算元素权重时,可以通过人类对问题的理解,只考虑部分其他元素,比如邻居,或者更远的元素。这种方法叫做Local Attention或Truncated Attention,但这种只关注局部信息的操作很类似CNN,但是加快了注意力矩阵的运算,并且像CNN在进行卷积操作时可以应用stride一样,计算Attention也可以,这种方法称之为Stride Attention。尽管Local Attention加快了注意力矩阵的计算,但是带来的弊端就是失去了全局信息,为了补回全局的信息,可以通过引入额外的元素,这个元素先与其他全部元素进行计算获取全局信息,然后再计算其他元素的注意力权重时只与这个具有全局信息的元素进行运算以获得全局信息。通过使用不同注意力技巧可以产生各种不同的模型。
在Longformer中,作者结合Sliding Attention、Stride Attention和Global Attention等操作来计算注意力矩阵;在Big Bird中,作者除了应用上述提到的各种注意力技巧外,还额外的引入了Random Attention。
上述提到的方式虽然加快了网络的计算,但是仅仅靠人类的先验知识往往不能取得最好的结果。在计算注意力矩阵时,结果矩阵有可能会出现特别小的值,为了加快网络的计算我们可以简单的将阈值一下的注意力权重赋值为零,也会加快网络的训练和推理。类似上面提到的简单方法,我们可以考虑让模型注意到重点的地方,具体来说像Reformer和Routing Transformer一样,先对query和key进行聚类操作,将相似的query和key分为一组,然后在计算注意力权重时,只将query与在一组的key进行计算,其他元素直接设置为零,最终得到注意力矩阵。
为了更进一步,我们可以通过神经网络来训练出需要计算哪些query和key之间的权重值,在Sparse Sinkhorn Attention中,作者使用另外一个神经网络来输出需要计算的query和key的二值矩阵,然后根据这个矩阵计算注意力矩阵。
但是我们真的需要计算每一个query和key这样一个NXN的注意力矩阵吗?Linformer指出,经常计算得出的注意力矩阵是一个低秩的矩阵,这说明矩阵中用重复的列,或者不同的列具有线性关系,那么只需要计算一个更小的矩阵就好了。具体来说,从N个key中挑选中具有代表性的key,同理也对value进行这样的操作。在Compressed Attention中,作者通过对N个key进行卷积操作,得到的key就作为代表性的key;而在Linformer中,作者通过将原先的N个query构成的矩阵乘上另外一个矩阵得到最终代表性的key。
在上文中,我们提到了各种XXFormer模型,对原始的Transformer分别进行了不同的改进,并在实践中取得了不错效果。在后续中我们可以共更多的角度对注意力机制进行改善,来提高我们的模型性能。
文章出处登录后可见!