(pytorch-深度学习系列)CNN中的池化层-学习笔记
CNN中的池化層
首先,池化(pooling)層的提出是為了緩解卷積層對位置的過度敏感性。
什么意思?
比如在圖像邊緣檢測問題中,實際圖像里,我們的目標物體不會總出現在固定位置,即使我們連續拍攝同一個物體也極有可能出現像素位置上的偏移。這會導致同一個邊緣對應的輸出可能出現在卷積輸出的邊緣的不同位置,從而對模式識別造成影響。
與卷積層類似,池化層每次也是對輸入數據的一個固定窗口內的元素計算輸出
但是池化層不同于卷積層,它不考慮輸入與核的互相關性,池化層直接計算池化窗口內數據的最大值或平均值,這分別對應與最大池化與平均池化。
對于二維最大池化,池化窗口從輸入數組的最左上方開始,按從左往右、從上往下的順序,依次在輸入數組上滑動。當池化窗口滑動到某一位置時,窗口中的輸入子數組的最大值即輸出數組中相應位置的元素。
[012345678]?[2?2最大池化層]=[4578]\begin{bmatrix} 0&1&2 \\ 3&4&5 \\ 6&7&8 \end{bmatrix} * \begin{bmatrix} 2*2 \\ 最大池化層 \end{bmatrix} = \begin{bmatrix} 4&5 \\ 7&8 \end{bmatrix} ???036?147?258?????[2?2最大池化層?]=[47?58?]
由:
max?(0,1,3,4)=4,max?(1,2,4,5)=5,max?(3,4,6,7)=7,max?(4,5,7,8)=8.\max(0,1,3,4)=4,\\ \max(1,2,4,5)=5,\\ \max(3,4,6,7)=7,\\ \max(4,5,7,8)=8. max(0,1,3,4)=4,max(1,2,4,5)=5,max(3,4,6,7)=7,max(4,5,7,8)=8.
·
構造一個實現最大池化和平均池化的層:
對于物體邊緣檢測的例子:
檢測圖像中物體的邊緣,即找到像素變化的位置。首先我們構造一張6×86×8的圖像(即高和寬分別為6像素和8像素的圖像)。它中間4列為黑(0),其余為白(1)。
然后我們構造一個高和寬分別為1和2的卷積核K。當它與輸入做互相關運算時,如果橫向相鄰元素相同,輸出為0;否則輸出為非0。
K = torch.tensor([[1, -1]])下面將輸入X和我們設計的卷積核K做互相關運算??梢钥闯?#xff0c;我們將從白到黑的邊緣和從黑到白的邊緣分別檢測成了1和-1。其余部分的輸出全是0。
def corr2d(X, K): h, w = K.shapeY = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i: i + h, j: j + w] * K).sum()return Y Y = corr2d(X, K) print(Y) tensor([[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.],[ 0., 1., 0., 0., 0., -1., 0.]])現在我們將卷積層的輸出作為2×2平均池化層的輸入。設該卷積層輸入是X、池化層輸出為Y。
無論是X[i, j]和X[i, j+1]值不同,還是X[i, j+1]和X[i, j+2]不同,池化層輸出均有Y[i, j]不等于0。也就是說,使用2×2平均池化層時,只要卷積層識別的模式在高和寬上移動不超過一個元素,我們依然可以將它檢測出來。
池化層的填充和步幅:
同卷積層一樣,池化層也可以在輸入的高和寬兩側的填充并調整窗口的移動步幅來改變輸出形狀。
先構造一個形狀為(1, 1, 4, 4)的輸入數據,前兩個維度分別是批量和通道。
X = torch.arange(16, dtype=torch.float).view((1, 1, 4, 4)) print(X) tensor([[[[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.],[12., 13., 14., 15.]]]])默認情況下,MaxPool2d實例里步幅和池化窗口形狀相同。下面使用形狀為(3, 3)的池化窗口,默認獲得形狀為(3, 3)的步幅。
pool2d = nn.MaxPool2d(3) pool2d(X)輸出為:
[0123456789101112131415]?[3?3最大池化層]=[10]\begin{bmatrix} 0&1&2&3 \\ 4&5&6&7 \\ 8&9&10&11 \\ 12&13&14&15 \end{bmatrix} * \begin{bmatrix} 3*3 \\ 最大池化層 \end{bmatrix} = \begin{bmatrix} 10 \end{bmatrix} ?????04812?15913?261014?371115???????[3?3最大池化層?]=[10?]
至于輸出為什么是[10],根據之前的blog中講過的卷積層的輸入輸出公式:
output=?(nh?kh+ph+sh)/sh?×?(nw?kw+pw+sw)/sw?=?(4?3+0×2+3)/3?×?(4?3+0×2+3)/3?=1×1output = \lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor= \\ \lfloor(4-3+0\times2+3)/3\rfloor \times \lfloor(4-3+0\times2+3)/3\rfloor = 1 \times 1 output=?(nh??kh?+ph?+sh?)/sh??×?(nw??kw?+pw?+sw?)/sw??=?(4?3+0×2+3)/3?×?(4?3+0×2+3)/3?=1×1
得出輸出維度為(1*1)
如果手動指定步幅和填充:
pool2d = nn.MaxPool2d(3, padding=1, stride=2) pool2d(X)output=?(nh?kh+ph+sh)/sh?×?(nw?kw+pw+sw)/sw?=?(4?3+1×2+2)/2?×?(4?3+1×2+2)/2?=2×2output = \lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor= \\ \lfloor(4-3+1\times2+2)/2\rfloor \times \lfloor(4-3+1\times2+2)/2\rfloor = 2 \times 2 output=?(nh??kh?+ph?+sh?)/sh??×?(nw??kw?+pw?+sw?)/sw??=?(4?3+1×2+2)/2?×?(4?3+1×2+2)/2?=2×2
tensor([[[[ 5., 7.],[13., 15.]]]])指定非正矩形的窗口:
pool2d = nn.MaxPool2d((2, 4), padding=(1, 2), stride=(2, 3)) pool2d(X)output=?(nh?kh+ph+sh)/sh?×?(nw?kw+pw+sw)/sw?=?(4?2+1×2+2)/2?×?(4?4+2×2+3)/3?=3×2output = \lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor= \\ \lfloor(4-2+1\times2+2)/2\rfloor \times \lfloor(4-4+2\times2+3)/3\rfloor = 3 \times 2 output=?(nh??kh?+ph?+sh?)/sh??×?(nw??kw?+pw?+sw?)/sw??=?(4?2+1×2+2)/2?×?(4?4+2×2+3)/3?=3×2
輸出為:
[000000000001230000456700008910110000121314150000000000]?[2?4最大池化層]=[139111315]\begin{bmatrix} 0&0&0&0&0&0&0&0\\ 0&0&0&1&2&3&0&0 \\ 0&0&4&5&6&7&0&0 \\ 0&0&8&9&10&11&0&0 \\ 0&0&12&13&14&15&0&0\\ 0&0&0&0&0&0&0&0 \end{bmatrix} * \begin{bmatrix} 2*4 \\ 最大池化層 \end{bmatrix} = \begin{bmatrix} 1&3\\ 9&11\\ 13&15\\ \end{bmatrix} ?????????000000?000000?0048120?0159130?02610140?03711150?000000?000000???????????[2?4最大池化層?]=???1913?31115????
池化層中的多通道
在處理多通道輸入數據時,池化層對每個輸入通道分別池化,而不是像卷積層那樣將各通道的輸入按通道相加。這意味著池化層的輸出通道數與輸入通道數相等。
例如:
X = torch.cat((X, X + 1), dim=1) print(X)輸出:
tensor([[[[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.],[12., 13., 14., 15.]],[[ 1., 2., 3., 4.],[ 5., 6., 7., 8.],[ 9., 10., 11., 12.],[13., 14., 15., 16.]]]]) pool2d = nn.MaxPool2d(3, padding=1, stride=2) pool2d(X)輸出通道數仍然是2
tensor([[[[ 5., 7.],[13., 15.]],[[ 6., 8.],[14., 16.]]]])總結
以上是生活随笔為你收集整理的(pytorch-深度学习系列)CNN中的池化层-学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (pytorch-深度学习)深度循环神经
- 下一篇: java应用开发_开发简单的Java应用