繁体   English   中英

如何实现maxpool:在图像或张量上的滑动窗口上取最大值

[英]How to implement maxpool: taking a maximum on sliding window on image or tensor

总之:我在寻找一个简单的numpy (也许oneliner)实施Maxpool -最大的窗口上numpy.narray跨维度窗口的所有位置。

更详细地说:我正在实现一个卷积神经网络(“CNN”),这种网络中的典型层之一是MaxPool层( 在这里查看例子)。 y = MaxPool(x, S)x是输入narrayS是参数,使用伪代码, MaxPool的输出由下MaxPool给出:

     y[b,h,w,c] = max(x[b, s*h + i, s*w + j, c]) over i = 0,..., S-1; j = 0,...,S-1.

也就是说, ynarray ,其中索引b,h,w,c等于沿着输入x的第二维和第三维的大小S x S的窗口所取的最大值,窗口“角”位于索引b,h,w,c

一些额外的细节:网络是使用numpy实现的。 CNN有许多“层”,其中一层的输出是下一层的输入。 层的输入是numpy.narray称为“张量”。 在我的情况下,张量是4维numpy.narray的, x 那就是x.shape是一个元组(B,H,W,C) 在张量处理层之后,每个尺寸的尺寸都会改变,例如,层i= 4的输入可以具有尺寸B = 10, H = 24, W = 24, C = 3 ,而输出,也就是输入到i+1层具有B = 10, H = 12, W = 12, C = 5 如评论中所示,应用MaxPool后的大小为(B, H - S + 1, W - S + 1, C)

具体来说:如果我使用

import numpy as np

y = np.amax(x, axis = (1,2)) 

其中x.shape(2,3,3,4)这将给我我想要的但是对于一个退化的情况,我最大化的窗口是3 x 3的大小,第二和第三维的大小x ,这不是我想要的。

这是一个使用np.lib.stride_tricks.as_strided创建滑动窗口的解决方案,形成一个6D阵列的形状: (B,H-S+1,W-S+1,S,S,C) ,然后简单地执行最大化第四和第五轴,产生一个形状的输出数组: (B,H-S+1,W-S+1,C) 中间6D阵列将是输入数组的视图,因此不会占用更多的内存。 max的后续操作是减少将有效地利用滑动views

因此,实施将是 -

# Based on http://stackoverflow.com/a/41850409/3293881
def patchify(img, patch_shape):
    a, X, Y, b = img.shape
    x, y = patch_shape
    shape = (a, X - x + 1, Y - y + 1, x, y, b)
    a_str, X_str, Y_str, b_str = img.strides
    strides = (a_str, X_str, Y_str, X_str, Y_str, b_str)
    return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides)

out = patchify(x, (S,S)).max(axis=(3,4))

样品运行 -

In [224]: x = np.random.randint(0,9,(10,24,24,3))

In [225]: S = 5

In [226]: np.may_share_memory(patchify(x, (S,S)), x)
Out[226]: True

In [227]: patchify(x, (S,S)).shape
Out[227]: (10, 20, 20, 5, 5, 3)

In [228]: patchify(x, (S,S)).max(axis=(3,4)).shape
Out[228]: (10, 20, 20, 3)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM