在numpy
中,计算 的最有效方法是什么x.T * x
,x
大型 (200,000 x 1000) 密集float32
矩阵.T
在哪里,转置算子在哪里?
为免生疑问,结果为 1000 x 1000。
编辑:在我原来的问题中,我说这np.dot(x.T, x)
需要几个小时。事实证明,我NaNs
偷偷溜进了矩阵,出于某种原因,这完全扼杀了性能np.dot
(任何关于为什么的见解?)现在已经解决了,但最初的问题仍然存在。
在numpy
中,计算 的最有效方法是什么x.T * x
,x
大型 (200,000 x 1000) 密集float32
矩阵.T
在哪里,转置算子在哪里?
为免生疑问,结果为 1000 x 1000。
编辑:在我原来的问题中,我说这np.dot(x.T, x)
需要几个小时。事实证明,我NaNs
偷偷溜进了矩阵,出于某种原因,这完全扼杀了性能np.dot
(任何关于为什么的见解?)现在已经解决了,但最初的问题仍然存在。
这可能不是您正在寻找的答案,但显着加快速度的一种方法是使用 gpu 而不是您的 cpu。如果你身边有一块功能相当强大的显卡,即使你的系统经过很好的调整,它也会在任何一天都超过你的 CPU。
为了与 numpy 完美集成,您可以使用 theano(如果您的显卡是由 nvidia 制造的)。以下代码中的计算会在几秒钟内为我运行(虽然我有一个非常强大的显卡):
$ THEANO_FLAGS=device=gpu0 python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import theano
Using gpu device 0: GeForce GTX 480
>>> from theano import tensor as T
>>> import numpy
>>> x = numpy.ones((200000, 1000), dtype=numpy.float32)
>>> m = T.matrix()
>>> mTm = T.dot(m.T, m)
>>> f = theano.function([m], mTm)
>>> f(x)
array([[ 200000., 200000., 200000., ..., 200000., 200000., 200000.],
[ 200000., 200000., 200000., ..., 200000., 200000., 200000.],
[ 200000., 200000., 200000., ..., 200000., 200000., 200000.],
...,
[ 200000., 200000., 200000., ..., 200000., 200000., 200000.],
[ 200000., 200000., 200000., ..., 200000., 200000., 200000.],
[ 200000., 200000., 200000., ..., 200000., 200000., 200000.]], dtype=float32)
>>> r = f(x)
>>> r.shape
(1000, 1000)
我本来打算通过比较来了解需要多长时间>>> numpy.dot(x.T, x)
,但我感到无聊......
您也可以尝试 PyCuda 或 PyOpenCL(如果您没有 nvidia 显卡),虽然我不知道他们的 numpy 支持是否同样简单。
首先,确保您使用优化的 blas/lapack,这会产生巨大的差异(最多一个数量级)。例如,如果您使用线程 ATLAS,它将相对有效地使用您的所有内核(不过,您需要使用最近的 ATLAS,而编译 ATLAS 是一个 PITA)。
至于为什么 Nan 会减慢所有完成的速度:这几乎是不可避免的,NaN 处理比 CPU 级别的“正常”浮点数要慢得多:http ://www.cygnus-software.com/papers/x86andinfinity.html 。这取决于 CPU 型号、您使用的指令集类型,当然还有您使用的算法/实现。
嗯,x 大约是 800 Mb,假设它需要相同的结果,你确定你有足够的物理内存并且它没有交换吗?
除此之外,numpy 应该使用 BLAS 函数,即使 numpy 使用的默认库可能相对较慢,它应该可以正常工作。
编辑
import numpy as npy
import time
def mm_timing():
print " n Gflops/s"
print "==============="
m = 1000
n = 200000
a = npy.random.rand(n, m)
flops = (2 * float(n) - 1) * float(m)**2
t1 = time.time()
c = npy.dot(a.T, a)
t2 = time.time()
perf = flops / (t2 - t1) / 1.e9
print "%4i" % n + " " + "%6.3f" % perf
mm_timing()