当前位置:   article > 正文

Transformer中的位置编码详解_transformer模型使用了一种独特的三角函数计算方法来进行位置编码

transformer模型使用了一种独特的三角函数计算方法来进行位置编码

什么是位置编码

  1. 位置编码概述 位置编码的目的是为了补充序列的位置信息,这是因为自注意力机制本身不包含位置的概念(例如顺序信息)。位置编码的具体作用是,对于不同的输入序列成分,赋予其不同的位置标识,确保序列信息在不同的上下文中仍然,即使是相同的文本序列也因位置不同而有不同的含义。

Transformers 使用的位置编码方法,其中每个位置/词素都被分配一个编号。到此,位置编码的输出是一个矩阵,其中每行的每一行代表序列中的一个特定词素与其位置信息相结合。下图演示了一个较小的位置编码矩阵示例的构成方式。

位置编码矩阵

位置编码矩阵示例 - 序列 ‘I am a robot’

三角函数 

  1. 三角函数 三角函数是数学中的基本概念,不仅可以表达周期性的现象,还能描述波动的基本特性。这些函数的图像通常在[-1, 1]的区间内。三角函数的一般形式包括正弦和余弦两种,它们的周期性是函数的重要特性。以下表格列出了几种常见的三角函数形式及其特性:

位置编码公式 

位置编码的数学公式用于为每一个位置(即序列中的词素)分配一个独特的编码,以使其能够在不同的上下文中区别对待。位置编码使用下述公式来生成位置编码矩阵:

\begin{aligned}&P(k,2i)=\sin\left(\frac k{n^{2i/d}}\right)\text{(1)}\\&P(k,2i+1)=\cos\left(\frac k{n^{2i/d}}\right)\text{(2)}\end{aligned}

其中:

  • k:词素(即序列中的某个元素)的索引位置的值,0≤k<L/2
  • d:编码矩阵的维度
  • P(k,j):位置编码,用于给定词素 k 的频率编码的 (k, j) 处的值
  • n:用户定义的常数(例如,"Attention Is All You Need" 论文中的常数为 10,000)
  • i:用于确定频率的位置,0≤i<d/2,相当于确定位置编码矩阵中的行

位置编码示例

通过具体例子理解位置编码。以序列 “I am a robot” 为例,设定 n = 100, d = 4。在这个例子中,我们计算了 n = 100 和 d = 4 的序列的位置编码,位置编码的计算结果如下表:

位置编码矩阵示例 - 序列 ‘I am a robot’ 

Python实现位置编码 

使用 NumPy 库进行矩阵和数学运算以及 Matplotlib 库进行图形绘制,下面是 Python 代码示例以及其输出结果。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. def getPositionEncoding(seq_len, d, n=10000):
  4. P = np.zeros((seq_len, d))
  5. for k in range(seq_len):
  6. for i in np.arange(int(d/2)):
  7. denominator = np.power(n, 2*i/d)
  8. P[k, 2*i] = np.sin(k/denominator)
  9. P[k, 2*i+1] = np.cos(k/denominator)
  10. return P
  11. P = getPositionEncoding(seq_len=4, d=4, n=100)
  12. print(P)

单个序列的可视化 

使用 Matplotlib 库绘制不同位置的三角函数图,下面是 Python 代码示例以及其生成的图形。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. def getPositionEncoding(seq_len, d, n=10000):
  4. P = np.zeros((seq_len, d))
  5. for k in range(seq_len):
  6. for i in np.arange(int(d/2)):
  7. denominator = np.power(n, 2*i/d)
  8. P[k, 2*i] = np.sin(k/denominator)
  9. P[k, 2*i+1] = np.cos(k/denominator)
  10. return P
  11. def plotSinusoid(k, d, n):
  12. x = np.arange(0, 100, 1)
  13. denominator = np.power(n, 2*k/d)
  14. y = np.sin(x/denominator)
  15. plt.plot(x, y)
  16. plt.title('k = ' + str(k))
  17. # 使用长序列和较大维度的参数
  18. seq_len = 100
  19. d = 512
  20. n = 10000
  21. P = getPositionEncoding(seq_len, d, n)
  22. # 正弦波绘图
  23. fig = plt.figure(figsize=(15, 4))
  24. for i in range(4):
  25. plt.subplot(1, 4, i + 1)
  26. plotSinusoid(i*4, d, n) # 确保传入函数的参数和生成P矩阵时的参数一致
  27. plt.show()

下图是四个不同 k 值的正弦波形图。可以看到,随着 k 值的增大,波形周期发生了变化。

可视化结果:四个不同 k 值的正弦波形图,分别对应 k=0, k=4, k=8, 和 k=12 的情况。随着 k 值的增大,波形周期发生变化,显示了不同频率和波长的正弦波。

热图可视化编码矩阵 

使用 Python 的 Matplotlib 库的 matshow() 函数,可以将位置编码矩阵以热图的形式可视化。热图可以直观地展示不同位置编码的值的大小。下面是 Python 代码示例以及热图的输出结果。

  1. # 热图绘图
  2. fig2 = plt.figure(figsize=(15, 4))
  3. cax = plt.matshow(P, aspect='auto') # aspect='auto'保证热图在x轴和y轴方向拉伸以填满画布
  4. plt.colorbar(cax)
  5. plt.show()

  

热图结果:展示了一个长为 100,宽为 512 的位置编码矩阵的热图。热图中的颜色变化表示不同位置编码值的大小,可以看到随着位置的变化,颜色也呈现出周期性的变化模式。

位置编码的整体流程 

Transformer模型的位置编码过程包括将词汇转换为向量,然后与位置编码相加,以保持位置信息。以下是该过程的详细描述:
 

  • 输入序列(Input sequence): I, am, a, Robot
  • 词向量嵌入(Word embedding): 将每个输入词转换为一个嵌入向量(embedding vector)。
    • v0​ 是 "I" 的嵌入向量
    • v1​ 是 "am" 的嵌入向量
    • v2​ 是 "a" 的嵌入向量
    • v3​ 是 "Robot" 的嵌入向量
  • 位置编码矩阵(Positional Encoding Matrix): 计算序列中每个词的位置编码向量。
    • P0​ 是 "I" 的位置编码向量
    • P1​ 是 "am" 的位置编码向量
    • P2​ 是 "a" 的位置编码向量
    • P3​ 是 "Robot" 的位置编码向量
  • 位置编码层的输出(Output of positional encoding layer): 词向量和位置编码向量相加,得到最终的编码向量。
    • y0​ 是 "I" 的位置编码
    • y1​ 是 "am" 的位置编码
    • y2​ 是 "a" 的位置编码
    • y3​ 是 "Robot" 的位置编码
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/656661
推荐阅读
相关标签
  

闽ICP备14008679号