最近,我一直试图找到最接近嵌入的词。这两种最显着的方法是通过余弦距离或欧几里德距离。
我正试图找到如何有效地计算形状张量的余弦距离[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功能的tensorflow应该能够并行执行这些批量计算。
谢谢!
答案 0 :(得分:31)
您拥有的输入是:
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