发布时间:2023-03-04 14:00
设任意二维数组 X 的 i 行 j 列的元素为 X[i, j] 。如果我们构造的卷积核输出 Y[i, j]=1 ,那么说明输⼊入中 X[i, j] 和 X[i, j+1] 数值不一样。这可能意味着物体边缘通过这两个元素之间。但实际图像⾥里,我们感兴趣的物体不会总出现在固定位置:即使我们连续拍摄同⼀个物体也极有可能出现像素位置上的偏移。这会导致同⼀个边缘对应的输出可能出现在卷积输出 Y 中的不同位置,进而对后面的模式识别造成不便。
为了缓解卷积层对位置的过度敏感性
同卷积层⼀样,池化层每次对输入数据的⼀个固定形状窗口(又称池化窗口)中的元素计算输出。不不同于卷积层里计算输入和核的互相关性,池化层直接计算池化窗口内元素的最大值或者平均值。该运算也分别叫做最大池化或平均池化。在二维最大池化中,池化窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。当池化窗口滑动到某一位置时,窗口中的输入子数组的最大值即输出数组中相应位置的元素。
阴影部分为第一个输出元素及其计算所使⽤用的输入元素。输出数组的高和宽分别为2,其中的4个元素由取最大值运算 得出:
二维平均池化的工作原理与二维最大池化类似,但将最大运算符替换成平均运算符。池化窗口形状为pq的池化层称为pq池化层,其中的池化运算叫作p*q池化。
回到物体边缘检测的例子。现在我们将卷积层的输出作为最大池化的输入。设该卷积层输入是 X 、池化层输出为 Y 。⽆无论是 X[i, j] 和 X[i, j+1] 值不同,还是 X[i,j+1] 和 X[i, j+2] 不同,池化层输出均有 Y[i, j]=1 。也就是说,使用最大池化层时,只要卷积层识别的模式在高和宽上移动不超过一个元素,我们依然可以将它检测出来。
def pool2d(X, pool_size, mode='max'): # 默认模式参数为最大池化 'max'
X = X.float()
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 来验证二维最大池化层的输出。
X = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
pool2d(X, (2, 2)) # 默认‘max’模式 最大池化
输出:
tensor([[4., 5.],
[7., 8.]])
平均池化:
pool2d(X, (2, 2), 'avg')
输出:
tensor([[2., 3.],
[5., 6.]])