编辑
火车语料库是我在此步骤之前构建的Spark数据框。我从实木复合地板格式加载它,并创建了一个“ Feed”类,该类将Gencorp火车上的迭代器提供给Gensim lib:
class Feed():
def __init__(self, train_data):
self.train_data = train_data
def __iter__(self):
for row in self.train_data.rdd.toLocalIterator():
yield \
gensim.models.doc2vec.TaggedDocument(\
words=[kw.lower() for kw in row["keywords"]] + list(row["tokens_filtered"]),\
tags=[row["id"]])
sdf = spark.read.parquet(save_dirname)
train_corpus = Feed(sdf)
结束编辑
我希望在约900万个新闻文本文档上训练Gensim Doc2Vec模型。这是我的模型定义:
model = gensim.models.doc2vec.Doc2Vec(
workers=8,
vector_size=300,
min_count=50,
epochs=10)
第一步是获取词汇表:
model.build_vocab(train_corpus)
它在90分钟内结束。这是此过程结束时的日志记录信息:
INFO:gensim.models.doc2vec:collected 4202859 word types and 8950263 unique tags from a corpus of 8950339 examples and 1565845381 words
INFO:gensim.models.word2vec:Loading a fresh vocabulary
INFO:gensim.models.word2vec:min_count=50 retains 325027 unique words (7% of original 4202859, drops 3877832)
INFO:gensim.models.word2vec:min_count=50 leaves 1546772183 word corpus (98% of original 1565845381, drops 19073198)
INFO:gensim.models.word2vec:deleting the raw counts dictionary of 4202859 items
INFO:gensim.models.word2vec:sample=0.001 downsamples 9 most-common words
INFO:gensim.models.word2vec:downsampling leaves estimated 1536820314 word corpus (99.4% of prior 1546772183)
INFO:gensim.models.base_any2vec:estimated required memory for 325027 words and 300 dimensions: 13472946500 bytes
然后我在训练语料库上使用迭代器类训练模型:
model.train(train_corpus, total_examples=nb_rows, epochs=model.epochs)
最后的训练记录是:
INFO:gensim.models.base_any2vec:EPOCH 1 - PROGRESS: at 99.99% examples, 201921 words/s, in_qsize 16, out_qsize 0
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 7 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 6 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 5 more threads
INFO:gensim.models.base_any2vec:worker thread finished; awaiting finish of 4 more threads
但是它永远不会完成剩余的线程。 这不是我第一次遇到这个问题,即使使用较小的火车语料库也是如此。通常,我会重新启动整个过程(词汇设置和模型训练),然后继续进行。
为了节省时间,我现在不想再计算词汇表,而是将先前成功计算出的词汇表放到位,而仅尝试再次训练模型。有没有办法只保存模型的vocab部分,然后将其加载以直接在训练语料库上训练模型?
答案 0 :(得分:0)
就挂起原因而言,看来您通常在做正确的事情,但是train_corpus
可能出了一些问题,您的构造尚未显示。
仔细检查其实现,然后编辑您的问题以显示其类型/初始化的更多详细信息。查看日志以查看是否有证据表明任何线程遇到错误,使它们处于未按要求进行报告的状态。
您可以.save()
模型的Doc2Vec
的各个部分,例如model.wv.save(wv_path)
–但是没有简单的方法可以从这些子部分重建模型。 (有可能,但是需要仔细检查对象的所需状态,从检查源开始,并且容易出错。)
而且更相关的是,您可以随时.save()
完整的Doc2Vec
模型-这可能是满足您需求的更好方法。也就是说,您可以在.save()
之后或在调用build_vocab()
等之后.train()
进行此操作。
如果实际上您当前的挂起在某个笔记本中,您可以在其中中断挂起的操作,并在新的单元格中执行新代码,则可以仅从此处保存模型,调试train_corpus
,然后重新执行加载和重新训练–只要语料库大小/词汇匹配build_vocab()
中学习到的内容。
但是,最后,这样一部分受过训练的.save()
将受到已经进行的几乎完全的训练的影响。因此,最终结果将不仅仅反映您的配置参数,还包括大量的临时培训。
如果您想在重新加载保存的Doc2Vec
模型之后“清除”部分训练的挥之不去的效果,我相信以下方法可以做到:
model.trainables.reset_weights(model.hs, model.negative, model.wv, model.docvecs)