python-pytorch使用日志
- 1. optimizer.zero_grad()和model.zero_grad()的区别
- 2. cbow和skip-gram的训练数据格式
- 3. 获取cbow和skip-gram训练后的中文词向量
- 4. 获取到词向量后可以做什么
- 5. 余弦相似度结果的解释
1. optimizer.zero_grad()和model.zero_grad()的区别
都是清空模型的梯度参数,如果模型中有多个model训练时,建议使用model.zero_grad();如果只有一个模型训练optimizer.zero_grad()和model.zero_grad()意义都一样
2. cbow和skip-gram的训练数据格式
cbow格式
data1 = []
for i in range(2, len(raw_text) - 2):
context = [raw_text[i - 2], raw_text[i - 1],
raw_text[i + 1], raw_text[i + 2]]
target = raw_text[i]
data1.append((context, target))
cbow最终格式
[([‘从零开始’, ‘Zookeeper’, ‘高’, ‘可靠’], ‘开源’), ([‘Zookeeper’, ‘开源’, ‘可靠’, ‘分布式’], ‘高’), ([‘开源’, ‘高’, ‘分布式’, ‘一致性’], ‘可靠’), ([‘高’, ‘可靠’, ‘一致性’, ‘协调’], ‘分布式’), ([‘可靠’, ‘分布式’, ‘协调’, ‘服务’], ‘一致性’)]
skip-gram格式
data3 = []
window_size1=2
for i,word in enumerate(raw_text):
target = raw_text[i]
contexts=raw_text[max(i - window_size1, 0): min(i + window_size1 + 1, len(raw_text))]
for context in contexts:
if target!=context:
data3.append((context,target))
data3,len(data3)
或者类似于
def create_skipgram_dataset(sentences, window_size=4):
data = [] # 初始化数据
for sentence in sentences: # 遍历句子
sentence = sentence.split() # 将句子分割成单词列表
for idx, word in enumerate(sentence): # 遍历单词及其索引
# 获取相邻的单词,将当前单词前后各 N 个单词作为相邻单词
for neighbor in sentence[max(idx - window_size, 0): min(idx + window_size + 1, len(sentence))]:
if neighbor != word: # 排除当前单词本身
# 将相邻单词与当前单词作为一组训练数据
data.append((neighbor, word))
return data
skip-gram最终格式
([(‘Zookeeper’, ‘从零开始’),
(‘开源’, ‘从零开始’),
(‘从零开始’, ‘Zookeeper’),
(‘开源’, ‘Zookeeper’),
(‘高’, ‘Zookeeper’),
(‘从零开始’, ‘开源’),
(‘Zookeeper’, ‘开源’),
(‘高’, ‘开源’),
(‘可靠’, ‘开源’),
(‘Zookeeper’, ‘高’),
(‘开源’, ‘高’),
(‘可靠’, ‘高’),
(‘分布式’, ‘高’),
(‘开源’, ‘可靠’)])
3. 获取cbow和skip-gram训练后的中文词向量
前提是需要使用中文去训练搭建的模型,可以参考
https://blog.csdn.net/Metal1/article/details/132886936
https://blog.csdn.net/L_goodboy/article/details/136347947
如果使用pytorch的Embeding的模型,获取的就是embeding层
class SkipGramModel(nn.Module):
def __init__(self, vocab_size, embedding_dim):
super(SkipGramModel, self).__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.linear = nn.Linear(embedding_dim, vocab_size)
def forward(self, center_word):
embedded = self.embedding(center_word)
output = self.linear(embedded)
"""
输出每个词的嵌入向量
for word, idx in word_to_idx.items():
print(f"{word}: {model.embedding.weight[:,idx].detach().numpy()}")
"""
如果使用原生的写的模型,获取的就是第一层的线性层
import torch.nn as nn # 导入 neural network
class SkipGram(nn.Module):
def __init__(self, voc_size, embedding_size):
super(SkipGram, self).__init__()
# 从词汇表大小到嵌入层大小(维度)的线性层(权重矩阵)
self.input_to_hidden = nn.Linear(voc_size, embedding_size, bias=False)
# 从嵌入层大小(维度)到词汇表大小的线性层(权重矩阵)
self.hidden_to_output = nn.Linear(embedding_size, voc_size, bias=False)
def forward(self, X): # 前向传播的方式,X 形状为 (batch_size, voc_size)
# 通过隐藏层,hidden 形状为 (batch_size, embedding_size)
hidden = self.input_to_hidden(X)
# 通过输出层,output_layer 形状为 (batch_size, voc_size)
output = self.hidden_to_output(hidden)
return output
"""
输出每个词的嵌入向量
for word, idx in word_to_idx.items():
print(f"{word}: {model.input_to_hidden .weight[:,idx].detach().numpy()}")
"""
4. 获取到词向量后可以做什么
“具有相同上下文的词语包含相似的语义”,使得语义相近的词在映射到欧式空间后中具有较高的余弦相似度。
-
语义相似性度量:词向量能够将语义上相近的词映射到向量空间中相近的位置。因此,可以通过计算两个词向量的余弦相似度或欧氏距离来度量它们之间的语义相似性。这在诸如词义消歧、同义词替换等任务中非常有用。
-
文本分类与情感分析:在文本分类任务(如新闻分类、电影评论情感分析)中,词向量可以作为特征输入到分类器中。通过将文本中的每个词表示为向量,并聚合这些向量(例如,通过取平均值或求和),可以得到整个文本的向量表示,进而用于分类或情感分析。
-
命名实体识别:在命名实体识别(NER)任务中,词向量可以帮助模型识别文本中的特定类型实体(如人名、地名、组织机构名等)。通过将词向量与序列标注模型(如BiLSTM-CRF)结合使用,可以提高NER的性能。
-
问答系统:在问答系统中,词向量可以用于表示问题和答案的语义信息。通过计算问题和答案的词向量之间的相似度,可以找出与问题最匹配的答案。
-
机器翻译:在机器翻译任务中,词向量可以用于捕捉源语言和目标语言之间的语义对应关系。通过训练跨语言的词向量表示(如跨语言词嵌入),可以实现更准确的翻译结果。
-
文本生成:在文本生成任务(如文本摘要、对话生成等)中,词向量可以作为生成模型的输入或隐层表示。通过利用词向量中的语义信息,模型可以生成更自然、更相关的文本内容。
-
知识图谱与实体链接:在知识图谱构建和实体链接任务中,词向量可以用于表示实体和概念之间的语义关系。通过将实体和概念映射到向量空间,可以方便地进行实体识别和关系推理。
5. 余弦相似度结果的解释
余弦相似度的结果范围通常在-1到1之间,这个范围可以用来解释两个向量之间的相似程度
-
值为1:当余弦相似度为1时,表示两个向量完全重合,即它们指向的方向完全相同,这意味着两个向量代表的文本或概念在语义上几乎完全相同。
-
值为-1:当余弦相似度为-1时,表示两个向量完全相反,即它们指向的方向完全相反。在文本相似度的上下文中,这通常意味着两个文本在语义上非常对立或相反。
-
值为0:当余弦相似度为0时,表示两个向量正交,即它们之间的夹角为90度。在文本相似度的语境中,这通常意味着两个文本在语义上没有直接的联系或相似性。
-
值在0到1之间:当余弦相似度在0和1之间时,表示两个向量之间的夹角小于90度,但不完全重合。数值越接近1,表示两个向量在方向上的相似性越高,即两个文本在语义上的相似性越高。
-
值在-1到0之间:当余弦相似度在-1和0之间时,表示两个向量之间的夹角大于90度但小于180度。数值越接近-1,表示两个向量在方向上的对立性越高,即两个文本在语义上的对立性越高
如
其中trained_vector_dic是通过模型获取的词向量字典
余弦相似度
trained_vector_dic={}
for word, idx in word_to_idx.items(): # 输出每个词的嵌入向量
trained_vector_dic[word]=model.embedding.weight[idx]
import torch
import torch.nn.functional as F
cosine_similarity1 = F.cosine_similarity(torch.tensor(trained_vector_dic["保持数据"].unsqueeze(0)), torch.tensor(trained_vector_dic["打印信息"]).unsqueeze(0))
print(cosine_similarity1)
"""
结果如下,表名不相似
tensor([-0.0029])
"""
点积相似度
dot_product = torch.dot(torch.tensor(trained_vector_dic["保持数据"]), torch.tensor(trained_vector_dic["打印信息"]))
x_length = torch.norm(torch.tensor(trained_vector_dic["保持数据"]))
y_length = torch.norm(torch.tensor(trained_vector_dic["打印信息"]))
similarity = dot_product / (x_length * y_length)
print(similarity)
"""
结果如下,表名不相似,与余弦结果一致
tensor([-0.0029])
"""