簡體   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