20 卷積層里的填充和步幅【動(dòng)手學(xué)深度學(xué)習(xí)v2】

使用更大的卷積核可以更快地減小輸出大小,在層數(shù)較大時(shí),圖像會(huì)變得過(guò)小。

解決方案1:填充

不填充的話邊緣上用到的信息次數(shù)沒(méi)有中間的多,填充后,可以增多邊緣信息的讀取次數(shù)。
下圖展示了常用的填充列數(shù)和行數(shù),基本思路是保持輸出和輸入數(shù)據(jù)形狀不變。

解決方案2:步幅

步幅對(duì)輸出形狀的影響(調(diào)整步幅通??梢詫?shù)據(jù)成倍縮小)

卷積核大小、數(shù)據(jù)填充量、步幅等都是卷積層的超參數(shù)
總結(jié):

代碼實(shí)現(xiàn)
在所有側(cè)邊填充一個(gè)像素
import torch from torch import nn # 為了方便起見(jiàn),我們定義了一個(gè)計(jì)算卷積層的函數(shù)。 # 此函數(shù)初始化卷積層權(quán)重,并對(duì)輸入和輸出提高和縮減相應(yīng)的維數(shù) def comp_conv2d(conv2d, X): # 這里的(1,1)表示批量大小和通道數(shù)都是1 X = X.reshape((1, 1) + X.shape) #此步是將二維數(shù)據(jù)X(8,8)轉(zhuǎn)化為四維數(shù)據(jù)X(1,1,8,8) Y = conv2d(X) # 省略前兩個(gè)維度:批量大小和通道 return Y.reshape(Y.shape[2:]) # 請(qǐng)注意,這里每邊都填充了1行或1列,因此總共添加了2行或2列 conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1) X = torch.rand(size=(8, 8)) comp_conv2d(conv2d, X).shape
輸出結(jié)果
torch.Size([8, 8])
填充不同的高度和寬度,同時(shí)調(diào)整卷積核大小,使輸入輸出數(shù)據(jù)形狀不變
conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1)) comp_conv2d(conv2d, X).shape
torch.Size([8, 8])
將高度和寬度步幅設(shè)為2(stride控制步幅)
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2) comp_conv2d(conv2d, X).shape
torch.Size([4, 4])
一個(gè)稍微復(fù)雜的例子。
conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4)) comp_conv2d(conv2d, X).shape
torch.Size([2, 2])
補(bǔ)充知識(shí):
填充(上下邊總填充量)一般取核邊長(zhǎng)-1
卷積步幅最好取1,一般取2,在計(jì)算量過(guò)大時(shí)取更大值
卷積核邊長(zhǎng)一般取奇數(shù),因?yàn)閜adding=kernel-1,而padding是分在圖片上下的,kernel為奇數(shù),padding就可以對(duì)半分。
標(biāo)簽: