web-dev-qa-db-ja.com

gensim Doc2Vec vsテンソルフローDoc2Vec

Doc2Vecの実装(tf経由)とgensims実装を比較しようとしています。 gensimのものがより良いパフォーマンスをしていることは、少なくとも視覚的に思われます。

Gensimモデルとその下のテンソルフローモデルをトレーニングするために、次のコードを実行しました。私の質問は次のとおりです。

  1. Doc2Vecの私のtf実装は正しいですか?基本的に、特定のコンテキストで中央の単語を予測するために、単語ベクトルと文書ベクトルを連結することになっていますか?
  2. window=5 gensimのパラメーターは、両側の2つの単語を使用して中央の単語を予測することを意味しますか?または、どちら側も5です。長さ10より小さいドキュメントがかなりあるということです。
  3. Gensimのパフォーマンスが向上した理由についての洞察はありますか?私のモデルは彼らがそれを実装する方法と何か違うのですか?
  4. これは事実上行列因数分解の問題であると考えると、TFモデルはなぜ答えを得ているのでしょうか?これにはランク不足の問題があるため、これには無限の解決策があります。 <-この最後の質問は単なるボーナスです。

ゲンシム

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モデルのパフォーマンスが向上しているように感じます。

45
sachinruk

古い質問ですが、回答は将来の訪問者に役立つでしょう。だからここに私の考えのいくつかがあります。

tensorflowの実装にはいくつかの問題があります。

  • windowは1辺のサイズなので、window=55*2+1 = 11ワードになります。
  • Doc2vecのPV-DMバージョンでは、batch_sizeがドキュメントの数になることに注意してください。したがって、train_Word_dataset図形はbatch_size * context_windowになり、train_doc_datasetおよびtrain_labels図形はbatch_sizeになります。
  • さらに重要なことは、sampled_softmax_lossnegative_sampling_lossではありません。これらは、softmax_lossの2つの異なる近似です。

OPにリストされている質問の場合:

  1. tensorflowdoc2vecのこの実装は、独自の方法で機能し、正しく動作しますが、gensimの実装と論文の両方とは異なります。
  2. windowは、上記の1辺のサイズです。ドキュメントのサイズがコンテキストサイズよりも小さい場合は、小さい方が使用されます。
  3. gensimの実装が速い理由はたくさんあります。最初に、gensimが大幅に最適化され、すべての操作が単純なpython操作、特にデータI/Oよりも高速です。2番目に、gensimでのmin_countフィルタリングなどの前処理ステップがデータセットサイズを縮小します。 、gensimnegative_sampling_lossを使用します。これはsampled_softmax_lossよりもはるかに高速です。これが主な理由だと思います。
  4. それらがたくさんあるときに何かを見つけるのは簡単ですか?冗談だ ;-)
    この非凸最適化問題には多くの解決策があるため、モデルは局所最適を見つけるだけです。興味深いことに、ニューラルネットワークでは、ほとんどのローカル最適値は「十分」です。確率的勾配降下法は、より大きなバッチ勾配降下法よりも優れた局所的最適値を見つけるように見えることが観察されていますが、これは現在の研究ではまだ謎です。
14
THN