深入理解Transformer中的位置编码

发布于:2024-11-04 ⋅ 阅读:(73) ⋅ 点赞:(0)

1 位置编码的作用

由于注意力的作用机制,不论输入序列的顺序如何,输出结果都是一样的。 也就是丢失了位置信息。 但是对于语言模型, 我们都知道顺序是很重要的, 所以需要对输入序列额外注入位置信息。

2 位置编码方式

Transformer 论文中采用了简单的相对位置编码, 用sin 和cos函数表示序列中不同位置的信息。

在这里插入图片描述

3 可视化展示

为了图像清晰起见, 嵌入维度选128(实际网络中是512)。
横轴表示嵌入维度, 纵轴是token在序列中的位置, 如输入是一个长度是32的序列。
在这里插入图片描述

从图上可以看出, 序列位置与位置编码有个近似的线性关系, 同时还有一定的周期特性,因此位置编码一定程度上反应了序列中的位置信息。

4 代码

import matplotlib.pyplot as plt
import numpy as np

d_model = 128
seq_len = 32

# 创建数据
x = np.linspace(0, d_model - 1, d_model)
y = np.linspace(0, seq_len - 1, seq_len)
X, Y = np.meshgrid(x, y)
Z_even = np.sin(Y / (np.power(10000, X / d_model)))
Z_odd = np.cos(Y / (np.power(10000, X / d_model)))

for i in range(d_model // 2):
    Z_odd[:, 2 * i] = Z_even[:, 2 * i]

# 绘制图像
plt.imshow(Z_odd, cmap='gray', aspect='auto', extent=[0, d_model, 0, seq_len], origin='upper')
plt.xlabel('embeddig_dimension')
plt.ylabel('seq_dimension')
plt.show()

5 位置编码其他实现方式

上述是Transformer原始论文Attention is All You Need中的实现方式,还有一些比较著名的实现Transformer的库, 如tensor2tensor, fairseq, 实现方式与原始论文有一些区别,位置信息有较大差异,但含义基本是一致的, 要注意区分。

tensor2tensor 的实现方式: https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/layers/common_attention.py

具体见get_timing_signal_1d 函数。

fairseq 中也沿用了tensor2tensor中的做法。 https://github.com/facebookresearch/fairseq/blob/main/fairseq/modules/sinusoidal_positional_embedding.py
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到