位置编码

纯粹的Attention模块是无法捕捉输入顺序的,因此对于Transformer模型来说,加入位置编码是非常必要的,否则模型无法区分不同位置的token。为此,大体有两个选择:

  1. 绝对位置编码
    将位置信息融入到输入中
  2. 相对位置编码
    调整Attention结构,使其能够分辨不同位置的token

绝对位置编码

一般来说,绝对位置编码会加到输入中:在输入的第个向量中加入位置向量,此时输入由变成 ,其中只依赖于位置编号

训练式

最朴素的绝对位置编码就是直接将位置编码当作可训练参数,比如最大长度为512,编码维度为768,那么就初始化一个 的矩阵作为位置向量,让它随着训练过程更新。BERT和GPT等模型就是用的这种位置编码。

对于这种训练式的绝对位置编码,一般认为它的缺点是没有外推性,即如果预训练最大长度为512的话,那么最多只能处理长度为512的句子,再长就处理不了了。当然,也可以将超过512的位置向量随机初始化,然后继续微调。

三角函数式

三角函数式位置编码也即Sinusoidal位置编码,也是Attention is All You Need中提出的显式解:

其中分别是位置的编码向量的第 个分量,是位置向量的维度。

三角函数式位置编码具有显式的生成规律,因此可以期望它具有一定的外推性。此外,由于 ,这表明位置 的向量可以表示成位置和位置的向量组合,这提供了表达相对位置信息的可能性。

递归式

原则上说,RNN不需要位置编码,它在结构上自带了学习到位置信息的可能性。因此,如果在输入后面先接一层RNN,然后再接Transformer,那么理论上就不需要再加位置编码了。

我们可以用RNN模型来学习一种绝对位置编码,比如从一个向量出发,通过递归公式 来得到各个位置的编码向量。

相对位置编码

相对位置并没有完整建模每个输入的位置信息,而是在计算Attention时考虑当前位置与被Attention位置的相对距离。由于自然语言一般更依赖于相对位置,所以相对位置编码通常有着优秀的表现。

经典式

Google在论文Self-Attention with Relative Position Representations中首次提出了相对位置编码。

计算的方式如下:

为了引入相对位置信息,Google把第一项位置去掉,第二项改为二元位置向量,那么注意力分数变成:

此外,将 中的换成

相对位置就是将原本依赖于二元坐标的向量
改为只依赖于相对距离 ,并且通常来说会进行截断以适应不同任意的距离:

这样只需要有限的位置编码,就可以表达出任意长度的相对位置。

T5式

如果分析每一项的含义,那么可以分别理解为“输入-输入”,“输入-位置”,“位置-输入”和“位置-位置”四项注意力的组合。如果认为输入信息和位置信息是解耦的,那么它们就不应该有过多的交互,所以“输入-位置”和“位置-输入”两项Attention可以删掉。而实际上只是一个依赖于的标量,可以直接将它作为参数训练出来,即简化为:

其实它就是在Attention矩阵的基础上添加一个可训练的偏置项

此外,XLNet和DeBERTa也对位置编码进行了改进,可参考苏剑林的博客

融合式

苏剑林基于通过绝对位置编码的方式实现相对位置编码这个出发点提出了RoPE,即旋转位置编码,将绝对位置编码和相对位置编码融于一体。RoPE位置编码通过将一个向量旋转某个角度,为其赋予位置信息。

首先,对于两个复数的内积而言,存在以下公式:

其中是共轭复数,右端的乘法是普通的复数乘法,表示取结果的实部。也就是说,两个二维向量的内积,等于把它们当成复数看待时,一个复数与另一个复数的共轭的乘积实部。

假设是所在位置分别为的二维行向量,如果给它们分别乘以,那么就相当于给它们添加了绝对位置编码了(因为显式地依赖绝对位置),然后放到内积中,就有:

也就是说,内积只依赖于相对位置 ,这就巧妙地将绝对位置和相对位置融合在一起了。

根据欧拉公式 ,我们可以得到:

也就是说,通过

赋予绝对位置信息,那么在Attention运算的时候也等价于相对位置编码。如果是多于二维的向量,那么可以考虑每两维为一组进行同样的运算,每一组的可以不一样。这样一来,我们就得到一种融合了绝对位置和相对位置于一体的位置编码方案。

【参考文献】

  1. 让研究人员绞尽脑汁的Transformer位置编码
  2. Transformer升级之路:2、博采众长的旋转式位置编码
  3. RoPE论文解读