python - gensim Doc2Vec vs tensorflow Doc2Vec

标签 python tensorflow nlp gensim doc2vec

我正在尝试比较我的 Doc2Vec 实现(通过 tf)和 gensims 实现。至少从视觉上看,gensim 的表现更好。

我运行以下代码来训练 gensim 模型和下面的代码来训练 tensorflow 模型。我的问题如下:

  1. 我对 Doc2Vec 的 tf 实现是否正确。基本上它应该是连接词向量和文档向量来预测特定上下文中的中间词吗?
  2. gensim 中的 window=5 参数是否意味着我在两侧使用两个单词来预测中间的单词?还是两边都是5。问题是有不少文件的长度小于 10。
  3. 您对 Gensim 表现更好的原因有何见解?我的模型与他们的实现方式有什么不同吗?
  4. 考虑到这实际上是一个矩阵分解问题,为什么 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 笔记本 here (我有两个模型在这里工作和测试)。感觉 gensim 模型在最初的分析中表现更好。

最佳答案

老问题,但答案对 future 的访问者很有用。所以这是我的一些想法。

tensorflow实现存在一些问题:

  • window 是 1 边大小,因此 window=5 将是 5*2+1 = 11 话。
  • 请注意,对于 PV-DM 版本的 doc2vec,batch_size 将是文档的数量。所以 train_word_dataset 形状将是 batch_size * context_window,而 train_doc_datasettrain_labels 形状将是 batch_size
  • 更重要的是,sampled_softmax_loss 不是 negative_sampling_loss。它们是 softmax_loss 的两种不同近似值。

所以对于 OP 列出的问题:

  1. tensorflow 中的这种 doc2vec 实现以它自己的方式工作和正确,但它不同于 gensim 实现和纸。
  2. window 是如上所述的 1 面大小。如果文档大小小于上下文大小,则使用较小的那个。
  3. gensim 实现速度更快的原因有很多。首先,gensim 进行了大量优化,所有操作都比简单的 python 操作更快,尤其是数据 I/O。其次,一些预处理步骤,例如 gensim 中的 min_count 过滤会减少数据集的大小。更重要的是,gensim使用了negative_sampling_loss,比sampled_softmax_loss快很多,我猜这是主要原因。
  4. 如果有很多东西,是不是更容易找到?开个玩笑;-)
    确实,这个非凸优化问题有很多解决方案,所以模型只会找到一个局部最优值。有趣的是,在神经网络中,大多数局部最优都“足够好”。据观察,随机梯度下降似乎比大批量梯度下降找到更好的局部最优值,尽管这在当前研究中仍然是一个谜。

关于python - gensim Doc2Vec vs tensorflow Doc2Vec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39843584/

相关文章:

python - 在 python 中结束线程的生命?

python - Fedora30 上 libpq.so.5 和 PQencryptPasswordConn 版本 RHPG_10 的问题

python - Python 中的命令输出解析

python - 为什么 tf.Variable 可迭代但不能迭代

python - 如何使用nltk从字符串中提取名称

machine-learning - 用于文档分类的监督潜在狄利克雷分配?

python - 如何快速找到操作 mlab/mayavi 图的语法?

python - 如何使用 Keras 生成器选择batch_size、steps_per_epoch 和 epoch

python - 使用正则化时,手动计算的验证损失与报告的 val_loss 不同

pip - 无法安装文本