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

时间:2017-01-19 09:03:51

标签: python-2.7 numpy python-imaging-library conv-neural-network

我试图弄清楚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,)

此外,还有一种计算速度更快的方法可将滤镜值与图像的像素值相乘,因为它需要花费很长时间才能在笔记本电脑上进行计算。 (英特尔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值)。

对不起有任何困惑。

图片我正在使用:

enter image description here

2 个答案:

答案 0 :(得分:1)

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

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参数,所以没有其他选择

答案 1 :(得分:1)

这是一种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