Gensim 训练不更新权重

Gensim train not updating weights

我有一个领域特定的语料库,我正在尝试为其训练嵌入。由于我想在词汇方面做到全面,所以我添加了来自 glove.6B.50d.txt 的词向量。 Post 从这里添加向量,我正在使用我拥有的语料库训练模型。

我正在尝试 here 的解决方案,但词嵌入似乎没有更新。

这是我目前的解决方案。

#read glove embeddings
glove_wv = KeyedVectors.load_word2vec_format(GLOVE_PATH, binary=False)

#initialize w2v model
model =  Word2Vec(vector_size=50, min_count=0, window=20, epochs=10, sg=1, workers=10, 
                      hs=1, ns_exponent=0.5, seed=42, sample=10**-2, shrink_windows=True)
model.build_vocab(sentences_tokenized)
training_examples_count = model.corpus_count

# add vocab from glove
model.build_vocab([list(glove_wv.key_to_index.keys())], update=True)
model.wv.vectors_lockf = np.zeros(len(model.wv)) # ALLOW UPDATE OF WEIGHTS FROM BACK PROP; 0 WILL SUPPRESS

# add glove embeddings
model.wv.intersect_word2vec_format(GLOVE_PATH,binary=False, lockf=1.0)

下面我正在训练模型并检查训练中明确存在的特定词的词嵌入

# train model
model.train(sentences_tokenized,total_examples=training_examples_count, epochs=model.epochs)

#CHECK IF EMBEDDING CHANGES FOR 'oyo'
print(model.wv.get_vector('oyo'))
print(glove_wv.get_vector('oyo'))

单词 oyo 的词嵌入在训练前后是相同的。我哪里错了?

输入语料库 - sentences_tokenized 包含几个包含单词 oyo 的句子。其中一个这样的句子-

'oyo global platform empowers entrepreneur small business hotel home providing full stack technology increase earnings eas operation bringing affordable trusted accommodation guest book instantly india largest budget hotel chain oyo room one preferred hotel booking destination vast majority student country hotel chain offer many benefit include early check in couple room id card flexibility oyo basically network budget hotel completely different famous hotel aggregator like goibibo yatra makemytrip partner zero two star hotel give makeover room bring customer hotel website mobile app'

你在这里做了很多即兴创作,但有很多潜在的错误或次优问题。特别注意:

  • 虽然(因为它是 Python)您始终可以根据需要改变模型以获得有趣的效果,使用外部词向量播种模型然后继续训练不受 Gensim 的正式或良好支持.据我所知——&我写了一堆这样的代码! – 没有任何好处 docs/examples 做好它,或者做必要的 tuning/validation 结果,或者证明这种技术的可靠优势。网上的大多数例子都是热切的人们在没有意识到权衡取舍的情况下继续前进,看到一个微不足道的完成指标或一点点令人鼓舞的结果,然后过于自信地展示他们的工作,就好像这是一个有充分根据的技术或最佳实践一样。它不是。如果不深入了解模型、审查源代码以及定期重新检查 sanity/improvement 的结果,就会有隐藏的陷阱。特别是,仅对所有单词的一个子集进行新训练可能会使这些单词与其他未接受训练的单词不兼容。
  • intersect_word2vec_format() 功能,尤其是 lockf 功能,也是实验性的 - 可能会提供一种混合其他词向量的方法,但没有任何理论支持。 (我还相信 intersect_word2vec_format() 在最近的(大约 4.1.2)Gensim 版本中仍然略有损坏,尽管可能有 simple workaround。)不过,lockf 功能可能需要棘手的手动初始化 &适应其他非标准步骤。要使用它,最好阅读并理解相关变量出现的Gensim源代码。

因此,如果您确实需要比最初的特定领域语料库更大的词汇量,最安全的方法可能是使用更多具有所需单词的文本来扩展您的训练语料库,就像在类似的语言上下文中使用的那样。 (例如,如果你的领域是科学话语,你会想用更多类似的科学文本来扩展你的语料库,以学习兼容的词——而不是经典小说。)然后所有的词都会经过充分表征的同步训练过程。

也就是说,如果您真的想继续尝试这种可能很复杂且容易出错的临时方法,您的主要问题可能是:

  • 使用字符串作为句子而不是标记列表(因此训练 'words' 实际上只是单个字符)
  • intersect_word2vec_format 错误相关的内容;在训练
  • 之前,检查 .vectors_lockf 是否是正确的长度,1.0 在所有正确的单词更新槽中

另外,其他观察结果:

  • min_count=0 通常不是一个好主意:当您完全丢弃稀有词时,这些模型会得到改善。 (虽然,在进行 .build_vocab(…, update=True) 词汇扩展时,通常对低频词和按频率排序的词汇进行巧妙处理的一堆事情变得很奇怪。)
  • hs=1 通常不应在不禁用通常首选的默认负采样 negative=0 的情况下设置。 (否则,您将创建一个混合弗兰肯模型,在内部神经网络的一侧使用两种模式,共享相同的输入词向量:一种慢得多的方法,不太可能比单独使用任何一种方法都好。)
  • ns_exponent=0.5 是非标准的,使用非标准值作为参数最有可能在特殊情况下提供好处(比如训练文本不是真正的自然语言句子),并且应该只能在线束内进行调整,以便将结果与替代值进行比较。
  • sample=10**-2 也是非标准的,如此大的值可能几乎等同于完全关闭 sample(比如使用 0 值)。如果您有丰富的训练数据,更常见的是希望使该参数更具攻击性(小于默认值)。

一般来说,虽然默认值不是神圣不可侵犯的,但您通常应该避免修改它们,直到您同时 (a) 很好地了解为什么您的 corpus/goals 可能会受益于不同的值; & (b) 一个系统,用于验证哪些改变有帮助或有害,例如对许多参数组合进行网格搜索,对结果模型的适用性进行评分(某些代理)你真正的最终任务。