【问题标题】:Gensim train not updating weightsGensim 火车不更新权重
【发布时间】:2021-12-30 14:48:04
【问题描述】:

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

我正在尝试来自 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 stanford-nlp gensim word2vec word-embedding


    【解决方案1】:

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

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

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

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

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

    另外,其他观察:

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

    一般来说,虽然默认值不是神圣的,但您通常应该避免修改它们,直到您对两者都有(a)很好地了解为什么您的语料库/目标可能会从不同的值中受益; & (b) 用于验证哪些更改是有帮助或有害的系统,例如对许多参数组合进行网格搜索,以对结果模型在(某些代理)您真正的最终任务上的适合度进行评分。

    【讨论】:

    • 嗨 gojomo,感谢您的详细回复和其他意见。如果继续对外部种子向量进行训练不是最优的,那么将新词汇添加到现有模型的最佳方法是什么?除了在扩展语料库上训练模型,有没有什么好的方法可以做到这一点?
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 2014-04-02
    • 2017-04-30
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多