问题场景
已知两组向量为:
现在要计算中每一个向量和中每一个向量的欧式距离。
解决思路一
把中向量使用tf.tile
复制m次,把中向量复制n次。
然后按照向量距离公式就可以得到的距离矩阵了。
缺点:
- 计算量大,复杂度大概是,为向量维度。
-
tf.tile
后要保存两个很大的矩阵,占资源
解决思路二
利用完全平方公式,对于距离矩阵中的元素(表示中第个向量和中的第个向量之间的欧式距离):
其中的矩阵可以由两个向量相乘快速计算。
import tensorflow as tf
def euclidean_dist(x, y):
square_x = tf.reduce_sum(tf.square(x), axis=-1)
square_y = tf.reduce_sum(tf.square(y), axis=-1)
# expand dims for broadcasting
ex = tf.expand_dims(square_x, axis=-1)
ey = tf.expand_dims(square_y, axis=-2)
# XY matrix
xy = tf.einsum('bij,bkj->bik', x, y)
# 如果没有batch_size这个维度,可以写成:
# xy = tf.einsum('ij,kj->ik', x, y)
# compute distance,浮点防溢出
dist = tf.sqrt(ex - 2 * xy + ey + 1e-10)
return dist
计算dist的时候加上了
1e-10
,因为在处导数不存在,需要做平滑。
优点:
- 和中向量的平方不用重复计算,加速运算。
- 矩阵是标量矩阵,节约显存资源,这个有时很重要!
网友评论