我尝试将句子映射到向量,以使句子相互比较。为了测试gensim的Doc2Vec模型,我下载了sklearn的新闻组数据集并在其上训练了模型。
为了比较两个句子,我使用了model.infer_vector(),我想知道为什么两个使用同一个句子的调用给了我不同的向量:
model = Doc2Vec(vector_size=100, window=8, min_count=5, workers=6)
model.build_vocab(documents)
epochs=10
for epoch in range(epochs):
print("Training epoch %d" % (epoch+1))
model.train(documents, total_examples=len(documents), epochs=epochs)
v1 = model.infer_vector("I feel good")
v2 = model.infer_vector("I feel good")
print(np.linalg.norm(v1-v2))
输出:
训练时代1
0.41606528
训练时代2
0.43440753
训练时代3
0.3203116
训练时代4
0.3039317
训练时代5
0.68224543
训练时代6
0.5862567
训练时代7
0.5424634
训练时代8
0.7618142
训练时代9
0.8170159
训练时代10
0.6028216
如果我设置alpha和min_alpha = 0,我会得到“我感觉很好”和“感觉很好”的一致向量,但是模型在每个时代都给了我相同的向量,所以它似乎没有学到任何东西:
训练时代1
0.043668125
训练时代2
0.043668125
训练时代3
0.043668125
训练时代4
0.043668125
训练时代5
0.043668125
训练时代6
0.043668125
训练时代7
0.043668125
训练时代8
0.043668125
训练时代9
0.043668125
训练时代10
0.043668125
所以我的问题是:
为什么我甚至可以为推理指定学习率?我希望模型只在训练期间而不是在推理过程中改变。
如果我指定alpha = 0进行推理,为什么这两个向量之间的距离在不同时期不会改变?
答案 0 :(得分:2)
推理使用alpha
因为它与训练是相同的迭代调整过程,仅限于更新一个新文本示例的一个新向量。
所以是的,模型的各种权重都被冻结了。但是,一个新的向量的权重(维度)从小的随机值开始,就像每个其他向量也开始一样,然后在多个训练周期中逐渐推进,以使向量更好地作为用于预测文本单词的doc-vector。然后返回最终的新向量。
这些微调从较大的起始alpha
值开始,最后变为可忽略不计的min_alpha
。如果alpha
为0.0,则不会发生任何训练/推断,因为对可更新权重的每次微调校正在应用之前都会乘以0.0,这意味着不会发生任何变化。
与此不同的是,您的代码存在许多可能妨碍预期结果的问题:
通过循环调用train()
epochs
次,然后为epochs
提供大于1的值,实际上您实际执行epochs * epochs
次培训通行证
此外,通过不指定alpha
和min_alpha
,每次调用train()
都会将有效alpha从其高值下降到每次调用的低值 - a锯齿模式不适用于这种随机梯度下降优化。 (您的日志中应该有关于此错误的警告。)
很少需要在循环中多次调用train()
。只需调用一次,使用正确的epochs
值,它就会做正确的事:多次通过,具有平滑衰减的alpha
学习率。
另外,在致电infer_vector()
时:
它需要一个令牌列表,就像培训示例的words
属性一样,documents
- 不是字符串中的项目。 (通过提供字符串,它看起来像一个字符列表,因此它将推断文档['I', ' ', 'f', 'e', 'e', 'l', ' ', 'g', 'o', 'o', 'd']
而不是 ['I', 'feel', 'good']
的文档向量。)
这些代币应该与培训文件一样进行预处理 - 例如,如果它们在那里小写,它们应该小写,然后转到infer_vector()
默认参数passes=5
非常小,特别是对于短文本 - 许多报告更好的结果,数值为数百或数百
默认参数alpha=0.1
与训练默认值0.025相比有些大;使用训练值(特别是使用更多passes
)通常可以提供更好的结果
最后,就像训练期间的算法利用随机化(调整单词预测上下文窗口,或随机抽样负面示例,或随机下采样高频词),推理也是如此。因此,即使提供完全相同的令牌也不会自动产生完全相同的推断向量。
但是,如果模型已经过充分训练,并且如上所述调整推理以获得更好的结果,则相同文本的向量应非常非常接近。并且因为这是一个随机算法,在运行之间存在一些固有的“抖动”,所以最好使您的下游评估并使用容忍这么小的差异。 (并且,如果您反而看到较大的差异,请更正其他模型/推理问题,通常需要更多数据或其他参数调整。)
如果你想强制确定性,那么在gensim project issue中讨论如何做到这一点。但是,理解&容忍小方差通常更符合这种随机影响算法的选择。