在numpy
中,计算x.T * x
的最有效方法是什么,其中x
是一个大的(200,000 x 1000)密集float32
矩阵和.T
是转置算子吗?
为避免疑义,结果为1000 x 1000。
修改:在我原来的问题中,我说np.dot(x.T, x)
需要几个小时。事实证明我有一些NaNs
潜入矩阵,并且由于某种原因,这完全扼杀了np.dot
的表现(任何见解为什么?)现在已经解决,但原始问题代表。
答案 0 :(得分:10)
这可能不是您正在寻找的答案,但加速它的一种方法是使用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支持是否直截了当。
答案 1 :(得分:5)
首先,确保使用优化的blas / lapack,这可以产生巨大的差异(最多一个数量级)。例如,如果您使用线程ATLAS,它将相对有效地使用所有核心(您需要使用最近的ATLAS,并且编译ATLAS是PITA)。
至于为什么Nan减慢了所做的一切:这几乎是不可避免的,NaN处理比CPU级别的“正常”浮动慢得多:http://www.cygnus-software.com/papers/x86andinfinity.html。这取决于CPU模型,您使用的是哪种指令集,当然还有您正在使用的算法/实现。
答案 2 :(得分:2)
嗯,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()