Gensim Word2vec模型在增加训练量时不会更新前一个单词的嵌入权重

问题描述

我想以一种增强的方式来训练以前训练过的word2vec模型,如果在先前的训练过程中已经看到过该单词,则更新该单词的权重,并创建和更新在以前的培训过程。例如:

from gensim.models import Word2Vec
# old corpus
corpus = [["0","1","2","3"],["2","3","1"]]
# first train on old corpus
model = Word2Vec(sentences=corpus,size=2,min_count=0,window=2)
# checkout the embedding weights for word "1"
print(model["1"])

# here comes a new corpus with new word "4" and "5"
newCorpus = [["4",["1","5","2"]]

# update the prevIoUs trained model
model.build_vocab(newCorpus,update=True)
model.train(newCorpus,total_examples=model.corpus_count,epochs=1)

# check if new word has embedding weights:
print(model["4"])  # yes

# check if prevIoUs word's embedding weights are updated
print(model["1"])  # output the same as before

即使新单词中的前一个单词的上下文已经改变,似乎前一个单词的嵌入也没有更新。有人可以告诉我如何更新以前的嵌入权重吗?

解决方法

原始问题的答案

尝试在打印之前和之后将它们打印出来(或什至只是几个主要尺寸,例如print(model['1'][:5])),以查看它们是否已更改。

或者在开始时,preEmbed是值的正确副本(例如:preEmbed = model['1'].copy())。

我认为您会看到这些值确实发生了变化。

您当前的preEmbed变量只是对与基础数组一起更改的数组的 view ,因此将始终返回True s以便以后检查。 / p>

查看Numpy Copies & Views上的文章将有助于解释更多示例的情况。

回答更新的代码

在随后的单周期训练中,很可能'1'的所有示例都将通过sample下采样功能被跳过,因为'1'在您的小圈子中是一个非常常见的词语料库:占所有单词的28.6%。 (在现实的自然语言语料库中,最常用的词不会超过所有词的百分之几。)

我怀疑如果您用sample=0禁用了此下采样功能,则会看到预期的更改。

(请注意,此功能对于获得足够的训练数据确实很有帮助,并且更一般而言,关于Word2Vec和相关算法的许多事情,尤其是其核心优势,需要大量的多样化数据,因此无法使用大小,或以玩具大小的数据集以预期的方式表现。)

还请注意:您的第二个.train()应该为newCorpus使用一个明确准确的计数。 (在提供额外数据时,使用total_examples=model.corpus_count重用缓存的语料库计数可能并不总是合适的,即使在这里行之有效。)

需要注意的另一件事:一旦开始对.most_similar()之类的更复杂的操作使用模型,它将为某些向量间的比较而缓存一些计算出的数据,而该数据将不会总是(至少通过gensim-3.8.3)进行了更多培训。因此,您可能必须舍弃该数据(在gensim-3.8.3中的model.wv.vectors_norm = None中),以确保获得新的单位归一向量或新的most_similar()(及相关方法)结果。>