当前位置:   article > 正文

使用Positional Encoding的作用和原因_positional encoding怎么做有什么用

positional encoding怎么做有什么用

提示:以下是本篇文章正文内容

一、位置编码代码和公式

class PositionalEncoding(nn.Module):
    """位置编码"""
    def __init__(self, num_hiddens, dropout, max_len=1000):
        super(PositionalEncoding, self).__init__()
        self.dropout = nn.Dropout(dropout)
        # 创建一个足够长的P
        self.P = torch.zeros((1, max_len, num_hiddens))
        X = torch.arange(max_len, dtype=torch.float32).reshape(
            -1, 1) / torch.pow(10000, torch.arange(
            0, num_hiddens, 2, dtype=torch.float32) / num_hiddens)
        self.P[:, :, 0::2] = torch.sin(X)
        self.P[:, :, 1::2] = torch.cos(X)

    def forward(self, X):
        X = X + self.P[:, :X.shape[1], :].to(X.device)
        return self.dropout(X)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在位置嵌入矩阵 P \mathbf{P} P中,[行代表词元在序列中的位置,列代表位置编码的不同维度]。

[位置编码]

在处理词元序列时,循环神经网络是逐个的重复地处理词元的,而自注意力则因为并行计算而放弃了顺序操作。

为了使用序列的顺序信息,我们通过在输入表示中添加位置编码(positional encoding)来注入绝对的或相对的位置信息。位置编码可以通过学习得到也可以直接固定得到。接下来,我们描述的是基于正弦函数和余弦函数的固定位置编码
在这里插入图片描述

假设输入表示 X ∈ R n × d \mathbf{X} \in \mathbb{R}^{n \times d} XRn×d包含一个序列中 n n n个词元的 d d d维嵌入表示。

位置编码使用相同形状的位置嵌入矩阵 P ∈ R n × d \mathbf{P} \in \mathbb{R}^{n \times d} PRn×d输出 X + P \mathbf{X} + \mathbf{P} X+P,矩阵第 i i i行、第 2 j 2j 2j列和 2 j + 1 2j+1 2j+1列上的元素为:
p i , 2 j = sin ⁡ ( i 1000 0 2 j / d ) , p i , 2 j + 1 = cos ⁡ ( i 1000 0 2 j / d ) .

pi,2j=sin(i100002j/d),pi,2j+1=cos(i100002j/d).
pi,2jpi,2j+1=sin(100002j/di),=cos(100002j/di).

其中公式中的i指的是下图中的索引Index of token,它表示的每一个次元的位置索引。j指的是词元中d维度方向把奇数列当作sin函数,偶数列当做cos函数。其中关于为什么要用cos和sin函数来进行位置信息的表示,在下文末尾进行说明讨论。

二、位置编码为什么可以反映前后位置关系

2.1 位置编码在单个位置向量上的位置信息

P t P_t Pt指的是序列中的第T位置或者时间步为T时刻的向量位置编码
在这里插入图片描述
最重要的是我们需要这个编码方式可以取得两个方向的编码信息。

1、是在每个词元所经过embeding后在维度上的每个位置( P 00 , P 01 . . . , P 0 d P_{00},P_{01}...,P_{0d} P00,P01...,P0d)的先后信息。

2、是每个词元的先后信息,也就是能体现输入序列的先后顺序的信息
在这里插入图片描述
对于邻近的奇偶数列地三角函数之间存在关系,因此在模型每层的特征提取中,模型可以捕捉到这种关系,从而确定邻近维度地前后关系。
s i n 2 + c o s 2 = 1

sin2+cos2=1
sin2+cos2=1
也就是对应的$P_t
s i n 2 ( w k t ) + c o s 2 ( w k t ) = 1
sin2(wkt)+cos2(wkt)=1
sin2(wkt)+cos2(wkt)=1

对于同一token中较长远的三角函数之间,由上图公式可以看到三角函数频率沿着向量维度递减。因此,它形成了一个几何级数,波长从 2 Π 2Π 10000 × 2 Π 10000×2Π 10000×也就是说在同一个token词元中,编码信息越靠后,对应的三角函数波长有规律地增长,模型也可以捕捉到这种关系,从而得到一个前后关系信息。
在这里插入图片描述

在下面的例子中,我们可以看到位置嵌入矩阵的第 6 6 6列和第 7 7 7列对应的三角函数频率高于第 8 8 8列和第 9 9 9列。

6 6 6列和第 7 7 7列之间的偏移量(第 8 8 8列和第 9 9 9列相同)是由于正弦函数和余弦函数的交替。第六列的三角函数波长就要大于第七列和后面序列的的波长。

在这里插入图片描述
下面是一个对映的热力图:
在这里插入图片描述

2.2 位置编码在整体编码信息反映的前后关系信息

在这里插入图片描述
我们选择这个函数是因为我们假设它可以让模型很容易地通过相对位置来学习,因为对于任何固定的偏移量k, P (Epos+k)可以表示为的线性函数

证明位置编码中相对位置之间的线性关系:有以下三角函和差化积的公式。
sin ⁡ ( A + B ) = sin ⁡ A cos ⁡ B + cos ⁡ A sin ⁡ B cos ⁡ ( A + B ) = cos ⁡ A cos ⁡ B − sin ⁡ A sin ⁡ B cos ⁡ ( A − B ) = cos ⁡ A cos ⁡ B + sin ⁡ A sin ⁡ B cos ⁡ ( A − B ) = cos ⁡ A cos ⁡ B + sin ⁡ A sin ⁡ B \sin(A + B) = \sin A \cos B + \cos A \sin B \\\cos(A + B) = \cos A \cos B - \sin A \sin B\\ \cos(A - B) = \cos A \cos B + \sin A \sin B \\\cos(A - B) = \cos A \cos B + \sin A \sin B sin(A+B)=sinAcosB+cosAsinBcos(A+B)=cosAcosBsinAsinBcos(AB)=cosAcosB+sinAsinBcos(AB)=cosAcosB+sinAsinB对于存在一个旋转矩阵 M ∈ R 2 × 2 M \in \mathbb{R}^{2\times2} MR2×2,等于以下旋转矩阵:

M = [ u 1 v 1 u 2 v 2 ] M=

[u1v1u2v2]
M=[u1u2v1v2]
继而对于假设任意时间步为t处的位置编码,乘以旋转矩阵 M M M,可以得到以下时间步为 t + ϕ t+\phi t+ϕ处的位置编码
[ u 1 v 1 u 2 v 2 ] . [ sin ⁡ ( ω k . t ) cos ⁡ ( ω k . t ) ] = [ sin ⁡ ( ω k . ( t + ϕ ) ) cos ⁡ ( ω k . ( t + ϕ ) ) ]
[u1v1u2v2]
.
[sin(ωk.t)cos(ωk.t)]
=
[sin(ωk.(t+ϕ))cos(ωk.(t+ϕ))]
%]]>
[u1u2v1v2].[sin(ωk.t)cos(ωk.t)]=[sin(ωk.(t+ϕ))cos(ωk.(t+ϕ))]

[ u 1 v 1 u 2 v 2 ] . [ sin ⁡ ( ω k . t ) cos ⁡ ( ω k . t ) ] = [ sin ⁡ ( ω k . t ) cos ⁡ ( ω k . ϕ ) + cos ⁡ ( ω k . t ) sin ⁡ ( ω k . ϕ ) cos ⁡ ( ω k . t ) cos ⁡ ( ω k . ϕ ) − sin ⁡ ( ω k . t ) sin ⁡ ( ω k . ϕ ) ] % <![CDATA[

[u1v1u2v2]
.
[sin(ωk.t)cos(ωk.t)]
=
[sin(ωk.t)cos(ωk.ϕ)+cos(ωk.t)sin(ωk.ϕ)cos(ωk.t)cos(ωk.ϕ)sin(ωk.t)sin(ωk.ϕ)]
%]]> [u1u2v1v2].[sin(ωk.t)cos(ωk.t)]=[sin(ωk.t)cos(ωk.ϕ)+cos(ωk.t)sin(ωk.ϕ)cos(ωk.t)cos(ωk.ϕ)sin(ωk.t)sin(ωk.ϕ)]

ϕ \phi ϕ是指的序列之间的位置的差值,具体说明见内容三。

u 1 =     cos ⁡ ( ω k . ϕ )     v 1 = sin ⁡ ( ω k . ϕ ) u 2 = − sin ⁡ ( ω k . ϕ )     v 2 = cos ⁡ ( ω k . ϕ ) % <![CDATA[

u1=   cos(ωk.ϕ)   v1=sin(ωk.ϕ)u2=sin(ωk.ϕ)   v2=cos(ωk.ϕ)
%]]> u1=   cos(ωk.ϕ)u2=sin(ωk.ϕ)   v1=sin(ωk.ϕ)   v2=cos(ωk.ϕ)

这里可以得到以下结论:

{ P E ( p o s + ϕ , 2 i ) = P E ( p o s , 2 i ) × P E ( ϕ , 2 i + 1 ) + P E ( p o s , 2 i + 1 ) × P E ( ϕ , 2 i ) P E ( p o s + ϕ , 2 i + 1 ) = P E ( p o s , 2 i + 1 ) × P E ( ϕ , 2 i + 1 ) − P E ( p o s , 2 i ) × P E ( ϕ , 2 i ) \left.\left\{

PE(pos+ϕ,2i)=PE(pos,2i)×PE(ϕ,2i+1)+PE(pos,2i+1)×PE(ϕ,2i)PE(pos+ϕ,2i+1)=PE(pos,2i+1)×PE(ϕ,2i+1)PE(pos,2i)×PE(ϕ,2i)
\right.\right. {PE(pos+ϕ,2i)=PE(pos,2i)×PE(ϕ,2i+1)+PE(pos,2i+1)×PE(ϕ,2i)PE(pos+ϕ,2i+1)=PE(pos,2i+1)×PE(ϕ,2i+1)PE(pos,2i)×PE(ϕ,2i)

我们先假设一个文本序列“I am a robor”,经过token划分和embeding操作后,开始进行位置编码。
在这里插入图片描述
设当前位置Pos = 2,那么对于 ϕ \phi ϕ=1,,由公式 P E ( p o s + ϕ , 2 i ) = P E ( p o s , 2 i ) × P E ( ϕ , 2 i + 1 ) + P E ( p o s , 2 i + 1 ) × P E ( ϕ , 2 i ) PE(pos+\phi,2i)=PE(pos,2i)\times PE(\phi,2i+1)+PE(pos,2i+1)\times PE(\phi,2i) PE(pos+ϕ,2i)=PE(pos,2i)×PE(ϕ,2i+1)+PE(pos,2i+1)×PE(ϕ,2i)

可以得到 P 30 = P 20 ∗ P 11 + P 21 ∗ P 10 P_{30} = P_{20}*P_{11} + P_{21}*P_{10} P30=P20P11+P21P10。也就是上图所示的0.1386 = 0.91×0.54-0.84×0.42。这样的隐藏的语义信息能被学习能力强大的模型提取,即使没有直接学到各个句子的关联信息,同时由于每层都有残差连接,将这样的位置信息保留下来让高层提取特征能力更强的深层次网络进行学习。

三、位置编码为什么使用三角函数

转自Transformer Architecture: The Positional Encoding

Why are both sine and cosine used?

1. I think a more intuitive explanation of positional embedding is to think about it as a clock (as cos and sin are just concept from unit circle). Every two dimension of the positional embedding just specifies one of the clock’s hand (the .0hour hand, the minute hand, the second hand, for example). Then moving from one position to the next position is just rotating those hands at different frequencies. Thus, without formal proof, it immediately tells you why a rotation matrix exist.
我认为位置嵌入更直观的解释是把它想象成一个时钟(因为cos和sin只是单位圆的概念)。位置嵌入的每两个维度只指定时钟的一个指针(例如,时针、分针、秒针)。然后从一个位置移动到下一个位置只是以不同的频率旋转这些手。因此,在没有正式证明的情况下,它立即告诉你为什么旋转矩阵存在。

2. Personally, I think, only by using both sine and cosine, we can express the sine(x+k) and cosine(x+k) as a linear transformation of sin(x) and cos(x). It seems that you can’t do the same thing with the single sine or cosine. If you can find a linear transformation for a single sine/cosine, please let me know in the comments section.
只有同时使用正弦和余弦,我们才能将sin(x +k)和cos(x +k)表示为sin(x)和cos(x)的线性变换。似乎你不能对单个正弦或余弦函数做同样的事情。

四、参考文献及链接

A Gentle Introduction to Positional Encoding in Transformer Models, Part 1

Transformer Architecture: The Positional Encoding

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/371470
推荐阅读
相关标签
  

闽ICP备14008679号