# Transformer中的Positional Encoding

## July 7, 2020 • Read: 29616 • Deep Learning • 阅读设置

One possible solution to give the model some sense of order is to add a piece of information to each word about its position in the sentence. We call this “piece of information”, the positional encoding.

### 理想的设计

• 它应该为每个字输出唯一的编码
• 不同长度的句子之间，任何两个字之间的差值应该保持一致
• 它的值应该是有界的

\begin{align} \vec{p_t}^{(i)} = f(t)^{(i)} & := \begin{cases} \sin({\omega_k} . t), & \text{if}\ i = 2k \\ \cos({\omega_k} . t), & \text{if}\ i = 2k + 1 \end{cases} \end{align}

$$\omega_k = \frac{1}{10000^{2k / d}}$$

$k$​指的是位置嵌入中维度的下标，为了使得位置嵌入和字嵌入能够相加，因此位置嵌入维度和字嵌入的维度必须相同，所以$i\in [0, d)$，因此就有$k\in [0, \frac{d-1}{2}]$

$$\vec{p_t} = \begin{bmatrix} \sin({\omega_0}.t)\\ \cos({\omega_0}.t)\\ \\ \sin({\omega_1}.t)\\ \cos({\omega_1}.t)\\ \\ \vdots\\ \\ \sin({\omega_{\frac{d}{2}-1}}.t)\\ \cos({\omega_{\frac{d}{2}-1}}.t) \end{bmatrix}_{d \times 1}$$

### 直观展示

\begin{align} 0: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} & & 8: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} \\ 1: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} & & 9: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} \\ 2: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} & & 2: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} \\ 3: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} & & 11: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} \\ 4: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} & & 12: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} \\ 5: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} & & 13: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} \\ 6: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} & & 14: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} \\ 7: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} & & 15: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} \\ \end{align}

### 参考文献

1. 一只小白

解开了我对position encoding的困惑。有一点小建议：补充一下position encoding如何解决开篇提出的两个问题，逻辑感觉更严密

1. mathor

@一只小白好的，这两天我再改改

2. chrisL

在任意时刻下的位置通过WT乘积送到sin/cos，在不同W下的频率实现不同数字编码，T记录时间步。也有一种解释，不同的频率本事就含有时间信息。博主好像最后没解释清楚最后如何表示这个position的。

3. gq

你好，请问这是怎么做到不同长度的句子之间，任何两个字之间的差值应该保持一致的？

4. 李白二

你好，博主解析的很漂亮！@(大拇指)
按照你说的理想条件： 1.它应该为每个字输出唯一的编码；2.不同长度的句子之间，任何两个字之间的差值应该保持一致； 3.它的值应该是有界的
注释：评论过长，只好分两次写了

5. 李白二

我想这样的函数应该都能满足理想条件：
向量V =（pos/C）*f(t) 其中，pos为字符的位置字符的位置索引，t为 t时刻字的位置编码（同你博客里边的t时刻意思一样）, C是一个比较大的常数；
博主，你怎么看？

1. mathor

@李白二是的，不过后来从bert开始，所有用到positional encoding的部分都不再是这种单纯的公式计算得到的，而是使用模型训练的，即nn.Embedding()

6. ctrlplayer

我有个问题，positional encoding层应该被训练吗?

1. mathor

@ctrlplayer在最原始的transformer的论文以及源码实现中，是不训练的

到了bert及其之后的论文里，是训练的

2. AI_magician

@mathor据说是因为在convolution 中的尝试中有用过但效果不好

3. AI_magician

@mathor据说是因为在convolution 中的尝试中有用过但效果不好

7. hhy

楼主好，我想请教一下，位置编码满足了不同长度的句子之间，任何两个字之间的差值应该保持一致，但是位置编码和嵌入向量相加之后，这些信息会被打乱，那么相加后的输入向量又是怎么体现出位置的前后关系的了

1. mathor

@hhy我的水平有限，无法解答你的问题，苏神最近有一篇关于位置编码的博客，或许可以帮到你
https://spaces.ac.cn/archives/8231

8. lp

真的很强，受益匪浅，非常感谢博主的分享！！

9. 张宇杰

博主您好，我想问一下，我训练好了一个transformer用于做机器翻译，但是用您的greedy_decoder方法取实现的时候我发现得到的decoder是乱的。顺便说一下，我用的是pytorch封装的transformer 就是 nn.TransformerEncoderLayer之类的

10. 亭亭玉立

你好，在k的取值范围应该可以取到（d-1）/2吧，这个上面写的是开区间

1. mathor

@亭亭玉立感谢提醒，已修改

11. Bryce

感谢分享@(真棒)

12. 深度学习 - Transformer详解 - StubbornHuang Blog

[...]如果不理解这里为何这么设计，可以看这篇文章Transformer 中的 Positional Encoding。[...]

13. 梦想就是摸鱼

赞啊，解释得太好了

14. wildstone

大神，​k指的是位置嵌入中维度的下标是不是写错了，应该是i把？k是成对的2个一组的组序号下标把？

15. 小鱼

谢谢博主！让我更加明白了这个transformer的位置编码的概念。不过对于这个t的取值我不是很清楚它的取值，能够详细的讲解一下嘛？它的取值我知道肯定是跟句子中的词位置是有关系的。

16. 小鱼

感谢博主，在你的另外的博客上面看到了，取值为[0,max_sentence_length)。

17. AI_magician

其实说白了的话也就是拼接，可以这么理解，先拼接一个独热编码向量，然后再乘以W矩阵，得到的结果也是这两个的相加，但是这个是可以learn的，效果不好才用一个公式得出数值相加

18. 菜鸟

很好的解释