Python 2.7 如何在CNN中实现过滤步幅(编码方面)?

Python 2.7 如何在CNN中实现过滤步幅(编码方面)?,python-2.7,numpy,python-imaging-library,conv-neural-network,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)

我正在试图弄清楚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:操作数无法与形状(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值)

对不起,有什么困惑

我正在使用的图像:

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

或消除幻数
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-事实上,由于Convalve2D没有
out
参数,因此没有替代方案不是最佳解决方案,因为它会在
堆栈中产生一个副本。但是:

或消除幻数
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-事实上,因为convalve2D没有
out
参数,所以没有其他选择

这里有一个包含步幅的方法-

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
这是一个包含步幅的方法-

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


输出阵列的形状是什么?您好,理想情况下,我想要一个输出,它可以被重塑为图片尺寸的自然尺寸。因此,如果可能的话,我希望能够将每个维度的形状调整为350(最小值)。修改您的循环代码,使其与
2x3x3
形状过滤器一起工作,因为这似乎是最终目标?您声明了-
“使用过滤器的每个像素的RGB值,”
。对于多维过滤器,有多种方法来解释过滤操作。因此,一个循环代码将有助于演示您的想法。您是否试图将
(2,2,3)
(600,800,3)
进行卷积?您想对每个颜色平面分别执行此操作,生成
(599,799,3)
输出,还是一起生成
(599,799)
输出?或者你的意思是2步,给
(300,400,3)
或者
(300,400)
?抱歉,给你带来了困惑。当图像未展平时,我希望步幅为1。我想要一个三维的输出。所以我假设(599799,3)将是输出,如果我使用1的步幅和(2,3,3)的过滤器。谢谢。输出阵列的形状是什么?嗨,理想情况下,我想要一个输出,它可以被重塑为图片尺寸的自然尺寸。因此,如果可能的话,我希望能够将每个维度的形状调整为350(最小值)。修改您的循环代码,使其与
2x3x3
形状过滤器一起工作,因为这似乎是最终目标?您声明了-
“使用过滤器的每个像素的RGB值,”
。对于多维过滤器,有多种方法来解释过滤操作。因此,一个循环代码将有助于演示您的想法。您是否试图将
(2,2,3)
(600,800,3)
进行卷积?您想对每个颜色平面分别执行此操作,生成
(599,799,3)
输出,还是一起生成
(599,799)
输出?或者你的意思是2步,给
(300,400,3)
或者
(300,400)
?抱歉,给你带来了困惑。当图像未展平时,我希望步幅为1。我想要一个三维的输出。所以我假设(599799,3)将是输出,如果我使用1的步幅和(2,3,3)的过滤器。谢谢。很遗憾,这不是大步对于卷积的意义。Stride的意思是
conv(img,filter)[::Stride]
,但显然您希望这样做,而不必计算所需的值discarded@Eric是的,早些时候错过了。更新。谢谢。我将首先阅读卷积2D(从未使用过它),然后玩转代码。遗憾的是,这不是STERID对于卷积的含义。Stride的意思是
conv(img,filter)[::Stride]
,但显然您希望这样做,而不必计算所需的值discarded@Eric是的,早些时候错过了。更新。谢谢。我将首先阅读Convalve2D(从未使用过它),然后再玩转代码。谢谢。我不知道卷积的事。这将需要一些时间,因为我将阅读有关first convolve2d的内容,但我将使用您提供的代码,看看是否有任何问题。谢谢。所以我在测试代码时,遇到了几个问题:
回溯(上次调用):文件“C:\Python27\PIL_Image.py”,第38行,在assert res.shape==(599,799,3)AssertionError
中,我认为这与我检查res shape时得到的文件(599798,3)没有多大问题。但是,当我尝试使用im=image.fromarray(res)将其转换回图像格式时,似乎遇到了一个错误,
TypeError:无法处理此数据类型
。有什么线索可以解释为什么我会打赌这个错误吗?@moondra:我把你的过滤器形状误读为(2,2,3),而不是(2,3,3)。是的,这个断言是垃圾。您的问题可能是
res
具有数据类型float