为什么矢量化Pinv慢于未矢量化?

时间:2019-03-10 03:38:05

标签: python numpy vectorization

我有十个6000 x 784矩阵。如果我先运行np.cov,然后对它们分别进行pinv,则总时间为:

%timeit for n in range(10): pinv(np.cov(A,rowvar = False))
1.64 s ± 78.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

如果我改为循环np.cov并计算3D堆栈的pinv,则会得到:

%timeit for n in range(10): dd[n] = np.cov(A,rowvar = False)
485 ms ± 18 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit pinv(dd)
4.59 s ± 369 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

为什么3D上的pinv这么慢?

要计算堆栈的np.cov和相应的pinv,我该怎么办?

1 个答案:

答案 0 :(得分:1)

这是由于实施。限制步骤是numpy matmul。首先,我认为SVD是限制步骤,但它线性扩展(每次迭代〜130 ms,十个包为1.3 s)。

以下是配置文件的某些部分:

1个电话(您的第一个摘录)

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.131    0.131    0.131    0.131 linalg.py:1299(svd)
    1    0.011    0.011    0.011    0.011 {built-in method numpy.core.multiarray.matmul}
    1    0.003    0.003    0.144    0.144 <ipython-input-76-2a63f1c84429>:1(pinv)

一包10张(第二段)的来电

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    2.952    2.952    2.952    2.952 {built-in method numpy.core.multiarray.matmul}
    1    1.265    1.265    1.265    1.265 linalg.py:1299(svd)
    1    0.026    0.026    4.266    4.266 <ipython-input-76-2a63f1c84429>:1(pinv)

也许是C排序的内部问题(但是最近的numpy版本应该解决这个问题),或者在这种情况下效率低下...尝试使用{{直接更改为BLAS接口3}},但这仅适用于二维矩阵。实际上已经提出了这些问题(matmul较慢)scipy implementation

最重要的是,将其非矢量化,或尝试使用其他实现。有时,矩阵乘法的最快方法是使用eigen函数,但我从未在多维问题中尝试过。