我想使用python提高卷积的性能,并希望获得一些关于如何最好地提高性能的见解。
我目前正在使用scipy执行卷积,使用的代码有点像下面的代码片段:
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倍。
发布于 2010-02-05 12:42:24
scipy中用于做2d卷积的代码有点凌乱和未优化。如果您想了解scipy的低级功能,请参阅http://svn.scipy.org/svn/scipy/trunk/scipy/signal/firfilter.c。
如果您所需要的只是使用像您所展示的那样的小的、恒定的内核进行处理,那么这样的函数可能会起作用:
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算术例程。根据我的测量,它比convolve2d函数快1000多倍。
发布于 2010-02-04 15:37:02
对于特定的示例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
并且第一个是可分解的-它可以通过对每行进行卷积(1111),然后对每列进行卷积来进行卷积。然后减去原始数据的9倍。这可能会更快,也可能不会更快,这取决于scipy程序员是否足够智能地自动执行此操作。(我已经有一段时间没有签到了。)
您可能想要做更多有趣的卷积,其中因子分解可能是可能的,也可能是不可能的。
发布于 2010-02-06 02:30:04
在将C与ctype结合使用之前,我建议在C中运行一个独立的卷积,看看限制在哪里。
CUDA、cython、scipy.weave也是如此……
增加了7feb: convolve33 8位数据与裁剪需要大约20个时钟周期的每个点,2个时钟周期每个内存访问,在我的mac g4与gcc 4.2的PCC.你的里程数会有所不同。
以下是一些微妙之处:
但是,如果你的C代码就地运行更新,那只是内存的一半,但是算法不同。
顺便说一句,谷歌theano卷积=>“一个卷积运算,应该模仿scipy.signal.convolve2d,但在开发中更快!”
https://stackoverflow.com/questions/2196693
复制相似问题