【问题标题】:Why is vectorized Pinv slower than unvectorized?为什么矢量化 Pinv 比未矢量化慢?
【发布时间】:2019-03-11 22:24:24
【问题描述】:

我有十个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?

【问题讨论】:

    标签: python numpy vectorization


    【解决方案1】:

    这是由于实施。限制步骤是 numpy matmul。首先,我认为 SVD 是限制步骤,但这会线性扩展(每次迭代约 130 毫秒,十个一组为 1.3 秒)。

    以下是分析的一些部分:

    1 次通话(您的第一个 sn-p)

       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 个中的 1 个(您的第二个 sn-p)

       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 版本应该处理它),或者在这种情况下效率低下...尝试直接使用 @987654321 直接更改为 BLAS 接口@,但这仅适用于二维矩阵。这些问题(matmul 很慢)实际上已经提出elsewhere

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

    【讨论】:

      猜你喜欢
      • 2014-08-10
      • 1970-01-01
      • 2010-11-28
      • 2013-05-29
      • 2014-07-19
      • 2017-01-04
      • 1970-01-01
      • 2016-05-07
      相关资源
      最近更新 更多