【NLP练习】Transformer中的位置编码
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
一、什么是位置编码
1. 位置编码定义
Transformer 模型中的位置编码是为了在处理序列数据时引入位置信息,以便模型能够分辨输入序列中不同位置的词或标记。
其中,每个位置/索引都映射到一个向量。因此,位置编码层的输出是一个矩阵,其中矩阵的每一行代表序列中的一个编码对象与其位置信息相加。下图为仅对位置信息进行编码的矩阵示例。
2. 三角函数
位置编码由不同频率的正弦和余弦函数给出,下图为正弦函数的快速回顾,不同波形的波长和频率如下所示:
3. 位置编码公式
假设有一个长度为L的输入序列,要计算第K个元素的位置编码。位置编码有不同频率的正弦和余弦函数给出:
P
(
k
,
2
i
)
=
s
i
n
(
k
n
2
i
/
d
)
.
P(k,2i) = sin(\frac k {n^{2i/d}}).
P(k,2i)=sin(n2i/dk).
P
(
k
,
2
i
+
1
)
=
c
o
s
(
k
n
2
i
/
d
)
.
P(k,2i + 1) = cos(\frac k {n^{2i/d}}).
P(k,2i+1)=cos(n2i/dk).
参数详解:
- k k k:对象 (即句子中的字符)在输入序列中的位置, 0 < = k < L 2 0 <= k < \frac L 2 0<=k<2L
- d d d:输出嵌入空间的维度
- P ( k , j ) P(k,j) P(k,j):位置函数,用于映射输入序列中 k k k处的元素到位置矩阵的 ( k , j ) (k,j) (k,j)处
- n n n:用户定义的标量(Transformer论文作者的值为10000)
-
i
i
i:用于映射到列索引,
0
<
=
i
<
d
2
0<=i<\frac d 2
0<=i<2d,单个值
i
i
i映射到正弦和余弦函数
4. 位置编码示例
为理解上述表达式,以短语"I am a robot"为例,其中
n
=
100
n=100
n=100,
d
=
4
d=4
d=4。下表显示了该短语的位置编码矩阵。对于任何
n
=
100
n=100
n=100,
d
=
4
d=4
d=4的四字母短语,位置编码矩阵都是相同的。
二、可视化理解位置编码
1. Python实现位置编码
import numpy as np
import matplotlib.pyplot as plt
def getPositionEncoding(seq_len, d, n=10000):
P = np.zeros((seq_len, d))
for k in range(seq_len):
for i in np.arange(int(d/2)):
denominator = np.power(n, 2*i/d)
P[k,2*i] = np.sin(k/denominator)
P[k,2*i+1] = np.cos(k/denominator)
return P
P = getPositionEncoding(seq_len = 4, d = 4, n = 100)
print(P)
输出如下:
[[ 0. 1. 0. 1. ]
[ 0.84147098 0.54030231 0.09983342 0.99500417]
[ 0.90929743 -0.41614684 0.19866933 0.98006658]
[ 0.14112001 -0.9899925 0.29552021 0.95533649]]
2. 单个字符可视化
查看 n = 10000 n=10000 n=10000和 d = 512 d=512 d=512的不同位置的正弦波开始
def plotSinusoid(k, d = 512, n = 10000):
x = np.arange(0, 100, 1)
denominator = np.power(n, 2*x/d)
y = np.sin(k/denominator)
plt.plot(x, y)
plt.title('k = ' + str(k))
fig = plt.figure(figsize=(15,4))
for i in range(4):
plt.subplot(141 + i)
plotSinusoid(i * 4)
输出:
上图可看出每个位置对应不同的正弦曲线,将单个位置编码为向量。
3. 整句话的位置编码可视化
可视化 n = 10000 n=10000 n=10000的位置矩阵
P = getPositionEncoding(seq_len = 100, d=512, n = 10000)
cax = plt.matshow(P)
plt.gcf().colorbar(cax)
输出:
三、位置编码的最终输出
Transformer中的位置编码层把位置向量与单词编码相加,并为后续层输出该矩阵。整个过程如下图所示:
四、总结
Transformer的位置编码一方面通过正弦和余弦函数来编码位置信息,这种编码方式能够使得不同位置的编码在空间上有良好的分布。
另一方面分别使用正弦和余弦函数来编码偶数和奇数位置,以确保位置编码能够捕捉到位置之间的关系。