二维最大池化层:
返回窗口中的最大值。
池化层与卷积层类似,都具有填充和步幅;
没有可学习的参数;
在每个输入通道应用池化层以获得相应的输出通道;
输出通道数==输入通道数
## 这里不用池化层做多通道融合的原因,是因为通道融合常常是卷积的任务。
除了最大池化层,还有一个平均池化层最常用。
池化层常常返回窗口的最大值或者平均值;
池化层的主要作用是缓解卷积对位置的敏感性,所以通常被放在卷积层后面。
同样有窗口大小、填充和步幅作为超参数。
Q&A:
额……今天的Q&A我并不觉得学到了什么,不写了。
代码:
import torch from torch import nn from d2l import torch as d2l # 池化层的正向传播 def pool2d(X, pool_size, mode='max'): #输入,窗口大小,模式(最大和平均) p_h, p_w = pool_size Y = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1)) for i in range(Y.shape[0]): for j in range(Y.shape[1]): if mode == 'max': Y[i, j] = X[i: i + p_h, j: j + p_w].max() elif mode == 'avg': Y[i, j] = X[i: i + p_h, j: j + p_w].mean() return Y X=torch.tensor([[0.0,1.0,2.0],[3.0,4.0,5.0],[6.0,7.0,8.0]]) print(pool2d(X,(2,2))) print(pool2d(X,(2,2),'avg')) # 用api实现以下 X=torch.arange(16,dtype=torch.float32).reshape((1,1,4,4)) print(X) pool2d=nn.MaxPool2d(3) # 这里解释一下为什么输出只有1个值,因为nn里的pool默认步幅和kernel_size一样,不信咱们下面重新指定一下步幅padding print(pool2d(X)) pool2d=nn.MaxPool2d(3,stride=1,padding=0) # 这里解释一下为什么输出只有1个值,因为nn里的pool默认步幅和kernel_size一样,不信咱们下面重新指定一下步幅padding print("you see,it has changed to 4 numbers:\n",pool2d(X)) # 类似卷积层,我仍然可以用不正的矩形做池化 pool2d=nn.MaxPool2d((2,3),padding=(1,1),stride=(2,3)) print(pool2d(X)) # 池化层在每个输入通道上做运算 Y=torch.stack((X,X+1),1) X=torch.cat((X,X+1),1) #这里的维度,0/1/2/3维度分别是样本数、通道数、高、宽,因此在这里拼接的是第一个维度,通道数 print(Y,"\n",X) print("可以看到,X和Y差了一个维度,这便是stack和cat的区别。在这里X本身已经是四维,不需要添加新的维度(轴)。stark总是会添加一个新轴,而cat会在原来的轴上做拼接。") pool2d=nn.MaxPool2d((2,3),padding=(1,1),stride=(2,3)) print(pool2d(X))