为什么需要Positional Encoding?
Transformer 模型没有像RNN那样的显式顺序信息(RNN是一个词一个词蹦出来的)。为了引入序列中单词的位置信息,位置编码被添加到输入嵌入中,以便模型能够理解单词在序列中的相对位置。
怎么做Positional Encoding?
在Transformer中,位置编码是通过一些特定的数学函数来实现的。
一种常见的位置编码方法是使用正弦和余弦函数。具体来说,位置编码为每个位置和每个维度生成一个值,然后将这些值添加到input embedding中。这样,每个位置的词向量就会有一个额外的位置信息。
下面是一个用于生成位置编码的公式,其中 `pos` 表示位置,`i` 表示维度:
PE(pos, 2i) = sin(pos / 10000^(2i / d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i / d_model))
在这个公式中,`d_model` 是词向量的维度。对于每个位置 `pos` 和维度 `i`,我们分别计算正弦和余弦值,并将它们添加到词向量中。
以下是一个简化的 Python 代码示例,用于生成位置编码:
python
import numpy as np
def positional_encoding(max_len, d_model):
position_enc = np.zeros((max_len, d_model))
for pos in range(max_len):
for i in range(0, d_model, 2):
position_enc[pos, i] = np.sin(pos / (10000 ** (i / d_model)))
position_enc[pos, i + 1] = np.cos(pos / (10000 ** (i / d_model)))
return position_enc
max_len = 100 # 最大句子长度
d_model = 256 # 词向量维度
pos_encodings = positional_encoding(max_len, d_model)
然后,你可以将生成的位置编码与输入词向量相加,从而在输入嵌入中引入位置信息,这样模型就可以更好地理解单词在序列中的顺序关系。