word2vec 实现小结 (Tensorflow)

原文发布在我的个人博客:Word2vec 实现小结(TensorFlow)

实现小结

  • skip-gram 模型使用 tf.nn.nce_loss;cbow 模型使用 tf.nn.sampled_softmax_loss
    • 两种 loss 的量级不同,sampled_softmax_loss 要比 nce_loss 小得多
    • 效果在 text8 上看不出多少区别,cbow 模型要稍好一些
  • 使用 GradientDescentOptimizer 而不是 AdadeltaOptimizer,且学习率设大一点(比如 1.0)
    • AdadeltaOptimizer(1e-3) 时,“nearest top k” 测试几乎不变化,或者说训练太慢了
    • AdadeltaOptimizer(1.0) 时,“nearest top k” 几乎都是高频词,比如 a, the, of, …
    • GradientDescentOptimizer(1e-3) 时,“nearest top k” 的变化也很慢
    • GradientDescentOptimizer(1.0) 是里面效果最好的,“nearest top k” 能看出确实有关

代码地址

[GitHub/imhuay/word2vec]

代码参考自 tensorflow 官方教程,模型基本没变;

主要修改:

  • 添加了 CBOW 模型
  • 调整了代码结构,加强了可读性
  • 重写了 data_helper,详细描述的 word2vec 的输入
  • 用 Bunch 集中了所有参数

数据需要提前下载:test8

Nearest top k 计算方法

# ...
# 先对 embeddings 正则化
self.embeddings = tf.nn.l2_normalize(embeddings, axis=1)
# 获取需要测试的 words 的 embeddings
valid_embeddings = tf.nn.embedding_lookup(self.embeddings, config.valid_words)
self.similarity = tf.matmul(valid_embeddings, tf.transpose(self.embeddings))

# ...

# 获取 Nearest top k
sim = sess.run(model.similarity)
for i in range(config.valid_size):
    valid_word = id2word[valid_data[i]]
    top_k = 10
    nearest = (-sim[i, :]).argsort()[1:top_k + 1]
    log = 'Nearest to %s:' % valid_word
    for k in range(top_k):
        close_word = id2word[nearest[k]]
        log = '%s %s,' % (log, close_word)
    tf.logging.info(log)
展开阅读全文

没有更多推荐了,返回首页