PyTorch中池化層的padding和ceil_mode參數設置

在池化操作的接口中,padding和ceil_mode這兩個參數會影響到輸出特徵圖的大小。padding即對特徵圖大小進行擴充的像素數量;ceil_mode指明,當剩餘的像素不足濾波器大小,是否仍對這些像素進行運算。
對於池化操作來說,當stride爲1時,希望輸出與輸入保持不變;當stride爲2時,希望輸出特徵圖的寬高均爲輸入的一半。下面以avg_pool2d講解如何儘量簡單達到上述目的:

import torch
import torch.nn.functional as f

y = torch.tensor([[[[1,5,4,9]]]])

print(f.avg_pool2d(y, (1, 3), stride=2, padding=0, ceil_mode=False)) # tensor([[[[3]]]])
print(f.avg_pool2d(y, (1, 3), stride=2, padding=0, ceil_mode=True))  # tensor([[[[3, 6]]]])
print(f.avg_pool2d(y, (1, 3), stride=2, padding=(0, 1), ceil_mode=False)) # tensor([[[[2, 6]]]])
print(f.avg_pool2d(y, (1, 3), stride=2, padding=(0, 1), ceil_mode=True))  # tensor([[[[2, 6, 4]]]])

print(f.avg_pool2d(y, (1, 3), stride=1, padding=0, ceil_mode=False)) # tensor([[[[3, 6]]]])
print(f.avg_pool2d(y, (1, 3), stride=1, padding=0, ceil_mode=True))  # tensor([[[[3, 6]]]])
print(f.avg_pool2d(y, (1, 3), stride=1, padding=(0, 1), ceil_mode=False)) # tensor([[[[2, 3, 6, 4]]]])
print(f.avg_pool2d(y, (1, 3), stride=1, padding=(0, 1), ceil_mode=True))  # tensor([[[[2, 3, 6, 4]]]])

stride=2時:
若padding爲0,則padding後仍爲[1, 5, 4, 9]。第一次運算對[1, 5, 4]進行,得到3(向下取整);由於stride=2,則 第二次運算只剩[4, 9]這一個像素,小於kernel_size,此時,若ceil_mode=False,則直接不對剩餘的部分運算,因此輸出大小爲1;若ceil_mode=True,則對剩餘部分繼續計算,取[4, 9]的均值6(向下取整),因此輸出大小爲2。若padding=1,PyTorch的默認padding值爲0,則該維度上padding後爲[0, 1, 5, 4, 9, 0],ceil_mode=False時,輸出爲[2, 6];ceil_mode=True時,輸出爲[2, 6, 4]。

stride=1時:
若padding=0,則輸出爲[3, 6];若padding=1,輸入爲[0, 1, 5, 4, 9, 0],輸出爲[2, 3, 6, 4]。stride=1時,ceil_mode的值不起作用,始終爲False。

總結:

stride=2,padding=1或ceil__mode=True;stride=1時,必須有padding=1,ceil_mode的設置不起作用。

推廣:

ceil_mode始終保持PyTorch的默認值False,且padding始終爲kernel_size // 2。

PyTorch中池化操作還有一個與padding有關的參數count_include_pad,默認爲True。意義是在運算(比如計算平均值或最大值)時,始終將padding的值納入計算。

import torch
import torch.nn.functional as f
y = torch.tensor([[[[1,5,4,9]]]])

print(f.avg_pool2d(y, (1, 3), stride=2, padding=(0, 1), ceil_mode=False)) # tensor([[[[2, 6]]]])
print(f.avg_pool2d(y, (1, 3), stride=2, padding=(0, 1), count_include_pad=False, ceil_mode=False)) # tensor([[[[3, 6]]]])

print(f.avg_pool2d(y, (1, 3), stride=1, padding=(0, 1), ceil_mode=False)) # tensor([[[[2, 3, 6, 4]]]])
print(f.avg_pool2d(y, (1, 3), stride=1, padding=(0, 1), count_include_pad=False, ceil_mode=False)) # tensor([[[[3, 3, 6, 4]]]])

如在上述例子中,stride=2,padding=1,ceil_mode=False時,若將count_include_pad設爲False,則結果由[2, 6]變爲[3, 6]。一般的,進行平均池化時,將該參數設爲False;進行最大池化時,可保持默認不變,爲True。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章