Реализация косинусного подобия в тензорном потоке - PullRequest
0 голосов
/ 08 мая 2019

Мой вопрос для приведенного ниже уравнения enter image description here

Уравнение выше одиночного вектора. Но если у меня есть несколько векторов, например, мои X и Y имеют размерность (Нет, 32), тогда возникнет некоторая проблема.

Также помните, что в среде программирования один пример внутри пакета уже имеет форму транспонирования. Моя проблема в том, что когда нам нужно сделать транспонирование в [Нет, 32], код не примет и не транспонирует для измерения без None. Поэтому я решаю это следующим образом:

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

И это исходит из следующего:

<XA.YA> = (XA)^T (YA)

        = tf.reduce_sum(tf.multiply((X A) , (Y A)), axis = 1)

Так что я просто хочу знать, правильна ли эта реализация? Или вы можете исправить меня, если я что-то упустил

1 Ответ

0 голосов
/ 09 мая 2019

Не уверен, что я понимаю вашу заботу о (ни одном) измерении.

Если я правильно понимаю, косинусное сходство между двумя матрицами одинаковой формы X и Y ([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]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...