首页 > 解决方案 > Gensim 的 word2vec 从 epoch 1 开始有 0 的损失?

问题描述

我正在使用 Gensim 库的 Word2vec 模块来训练词嵌入,数据集是 400k 句子和 100k 唯一词(不是英语)

我正在使用此代码来监控和计算损失:

class MonitorCallback(CallbackAny2Vec):
    def __init__(self, test_words):
        self._test_words = test_words

    def on_epoch_end(self, model):
        print("Model loss:", model.get_latest_training_loss())  # print loss
        for word in self._test_words:  # show wv logic changes
            print(model.wv.most_similar(word))


monitor = MonitorCallback(["MyWord"])  # monitor with demo words

w2v_model = gensim.models.word2vec.Word2Vec(size=W2V_SIZE, window=W2V_WINDOW, min_count=W2V_MIN_COUNT  , callbacks=[monitor])

w2v_model.build_vocab(tokenized_corpus)

words = w2v_model.wv.vocab.keys()
vocab_size = len(words)
print("Vocab size", vocab_size)

print("[*] Training...")

# Train Word Embeddings
w2v_model.train(tokenized_corpus, total_examples=len(tokenized_corpus), epochs=W2V_EPOCH)

问题是从 epoch 1 开始,loss 为 0,并且被监控词的向量根本没有改变!

[*] Training...
Model loss: 0.0
Model loss: 0.0
Model loss: 0.0
Model loss: 0.0

那么这里有什么问题呢?这是正常的吗?标记化语料库是一个列表列表,类似于 tokenized_corpus[0] = [ "word1" , "word2" , ...]

我用谷歌搜索,似乎一些旧版本的 gensim 在计算损失函数时有问题,但它们是差不多一年前的,现在应该修复了吗?

我也尝试了这个问题的答案中提供的代码,但损失仍然是 0 :

训练期间损失没有减少(Word2Vec,Gensim)

EDIT1:添加compute_loss=True后,损失出现了,但它越来越高,最相似的词和它们的相似度根本没有改变:

Model loss: 2187903.5
Model loss: 3245492.0
Model loss: 4103624.5
Model loss: 4798541.0
Model loss: 5413940.0
Model loss: 5993822.5
Model loss: 6532631.0
Model loss: 7048384.5
Model loss: 7547147.0

标签: nlppytorchgensimword2vec

解决方案


您的代码的最大问题是您没有使用Word2Vec切换丢失跟踪所需的初始化参数:compute_loss=True

(参见https://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec的“参数”部分)

即使有了这个修复,损失报告仍然有很多错误(截至gensim-3.8.32020 年 8 月撰写本文时):

  • 这不是人们可能期望的每个时期的总数或每个示例的平均值。(因此,如果您需要,作为一种解决方法,您的回调应该记住最后一个值并计算增量,或者将内部计数器重置为0.0,每个时期的结束。)
  • 它在较大的训练运行中肯定会失去精度,最终变得无用。(这对您来说可能不是问题。)
  • 由于多线程值覆盖,它可能会丢失一些计数。(这对您来说可能不是一个实际问题,具体取决于您咨询损失值的原因。)

推荐阅读