在 TensorFlow 嵌入中高效地找到最接近的词

Efficiently Finding Closest Word In 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 做这件事相当快,而 tensorflow 凭借 gpu 的强大功能,应该能够并行执行这些批处理计算。

谢谢!

余弦相似度公式为:


您的输入是:

  • 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)与批处理[=42]中的所有数组的点积=](共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