在TensorFlow嵌入中有效地找到最近的单词

时间:2016-06-01 03:26:13

标签: distance tensorflow embedding

最近,我一直试图找到最接近嵌入的词。这两种最显着的方法是通过余弦距离或欧几里德距离。

我正试图找到如何有效地计算形状张量的余弦距离[batch_size x embedding_size]

一种方法是解压缩张量并计算余弦距离

  #embedding is shape [vocab_size x embedding size]
  array_list = tf.unpack(batch_array)
  word_class_list = tf.unpack(embedding)
  index_list_of_closest_word = []
  for eacharray in array_list:
    list_of_distances = []
    for eachwordclass in word_class_list:
      list_of_distances.append(cosine_distance(eacharray, eachwordclass))
    index_list_of_closest_word.append(tf.argmax(tf.pack(list_of_distances)))

然而,这种方法非常低效。是否有更有效的方式来做到这一点?我知道word2vec做得非常快,并且具有gpu功能的te​​nsorflow应该能够并行执行这些批量计算。

谢谢!

1 个答案:

答案 0 :(得分:31)

余弦相似度公式是:
cosine similarity

您拥有的输入是:

  • embedding:形状[vocab_size, embedding_size]
  • 的嵌入矩阵
  • batch_array:一组嵌入,您想要找到最接近的单词,形状为[batch_size, embedding_size]
embedding = tf.placeholder(tf.float32, [vocab_size, embedding_size])
batch_array = tf.placeholder(tf.float32, [batch_size, embedding_size])

要计算余弦相似度,您可以先对两个输入进行L2归一化:
(您可能希望存储标准嵌入,因为您将重复使用它)

normed_embedding = tf.nn.l2_normalize(embedding, dim=1)
normed_array = tf.nn.l2_normalize(batch_array, dim=1)

然后你必须计算所有单词(总共vocab_size)与批次中的所有数组batch_size}的点积总计):

cosine_similarity = tf.matmul(normed_array, tf.transpose(normed_embedding, [1, 0]))

您最终可以计算批次中每个元素的argmax:

closest_words = tf.argmax(cosine_similarity, 1)  # shape [batch_size], type int64