我正在使用 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 开始,损失为 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:
Loss does not decrease during training (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
最佳答案
您的代码的最大问题是您没有使用打开丢失跟踪所需的 Word2Vec
初始化参数:compute_loss=True
(请参阅 https://radimrehurek.com/gensim/models/word2vec.html#gensim.models.word2vec.Word2Vec 的“参数”部分)
即使进行了修复,丢失报告仍然存在很多错误(截至 gensim-3.8.3 以及 2020 年 8 月撰写的本文):
- 这不是人们可能期望的每个时期的总数或每个示例的平均值。 (因此,如果您需要这样做,作为解决方法,您的回调应该记住最后一个值并计算增量,或者将内部计数器重置为
0.0
,即每个纪元的结束。) - 它在较大的训练运行中肯定会失去精度,最终变得毫无用处。 (这对您来说可能不是问题。)
- 由于多线程值覆盖,它可能会丢失一些计数。 (这对您来说可能不是一个实际问题,具体取决于您查询损失值的原因。)
关于nlp - Gensim 的 word2vec 从 epoch 1 开始损失为 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63509864/