不同维度的python卷积

Vit*_*ang 4 python numpy scipy deep-learning

我正在尝试用Python实现卷积神经网络.
但是,当我使用signal.convolve或np.convolve时,它不能对X,Y进行卷积(X是3d,Y是2d).X正在训练小型车.Y是过滤器.我不想为每个训练向量做循环,如:

for i in xrange(X.shape[2]):
    result = signal.convolve(X[:,:,i], Y, 'valid')
    ....
Run Code Online (Sandbox Code Playgroud)

那么,有什么功能可以用来有效地进行卷积吗?

Ima*_*ngo 5

Scipy实现了标准的N维卷积,因此要卷积的矩阵和内核都是N维的.

快速解决方法是添加额外的维度,Y使其Y为3维:

result = signal.convolve(X, Y[..., None], 'valid')
Run Code Online (Sandbox Code Playgroud)

我在这里假设最后一个轴对应于您的示例[width, height, image_idx](或[height, width, image_idx])中的图像索引.如果是相反的方式并且图像在第一轴上被索引(因为它在C排序数组中更常见),您应该替换Y[..., None]Y[None, ...].

该行将Y[..., None]添加一个额外的轴Y,使其成为三维[kernel_width, kernel_height, 1],从而将其转换为有效的三维卷积内核.

注意:这假设您的所有输入小批量都具有相同的width x height,这是CNN的标准.


编辑:@Divakar建议的一些时间.

测试框架设置如下:

def test(S, N, K):
    """ S: image size, N: num images, K: kernel size"""
    a = np.random.randn(S, S, N)
    b = np.random.randn(K, K)
    valid = [slice(K//2, -K//2+1), slice(K//2, -K//2+1)]

    %timeit signal.convolve(a, b[..., None], 'valid')
    %timeit signal.fftconvolve(a, b[..., None], 'valid')
    %timeit ndimage.convolve(a, b[..., None])[valid]
Run Code Online (Sandbox Code Playgroud)

查找不同配置的波纹管测试:

  • 图像尺寸不同S:

    >>> test(100, 50, 11) # 100x100 images
    1 loop, best of 3: 909 ms per loop
    10 loops, best of 3: 116 ms per loop
    10 loops, best of 3: 54.9 ms per loop
    
    >>> test(1000, 50, 11) # 1000x1000 images
    1 loop, best of 3: 1min 51s per loop
    1 loop, best of 3: 16.5 s per loop
    1 loop, best of 3: 5.66 s per loop
    
    Run Code Online (Sandbox Code Playgroud)
  • 不同数量的图像N:

    >>> test(100, 5, 11) # 5 images
    10 loops, best of 3: 90.7 ms per loop
    10 loops, best of 3: 26.7 ms per loop
    100 loops, best of 3: 5.7 ms per loop
    
    >>> test(100, 500, 11) # 500 images
    1 loop, best of 3: 9.75 s per loop
    1 loop, best of 3: 888 ms per loop
    1 loop, best of 3: 727 ms per loop
    
    Run Code Online (Sandbox Code Playgroud)
  • 改变内核大小K:

    >>> test(100, 50, 5) # 5x5 kernels
    1 loop, best of 3: 217 ms per loop
    10 loops, best of 3: 100 ms per loop
    100 loops, best of 3: 11.4 ms per loop
    
    >>> test(100, 50, 31) # 31x31 kernels
    1 loop, best of 3: 4.39 s per loop
    1 loop, best of 3: 220 ms per loop
    1 loop, best of 3: 560 ms per loop
    
    Run Code Online (Sandbox Code Playgroud)

因此,简而言之,ndimage.convolve总是更快,除非内核大小非常大(如上K = 31一次测试).