参考:
- https://arxiv.org/abs/1706.03762
- https://www.zhihu.com/question/347678607
- https://kazemnejad.com/blog/transformer_architecture_positional_encoding/#what-is-positional-encoding-and-why-do-we-need-it-in-the-first-place
- https://blog.csdn.net/Datawhale/article/details/119582757?utm_medium=distribute.pc_aggpa
证明部分:
- https://kazemnejad.com/blog/transformer_architecture_positional_encoding/#what-is-positional-encoding-and-why-do-we-need-it-in-the-first-place
- https://timodenk.com/blog/linear-relationships-in-the-transformers-positional-encoding/
一、为什么要有Positional Encoding?
像论文中介绍的,由于Transformer中没有循环以及卷积结构,为了使模型能够利用序列的顺序,作者们需要插入一些关于tokens在序列中相对或绝对位置的信息。因此,作者们提出了“Positional Encoding位置编码”的概念。 Positional Encoding和token embedding具有同样的维度,Positional Encoding和token embedding可以直接相加,结果作为Encoder和Decoder的底部输入。
二、怎么定义Positional Encoding?
现在知道我们需要Positional Encoding,那怎么定义它呢?
我们可以从头构思一下,直接编号行不?
直接编号
假设给定一个长度为
T
T
T 的序列,token在序列中的位置记作
p
o
s
pos
pos,那么token的位置编码
P
E
=
p
o
s
=
0
,
1
,
2
,
.
.
.
,
T
?
1
PE=pos=0,1,2,...,T-1
PE=pos=0,1,2,...,T?1 但是这就有个问题,如果有一段很长的序列(假如为1000),那么最后一个token的位置编码非常大,这是很不合适的:
- 它比第一个token的编码大太多,和token embedding合并以后难免会出现特征在数值上的倾斜;
- 它比一般的token embedding的数值要大,模型可能会把它当作主要信息,对模型可能有一定的干扰。
那么,位置编码最好具有一定的值域范围!
对每个位置
p
o
s
pos
pos作归一化
我们可以使用序列长度
T
T
T 对每个位置
p
o
s
pos
pos 作归一化,也就是
P
E
=
p
o
s
T
?
1
P E=\frac{pos}{T-1}
PE=T?1pos?
上面两种方法都是建立一个长度为
T
T
T 的词表,按词表的长度来分配position encoding,这两个方法都属于表格型。
这样固然使得所有位置编码都落入区间
[
0
,
1
]
[0,1]
[0,1],但是问题也是显著的: 不同长度序列的位置编码的步长是不同的,在较短序列中相邻的两个token的位置编码的差异,会比长序列中相邻的两个token的位置编码差异更小。如果使用这种方法,那么在长文本中相对次序关系会被“稀释”。
我们关注的位置信息,最核心的就是相对次序关系,尤其是上下文中的次序关系。也就是关注一个token与另一个token距离的相对位置(距离差几个token)。应该让位置1和位置2的距离比位置3和位置10的距离更近,位置1和位置2与位置3和位置4都只相差1。
总结一下,position encoding的定义要满足下列需求:
- 每个位置有一个唯一的positional encoding;
- 最好具有一定的值域范围,否则它比一般的字嵌入的数值要大,难免会抢了字嵌入的「风头」,对模型可能有一定的干扰;
- 需要体现一定的相对次序关系,并且在一定范围内的编码差异不应该依赖于文本长度,具有一定translation invariant平移不变性。
函数型
一种思路是使用有界的周期性函数。在前面的两种方法中,我们为了体现某个字在句子中的绝对位置,使用了一个单调的函数,使得任意后续的字符的位置编码都大于前面的字,如果我们放弃对绝对位置的追求,转而要求位置编码仅仅关注一定范围内的相对次序关系,那么使用一个sin/cos函数就是很好的选择,因为sin/cos函数的周期变化规律非常稳定,所以编码具有一定的平移不变性。如下:
P
E
(
p
o
s
)
=
sin
?
(
ω
?
p
o
s
)
P E(p o s)=\sin \left({\omega \cdot p o s}\right)
PE(pos)=sin(ω?pos)
其中,
ω
{\omega }
ω 越小,波长越长,即相邻的token的位置编码之间的差异越小。
但这样也存在一些问题:
- 如果
ω
{\omega }
ω 比较大,相邻token之间的位置差异不明显;
- 如果
ω
{\omega }
ω 比较小,在长序列中可能会有一些不同位置的token的位置编码一样,这是因为PE的值域
[
?
1
,
1
]
[-1,1]
[?1,1] 的表现范围有限。
既然token embedding的维度是
d
model?
d_{\text {model }}
dmodel??(论文中
d
model?
=
512
d_{\text {model }}=512
dmodel??=512),那么也可以使用一个
d
model?
d_{\text {model }}
dmodel??维向量来表示位置编码,这样的话,表示范围要远大于
[
?
1
,
1
]
[-1,1]
[?1,1] ,也方便后面和token embedding直接相加。
三、论文中的公式
论文中给出:positional encoding是一个向量,且
P
E
→
p
o
s
∈
R
d
model?
\overrightarrow{PE}_{pos} \in \mathbb{R}^{d_{\text {model }}}
PE
pos?∈Rdmodel??,
f
:
N
→
R
d
model?
f: \mathbb{N} \rightarrow \mathbb{R}^{d_{\text {model }}}
f:N→Rdmodel??,
P
E
→
p
o
s
\overrightarrow{PE}_{pos}
PE
pos? 定义为
P
E
(
p
o
s
,
2
i
)
=
sin
?
(
p
o
s
/
1000
0
2
i
/
d
model?
)
P
E
(
p
o
s
,
2
i
+
1
)
=
cos
?
(
p
o
s
/
1000
0
2
i
/
d
model?
)
\begin{aligned} P E_{(p o s, 2 i)} &=\sin \left(p o s / 10000^{2 i / d_{\text {model }}}\right) \\ P E_{(p o s, 2 i+1)} &=\cos \left(p o s / 10000^{2 i / d_{\text {model }}}\right) \end{aligned}
PE(pos,2i)?PE(pos,2i+1)??=sin(pos/100002i/dmodel??)=cos(pos/100002i/dmodel??)?
也可以写作:
P
E
→
p
o
s
(
i
)
=
f
(
p
o
s
)
(
i
)
:
=
{
sin
?
(
ω
k
?
p
o
s
)
,
?if?
i
=
2
k
cos
?
(
ω
k
?
p
o
s
)
,
?if?
i
=
2
k
+
1
\overrightarrow{PE}_{pos}^{(i)}=f(pos)^{(i)}:=\left\{\begin{array}{ll} \sin \left(\omega_{k} \cdot pos\right), & \text { if } i=2 k \\ \cos \left(\omega_{k} \cdot pos\right), & \text { if } i=2 k+1 \end{array}\right.
PE
pos(i)?=f(pos)(i):={sin(ωk??pos),cos(ωk??pos),??if?i=2k?if?i=2k+1?
其中,
ω
k
=
1
1000
0
2
k
/
d
model?
\omega_{k}=\frac{1}{10000^{2 k / d_{\text {model }}}}
ωk?=100002k/dmodel??1?
i
i
i 表示
P
E
→
p
o
s
\overrightarrow{PE}_{pos}
PE
pos? 的维度,
i
i
i 的取值范围是
[
0
,
…
,
d
model?
/
2
)
\left[0, \ldots, d_{\text {model }} / 2\right)
[0,…,dmodel??/2)。
具体描述
我们可以想象出这是一个由每一个频率产生的
sin
?
/
cos
?
{\sin}/{\cos}
sin/cos对组成的向量(注意这里
d
model?
d_{\text {model }}
dmodel?? 要除以
2
2
2 ):
P
E
→
p
o
s
=
[
sin
?
(
ω
0
?
p
o
s
)
cos
?
(
ω
0
?
p
o
s
)
sin
?
(
ω
1
?
p
o
s
)
cos
?
(
ω
1
?
p
o
s
)
?
sin
?
(
ω
d
model?
/
2
?
1
?
p
o
s
)
cos
?
(
ω
d
model?
/
2
?
1
?
p
o
s
)
]
d
model?
×
1
\overrightarrow{PE}_{pos}=\left[\begin{array}{c} \sin \left(\omega_{0} \cdot pos\right) \\ \cos \left(\omega_{0} \cdot pos\right) \\ \sin \left(\omega_{1} \cdot pos\right) \\ \cos \left(\omega_{1} \cdot pos\right) \\ \vdots \\ \sin \left(\omega_{d_{\text {model }} / 2-1} \cdot pos\right) \\ \cos \left(\omega_{d_{\text {model }} / 2-1} \cdot pos\right) \end{array}\right]_{d_{\text {model }} \times 1}
PE
pos?=????????????sin(ω0??pos)cos(ω0??pos)sin(ω1??pos)cos(ω1??pos)?sin(ωdmodel??/2?1??pos)cos(ωdmodel??/2?1??pos)?????????????dmodel??×1? 论文说,频率沿着向量维度递减,波长
1000
0
2
k
/
d
model?
10000^{2 k / d_{\text {model }}}
100002k/dmodel?? 呈几何级数增长,从从
2
π
2 \pi
2π 增长到
10000
?
2
π
10000 \cdot 2 \pi
10000?2π(不过我算着是到约
9646.61612
?
2
π
9646.61612\cdot 2 \pi
9646.61612?2π) 。
P
E
→
p
o
s
=
[
sin
?
(
p
o
s
/
1000
0
2
×
0
512
)
cos
?
(
p
o
s
/
1000
0
2
×
0
512
)
?
sin
?
(
p
o
s
/
1000
0
2
×
255
512
)
cos
?
(
p
o
s
/
1000
0
2
×
255
512
)
]
d
model?
×
1
≈
[
sin
?
(
p
o
s
)
cos
?
(
p
o
s
)
?
sin
?
(
9646.61612
?
p
o
s
)
cos
?
(
9646.61612
?
p
o
s
)
]
d
model?
×
1
\overrightarrow{PE}_{pos}=\left[\begin{array}{c} \sin \left(pos / 10000^{2 \times \frac{0}{512}}\right) \\ \cos \left(pos / 10000^{2 \times \frac{0}{512}}\right) \\ \vdots \\ \sin \left(pos / 10000^{2 \times \frac{255}{512}}\right)\\ \cos \left(pos / 10000^{2 \times \frac{255}{512}}\right) \end{array}\right]_{d_{\text {model }} \times 1} \approx \left[\begin{array}{c} \sin \left(pos\right) \\ \cos \left(pos\right) \\ \vdots \\ \sin \left(9646.61612 \cdot pos \right)\\ \cos \left(9646.61612 \cdot pos\right) \end{array}\right]_{d_{\text {model }} \times 1}
PE
pos?=????????????sin(pos/100002×5120?)cos(pos/100002×5120?)?sin(pos/100002×512255?)cos(pos/100002×512255?)?????????????dmodel??×1?≈????????sin(pos)cos(pos)?sin(9646.61612?pos)cos(9646.61612?pos)?????????dmodel??×1?
不过这样定义positional encoding,仍会陷入循环, 这里人为地将最大不重复序列长度限制为 512。例如,在 BERT 中就是这样做的(尽管值得一提的是他们使用了学习位置嵌入,但那是另一回事了)。 如果不这样做,模型确实无法区分序列中的第一个token和第513个token的位置编码。
四、为什么公式可以体现出相对次序关系?
1.相对次序关系怎么表示?
论文原文:
We chose this function because we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset k, PEpos+k can be represented as a linear function of PEpos.
如果说Positional Encoding向量可以表示相对次序关系,那么
P
E
→
p
o
s
\overrightarrow{PE}_{pos}
PE
pos? 应该满足
P
E
→
p
o
s
+
k
\overrightarrow{PE}_{pos+k}
PE
pos+k? 是
P
E
→
p
o
s
\overrightarrow{PE}_{pos}
PE
pos? 的线性变换,即:
对于任意固定的偏移量
k
k
k,存在线性变换
T
(
k
)
∈
R
d
model?
×
d
model?
\boldsymbol{T}^{(k)} \in \mathbb{R}^{d_{\text {model }} \times d_{\text {model }}}
T(k)∈Rdmodel??×dmodel??,使得
T
(
k
)
?
P
E
→
p
o
s
=
P
E
→
p
o
s
+
k
\boldsymbol{T}^{(k)} \cdot\overrightarrow{PE}_{pos} = \overrightarrow{PE}_{pos+k}
T(k)?PE
pos?=PE
pos+k? 这一等式对于序列中任何有效位置
t
∈
{
0
,
1
,
…
,
n
?
k
?
1
}
t\in\left\{0,1,\dots,n-k-1\right\}
t∈{0,1,…,n?k?1} 的任何位置偏移
k
∈
{
1
,
…
,
n
}
k\in\left\{1,\dots,n\right\}
k∈{1,…,n} 成立。
为什么满足这个公式,Positional Encoding向量就可以表示相对次序?
这里就谈到了对线性变换的理解,矩阵对向量的线性变换,其实是施加在其基底上的变换,而新的向量是关于新的基底的线性组合,与原来的向量关于原来的基底的线性组合,是一样的。是不是就可以对应上:新的向量
P
E
→
p
o
s
+
k
\overrightarrow{PE}_{pos+k}
PE
pos+k? 是关于新的基底的线性组合,与原来的向量
P
E
→
p
o
s
\overrightarrow{PE}_{pos}
PE
pos? 关于原来的基底的线性组合,是一样的。也就是说,他们之间的线性变换不受这个位置为
p
o
s
pos
pos 的token在序列中的绝对位置的影响,这个线性变换矩阵
T
(
k
)
\boldsymbol{T}^{(k)}
T(k) 可以表示出了不同距离的token的相对关系。
更多关于线性变换的直观理解:https://blog.csdn.net/xiaoyink/article/details/90705106
2.那论文公式满足这个相对次序关系的表示吗?
要使
T
(
k
)
?
P
E
→
p
o
s
=
P
E
→
p
o
s
+
k
\boldsymbol{T}^{(k)} \cdot\overrightarrow{PE}_{pos} = \overrightarrow{PE}_{pos+k}
T(k)?PE
pos?=PE
pos+k?,需要使
T
(
k
)
\boldsymbol{T}^{(k)}
T(k)不依赖于
p
o
s
pos
pos。
证明:
设
T
(
k
)
\boldsymbol{T}^{(k)}
T(k) 是一个
2
×
2
2 \times 2
2×2矩阵,
T
(
k
)
=
[
u
1
v
1
u
2
v
2
]
\boldsymbol{T}^{(k)} = \begin{bmatrix} u_1 & v_1 \\ u_2 & v_2 \end{bmatrix}
T(k)=[u1?u2??v1?v2??],
则
T
(
k
)
?
P
E
→
p
o
s
=
P
E
→
p
o
s
+
k
\boldsymbol{T}^{(k)} \cdot\overrightarrow{PE}_{pos} = \overrightarrow{PE}_{pos+k}
T(k)?PE
pos?=PE
pos+k?可写作:
[
u
1
v
1
u
2
v
2
]
.
[
sin
?
(
ω
k
?
p
o
s
)
cos
?
(
ω
k
?
p
o
s
)
]
=
[
sin
?
(
ω
k
?
(
p
o
s
+
?
)
)
cos
?
(
ω
k
?
(
p
o
s
+
?
)
)
]
% <![CDATA[ \begin{bmatrix} u_1 & v_1 \\ u_2 & v_2 \end{bmatrix} .\begin{bmatrix} \sin(\omega_k \cdot pos) \\ \cos(\omega_k \cdot pos) \end{bmatrix} = \begin{bmatrix} \sin(\omega_k \cdot (pos + \phi)) \\ \cos(\omega_k \cdot (pos + \phi)) \end{bmatrix} %]]>
[u1?u2??v1?v2??].[sin(ωk??pos)cos(ωk??pos)?]=[sin(ωk??(pos+?))cos(ωk??(pos+?))?] 等式右边使用三角函数正余弦公式,可化为:
[
u
1
v
1
u
2
v
2
]
.
[
sin
?
(
ω
k
?
p
o
s
)
cos
?
(
ω
k
?
p
o
s
)
]
=
[
sin
?
(
ω
k
?
p
o
s
)
cos
?
(
ω
k
?
?
)
+
cos
?
(
ω
k
?
p
o
s
)
sin
?
(
ω
k
?
?
)
cos
?
(
ω
k
?
p
o
s
)
cos
?
(
ω
k
?
?
)
?
sin
?
(
ω
k
?
p
o
s
)
sin
?
(
ω
k
?
?
)
]
% <![CDATA[ \begin{bmatrix} u_1 & v_1 \\ u_2 & v_2 \end{bmatrix} .\begin{bmatrix} \sin(\omega_k \cdot pos) \\ \cos(\omega_k \cdot pos) \end{bmatrix} = \begin{bmatrix} \sin(\omega_k \cdot pos)\cos(\omega_k \cdot\phi) + \cos(\omega_k \cdot pos)\sin(\omega_k \cdot\phi) \\ \cos(\omega_k \cdot pos)\cos(\omega_k \cdot\phi) - \sin(\omega_k \cdot pos)\sin(\omega_k \cdot \phi) \end{bmatrix} %]]>
[u1?u2??v1?v2??].[sin(ωk??pos)cos(ωk??pos)?]=[sin(ωk??pos)cos(ωk???)+cos(ωk??pos)sin(ωk???)cos(ωk??pos)cos(ωk???)?sin(ωk??pos)sin(ωk???)?]
可以得到以下两个等式:
u
1
sin
?
(
ω
k
?
p
o
s
)
+
v
1
cos
?
(
ω
k
?
p
o
s
)
=
????
cos
?
(
ω
k
?
?
)
sin
?
(
ω
k
?
p
o
s
)
+
sin
?
(
ω
k
?
?
)
cos
?
(
ω
k
?
p
o
s
)
u
2
sin
?
(
ω
k
?
p
o
s
)
+
v
2
cos
?
(
ω
k
?
p
o
s
)
=
?
sin
?
(
ω
k
?
?
)
sin
?
(
ω
k
?
p
o
s
)
+
cos
?
(
ω
k
?
?
)
cos
?
(
ω
k
?
p
o
s
)
u_1 \sin(\omega_k \cdot pos) + v_1 \cos(\omega_k \cdot pos) = \ \ \ \ \cos(\omega_k \cdot\phi)\sin(\omega_k \cdot pos) + \sin(\omega_k \cdot\phi)\cos(\omega_k \cdot pos) \\ u_2 \sin(\omega_k \cdot pos) + v_2 \cos(\omega_k \cdot pos) = - \sin(\omega_k \cdot\phi)\sin(\omega_k \cdot pos) + \cos(\omega_k \cdot\phi)\cos(\omega_k \cdot pos)
u1?sin(ωk??pos)+v1?cos(ωk??pos)=????cos(ωk???)sin(ωk??pos)+sin(ωk???)cos(ωk??pos)u2?sin(ωk??pos)+v2?cos(ωk??pos)=?sin(ωk???)sin(ωk??pos)+cos(ωk???)cos(ωk??pos)
求解上述方程,得到:
T
?
,
k
=
[
????
cos
?
(
ω
k
.
?
)
sin
?
(
ω
k
.
?
)
?
sin
?
(
ω
k
.
?
)
cos
?
(
ω
k
.
?
)
]
T_{\phi,k} = \begin{bmatrix} \ \ \ \ \cos(\omega_k .\phi) & \sin(\omega_k .\phi) \\ - \sin(\omega_k . \phi) & \cos(\omega_k .\phi) \end{bmatrix}
T?,k?=[????cos(ωk?.?)?sin(ωk?.?)?sin(ωk?.?)cos(ωk?.?)?] 即
T
(
k
)
\boldsymbol{T}^{(k)}
T(k) 不依赖于
p
o
s
pos
pos。 而且可以发现,
T
(
k
)
\boldsymbol{T}^{(k)}
T(k) 跟旋转矩阵很相似。
|