【问题标题】:Numpy efficient matrix self-multiplication (gram matrix)Numpy 高效矩阵自乘(gram 矩阵)
【发布时间】:2018-11-16 21:24:23
【问题描述】:

我想在 numpy 中乘以 B = A @ A.T。显然,答案将是一个对称矩阵(即B[i, j] == B[j, i])。

但是,我不清楚如何轻松利用它来将计算时间减少一半(仅计算 B 的下三角形,然后使用它免费获得上三角形)。

有没有办法以最佳方式执行此操作?

【问题讨论】:

  • 在 BLAS 或其他优化库中搜索此类函数,并使用 cython 或其他此类工具将其链接到您的代码。对于现有的numpy 函数来说,它太专业了。
  • @hpaulj。但也许不是为了 scipy?
  • 其实 numpy 为你做的,见this 帖子。
  • @PaulPanzer,你是怎么找到的!想想我对这个话题发表了评论,但不记得了 :( 内存一定会消失。dot 正在检测特殊情况并使用不同的BLAS 调用。
  • @hpaulj 想想我对这个话题发表了评论,却不记得了是的,记忆是一件有趣的事情。我,实际上确实记得,因为我当时觉得它很迷人。

标签: python numpy matrix-multiplication


【解决方案1】:

正如@PaulPanzer 的链接中所述,dot 可以检测到这种情况。这是时间证明:

In [355]: A = np.random.rand(1000,1000)
In [356]: timeit A.dot(A.T)
57.4 ms ± 960 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [357]: B = A.T.copy()
In [358]: timeit A.dot(B)
98.6 ms ± 805 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Numpy dot too clever about symmetric multiplications

【讨论】:

  • 使用A = np.random.rand(1000,3); B = A.T.copy()。我得到:%timeit A.dot(B) : 1000 loops, best of 3: 1.37 ms per loop%timeit A.dot(A.T) : 100 loops, best of 3: 2.2 ms per loop。你能重现吗?如果是这样,您知道为什么在这种小号的情况下转置版本会变慢吗?科尔斯? syrk 的速度慢吗?
【解决方案2】:

您可以随时使用sklearns's pairwise_distances

用法:

from sklearn.metrics.pairwise import pairwise_distances
gram = pairwise_distance(x, metric=metric)

metric 是一个可调用的或定义其实现的指标之一的字符串(上面链接中的完整列表)


但是,我前段时间为自己写了这篇文章,所以我可以分享我所做的:

import numpy as np

def computeGram(elements, dist):
    n    = len(elements)
    gram = np.zeros([n, n])
    for i in range(n):
        for j in range(i + 1):
            gram[i, j] = dist(elements[i], elements[j])

    upTriIdxs       = np.triu_indices(n)
    gram[upTriIdxs] = gram.T[upTriIdxs]

    return gram

dist 是可调用的,在您的情况下为 np.inner

【讨论】:

  • 在我的示例测试中,这些计算比 x.dot(x) 慢 20 倍。
  • @hpaulj 是的,dot() 有点过头了,我写这个是为了处理更复杂的指标
猜你喜欢
  • 2013-10-21
  • 1970-01-01
  • 2017-07-20
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-11
相关资源
最近更新 更多