【位置编码】【Positional Encoding】直观理解位置编码!把位置编码想象成秒针!
你们有没有好奇过为啥位置编码非得长成这样:
P
E
(
p
o
s
,
2
i
)
=
s
i
n
(
p
o
s
1000
0
2
i
/
d
m
o
d
e
l
)
P
E
(
p
o
s
,
2
i
+
1
)
=
c
o
s
(
p
o
s
1000
0
2
i
/
d
m
o
d
e
l
)
PE(pos,2i)=sin(\frac{pos}{10000^{2i/d_{model}}})\\ PE(pos,2i+1)=cos(\frac{pos}{10000^{2i/d_{model}}})
PE(pos,2i)=sin(100002i/dmodelpos)PE(pos,2i+1)=cos(100002i/dmodelpos)
- 为什么位置编码一定要分为奇数和偶数分别考虑?
- 为什么又要有sin又要有cos?
这里提供一个直观的理解方案,位置编码想象成秒针可以帮助你轻松理解为什么要如此编码。
【转载注明出处】
为了解释位置编码,我们先考虑下面的场景:
不一样的秒表
假设我们手上有三个不一样的“秒表”,这些秒表长这样:
这三个秒表都只有一个指针,不同的是第一个秒表的指针10s转一圈,第二个秒表的指针100s转一圈,第三个秒表1000s转一圈。
现在,考虑一个问题:
Q: 如果我在
0
0
0秒时同时按下这3个秒表,问在
t
t
t秒时这三个表的指针转过的角度
ϕ
1
,
ϕ
2
,
ϕ
3
\phi_1,\phi_2,\phi_3
ϕ1,ϕ2,ϕ3分别是多少?
这个答案很简单!
A: 我们可以知道,第一个表每秒钟转
2
π
/
10
2\pi/10
2π/10,第二个表每秒钟转
2
π
/
100
2\pi/100
2π/100,第三个表每秒钟转
2
π
/
1000
2\pi/1000
2π/1000,因此:
ϕ
1
=
t
×
2
π
/
10
,
ϕ
2
=
t
×
2
π
/
100
,
ϕ
3
=
t
×
2
π
/
1000
\phi_1=t\times2\pi/10,\phi_2=t\times2\pi/100,\phi_3=t\times2\pi/1000
ϕ1=t×2π/10,ϕ2=t×2π/100,ϕ3=t×2π/1000
从时间到角度
现在,其实我们可以把每个时间
t
t
t对应成一个坐标:
t
→
(
ϕ
1
,
ϕ
2
,
ϕ
3
)
t\rightarrow(\phi_1,\phi_2,\phi_3)
t→(ϕ1,ϕ2,ϕ3)同样的这样的一个坐标也能唯一的对应一个时间!(如果第三个秒表没有转完完整一圈的话)
从角度到坐标
进一步,我们还可以用三角函数来表达一个角度
ϕ
\phi
ϕ,比如在0到2
π
\pi
π的范围内
(
s
i
n
(
ϕ
)
,
c
o
s
(
ϕ
)
)
(sin(\phi),cos(\phi))
(sin(ϕ),cos(ϕ))这个坐标可以唯一确定
ϕ
\phi
ϕ。这个坐标也就是指针的端点的平面坐标(指针长度为1的话):
到目前为止我们就得到了这样的一个变化过程:
t
→
(
ϕ
1
,
ϕ
2
,
ϕ
3
)
→
(
s
i
n
(
ϕ
1
)
,
c
o
s
(
ϕ
1
)
,
s
i
n
(
ϕ
2
)
,
c
o
s
(
ϕ
2
)
,
s
i
n
(
ϕ
3
)
,
c
o
s
(
ϕ
3
)
)
t\rightarrow(\phi_1,\phi_2,\phi_3)\\\rightarrow(sin(\phi_1),cos(\phi_1),sin(\phi_2),cos(\phi_2),sin(\phi_3),cos(\phi_3))
t→(ϕ1,ϕ2,ϕ3)→(sin(ϕ1),cos(ϕ1),sin(ϕ2),cos(ϕ2),sin(ϕ3),cos(ϕ3))
因此我们就可以反过来,用这些角度表达时间
t
t
t:
(
s
i
n
(
ϕ
1
)
,
c
o
s
(
ϕ
1
)
,
s
i
n
(
ϕ
2
)
,
c
o
s
(
ϕ
2
)
,
s
i
n
(
ϕ
3
)
,
c
o
s
(
ϕ
3
)
)
→
t
(sin(\phi_1),cos(\phi_1),sin(\phi_2),cos(\phi_2),sin(\phi_3),cos(\phi_3))\rightarrow t
(sin(ϕ1),cos(ϕ1),sin(ϕ2),cos(ϕ2),sin(ϕ3),cos(ϕ3))→t其中
ϕ
1
=
t
×
2
π
/
10
,
ϕ
2
=
t
×
2
π
/
100
,
ϕ
3
=
t
×
2
π
/
1000
\phi_1=t\times2\pi/10,\phi_2=t\times2\pi/100,\phi_3=t\times2\pi/1000
ϕ1=t×2π/10,ϕ2=t×2π/100,ϕ3=t×2π/1000
位置编码
在上述的例子中,令时间
t
←
p
o
s
t\leftarrow pos
t←pos。且我们有
d
m
o
d
e
l
/
2
d_{model}/2
dmodel/2个秒表,第
i
i
i个秒表转一圈的需要的时间是
2
π
×
1000
0
2
i
/
d
m
o
d
e
l
2\pi\times 10000^{2i/d_{model}}
2π×100002i/dmodel,那么经过时间
p
o
s
pos
pos之后第
i
i
i个秒表的角度
ϕ
i
=
p
o
s
×
2
π
2
π
×
1000
0
2
i
/
d
m
o
d
e
l
=
p
o
s
1000
0
2
i
/
d
m
o
d
e
l
\phi_i=pos\times \frac{2\pi}{2\pi\times10000^{2i/d_{model}}}=\frac{pos}{10000^{2i/d_{model}}}
ϕi=pos×2π×100002i/dmodel2π=100002i/dmodelpos
那么我们同样可以用这
d
m
o
d
e
l
/
2
d_{model}/2
dmodel/2个秒表的端点坐标表达
p
o
s
pos
pos
(
s
i
n
(
ϕ
1
)
,
c
o
s
(
ϕ
1
)
,
⋯
)
→
p
o
s
(sin(\phi_1),cos(\phi_1),\cdots)\rightarrow pos
(sin(ϕ1),cos(ϕ1),⋯)→pos
可以直接注意到,上式就是我们提到的位置编码!
P
E
(
p
o
s
,
2
i
)
=
s
i
n
(
p
o
s
1000
0
2
i
/
d
m
o
d
e
l
)
P
E
(
p
o
s
,
2
i
+
1
)
=
c
o
s
(
p
o
s
1000
0
2
i
/
d
m
o
d
e
l
)
PE(pos,2i)=sin(\frac{pos}{10000^{2i/d_{model}}})\\ PE(pos,2i+1)=cos(\frac{pos}{10000^{2i/d_{model}}})
PE(pos,2i)=sin(100002i/dmodelpos)PE(pos,2i+1)=cos(100002i/dmodelpos) 一摸一样!