在本节中我们介绍池化(pooling)层,它的提出是为了缓解卷积层对位置的过度敏感性。
二维最大池化层与平均池化层
同卷积层一样,池化层每次对输入数据的一个固定形状窗口(又称池化窗口)中的元素计算输出。不同于卷积层里计算输入和核的互相关性,池化层直接计算池化窗口内元素的最大值或者平均值。该运算也分别叫做最大池化或平均池化。在二维最大池化中,池化窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。当池化窗口滑动到某一位置时,窗口中的输入子数组的最大值即输出数组中相应位置的元素。
注意一下,要对tensor进行取均值操作的话,那么tensor必须是float型
代码:
import torchfrom torch import nndef pool2d(x, pool_size, mode="max"):x = x.float()p_h, p_w = pool_sizey = torch.zeros(x.shape[0] - p_h + 1, x.shape[1] - p_w + 1)for i in range(0, y.shape[0]):for j in range(0, y.shape[1]):if mode == "max":y[i][j] = x[i:i + p_h, j:j + p_w].max()if mode == "mean":y[i][j] = x[i:i + p_h, j:j + p_w].mean()return yif __name__ == '__main__':X = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]])print(pool2d(X, (2, 2)))print(pool2d(X, (2, 2), "mean"))结果:tensor([[4., 5.],[7., 8.]])tensor([[2., 3.],[5., 6.]])
填充与步幅
nn中的MaxPool2d即二维最大池化层可以进行方便的操作。MaxPool2d的构造函数可以支持指定步幅和填充。默认情况下,padding为0,步幅与池化窗口形状相同。
做一个实验:
if __name__ == '__main__':X = torch.arange(16, dtype=torch.float).view((1, 1, 4, 4))pool2dx = nn.MaxPool2d(3)print(pool2dx(X))pool2dx = nn.MaxPool2d(3, stride=1)print(pool2dx(X))结果:tensor([[[[10.]]]])tensor([[[[10., 11.],[14., 15.]]]])
也可以指定非正方形的池化窗口:
pool2dx = nn.MaxPool2d((2, 4), padding=(1, 2), stride=(2, 3))print(pool2dx(X))结果:tensor([[[[ 1., 3.],[ 9., 11.],[13., 15.]]]])
多通道
在处理多通道输入数据时,池化层对每个输入通道分别池化,而不是像卷积层那样将各通道的输入按通道相加。这意味着池化层的输出通道数与输入通道数相等。
