如何在 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值)
对于任何混淆,我们深表歉意。
我正在使用的图像:
不是最佳解决方案,因为它会在 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
参数,所以别无选择
这是一种使用 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
我正在尝试弄清楚 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值)
对于任何混淆,我们深表歉意。
我正在使用的图像:
不是最佳解决方案,因为它会在 1 中产生一个副本。但是:stack
、
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