在 TensorFlow Embedding 中有效地找到最接近的词

Posted

技术标签:

【中文标题】在 TensorFlow Embedding 中有效地找到最接近的词【英文标题】:Efficiently Finding Closest Word In TensorFlow Embedding 【发布时间】:2016-09-30 05:53:13 【问题描述】:

最近,我一直在尝试找到最接近嵌入的单词。两种最值得注意的方法是余弦距离或欧几里得距离。

我正在尝试找到如何有效地计算形状为 [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 的强大功能,应该能够并行执行这些批量计算。

谢谢!

【问题讨论】:

【参考方案1】:

余弦相似度公式为:


您的输入是:

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

【讨论】:

正如公式所说,我不知道为什么计算余弦相似度会错过上面的除法运算? 这里没有划分,因为我们之前已经对嵌入进行了归一化。如果AB 已经在等式中归一化,则可以只取点积。 要找到最相似的前k个,您也可以这样做:closest_k_words = tf.nn.top_k(cosine_similarity,k=10)

以上是关于在 TensorFlow Embedding 中有效地找到最接近的词的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow中 tf.nn.embedding_lookup

在 TensorFlow Embedding 中有效地找到最接近的词

embedding based logistic regression-神经网络逻辑回归tensorflow

tensorflow 在加载大型的embedding模型参数时,会遇到cannot be larger than 2GB

TensorFlow实现FM

如何在TensorFlow嵌入层中更改input_length?