2017-04-11 2217 views
5

我有兩個歸一化張量,我需要計算這些張量之間的餘弦相似度。我如何用TensorFlow做到這一點?如何計算兩個張量之間的餘弦相似度?

cosine(normalize_a,normalize_b) 

    a = tf.placeholder(tf.float32, shape=[None], name="input_placeholder_a") 
    b = tf.placeholder(tf.float32, shape=[None], name="input_placeholder_b") 
    normalize_a = tf.nn.l2_normalize(a,0)   
    normalize_b = tf.nn.l2_normalize(b,0) 

回答

9

這將做的工作:

a = tf.placeholder(tf.float32, shape=[None], name="input_placeholder_a") 
b = tf.placeholder(tf.float32, shape=[None], name="input_placeholder_b") 
normalize_a = tf.nn.l2_normalize(a,0)   
normalize_b = tf.nn.l2_normalize(b,0) 
cos_similarity=tf.reduce_sum(tf.multiply(normalize_a,normalize_b)) 
sess=tf.Session() 
cos_sim=sess.run(cos_similarity,feed_dict={a:[1,2,3],b:[2,4,6]}) 

這將打印0.99999988

+0

謝謝你很多關於你的答案。餘弦相似性公式是通過首先對輸入進行歸一化來簡化的嗎?你的公式似乎比維基百科的東西少一些https://en.wikipedia.org/wiki/Cosine_similarity – Matias

+3

如果你不會先標準化,那麼在計算內積a * b之後,你必須除以產品a和b的規範。但是,如果您提前正常化,則不需要那樣做。這是因爲normalize_a = a/|| a || (和b類似)。 –

+0

爲什麼不matmul? –

10

時代在變。使用最新的TF API,可以通過調用tf.losses.cosine_distance來計算。

實施例:

import tensorflow as tf 
import numpy as np 


x = tf.constant(np.random.uniform(-1, 1, 10)) 
y = tf.constant(np.random.uniform(-1, 1, 10)) 
s = tf.losses.cosine_distance(tf.nn.l2_normalize(x, 0), tf.nn.l2_normalize(y, 0), dim=0) 
print(tf.Session().run(s)) 

當然,1 - s是餘弦相似性!

+0

爲什麼1-s是餘弦相似? –

+2

因爲''s'''是餘弦距離,而不是相似度。 –

+0

'''1-s'''不需要。該函數稱爲距離,但返回相似性。我想是因爲它在tf.losses。看看代碼,我可能是錯的。第274行。losses = 1 - math_ops.reduce_sum(radial_diffs,axis =(dim,),keep_dims = True)https://github.com/tensorflow/tensorflow/blob/r1.4/tensorflow/python/ops/losses/ losses_impl.py –

0

可以歸你向量或矩陣這樣的:

[batch_size*hidden_num] 
states_norm=tf.nn.l2_normalize(states,dim=1) 
[batch_size * embedding_dims] 
embedding_norm=tf.nn.l2_normalize(embedding,dim=1) 
#assert hidden_num == embbeding_dims 
after mat [batch_size*embedding] 
user_app_scores = tf.matmul(states_norm,embedding_norm,transpose_b=True)