如何在 CNN 中实现过滤器步幅(编码方式)?

How are filter strides implemented (coding wise) in CNNs?

我正在尝试弄清楚 CNN 中的步幅是如何编码的,但我似乎无法有效地实现它——脚本需要很长时间才能完成计算,否则我 运行 会出错

from PIL import Image

img = Image.open('C:\sample_pic.jpeg').convert("RGB") #800 x600 dimensions
pixels =np.array(img)  # However PIL inverts height and width so #600 X800
print(pixels.shape)    # (600L, 800L, 3L)

理想情况下,我不想展平图像,但我不知道如何在正确使用步幅为 1 时将 600 x 800 x 3 图像与 2x3x3 过滤器相乘。所以我试图展平阵列,因为我觉得这样会更容易。

   flat = pixels.flatten()
   filter1= np.array([1,1,0],) 
   pixels2 = np.array([])

for i in range(0, len(flat),2):
   pixels2 =np.append(pixels2,np.sum((flat[i:i+3] * filter1)))

所以我尝试将每个像素的 RGB 值与过滤器相乘,然后求和然后滑动 2。我正在尝试可视化 CNN 的第一个卷积层。 在这里,我无法弄清楚如何告诉循环仅在 i+3 元素可用时才迭代。我认为这就是我收到以下错误的原因

ValueError: operands could not be broadcast together with shapes (2,) (3,)

还有一种计算速度更快的方法可以将滤镜值与图像的像素值相乘,因为我的笔记本电脑需要很长时间才能计算出来。 (Intel i-7 3610QM @2.30 Geforce 650M GT 2GB)

编辑:为清楚起见进行编辑。如果可以将 600x800x3 数组与 2x3x3 的过滤器相乘,那么我想使用 1 的步幅。 我希望过滤器看起来像这样,

[[[1,1,0]
[1,1,0]
[1,1,0]]


[[1,1,0]
[1,1,0]
[1,1,0]]]

2 行,每行 3 列,每列有三个值 [1,1,0]

原图有600行(高)800列(宽)3个值(RGB值)

对于任何混淆,我们深表歉意。

我正在使用的图像:

不是最佳解决方案,因为它会在 stack1 中产生一个副本。但是:

from scipy.signal import convolve2d

res = np.stack([
    convolve2d(pixels[...,i], filter[...,i], mode='valid')
    for i in range(3)
], axis=-1)

或者消除幻数3:

res = np.stack([
    convolve2d(plane, filterp, mode='valid')
    for plane, filterp in zip(np.rollaxis(pixels, -1), np.rollaxis(filter, -1))
], axis=-1)

1 - 实际上,因为 convolve2d 没有 out 参数,所以别无选择

这是一种使用 Scipy's 2D convolution 并结合步幅 -

的方法
from scipy.signal import convolve2d as conv2

def filter_images3D(img3D, filter3D, stride=1):
    M1,N1 = img3D.shape[:2]
    M2,N2 = filter3D.shape[:2]
    O1,O2 = (M1-M2+stride)//stride, (N1-N2+stride)//stride

    n = img3D.shape[-1]
    out = np.empty((O1,O2,n))
    for i in range(n):
        out[...,i] = conv2(img3D[...,i],filter3D[...,i],'valid')[::stride,::stride]
    return out