In [165]: # Setup
...: X = np.random.randn(10000, 512)
...: gamma = 0.01
...: var = 5.0
In [166]: %timeit app0(X, gamma, var)
...: %timeit app1(X, gamma, var)
...: %timeit app2(X, gamma, var)
1 loop, best of 3: 1.25 s per loop
1 loop, best of 3: 1.24 s per loop
1 loop, best of 3: 973 ms per loop
In [167]: np.allclose(app0(X, gamma, var), app1(X, gamma, var))
Out[167]: True
In [168]: np.allclose(app0(X, gamma, var), app2(X, gamma, var))
Out[168]: True
你在你的^{} 中做了很多优化。我想再增加一些(主要是微调)。我将以答案帖子中的获胜者为基础,这似乎是基于
numexpr
。调整1
首先,
np.sum(X ** 2, axis = -1)
可以用np.einsum
进行优化。虽然这部分不是最大的开销,但是任何优化都不会有什么坏处。所以,这个总和可以表示为-调整2
其次,我们可以利用Scipy支持的blas函数,如果允许的话,可以使用单精度的dtype来显著提高其性能。因此,} 来计算,就像-
np.dot(X, X.T)
可以用^{在用
gamma
重新排列负号方面,再做一些调整,我们就可以为sgemm
提供更多信息。此外,我们将把gamma
推入alpha
项。调整后的实现
因此,通过这两个优化,我们将拥有
numexpr
方法的另外两个变体(如果我可以这么说的话),如下所示-运行时测试
从你的回复帖子中找到一个基于Numexpr的-
计时和验证-
我将介绍四种不同的方法来计算这样一个内核,然后比较它们的运行时。
使用纯numpy
在这里,我使用的事实是
||x-y||^2 = ||x||^2 + ||y||^2 - 2 * x^T * y
。使用numexpr
^{} 是一个python包,它允许对numpy数组执行高效的并行数组操作。我们可以使用它执行与上面相同的计算:
使用
scipy.spatial.distance.pdist
我们还可以使用^{} 来计算成对平方欧氏距离的非冗余数组,计算该数组上的核,然后将其转换为平方矩阵:
使用
sklearn.metrics.pairwise.rbf_kernel
sklearn
提供直接计算RBF内核的built-in method:运行时比较
我使用25000个512维随机样本在英特尔酷睿i7-7700HQ(4核,2.8ghz)上进行测试和实验。更准确地说:
每个方法运行7次,并报告每次执行时间的平均值和标准偏差。
首先,
scipy.spatial.distance.pdist
是惊人的慢。numexpr
几乎比纯的numpy
方法快3倍,但是这个加速因子将随可用cpu的数量而变化。sklearn.metrics.pairwise.rbf_kernel
不是最快的方法,但只比numexpr
慢一点。相关问题 更多 >
编程相关推荐