我正在尝试比较我的Doc2Vec实现(通过tf)和gensim的实现。至少从视觉上看,gensim的表现更好。
我运行了以下代码以训练gensim模型,下面的代码用于tensorflow模型。我的问题如下:
- 我的Doc2Vec tf实现是否正确?基本上,它是否应该将单词向量和文档向量连接起来以预测特定上下文中的中间词?
- gensim中的
window=5
参数是否意味着我在使用两个相邻的单词来预测中间一个?还是一侧有5个单词?事实上,有很多文档长度小于10。 - 为什么Gensim表现更好?我的模型与他们的实现有何不同?
- 考虑到这实际上是一个矩阵分解问题,为什么TF模型会得到答案?由于它是一个秩缺乏的问题,因此存在无限个解。<-最后一个问题只是一个额外的奖励。
Gensim
model = Doc2Vec(dm=1, dm_concat=1, size=100, window=5, negative=10, hs=0, min_count=2, workers=cores)
model.build_vocab(corpus)
epochs = 100
for i in range(epochs):
model.train(corpus)
TF
batch_size = 512
embedding_size = 100 # Dimension of the embedding vector.
num_sampled = 10 # Number of negative examples to sample.
graph = tf.Graph()
with graph.as_default(), tf.device('/cpu:0'):
# Input data.
train_word_dataset = tf.placeholder(tf.int32, shape=[batch_size])
train_doc_dataset = tf.placeholder(tf.int32, shape=[batch_size/context_window])
train_labels = tf.placeholder(tf.int32, shape=[batch_size/context_window, 1])
# The variables
word_embeddings = tf.Variable(tf.random_uniform([vocabulary_size,embedding_size],-1.0,1.0))
doc_embeddings = tf.Variable(tf.random_uniform([len_docs,embedding_size],-1.0,1.0))
softmax_weights = tf.Variable(tf.truncated_normal([vocabulary_size, (context_window+1)*embedding_size],
stddev=1.0 / np.sqrt(embedding_size)))
softmax_biases = tf.Variable(tf.zeros([vocabulary_size]))
###########################
# Model.
###########################
# Look up embeddings for inputs and stack words side by side
embed_words = tf.reshape(tf.nn.embedding_lookup(word_embeddings, train_word_dataset),
shape=[int(batch_size/context_window),-1])
embed_docs = tf.nn.embedding_lookup(doc_embeddings, train_doc_dataset)
embed = tf.concat(1,[embed_words, embed_docs])
# Compute the softmax loss, using a sample of the negative labels each time.
loss = tf.reduce_mean(tf.nn.sampled_softmax_loss(softmax_weights, softmax_biases, embed,
train_labels, num_sampled, vocabulary_size))
# Optimizer.
optimizer = tf.train.AdagradOptimizer(1.0).minimize(loss)
更新:
请查看Jupyter笔记本此处(我在这里运行测试了两个模型)。在这个初步分析中,似乎gensim模型的表现更好。
dm_concat
模式会导致模型更大、训练速度更慢,可能需要比常用的 PV-DBOW 或 PV-DM-with-context-window-averaging 更多的数据(或训练次数)。我最初添加dm_concat
模式到 gensim 中,是为了尝试紧密复现使用该模式的“段落向量”论文结果。(我无法做到;也没有其他人尝试过。)我个人没有发现任何数据集/评估,其中dm_concat
值得额外的努力 - 但也许它们存在于真正大的文档语料库中。 - gojomo