正弦位置编码 – Attention is all you need

Attention Is All You Need中,作者们实现了一种位置编码(它增加了关于单词在序列中位置的信息)。为此,他们使用了正弦位置编码:

PE(pos,2i) = sin(pos/10000**(2*i/hidden_units))PE(pos,2i+1) = cos(pos/10000**(2*i/hidden_units))

其中pos是位置,i是维度。这必须生成一个形状为[max_length, embedding_size]的嵌入矩阵,即,给定序列中的一个位置,它返回PE[position,:]的张量。

我找到了Kyubyong的实现,但我不是完全理解它。

我尝试用numpy这样实现它:

hidden_units = 100 # 嵌入的维度vocab_size = 10 # 最大句子长度# 矩阵[[1, ..., 99], [1, ..., 99], ...]i = np.tile(np.expand_dims(range(hidden_units), 0), [vocab_size, 1])# 矩阵[[1, ..., 1], [2, ..., 2], ...]pos = np.tile(np.expand_dims(range(vocab_size), 1), [1, hidden_units])# 应用中间函数pos = np.multiply(pos, 1/10000.0)i = np.multiply(i, 2.0/hidden_units)matrix = np.power(pos, i)# 对偶数列应用正弦函数matrix[:, 1::2] = np.sin(matrix[:, 1::2]) # 偶数# 对奇数列应用余弦函数matrix[:, ::2] = np.cos(matrix[:, ::2]) # 奇数# 绘图im = plt.imshow(matrix, cmap='hot', aspect='auto')

矩阵绘图结果

我不明白这个矩阵如何提供输入位置的信息。有人能首先告诉我这是否是计算它的正确方法,其次是背后的原理是什么吗?

谢谢你。


回答:

我在pytorch实现中找到了答案:

# 保留维度0用于填充标记的位置编码零向量position_enc = np.array([    [pos / np.power(10000, 2*i/d_pos_vec) for i in range(d_pos_vec)]    if pos != 0 else np.zeros(d_pos_vec) for pos in range(n_position)])position_enc[1:, 0::2] = np.sin(position_enc[1:, 0::2]) # 维度2iposition_enc[1:, 1::2] = np.cos(position_enc[1:, 1::2]) # 维度2i+1return torch.from_numpy(position_enc).type(torch.FloatTensor)

其中d_pos_vec是嵌入维度,n_position是最大序列长度。

编辑:

在论文中,作者们说这种嵌入矩阵的表示允许“模型推断到比训练期间遇到的序列长度更长的序列”。

两个位置之间的唯一区别是pos变量。查看下面的图像以获得图形表示。

嵌入

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注