这期内容当中小编将会给大家带来有关Word2Vec论文总结和实现是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
一、总结
1. word2vec可以在百万数量级的词典和上亿的数据集上进行高效的训练;该工具得到词向量(word embedding)的训练结果,可以很好的度量词与词之间的相似性。
2. word2vec算法背后时一个浅层神经网络。word2vec算法或模型指的是计算word vector的CBOW模型和skip-gram模型。
3. Skip-gram的公式及说明
当时间窗口大小为m时,跳字模型需要最大化给定任一中心词生成背景词的概率为:
损失函数中中心词生成背景词的概率可以使用 softmax 函数进行定义:
说明:
4. CBOW公式及说明
5. 负采样(negative sample)
负采样每次让一个训练样本仅仅更新一小部分的权重 。 在论文中,作者指出指出对于小规模数据集,选择5-20个negative words会比较好,对于大规模数据集可以仅选择2-5个negative words。 大规模数据集反而取负采样词少,1)减少计算量,2)经验。负采样最后会变成1,0(正负样本)的逻辑回归问题。
负采样词根据公式进行选择,
一个单词的负采样概率越大,它被选中的概率越大。负采样我这样理解,现在需要取20个负样本,语料库中有1w个词,每个词都有根据频率计算的概率(和是1),我现在随机选0-1之间的数,落在哪个位置就选哪个词,选20次即可。
6. 层序softmax
在模型的训练过程中,通过Huffman编码,构造了一颗庞大的Huffman树,同时会给非叶子结点赋予向量。我们要计算的是目标词w的概率,这个概率的具体含义,是指从root结点开始随机走,走到目标词w的概率。因此在途中路过非叶子结点(包括root)时,需要分别知道往左走和往右走的概率。例如到达非叶子节点n的时候往左边走和往右边走的概率分别是:
由此,我们就可以使用随机梯度下降在跳字模型和连续词袋模型中不断迭代计算词典中所有词向量 v 和非叶子节点的向量 u。每次迭代的计算开销由 O(|V|) 降为二叉树的高度 O(log|V|)。
二、实现
根据简单语料,展示预料库中词关系,为相似度计算提供基础。
# 1. 导入基础包,全局参数 import torch import numpy as np import matplotlib.pyplot as plt from torch import nn, optim from torch.utils.data import TensorDataset, DataLoader device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 2. 语料及语料库大小, 词与索引关系 sentences = ['i like dog', 'jack hate coffee', 'i love milk', 'jack study natural language process', 'word2vec conclude skip-gram and cbow model', 'jack like coffee', 'dog coffee milk'] word_list = ' '.join(sentences).split() vocab = list(set(word_list)) vocab_size = len(vocab) word2idx = {w:i for i, w in enumerate(vocab)} idx2word = {i:w for i, w in enumerate(vocab)} # 3. 窗口,skip_gram, 输入输出 window = 2 batch_size = 8 # 生成skip_gram skip_gram = [] for center_idx in range(len(word_list)): center = word2idx[word_list[center_idx]] for context_idx in (list(range(center_idx - window, center_idx)) + list(range(center_idx + 1, center_idx + 1 + window))): if context_idx < 0 or context_idx > len(word_list) - 1: continue else: context = word2idx[word_list[context_idx]] skip_gram.append([center, context]) def get_data(): input_data = [] target_data = [] for i in range(len(skip_gram)): input_data.append(np.eye(vocab_size)[skip_gram[i][0]]) target_data.append(skip_gram[i][1]) return input_data, target_data input, target = get_data() input, target = torch.Tensor(input), torch.LongTensor(target) # 4. 形成训练所需的dataloader dataset = TensorDataset(input, target) dataloder = DataLoader(dataset, batch_size, True) # 5. 模型实现,优化器,损失函数 class Word2Vec(nn.Module): def __init__(self): super(Word2Vec, self).__init__() self.embed_size = 2 self.W = nn.Parameter(torch.randn(vocab_size, self.embed_size).type(torch.Tensor)) self.V = nn.Parameter(torch.randn(self.embed_size, vocab_size).type(torch.Tensor)) def forward(self, x): # x[batch_size, vocab_size] one_hot out = torch.mm(torch.mm(x, self.W), self.V) return out model = Word2Vec().to(device) criteriom = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=1e-3) # 6. 训练 for epoch in range(2000): for i, (input_x, target_y) in enumerate(dataloder): input_x = input_x.to(device) target_y = target_y.to(device) pred = model(input_x) loss = criteriom(pred, target_y) optimizer.zero_grad() loss.backward() optimizer.step() if (epoch + 1) % 500 == 0 and i == 0: print(epoch + 1, loss.item()) # 7. 通过图像展示向量之间的关系 for i, label in enumerate(vocab): W, WT = model.parameters() x,y = float(W[i][0]), float(W[i][1]) plt.scatter(x, y) plt.annotate(label, xy=(x, y), xytext=(5, 2), textcoords='offset points', ha='right', va='bottom') plt.show()
上述就是小编为大家分享的Word2Vec论文总结和实现是怎样的了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。