我想使用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倍。
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倍以上。