【问题标题】:Pairwise Cosine Similarity using TensorFlow使用 TensorFlow 的成对余弦相似度
【发布时间】:2018-01-28 10:34:15
【问题描述】:

我们如何使用 TensorFlow 有效地计算矩阵中的成对余弦距离?给定一个MxN 矩阵,结果应该是一个MxM 矩阵,其中[i][j] 位置的元素是输入矩阵中第i 行和第j 行/向量之间的余弦距离。

这可以通过 Scikit-Learn 轻松完成,如下所示:

from sklearn.metrics.pairwise import pairwise_distances

pairwise_distances(input_matrix, metric='cosine')

TensorFlow中是否有等效的方法?

【问题讨论】:

    标签: matrix tensorflow


    【解决方案1】:

    这里有一个获得单个余弦距离的答案:https://stackoverflow.com/a/46057597/288875。这是基于tf.losses.cosine_distance

    这是一个对矩阵执行此操作的解决方案:

    import tensorflow as tf
    import numpy as np
    
    with tf.Session() as sess:
    
        M = 3
    
        # input
        input = tf.placeholder(tf.float32, shape = (M, M))
    
        # normalize each row
        normalized = tf.nn.l2_normalize(input, dim = 1)
    
        # multiply row i with row j using transpose
        # element wise product
        prod = tf.matmul(normalized, normalized,
                         adjoint_b = True # transpose second matrix
                         )
    
        dist = 1 - prod
    
        input_matrix = np.array(
            [[ 1, 1, 1 ],
             [ 0, 1, 1 ],
             [ 0, 0, 1 ],
             ],
            dtype = 'float32')
    
        print "input_matrix:"
        print input_matrix
    
        from sklearn.metrics.pairwise import pairwise_distances
        print "sklearn:"
        print pairwise_distances(input_matrix, metric='cosine')
    
        print "tensorflow:"
        print sess.run(dist, feed_dict = { input : input_matrix })
    

    这给了我:

    input_matrix:
    [[ 1.  1.  1.]
     [ 0.  1.  1.]
     [ 0.  0.  1.]]
    sklearn:
    [[ 0.          0.18350345  0.42264974]
     [ 0.18350345  0.          0.29289323]
     [ 0.42264974  0.29289323  0.        ]]
    tensorflow:
    [[  5.96046448e-08   1.83503449e-01   4.22649741e-01]
     [  1.83503449e-01   5.96046448e-08   2.92893231e-01]
     [  4.22649741e-01   2.92893231e-01   0.00000000e+00]]
    

    请注意,此解决方案可能不是最佳解决方案,因为它会计算(对称)结果矩阵的所有条目,即几乎进行了两次计算。对于小矩阵,这可能不是问题,对于大矩阵,循环组合可能会更快。

    另请注意,这没有小批量维度,因此仅适用于单个矩阵。

    【讨论】:

      【解决方案2】:

      优雅的解决方案(输出与 scikit-learn pairwise_distances 函数的输出相同):

      def compute_cosine_distances(a, b):
          # x shape is n_a * dim
          # y shape is n_b * dim
          # results shape is n_a * n_b
      
          normalize_a = tf.nn.l2_normalize(a,1)        
          normalize_b = tf.nn.l2_normalize(b,1)
          distance = 1 - tf.matmul(normalize_a, normalize_b, transpose_b=True)
          return distance
      

      测试

      input_matrix = np.array([[1, 1, 1],
                               [0, 1, 1],
                               [0, 0, 1]], dtype = 'float32')
      
      compute_cosine_distances(input_matrix, input_matrix)
      

      输出:

      <tf.Tensor: id=442, shape=(3, 3), dtype=float32, numpy=
      array([[5.9604645e-08, 1.8350345e-01, 4.2264974e-01],
             [1.8350345e-01, 5.9604645e-08, 2.9289323e-01],
             [4.2264974e-01, 2.9289323e-01, 0.0000000e+00]], dtype=float32)>
      

      【讨论】:

      • 我认为您应该将变量相似性重命名为距离
      猜你喜欢
      • 2022-07-07
      • 2020-08-12
      • 2016-10-17
      • 2011-01-01
      • 2013-02-12
      • 2016-08-14
      • 2017-12-12
      • 1970-01-01
      相关资源
      最近更新 更多