最近我切换到gensim 3.6,主要原因是优化了训练过程,该训练过程直接从文件中传输训练数据,从而避免了GIL性能的损失。
这是我以前修剪过doc2vec的方式:
training_iterations = 20
d2v = Doc2Vec(vector_size=200, workers=cpu_count(), alpha=0.025, min_alpha=0.00025, dm=0)
d2v.build_vocab(corpus)
for epoch in range(training_iterations):
d2v.train(corpus, total_examples=d2v.corpus_count, epochs=d2v.iter)
d2v.alpha -= 0.0002
d2v.min_alpha = d2v.alpha
它对文档的分类很好,唯一的缺点是经过培训的CPU使用率达到了70%
所以是新方法:
corpus_fname = "spped.data"
save_as_line_sentence(corpus, corpus_fname)
# Choose num of cores that you want to use (let's use all, models scale linearly now!)
num_cores = cpu_count()
# Train models using all cores
d2v_model = Doc2Vec(corpus_file=corpus_fname, workers=num_cores, dm=0, vector_size=200, epochs=50)
现在所有CPU的利用率均为100%
,但是模型的效果非常差。 根据文档,我也不应该同时使用train方法,我应该仅使用时期计数而不是迭代,并且也不应使用min_aplpha和aplha值。
两个Doc2Vec的配置在我看来都一样,因此我的新设置或配置是否有问题,或者新版本的gensim有问题吗?
P.S我在两种情况下都使用相同的语料,也尝试过历元= 100,也使用较小的数字(如5-20),但是我没有运气
编辑:第一个模型每个迭代进行5个时代,共20个迭代,第二个模型进行50个时代,因此让第二个模型进行100个时代,使其表现更好,因为我不再管理Alpha独自一人。
关于突然出现的第二个问题:向文件提供行文档时,文档ID并不总是与行相对应,我没有设法弄清楚是什么原因造成的,对于小规模的用户来说似乎很好语料库,如果我发现自己在做什么错,我将更新此答案。
大小为4GB的语料库的最终配置如下:
d2v = Doc2Vec(vector_size=200, workers=cpu_count(), alpha=0.025, min_alpha=0.00025, dm=0)
d2v.build_vocab(corpus)
d2v.train(corpus, total_examples=d2v.corpus_count, epochs=100)
答案 0 :(得分:1)
大多数用户不应在自己的循环中多次调用train()
,而在循环中他们自己尝试管理alpha
和迭代。错误做起来太容易了。
特别是,您在循环中调用train()
的代码做错了。无论您以此代码为模型的任何在线资源或教程,都应停止咨询,因为它具有误导性或已过时。 (与gensim捆绑在一起的笔记本是可以作为任何代码基础的更好的示例。)
更具体地说:您的循环代码实际上是对数据进行100次传递,对您的外部循环进行20次传递,然后对每个d2v.iter
进行默认的train()
5次调用。而您的第一个train()
调用是将有效alpha
从0.025平滑衰减到0.00025,减少了100倍。但是随后您的下一个train()
调用将固定alpha
设置为0.0248,共5次传递。然后是0.0246,依此类推,直到最后一个循环在alpha=0.0212
处经过5次为止–甚至还没有起始值的80%。也就是说,在您的训练开始时便已达到最低的alpha值。
除了指定corpus_file
的方式(而不是可迭代的语料库)以外,完全相同地调用这两个选项。
您应该从两种语料库形式中获得相似的结果。 (如果您有一个可重现的测试用例,其中相同的语料库获得的质量结果非常不同,并且没有其他错误,那么可能值得向gensim
报告错误。)
如果两种方法的结果都不如错误地管理train()
和alpha
时好,那可能是因为您没有进行相当数量的总培训。