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

Gensim Word2vec model is not updating the previous word's embedding weights during increased training

我想以增加的方式训练之前训练过的 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", "2", "3"], ["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 变量将只是一个 查看 到随基础数组一起更改的数组中,因此将始终 return Trues 供您稍后检查。

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

更新代码的答案

可能在您随后的 single-epoch 训练中,'1' 的所有示例都通过 sample 下采样功能被跳过,因为 '1' 是 very-frequent 你的小语料库中的单词:占所有单词的 28.6%。 (在现实的 natural-language 语料库中,most-frequent 词不会超过所有词的百分之几。)

我怀疑如果您使用 sample=0 禁用此下采样功能,您会看到预期的变化。

(请注意,此功能对于足够的训练数据非常有用,更一般地说,关于 Word2Vec 和相关算法的很多事情,尤其是它们的核心优势,需要大量不同的数据——而且不会'使用 toy-sized 数据集时效果不佳或表现不佳。)

另请注意:您的第二个 .train() 应该对 newCorpus 使用明确准确的计数。 (使用 total_examples=model.corpus_count 到 re-use 缓存的语料库计数在您提供额外数据时可能并不总是合适的,即使它在这里工作正常。)

另一件需要注意的事情:一旦你开始使用模型进行 more-sophisticated 操作,如 .most_similar(),它会缓存一些计算数据用于 vector-to-vector 比较,并且这些数据不会总是(至少通过 gensim-3.8.3)通过更多的培训来刷新。因此,您可能必须丢弃该数据(在 gensim-3.8.3model.wv.vectors_norm = None)以确保获得新的 unit-normed 向量或新的 most_similar()(及相关方法)结果。