在 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
【讨论】:
正如公式所说,我不知道为什么计算余弦相似度会错过上面的除法运算? 这里没有划分,因为我们之前已经对嵌入进行了归一化。如果A
和B
已经在等式中归一化,则可以只取点积。
要找到最相似的前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