Gensim doc2vec 文件流训练性能较差
Gensim doc2vec file stream training worse performance
最近我切换到 gensim 3.6,主要原因是优化了训练过程,它直接从文件中流式传输训练数据,从而避免了 GIL 性能损失。
这就是我过去使用 trin 我的 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 我在这两种情况下使用相同的语料库,我也尝试过 epoch count = 100,也尝试过较小的数字,如 5-20,但我没有运气
编辑:第一个模型进行了 20 次迭代,每次迭代 5 个迭代,第二个模型进行了 50 个迭代,所以让第二个模型进行 100 个迭代使其表现更好,因为我是不再自己管理 alpha。
关于弹出的第二个问题:提供行文件的文件时,doc ids并不总是对应于行,我没弄清楚是什么原因造成的,似乎工作正常对于小语料库,如果我发现我做错了什么,我会更新这个答案。
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)
大多数用户不应该在他们自己的循环中多次调用 train()
,他们试图自己管理 alpha
和迭代。太容易做错了。
具体来说,您在循环中调用 train()
的代码是错误的。无论您以此代码为模型的在线资源或教程是什么,您都应该停止咨询,因为它具有误导性或已过时。 (与 gensim 捆绑在一起的笔记本是更好的示例,可作为任何代码的基础。)
更具体地说:您的循环代码实际上对数据执行 100 次传递,20 次外循环,然后默认 d2v.iter
每次调用 train()
5 次。您的第一个 train()
调用正在平稳地将有效 alpha
从 0.025 衰减到 0.00025,减少了 100 倍。但是你的下一个 train()
调用使用 0.0248 的固定 alpha
进行 5 次传递。然后是 0.0246,等等,直到你的最后一个循环在 alpha=0.0212
处进行了 5 次传递——甚至不到起始值的 80%。也就是说,最低的 alpha 将在您的训练早期达到。
除了指定corpus_file
的方式,而不是可迭代的语料库之外,完全相同地调用两个选项。
你应该从两种语料库形式中得到相似的结果。 (如果您有一个可重现的测试用例,其中相同的语料库得到非常不同质量的结果,并且没有其他错误,那么值得将其作为错误报告给 gensim
。)
如果两者的结果都不如您错误地管理 train()
和 alpha
时好,这可能是因为您没有进行相当数量的总训练。
最近我切换到 gensim 3.6,主要原因是优化了训练过程,它直接从文件中流式传输训练数据,从而避免了 GIL 性能损失。
这就是我过去使用 trin 我的 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 我在这两种情况下使用相同的语料库,我也尝试过 epoch count = 100,也尝试过较小的数字,如 5-20,但我没有运气
编辑:第一个模型进行了 20 次迭代,每次迭代 5 个迭代,第二个模型进行了 50 个迭代,所以让第二个模型进行 100 个迭代使其表现更好,因为我是不再自己管理 alpha。
关于弹出的第二个问题:提供行文件的文件时,doc ids并不总是对应于行,我没弄清楚是什么原因造成的,似乎工作正常对于小语料库,如果我发现我做错了什么,我会更新这个答案。
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)
大多数用户不应该在他们自己的循环中多次调用 train()
,他们试图自己管理 alpha
和迭代。太容易做错了。
具体来说,您在循环中调用 train()
的代码是错误的。无论您以此代码为模型的在线资源或教程是什么,您都应该停止咨询,因为它具有误导性或已过时。 (与 gensim 捆绑在一起的笔记本是更好的示例,可作为任何代码的基础。)
更具体地说:您的循环代码实际上对数据执行 100 次传递,20 次外循环,然后默认 d2v.iter
每次调用 train()
5 次。您的第一个 train()
调用正在平稳地将有效 alpha
从 0.025 衰减到 0.00025,减少了 100 倍。但是你的下一个 train()
调用使用 0.0248 的固定 alpha
进行 5 次传递。然后是 0.0246,等等,直到你的最后一个循环在 alpha=0.0212
处进行了 5 次传递——甚至不到起始值的 80%。也就是说,最低的 alpha 将在您的训练早期达到。
除了指定corpus_file
的方式,而不是可迭代的语料库之外,完全相同地调用两个选项。
你应该从两种语料库形式中得到相似的结果。 (如果您有一个可重现的测试用例,其中相同的语料库得到非常不同质量的结果,并且没有其他错误,那么值得将其作为错误报告给 gensim
。)
如果两者的结果都不如您错误地管理 train()
和 alpha
时好,这可能是因为您没有进行相当数量的总训练。