有没有一种简单的方法可以在TensorFlow中计算欧几里得距离矩阵?

问题描述

给定Gram矩阵或坐标,是否有一种有效的方法来计算TensorFlow中的欧几里得距离矩阵?

欧几里得距离矩阵是一个n×n矩阵,其项由每对点(x,y,z)之间的平方距离给出。克矩阵只是内部乘积的矩阵。因此,如果X是一个3×n矩阵,其列为点,则Gram矩阵由X ^ T @ X给出。有一个简单的公式可以将Gram矩阵转换为距离平方矩阵。

换句话说,是否有一种简单的方法可以在TensorFlow(尤其是v1)中编写以下numpy / scipy函数?如果是这样,哪个会更有效?

# Compute Euclidean distance matrix from Gram matrix
def euclidean_dist_from_gram(gram):
    temp = np.tile(np.diag(gram),(nodes,1))
    return temp + temp.T - 2*gram
# Compute Euclidean distance matrix from coordinates
def euclidean_dist_from_pts(xyz):
    return spt.distance.squareform(spt.distance.pdist(xyz.T,'sqeuclidean'))

编辑:通过首先导入以下依赖项并生成随机数据,可以在numpy和scipy中运行以上两个函数

import scipy.spatial as spt
xyz = np.random.uniform(-20,20,(3,500))
gram = xyz.T@xyz

解决方法

弄清楚了,所以我想我会针对自己的问题发布答案。从Gram矩阵计算欧几里得距离矩阵最简单,因此这里是TensorFlow实现(假设3 x n坐标矩阵xyz)。我没有意识到的是,我必须使用tf.expand_dims才能使用tf.tile,然后它与numpy实现相匹配。

gram = tf.linalg.matmul(tf.transpose(xyz),xyz)
g = tf.tile(tf.expand_dims(tf.linalg.diag_part(gram),0),tf.constant([n,1]))
euclidean_dist = g + tf.transpose(g) - 2*gram