gpt4 book ai didi

python - theano 张量的 pdist

转载 作者:太空狗 更新时间:2023-10-29 22:13:13 27 4
gpt4 key购买 nike

我有一个 theano 符号矩阵

x = T.fmatrix('input')

x 稍后将由 n 个暗淡的 d 向量填充(在训练时)。

我想要 theano 等同于 pdist(scipy.spatial.distance.pdistpdist),类似于

D = theano.pdist( x )

我怎样才能做到这一点?

x 上直接调用 scipy.spatial.distance.pdist 不起作用,因为 x 在这个阶段只是象征性的...

更新:我非常希望能够模仿 pdist“紧凑”行为:也就是说,只计算 n 的 ~1/2 xn 个距离矩阵的条目。

最佳答案

scipy 中的

pdist 是不同函数的集合——不存在一个 Theano 等价于所有函数的集合。然而,每个特定的距离,作为一个封闭形式的数学表达式,都可以直接写在 Theano 中然后编译。

以minkowski p范数距离为例(复制+粘贴):

import theano
import theano.tensor as T
X = T.fmatrix('X')
Y = T.fmatrix('Y')
P = T.scalar('P')
translation_vectors = X.reshape((X.shape[0], 1, -1)) - Y.reshape((1, Y.shape[0], -1))
minkowski_distances = (abs(translation_vectors) ** P).sum(2) ** (1. / P)
f_minkowski = theano.function([X, Y, P], minkowski_distances)

注意abs调用内置的__abs__,所以abs也是一个theano函数。我们现在可以将其与 pdist 进行比较:

import numpy as np
from scipy.spatial.distance import pdist

rng = np.random.RandomState(42)
d = 20 # dimension
nX = 10
nY = 30
x = rng.randn(nX, d).astype(np.float32)
y = rng.randn(nY, d).astype(np.float32)

ps = [1., 3., 2.]

for p in ps:
d_theano = f_minkowski(x, x, p)[np.triu_indices(nX, 1)]
d_scipy = pdist(x, p=p, metric='minkowski')
print "Testing p=%1.2f, discrepancy %1.3e" % (p, np.sqrt(((d_theano - d_scipy) ** 2).sum()))

这产生

Testing p=1.00, discrepancy 1.322e-06
Testing p=3.00, discrepancy 4.277e-07
Testing p=2.00, discrepancy 4.789e-07

如您所见,对应关系就在那里,但是函数 f_minkowski 稍微更通用一些,因为它比较两个可能不同的数组的行。如果两次相同的数组作为输入传递,f_minkowski 返回一个矩阵,而 pdist 返回一个没有冗余的列表。如果需要这种行为,它也可以完全动态地实现,但我将在这里坚持一般情况。

但是应该注意一种特殊化的可能性:在 p=2 的情况下,通过二项式公式计算变得更简单,这可以用来节省宝贵的内存空间:而一般 Minkowski 距离,如上实现,创建一个 3D 数组(由于避免了循环和累积求和),这是禁止的,取决于维度 d(和 nX, nY), 对于 p=2 我们可以这样写

squared_euclidean_distances = (X ** 2).sum(1).reshape((X.shape[0], 1)) + (Y ** 2).sum(1).reshape((1, Y.shape[0])) - 2 * X.dot(Y.T)
f_euclidean = theano.function([X, Y], T.sqrt(squared_euclidean_distances))

它只使用 O(nX * nY) 空间而不是 O(nX * nY * d) 我们检查对应关系,这次是针对一般问题:

d_eucl = f_euclidean(x, y)
d_minkowski2 = f_minkowski(x, y, 2.)
print "Comparing f_minkowski, p=2 and f_euclidean: l2-discrepancy %1.3e" % ((d_eucl - d_minkowski2) ** 2).sum()

屈服

Comparing f_minkowski, p=2 and f_euclidean: l2-discrepancy 1.464e-11

关于python - theano 张量的 pdist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25886374/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com