python - 为什么矢量化 Pinv 比未矢量化慢?
问题描述
我有十个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?
解决方案
这是由于实施。限制步骤是 numpy matmul
。首先,我认为 SVD 是限制步骤,但这会线性扩展(每次迭代约 130 毫秒,十个一组为 1.3 秒)。
以下是分析的一些部分:
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 个的 1 个电话(您的第二个片段)
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 版本应该处理它),或者在这种情况下效率低下......尝试使用scipy 实现直接更改为 BLAS 接口,但这仅适用于二维矩阵。这些问题(matmul 很慢)实际上已在其他地方提出。
底线,做非矢量化或尝试使用其他实现。有时矩阵乘法的最快方法是使用eigen
函数,但我从未在多维问题中尝试过。
推荐阅读
- javascript - (添加 SQL)Sequelize hasMany 与选项的关联
- delphi - Delphi - 使用 Streams 将记录保存到文件
- c - 为什么我的代码没有从文件中读取正确的整数?
- wordpress - 饼干横幅,需要我吗?
- python - python的os模块关于os.linesep
- apache-spark - 在 Spark 中使用 Kinesis 生产者库
- html - 在 HTML5 中注入自定义元素,然后使用 XPath 检索其值返回空白
- html - 放大 (ctrl+, ctrl-) 时,我的导航栏无法使用?
- django - 如何在 django-tables2 中修复“需要 tableXXX 的参数数据”?
- python - 在python中编写模式“a”