我有一个现有的 gensim Doc2Vec 模型,我正在尝试对训练集和模型进行迭代更新。
我接受新文件,并照常执行预处理:
stoplist = nltk.corpus.stopwords.words('english')
train_corpus= []
for i, document in enumerate(corpus_update['body'].values.tolist()):
train_corpus.append(gensim.models.doc2vec.TaggedDocument([word for word in gensim.utils.simple_preprocess(document) if word not in stoplist], [i]))
Run Code Online (Sandbox Code Playgroud)
然后我加载原始模型,更新词汇表,并重新训练:
#### Original model
## model = gensim.models.doc2vec.Doc2Vec(dm=0, size=300, hs=1, min_count=10, dbow_words= 1, negative=5, workers=cores)
model = Doc2Vec.load('pvdbow_model_6_06_12_17.doc2vec')
model.build_vocab(train_corpus, update=True)
model.train(train_corpus, total_examples=model.corpus_count, epochs=model.iter)
Run Code Online (Sandbox Code Playgroud)
然后我通过附加新数据来更新训练集 Pandas 数据框,并重置索引。
corpus = corpus.append(corpus_update)
corpus = corpus.reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试将 infer_vector() 与更新的模型一起使用时:
inferred_vector = model1.infer_vector(tokens)
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
Run Code Online (Sandbox Code Playgroud)
结果质量很差,表明模型和训练集数据框的索引不再匹配。
当我将它与未更新的训练集数据框(再次使用更新的模型)进行比较时,结果很好 - 但是,显然我错过了新文档。
无论如何都要更新两者,因为我希望能够在不完全重新训练模型的情况下对模型进行频繁更新?
GensimDoc2Vec还没有官方支持扩展词汇表(通过build_vocab(..., update=True)),所以这里的模型行为没有被定义为做任何有用的事情。事实上,我认为任何现有的 doc-tags 都将被完全丢弃并替换为最新语料库中的任何一个。(此外,在尝试使用update_vocab()with时,还有未解决的内存故障进程崩溃报告Doc2Vec,例如此问题。)
即使这样做有效,如果继续调用train()文本与初始训练集不同的模型,也需要考虑许多模糊的平衡问题。特别是,每次这样的训练都会促使模型在新示例上变得更好,但会失去原始训练的价值,可能会使模型在某些情况下或整体上变得更糟。
对于不断增长的语料库,最可靠的策略是偶尔从头开始重新训练,将所有训练示例合并到一个语料库中。在我最近发布到 gensim 讨论列表的帖子中讨论了对模型进行滚动更新的可能过程的另一个大纲。
关于您的设置的其他一些评论:
同时使用分层 softmax ( hs=1) 和负采样(negative> 0)会增加模型大小和训练时间,但与仅使用具有更多迭代(或其他调整)的一种模式相比,可能不会提供任何优势——因此很少有同时使用这两种模式模式激活
通过不指定 an iter,您使用的是“5”的默认继承自 Word2Vec,而已发布的 Doc2Vec 工作通常使用 10-20 次或更多次迭代
许多报告infer_vector使用更高的可选参数值steps(默认值为 only 5)和/或较小的值alpha(默认值为0.1)时效果更好
| 归档时间: |
|
| 查看次数: |
2645 次 |
| 最近记录: |