The fftconvolve
您正在使用的函数可能来自SciPy http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.fftconvolve.html。如果是这样,请注意它需要 N 维数组。因此,进行卷积的更快方法是生成 3d 内核,该内核对应于在x
and y
维度并进行一维高斯卷积z.
下面是一些代码和计时结果。在我的机器上并使用一些玩具数据,这导致了 10 倍的加速,如您所见:
import numpy as np
from scipy.signal import fftconvolve
from scipy.ndimage.filters import gaussian_filter
# use scipy filtering functions designed to apply kernels to isolate a 1d gaussian kernel
kernel_base = np.ones(shape=(5))
kernel_1d = gaussian_filter(kernel_base, sigma=1, mode='constant')
kernel_1d = kernel_1d / np.sum(kernel_1d)
# make the 3d kernel that does gaussian convolution in z axis only
kernel_3d = np.zeros(shape=(1, 1, 5,))
kernel_3d[0, 0, :] = kernel_1d
# generate random data
data = np.random.random(size=(50, 50, 50))
# define a function for loop based convolution for easy timeit invocation
def convolve_with_loops(data):
nx, ny, nz = data.shape
convolved=np.zeros((nx, ny, nz))
for i in range(0, nx):
for j in range(0, ny):
convolved[i,j,:]= fftconvolve(data[i, j, :], kernel_1d, mode='same')
return convolved
# compute the convolution two diff. ways: with loops (first) or as a 3d convolution (2nd)
convolved = convolve_with_loops(data)
convolved_2 = fftconvolve(data, kernel_3d, mode='same')
# raise an error unless the two computations return equivalent results
assert np.all(np.isclose(convolved, convolved_2))
# time the two routes of the computation
%timeit convolved = convolve_with_loops(data)
%timeit convolved_2 = fftconvolve(data, kernel_3d, mode='same')
timeit
结果:
10 loops, best of 3: 198 ms per loop
100 loops, best of 3: 18.1 ms per loop