我正在尝试比较我的Doc2Vec(通过tf)和gensims实现的实现.从视觉上看,gensim的表现更好.
我运行以下代码来训练gensim模型和下面的那个用于tensorflow模型.我的问题如下:
我的Doc2Vec实现是否正确.基本上它应该是连接单词向量和文档向量来预测某个上下文中的中间单词吗?
window=5
gensim中的参数是否意味着我在两边使用两个词来预测中间的一个?或者两边都是5.事情是有相当多的文件小于长度10.
关于为什么Gensim表现更好的任何见解?我的模型与他们如何实现它有什么不同吗?
考虑到这实际上是一个矩阵分解问题,为什么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)
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模型仍然表现得更好.
老问题,但答案对未来的访客有用.所以这是我的一些想法.
实施中存在一些问题tensorflow
:
window
是单边大小,所以window=5
是5*2+1
= 11
单词.
请注意,对于PV-DM版本的doc2vec,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
如上所述是单面尺寸.如果文档大小小于上下文大小,则使用较小的文档大小.
gensim
实施速度更快的原因有很多.首先,gensim
进行了大量优化,所有操作都比天真的python操作更快,尤其是数据I/O. 其次,一些预处理步骤(如min_count
过滤)gensim
会减少数据集大小.更重要的是,gensim
使用negative_sampling_loss
速度要快得多sampled_softmax_loss
,我猜这是主要原因.
当有很多东西时,更容易找到一些东西吗?开玩笑;-)
确实,这个非凸优化问题有很多解决方案,所以模型只能找到局部最优.有趣的是,在神经网络中,大多数局部最优都是"足够好".已经观察到随机梯度下降似乎比较大的批量梯度下降找到更好的局部最优值,尽管这仍然是当前研究中的一个例子.