在张量流中实现余弦相似度

时间:2019-05-08 19:27:29

标签: tensorflow cosine-similarity

我的问题是关于下面的方程enter image description here

上面单个向量的等式。但是,如果我有一批矢量,例如我的X和Y的尺寸为(None,32),那么就会出现问题。

还请记住,在编码环境中,批处理中的一个示例已经处于转置形状。我的问题是当我们需要在[None,32]上进行转置时,代码将不会接受和转置None尺寸。因此,我可以通过以下方式解决它:

df %>% 
   separate(Interaction, c('var1', 'var2'), sep = '[|]')

这是来自以下方面:

def Cosine_similarity(X, Y, feature_dim):

  L = tf.compat.v1.initializers.glorot_normal()(shape=[feature_dim, feature_dim])

  out1 = tf.matmul(X, L)
  out2 = tf.matmul(Y, L)

  out_numerator = tf.reduce_sum(tf.multiply(out1, out2), axis = 1)

  out3 = tf.reduce_sum(tf.multiply(out1, out1), axis = 1)
  out3 = tf.sqrt(out3)

  out4 = tf.reduce_sum(tf.multiply(out2, out2), axis = 1)
  out4 = tf.sqrt(out4)

  out_denominator = tf.multiply(out3, out4)

  final_out = tf.divide(out_numerator, out_denominator)

return final_out

所以我只想知道这种实现是否正确?或者,如果我缺少某些东西,您可以纠正我

1 个答案:

答案 0 :(得分:0)

不确定我了解您对(无)维度的关注。

如果我正确理解了两个形状相同的矩阵XY[batch, target_dim])之间的余弦相似度,只是X * Y^T的矩阵乘以L2归一化。请注意,X是您的out1,而Y是您的out2

def Cosine_similarity(x, y, A):
  """Pair-wise Cosine similarity.

  First `x` and `y` are transformed by A.
  `X = xA^T` with shape [batch, target_dim],
  `Y = yA^T` with shape [batch, target_dim].

  Args:
    x: shaped [batch, feature_dim].
    y: shaped [batch, feature_dim].
    A: shaped [targte_dim, feature_dim]. Transformation matrix to project
      from `feature_dim` to `target_dim`.

  Returns:
    A cosine similarity matrix shaped [batch, batch]. The entry
    at (i, j) is the cosine similarity value between vector `X[i, :]` and
    `Y[j, :]` where `X`, `Y` are the transformed `x` and y` by `A` 
    respectively. In the other word, entry at (i, j) is the pair-wise 
    cosine similarity value between the i-th example of `x` and the j-th 
    example of `y`.
  """

  x = tf.matmul(x, A, transpose_b=True)
  y = tf.matmul(y, A, transpose_b=True)
  x_norm = tf.nn.l2_normalize(x, axis=-1)
  y_norm = tf.nn.l2_normalize(y, axis=-1)
  y_norm_trans = tf.transpose(y_norm, [1, 0])
  sim = tf.matmul(x_norm, y_norm_trans)
  return sim

import numpy as np

feature_dim = 8
target_dim = 4
batch_size = 2
x = tf.placeholder(tf.float32, shape=(None, dim))
y = tf.placeholder(tf.float32, shape=(None, dim))
A = tf.placeholder(tf.float32, shape=(target_dim, feature_dim))

sim = Cosine_similarity(x, y, A)

with tf.Session() as sess:
  x, y, sim = sess.run([x, y, sim], feed_dict={
      x: np.ones((batch_size, feature_dim)), 
      y: np.random.rand(batch_size, feature_dim),
      A: np.random.rand(target_dim, feature_dim)})
  print 'x=\n', x
  print 'y=\n', y
  print 'sim=\n', sim

结果:

x=
[[ 1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.]]
y=
[[ 0.01471654  0.76577073  0.97747731  0.06429122  0.91344446  0.47987637
   0.09899797  0.773938  ]
 [ 0.8555786   0.43403915  0.92445409  0.03393625  0.30154493  0.60895061
   0.1233703   0.58597666]]
sim=
[[ 0.95917791  0.98181278]
 [ 0.95917791  0.98181278]]