位置编码在Transformer模型中是用于注入序列中位置信息的,因为Transformer的自注意力机制本身不考虑单词的顺序。为了计算位置编码,通常使用不同频率的正弦和余弦函数。
import torch
seq_len = 10 # 序列长度
d_model = 512 # 模型的维度
# 初始化位置编码张量
position_encoding = torch.zeros(seq_len, d_model)
# 生成位置索引并增加一个维度以便广播
position = torch.arange(0, seq_len, dtype=torch.float).unsqueeze(1)
'''
torch.arange(0, seq_len, dtype=torch.float)生成了一个从0到seq_len - 1的一维张量,并将其数据类型设置为float。这个张量代表了序列中的位置索引。
.unsqueeze(1)用于增加张量的维度。在索引为1的维度上增加了一个大小为1的维度。如果原始张量的形状是(seq_len,),那么unsqueeze(1)之后的张量形状将变为(seq_len, 1)。这样做是为了后续能够与位置编码的其他维度进行广播操作。
'''
# 计算用于调节频率的分母项
div_term = torch.exp(torch.arange(0, d_model, 2).float() * -(torch.log(torch.tensor(10000.0)) / d_model))
'''
div_term用于计算一个随着维度索引增加而减小的值,这个值用于调节正弦和余弦函数的频率。通过这种方式,每个维度上的位置编码都会有一个不同的频率,从而允许模型捕捉到更丰富的位置信息。
'''
# 使用正弦函数填充偶数索引的位置编码
position_encodi