【问题标题】:How to perform max pooling operation over 3D convolution array?如何对 3D 卷积数组执行最大池化操作?
【发布时间】:2019-10-11 14:26:51
【问题描述】:

我正在使用 numpy 构建卷积神经网络,但我不确定我对 3D (HxWxD) 输入图像的池化处理是否正确。

例如,我有一个形状为 (12x12x3) 的图像,我将其卷积为 (6x6x3),并且我想执行最大池化以获得 (3x3x3) 图像。为此,我选择了 (2x2) 的过滤器大小和 2 的步幅。

output_size = int((conv.shape[0]-F)/S + 1)
pool = np.zeros((output_size,output_volume,3)) # pool array
for k in range(conv.shape[-1]): # loop over conv depth
    i_stride = 0 
    for i in range(output_size): 
        j_stride = 0
        for j in range(output_size):
            pool[i,j,k] = np.amax(conv[i_stride:i_stride+F,
                                                j_stride:j_stride+F,k],0)
            j_stride+=S 
        i_stride+=S

对于我的卷积数组conv[:,:,0]I obtain the following的第一个通道。 将此与最大池化数组pool[:,:,0]I get 的第一个通道进行比较。乍一看,我可以看出池化操作不正确,conv[0:2,0:2,0](大部分是灰色)绝对不是pool[0,0,0](黑色),你会认为它是灰色阴影之一。所以,我确信这里肯定有问题。我的 for 循环或我正在进行的两个比较都关闭了。

如果有人能帮助我更好地理解对 3 维数组的池化操作,那肯定会有所帮助。

【问题讨论】:

    标签: python arrays tensorflow neural-network conv-neural-network


    【解决方案1】:

    最大池化产生与输入相同的深度。考虑到这一点,我们可以专注于输入转换的单个切片(沿深度)。对于任意索引处的单个切片,您有一个 NxN 维度的简单图像。您定义了过滤器大小 2 和步幅 2。最大池化只不过是迭代输入图像并在当前“子图像”上获得最大值。

    import numpy as np
    
    F = 2
    S = 2
    conv = np.array(
        [
            [
                [[.5, .1], [.1, .0], [.2, .7], [.1, .3], [.0, .1], [.3, .8]],
                [[.0, .9], [.5, .7], [.3, .1], [.9, .2], [.8, .7], [.1, .9]],
                [[.1, .8], [.1, .2], [.6, .2], [.0, .3], [.1, .3], [.0, .8]],
                [[.0, .6], [.6, .4], [.2, .8], [.6, .8], [.9, .1], [.3, .1]],
                [[.3, .9], [.7, .6], [.7, .6], [.5, .4], [.7, .2], [.8, .1]],
                [[.1, .8], [.9, .3], [.2, .7], [.8, .4], [.0, .5], [.8, .0]]
            ],
            [
                [[.1, .2], [.1, .0], [.5, .3], [.0, .4], [.0, .5], [.0, .6]],
                [[.3, .6], [.6, .4], [.1, .2], [.6, .2], [.2, .3], [.2, .4]],
                [[.2, .1], [.4, .2], [.0, .4], [.5, .6], [.7, .6], [.7, .2]],
                [[.0, .7], [.5, .3], [.4, .0], [.4, .6], [.2, .2], [.2, .7]],
                [[.0, .5], [.3, .0], [.3, .8], [.3, .2], [.6, .3], [.5, .2]],
                [[.6, .2], [.2, .5], [.5, .4], [.1, .0], [.2, .6], [.1, .8]]
            ]
        ])
    
    number_of_images, image_height, image_width, image_depth = conv.shape
    output_height = (image_height - F) // S + 1
    output_width = (image_width - F) // S + 1
    
    pool = np.zeros((number_of_images, output_height, output_width, image_depth))
    for k in range(number_of_images):
        for i in range(output_height):
            for j in range(output_width):
                pool[k, i, j, :] = np.max(conv[k, i*S:i*S+F, j*S:j*S+F, :])
    
    print(pool[0, :, :, 0])
    [[0.9 0.9 0.9]
     [0.8 0.8 0.9]
     [0.9 0.8 0.8]]
    print(pool[0, :, :, 1])
    [[0.9 0.9 0.9]
     [0.8 0.8 0.9]
     [0.9 0.8 0.8]]
    print(pool[1, :, :, 0])
    [[0.6 0.6 0.6]
     [0.7 0.6 0.7]
     [0.6 0.8 0.8]]
    print(pool[1, :, :, 1])
    [[0.6 0.6 0.6]
     [0.7 0.6 0.7]
     [0.6 0.8 0.8]]
    

    我不清楚你为什么对池中的单个元素使用最大行的转置。

    【讨论】:

    • 我认为我最初的困惑来自于卷积操作和池化操作的半相似性。对于卷积操作,需要循环深度以更新每个颜色通道的内核。这是我最大的问题所在。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 2017-10-26
    • 2019-12-15
    • 2018-04-30
    相关资源
    最近更新 更多