如何提高Numpy性能?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (23)

我希望使用python来改进卷积的性能,并希望能够了解如何最好地改进性能。

我目前正在使用cip执行卷积,使用的代码有点像下面的代码片段:

import numpy
import scipy
import scipy.signal
import timeit

a=numpy.array ( [ range(1000000) ] )
a.reshape(1000,1000)
filt=numpy.array( [ [ 1, 1, 1 ], [1, -8, 1], [1,1,1] ] )

def convolve():
  global a, filt
  scipy.signal.convolve2d ( a, filt, mode="same" )

t=timeit.Timer("convolve()", "from __main__ import convolve")
print "%.2f sec/pass" % (10 * t.timeit(number=10)/100)

我正在处理图像数据,使用灰度(整数值在0到255之间),目前我每卷积大约得到四分之一秒。我的想法是做以下工作之一:

使用corepy,最好使用一些优化,用ICC&ikml重新编译numpy。使用python-Cuda。

我想知道是否有人对这些方法有任何经验(什么样的收益是典型的,是否值得花时间),或者是否有人知道有一个更好的库来执行Numpy的卷积。通过使用Numpy重写C中的python循环,可以加快大约10倍的速度。

提问于
用户回答回答于

用于进行2d卷积的cipy中的代码有点混乱,而且没有优化。如果您只想使用一个小的、常量内核来处理,就像您展示的那样,这样的函数可能会工作:

def specialconvolve(a):
    # sorry, you must pad the input yourself
    rowconvol = a[1:-1,:] + a[:-2,:] + a[2:,:]
    colconvol = rowconvol[:,1:-1] + rowconvol[:,:-2] + rowconvol[:,2:] - 9*a[1:-1,1:-1]
    return colconvol

该函数利用了上面所建议的DarenW内核的可分性,并利用了更优化的numpy算术例程。根据我的测量,它比卷积2d函数快1000多倍。

用户回答回答于

对于3x3内核,我会注意到

1  1  1
1 -8  1
1  1  1

  1  1  1     0  0  0
= 1  1  1  +  0 -9  0
  1  1  1     0  0  0

其中第一个是可分解的,它可以通过每一行的卷积(11,1)来卷积,然后再对每一列进行卷积。然后减去9倍的原始数据。这可能会更快,也可能不会更快。

扫码关注云+社区