池化层
卷积对位置敏感,可以检测垂直边缘。需要有一定程度的平移不变性,而在平时图片的拍摄,会因为图片的照明,物体位置,比例,外观等因素会导致对位置过度敏感。池化层的出现解决了这一问题。
池化层的作用:使得模型对图片的位置信息没那么敏感;降低对空间降采样表示的敏感性。
为什么先池化层再应用中出现概率不高呢?因为现在对数据处理之前做扰动操作,淡化了池化层的作用。
二维池化层
- 返回滑动窗口的最大值
池化的效果:模糊效果,在临近的列可以取得相同的特征(池化层对于像素偏移的容忍性)
超参数
同卷积,有填充,步幅的超参数;多个通道的池化会不会将最后的结果相加,故输入通道和输出通道的个数相同。没有可学习的参数,即没有卷积核超参数的学习。
池化层的分类
- 最大池化层:每个窗口中最强的模式信号
- 平均池化层:将最大池化层中的“最大”操作替换为“平均”
代码实现
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]])
pool2d(X, (2, 2)) pool2d(X, (2, 2), 'avg')
--------------------------------------------------------------
tensor([[4., 5.], tensor([[2., 3.],
[7., 8.]]) [5., 6.]])
填充和步幅
同卷积操作中的填充和步幅
# 定义一个矩阵
X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
-------------------------------------------------------------------
tensor([[[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]]])
# 池化操作,3*3的池化操作,不够3*3不继续进行运算
pool2d = nn.MaxPool2d(3)
pool2d(X)
-------------------------------------------------------------------
tensor([[[[10.]]]])
# 核大小为2*3,第一个位置都是行操作,第二个位置都是列操作
pool2d = nn.MaxPool2d((2, 3), stride=(2, 3), padding=(0, 1))
pool2d(X)
---------------------------------------------------------------
tensor([[[[ 5., 7.],
[13., 15.]]]])
多个通道
池化处理多通道输入数据时,池化层在每个输入通道上单独运算,不像卷积层在通道上对输入进行汇总。
# 输入数据变成 1*2*4*4
X = torch.cat((X, X + 1), 1)
--------------------------------------------
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)
---------------------------------------------
tensor([[[[ 5., 7.],
[13., 15.]],
[[ 6., 8.],
[14., 16.]]]])
发现pool2d和maxpool2d的区别:
MaxPool2d 的行为
- 不满足核大小时:在
MaxPool2d
中,如果输入特征图的某个区域(例如最后一部分)小于指定的核大小,不会进行池化运算。这意味着最后的一部分数据如果不满足核的大小,将被忽略,直接跳过计算。
Pool2d 的行为
- 始终进行运算:相比之下,
pool2d
(或在 PyTorch 中的F.avg_pool2d
和F.max_pool2d
)会处理整个输入,即使最后一部分数据不满足核的大小。在这种情况下,pool2d
会对不足的部分执行计算,而不会忽略它们。
总结
-
池化层返回窗口中最大或平均值
-
缓解卷积层对位置的敏感性
-
同样 有窗口大小、填充和步幅作为超参数
-
池化的本质是增强泛化 避免过拟合
池化层窗口的重叠与没有重叠的差别没有很大差别。