J'essaie de comparer mon implémentation de Doc2Vec (via tf) et l'implémentation de gensims. Il semble au moins visuellement que les gens du monde fonctionnent mieux.
J'ai exécuté le code suivant pour former le modèle gensim et celui ci-dessous pour le modèle tensorflow. Mes questions sont les suivantes:
window=5
paramètre dans gensim signifie que j'utilise deux mots de chaque côté pour prédire celui du milieu? Ou est-ce 5 de chaque côté. Le fait est qu'il y a pas mal de documents qui sont plus petits que la longueur 10.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)
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)
Consultez le cahier jupyter ici (J'ai les deux modèles qui fonctionnent et sont testés ici). Il semble toujours que le modèle gensim fonctionne mieux dans cette analyse initiale.
Vieille question, mais une réponse serait utile pour les futurs visiteurs. Voici donc certaines de mes pensées.
Il y a quelques problèmes dans l'implémentation de tensorflow
:
window
est de la taille d'un côté, donc window=5
serait 5*2+1
= 11
mots.batch_size
serait le nombre de documents. Alors train_Word_dataset
la forme serait batch_size * context_window
, tandis que train_doc_dataset
et train_labels
les formes seraient batch_size
.sampled_softmax_loss
n'est pas negative_sampling_loss
. Ce sont deux approximations différentes de softmax_loss
.Donc, pour les questions énumérées du PO:
doc2vec
in tensorflow
fonctionne et se corrige à sa manière, mais il est différent de l'implémentation gensim
et du papier.window
est de la taille d'un côté comme indiqué ci-dessus. Si la taille du document est inférieure à la taille du contexte, alors le plus petit serait utilisé.gensim
est plus rapide. Premièrement, gensim
a été fortement optimisé, toutes les opérations sont plus rapides que les opérations naïves python, en particulier les E/S de données. Deuxièmement, certaines étapes de prétraitement telles que min_count
le filtrage dans gensim
réduirait la taille de l'ensemble de données. Plus important encore, gensim
utilise negative_sampling_loss
, ce qui est beaucoup plus rapide que sampled_softmax_loss
, Je suppose que c'est la principale raison.