正弦位置编码 – 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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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