我的 Doc2Vec 代码,经过多次训练循环后,并没有给出好的结果。可能有什么问题?

goj*_*omo 1 gensim word2vec doc2vec

我正在Doc2Vec使用以下代码训练模型,其中tagged_dataTaggedDocument我之前设置的实例列表:

max_epochs = 40

model = Doc2Vec(alpha=0.025, 
                min_alpha=0.001)

model.build_vocab(tagged_data)

for epoch in range(max_epochs):
    print('iteration {0}'.format(epoch))
    model.train(tagged_data,
                total_examples=model.corpus_count,
                epochs=model.iter)
    # decrease the learning rate
    model.alpha -= 0.001
    # fix the learning rate, no decay
    model.min_alpha = model.alpha

model.save("d2v.model")
print("Model Saved")
Run Code Online (Sandbox Code Playgroud)

当我后来检查模型结果时,它们并不好。可能出了什么问题?

goj*_*omo 5

不要.train()在您自己的尝试进行alpha算术的循环中多次调用。

这是不必要的,而且容易出错。

具体来说,在上面的代码中,将原始0.025alpha 减少0.00140 倍导致 ( 0.025 - 40*0.001) -0.015final alpha,这对于许多训练时期也是负数。但是负alpha 学习率是荒谬的:它本质上要求模型在每次批量训练更新时,将其预测推向错误的方向,而不是正确的方向。(此外,由于model.iter默认情况下是 5,因此上面的代码实际上执行了40 * 5训练传递 – 200– 这可能不是有意识的意图。但这只会混淆代码的读者和缓慢的训练,而不是完全破坏结果,例如alpha处理不当。)

这里还有其他常见的错误变体。如果alpha减少0.0001,则 40 次减少只会将最终减少alpha0.021- 而这种具有线性学习率衰减的 SGD(随机梯度下降)风格的正确做法是让值结束“非常接近0.000”)。如果用户开始摆弄max_epochs- 毕竟,这是一个最重要的参数!– 但不要每次都调整减量,它们很可能远低于或远高于0.000

所以不要使用这种模式。

不幸的是,许多不好的网上例子都复制互相这种反模式,在自己做出严重错误epochsalpha处理。请不要复制他们的错误,并请让他们的作者知道他们在出现此问题的任何地方都在误导人们。

上面的代码可以通过更简单的替换来改进:

max_epochs = 40
model = Doc2Vec()  # of course, if non-default parameters needed, use them here
                   # but most users won't need to change alpha/min_alpha at all

model.build_vocab(tagged_data)
model.train(tagged_data, total_examples=model.corpus_count, epochs=max_epochs)

model.save("d2v.model")
Run Code Online (Sandbox Code Playgroud)

在这里,该.train()方法将准确地执行请求的次数epochs,将内部有效值alpha从其默认起始值平滑地减少到接近零。(很少需要更改开始alpha,但即使您愿意,只需在初始模型创建时设置一个新的非默认值就足够了。)