1. 前言
我在学习NLP的时候,围绕着我不懂得技术点,逐个击破,以此期望能够把各个模块理解的更深入,使我在今后的学习中,能够更深入的分析,让自己更通透。接下来切入正题,介绍下Transformer中需要使用的Positional encoding,它主要为Transformer这种并行计算模型,难以理解输入句子的语序而针对性设计的。
2. 产生背景
我看了很多关于RNN和LSTM的资料,这种模型有一个突出的特点就是串行输出(尽管计算起来比较慢),具有语句顺序。可是,在Transformer中利用的大量self attention,是并行计算的,也就是说每个token的位置是等价的,是没有真正的语言顺序,如下图所示:
对于人来讲,我们可以直观的知道token的位置,但是机器是却不能了解,如何让机器了解他的位置信息呢,即:
- 绝对位置信息,即a1排在第1个,a3排在第3个(全局层面)。
- 相对位置信息,即a2在a1的后面,a3在a2的前面(元素层面)。
- 不同位置间的距离。a1和a3差两个位置,a1和a4差三个位置
一个直观的方法就是,我们构建一个位置向量告诉模型,每个token在模型中所处的位置。
3. 位置编码的演变历程
如何构建一个非常合适的Positional encoding,是一个关键的问题,在原始论文中,作者采用了sin与con三角函数进行表示,但是并没有在文中解释为什么这么做,网上有很多材料进行分析,从傅里叶级数等进行分析,很有深度。知乎上,有位作者猛猿的回答, 简单易懂地解释了Positional encoding作用和实现方式,下面我们就沿着他的行文思路,对整个过程进行一个简单梳理,旨在加深印象。
3.1 用整数型标记位置
在对token进行Positional encoding时,一种特别直观的方法是采用整数数据的方式,比如【1,2,3,4,5,6,…】。可是这种方法存在一些问题。
- 模型可能遇见比训练时所用的序列更长的序列。不利于模型的泛化。
- 模型的位置表示是无界的。随着序列长度的增加,位置值会越来越大,这样数据分布不平衡,可能会引起扰动,难以训练。
3.2 用【0,1】范围进行标记
沿着3.1小节的思路,很容易想到的是,将整数标记的Positional encoding向量进行归一化操作。假设句子长度为,则产生的位置向量为。上述方法解决的整数标记位置存在的问题(存在更长的位置序列;位置表示无界),但是也导师了的新的问题,就是位置距离的不一致。假设一句话有4个单词,位置向量为,如果一句话有两个单词,则位置向量为。第一句话之间的位置距离是0.25,第二段话之间的位置距离为0.5。
因此,我们需要这样一种位置表示方式,满足于:
- 它能用来表示一个token在序列中的绝对位置
- 在序列长度不同的情况下,不同序列中token的相对位置/距离也要保持一致
- 可以用来表示模型在训练过程中从来没有看到过的句子长度
3.3 利用二进制向量表述位置信息
这一种方法,我认为理解起来还是特别的容易的。与BCD编码类似,假设一个句子叫zero one two three four five six three我采用二进制编码的如下所示:
尽管这种方法有上界1,但是这种方法是离散不连续,难以直接训练。
3.4 用周期函数(sin)来表示位置
经过上文分析,我们知晓好的Positional encoding方式,不仅可以让机器知道每个token的位置信息,而且最好上有界且连续的。其中sin是有这种良好性质的函数。所以可以考虑将每一个token位置向量元素用sin函数表示。所以第k个token的位置向量可以定义为:
但是缺点在于三角函数具有周期性,可能出现pos值(一句话中的第几个单词,这里的表达和基本一致)不同但是PE值相同的情况。我在阅读原作者这里分析时,当时并不理解,在看到这篇博文时Positional Encoding的原理和计算,我深刻明白了作者想要表达的意思。简单解释就是,sin是一个周期性震荡函数,当我们选择较大的频率时,很有可能出值不同,但是相同的这种情况。其实想象一下也是比较容易理解的,如果频率偏大,sin函数的波长就很短,当t位置比较大时,计算出的位置向量的值,大概率不是在第一个周期计算得到,这样位置向量呈现的结果将不是单调的,所以可能会相同。这仅仅是推测,知乎作者 给出了一个图,来证实这个想法,具体如下所示,在d_model = 3时,图中的点表示每个token的位置向量,颜色越深,token的位置越往后,在频率偏大的情况下,位置响亮点连成了一个闭环,靠前位置(黄色)和靠后位置(棕黑色)竟然靠得非常近:
为了避免这种情况,我们尽量将函数的波长拉长。一种简单的解决办法是同一把所有的频率都设成一个非常小的值。具体如下:
到此位置这个Positional encoding,我认为已经是非常的巧妙了,他解决的连续性和唯一性的问题,但是论文原始作者更精进一步,通过sin和cos交替解决了相对位置的表达。
3.5 用sin和cos交替来表达位置
这一块我认为知乎作者解释的特别好,便直接引述了他的表达,下式不仅可以表达绝对位置信息,也可以表达相对位置信息
其中,T表示一个线性变换矩阵。观察这个目标式子,联想到在向量空间中一种常用的线形变换——旋转。在这里,我们将t想象为一个角度,那么 就是其旋转的角度,则上面的式子可以进一步写成:
有了这个构想,就可以把原来元素全都是sin函数的做一个替换,让位置两两一组,分别用sin和cos的函数对来表示它们,则现在有:
在这样的表示下,我们可以很容易用一个线性变换,把转变为:
参考
如何理解Transformer论文中的positional encoding,和三角函数有什么关系?Positional Encoding的原理和计算
标签:Transformer,encoding,位置,Positional,token,sin,向量 From: https://blog.51cto.com/lihuanyu/6181067