Подтвердить что ты не робот

Gensim Doc2Vec vs tensorflow Doc2Vec

Я пытаюсь сравнить мою реализацию реализации Doc2Vec (через tf) и gensims. Кажется, по крайней мере визуально, что gensim работают лучше.

Я проверил следующий код для обучения модели gensim и ниже, приведенной ниже для модели tensorflow. Мои вопросы таковы:

  • Правильно ли реализована моя реализация Doc2Vec. В принципе, предполагается, что он будет конкатенировать векторы слов и вектор документа, чтобы предсказать среднее слово в определенном контексте?
  • Параметр window=5 в gensim означает, что я использую два слова с каждой стороны, чтобы предсказать средний? Или это 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.

4b9b3361

Ответ 1

Старый вопрос, но ответ будет полезен для будущих посетителей. Вот некоторые из моих мыслей.

В реализации tensorflow есть некоторые проблемы:

  • window - размер 1 стороны, поэтому window=5 будет 5*2+1= 11 словами.
  • Обратите внимание, что с версией doc2vec PV-DM, batch_size будет числом документов. Таким образом, форма train_word_dataset будет batch_size * context_window, а фигуры train_doc_dataset и train_labels будут batch_size.
  • Что еще более важно, sampled_softmax_loss не negative_sampling_loss. Это два разных приближения softmax_loss.

Итак, для вопросов, перечисленных в OP:

  • Эта реализация doc2vec в tensorflow работает и исправляется по-своему, но отличается от реализации gensim и бумаги.
  • window - размер 1 стороны, как указано выше. Если размер документа меньше, чем размер контекста, то меньшим будет использование.
  • Существует множество причин, по которым реализация gensim выполняется быстрее. Во-первых, gensim был оптимизирован сильно, все операции выполняются быстрее, чем наивные операции python, особенно данные ввода/вывода. Во-вторых, некоторые этапы предварительной обработки, такие как фильтрация min_count в gensim, уменьшали бы размер набора данных. Что еще более важно, gensim использует negative_sampling_loss, который намного быстрее, чем sampled_softmax_loss. Я полагаю, что это основная причина.
  • Легче ли найти что-то, когда их много? Просто шучу;-)
    Верно, что в этой невыпуклой проблеме оптимизации существует много решений, поэтому модель просто найдет локальный оптимум. Интересно, что в нейронной сети большинство локальных оптимумов "достаточно хороши". Было замечено, что стохастический градиентный спуск, по-видимому, находит лучшие локальные оптимумы, чем больший градиентный спуск партии, хотя это все еще загадка в текущих исследованиях.