@ -12,6 +12,20 @@ WHAT: 位置编码是一种向模型输入的每个单词嵌入向量中添加
### 位置编码应该怎么设计
如何设计我们需要考虑几个问题:
1. 如果是用整些数值表示,推理时可能会遇到比训练时还要长的序列;而且随着序列长度的增加,位置值会越来越大。
2. 如果用[-1,+1]之间进行表示, 要解决序列长度不同时, 能表示token在序列中的绝对位置; 而且在序列长度不同时, 也要在不同序列中token的相对位置/距离保持一致。
所以我们希望:
1. 它是有界的,即可以处理推理(预测)时,遇到的更长的句子。
2. 每个时间步长(组),输出的值是唯一的。
3. 任意两个时间步长(组)之间的距离,在不同长度的序列中应该一致。
4. 它必须是确定性的。
### 位置编码是怎么算的?
在《Attention is all you need》中, 位置编码是有正弦和余弦函数计算出来的, 且是固定的。
@ -85,15 +99,26 @@ tensor([-1.0000, 0.0044, -0.9673, -0.2535, -0.8724, -0.4889, -0.7253, -0.6884,
< img src = "../assets/image-20240427180954246.png" alt = "image-20240427180954246" style = "zoom:50%;" / >
为什么是用正弦和余弦函数, 对于正弦函( sin) : 最大值是 1, 最小值是 -1。对于余弦函数( cos) : 最大值是 1, 最小值是 -1。也就是它们可以保证值是比较小的, 而且也是符合深度学习模型可学习的参数。
为什么是用正弦和余弦函数, 对于正弦函( sin) : 最大值是 +1, 最小值是 -1。对于余弦函数( cos) : 最大值是 +1, 最小值是 -1。也就是它们可以保证值是比较小的, 而且也是符合深度学习模型可学习的参数。
其中最重要的是允许模型学习相对位置:由于正弦和余弦函数的周期性(且是不同周期),对于任意固定偏移量 `k` , `PE(pos+k)`可以表示为 `PE(pos)` 的线性函数。这意味着模型可以很容易地通过学习注意力权重来关注相对位置,因为相对位置的编码可以通过简单的线性变换来获得。即我知道了绝对距离,也能知道相对距离。
其中最重要的是允许模型学习相对位置:由于正弦和余弦函数的周期性,对于任意固定偏移量 `k` , `PE(pos+k)`可以表示为 `PE(pos)` 的线性函数。这意味着模型可以很容易地通过学习注意力权重来关注相对位置,因为相对位置的编码可以通过简单的线性变换来获得。
正弦和余弦函数是线性函数的基础,因为它们满足以下的加法公式:
$$
[ \sin(a + b) = \sin(a)\cos(b) + \cos(a)\sin(b) ]
\\
[ \cos(a + b) = \cos(a)\cos(b) - \sin(a)\sin(b) ]
$$
~~~markdown
原文:
We chose this function because we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset k, PE(pos+k) can be represented as a linear function of PE(pos).
~~~
[可视化地址 ](https://erdem.pl/2021/05/understanding-positional-encoding-in-transformers#positional-encoding-visualization )你可以看到4个相对靠近的值, 但是因为在不同的位置, 值相差的完全不一样, 也就是由正弦和余弦函数造的数据, 在每个位置的值都是唯一的!
< img src = "../assets/image-20240430152239833.png" alt = "image-20240430152239833" style = "zoom:50%;" / >
我们用更简单的语言来解释这个概念: