词向量的生成可以通过嵌入层(Embedding Layer)来完成。嵌入层是神经网络中的一种常用层,用于将离散的词索引转换为密集的词向量。以下是一个典型的步骤:
建立词表:首先,需要从训练数据中收集所有的词汇,并为每个词汇分配一个唯一的索引。这个过程称为建立词表。词表中包含了所有可能的词汇以及它们的索引,通常是一个字典或者哈希表的形式。
初始化词向量矩阵:对于每个词汇,都会有一个对应的词向量。可以随机初始化这些词向量,也可以使用预训练的词向量,比如Word2Vec、GloVe或FastText。
嵌入层映射:嵌入层将词索引作为输入,并输出对应的词向量。在训练过程中,这些词向量会被优化以最大化模型的性能。
词向量缩放:在Transformer模型中,通常会对词向量进行缩放,以确保它们具有适当的尺度。这个缩放因子通常是词向量的维度的平方根,如示例中的 math.sqrt(self.d_model)。
具体到代码中的示例,self.lut(x) 可以理解为嵌入层,它接收一个词的索引作为输入,然后从词向量矩阵中检索对应的词向量。乘以 math.sqrt(self.d_model) 的操作则是对词向量进行缩放,以确保其数值范围适合模型的需求。
找到单词在词表中对应的索引:首先,根据单词在词汇表中的位置或唯一标识,找到该单词在词表中的索引位置。
将索引映射为512维的向量:通过嵌入层,将单词的索引映射为一个固定维度的向量,通常这个向量的维度是预先指定的,比如512维。
这样,每个单词都被映射为一个固定长度的密集向量,而这些向量通常包含了单词的语义信息。这些向量随后将作为模型的输入,用于进行后续的计算,比如在Transformer模型中进行自注意力机制等操作。
import torch
import torch.nn as nn
# 假设词表大小为100,即有100个不同的单词
vocab_size = 100
# 定义嵌入层,将索引映射为10维的向量
embedding_layer = nn.Embedding(vocab_size, 10)
# 定义一个输入单词的索引
word_index = torch.tensor([5]) # 假设单词的索引是5
# 通过嵌入层,将索引映射为10维的向量
embedded_vector = embedding_layer(word_index)
print("嵌入后的向量:", embedded_vector)
embedding = nn.Embedding(10,3,padding_idx=0) #,padding_idx=0 数字0转换的多维度数据都是0
# input1 = torch.LongTensor([[1,2,4,5],[3,2,4,6]])
input1 = torch.LongTensor([[1,0,4,0]])
print(embedding(input1))
###########################
tensor([[[ 0.1610, -1.2377, 1.3285],
[ 0.0000, 0.0000, 0.0000],
[ 2.4994, 0.9405, -0.8696],
[ 0.0000, 0.0000, 0.0000]]], grad_fn=<EmbeddingBackward>)
2、位置编码
计算结果一致,结论是sin-cos这种位置编码方式,任意位置的位置编码都可以表达为一个已
知位置的位置编码的关于距离的线性组合。也是因为有这个特质采用三角函数表征位置信息,
同时由于padding的词不需要存在这种相对位置表达性质,因此对padding的位置向量做了全
0处理。
同一个单词相对位置进行记录,同时值在-1,1 之间比较小
位置编码的介绍:https://zhuanlan.zhihu.com/p/525552086