深度学习-卷积神经网络CNN-池化层 Pooling

发布于:2025-08-09 ⋅ 阅读:(13) ⋅ 点赞:(0)

池化层是卷积神经网络(Convolutional Neural Network, CNN)中关键的组成部分。它位于卷积层之后,主要目的是对卷积层输出的特征图进行降采样,降低特征图的空间尺寸,同时保留重要的特征信息。通常使用的池化操作有最大池化(Max Pooling)平均池化(Average Pooling)

  1. 最大池化
    1. 原理:在特征图上滑动一个池化窗口,取窗口内的最大值作为池化后的结果。例如,对于一个 4×4 的特征图,使用 2×2 的池化窗口,步长为 2,经过最大池化后会得到一个 2×2 的特征图。每个元素都是原特征图中对应 2×2 区域的最大值。
    2. 作用:能够突出局部区域内的显著特征,对图像中的边缘、角点等重要特征具有较好的保留效果。并且对图像的平移具有一定的鲁棒性,即使图像有小幅平移,最大值的位置和大小变化相对较小,从而能够减少过拟合。
  2. 平均池化
    1. 原理:同样是在特征图上滑动池化窗口,取窗口内所有元素的平均值作为池化后的结果。以同样 4×4 的特征图和 2×2 的池化窗口为例,得到的 2×2 特征图中的每个元素是对应区域的平均值。
    2. 作用:可以平滑特征图,减少噪声的影响。因为它考虑了局部区域内的所有像素值,在一定程度上能够抑制一些随机的、微弱的噪声特征,使特征图更加平滑,有助于后续的特征提取和分类等任务。

池化层的优势:

1. 空间维度缩减

  • 降低计算量:随着特征图尺寸的减小,后续卷积层和全连接层的计算量大幅减少。
  • 例如,一个 32×32×64 的特征图经过一次 2×2 的池化操作后,变为 16×16×64,参数数量和计算量都大大降低,这使得网络能够更高效地进行训练和推理。

2. 特征抽象和语义提升

  • 强调重要特征:通过池化操作,特征图变得更加抽象,突出显示了更高层次的语义信息。
  • 例如,在图像分类任务中,卷积层提取的基础特征(如边缘、纹理等)经过池化后,能够逐渐抽象出更具代表性的物体局部或整体特征,有助于模型更好地理解和区分不同类别。

3. 提高模型的泛化能力

  • 不变性增强:池化层的平移、缩放和旋转不变性使得模型对图像的一些局部变化不敏感。
  • 例如,在识别猫的图像时,即使猫的位置在图像中有所移动或者图像有轻微的缩放,池化操作后的特征图仍然能够较好地捕捉到猫的关键特征,从而提高模型在不同场景下的泛化能力。
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))

输出:
tensor([[2., 3.],
        [5., 6.]])

填充和步幅:

X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
X

输出X为:
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.]]]])

填充和步幅可以手动设定。

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)

输出:
tensor([[[[ 5.,  7.],[13., 15.]]]])

当然,我们可以设定一个任意大小的矩形汇聚窗口,并分别设定填充和步幅的高度和宽a度。

pool2d = nn.MaxPool2d((2, 3), stride=(2, 3), padding=(0, 1))
pool2d(X)

输出:
tensor([[[[ 5.,  7.],[13., 15.]]]])

在处理多通道输入数据时,汇聚层在每个输入通道上单独运算,而不是像卷积层一样在通道上对输入进行汇总

这意味着汇聚层的输出通道数与输入通道数相同。

下面,我们将在通道维度上连结张量XX + 1,以构建具有2个通道的输入

X = torch.cat((X, X + 1), 1)
X

输出:
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.]]]])

如下所示,汇聚后输出通道的数量仍然是2

pool2d = nn.MaxPool2d(3, padding=1, stride=2)
pool2d(X)

输出:
tensor([[[[ 5.,  7.],
          [13., 15.]],
          
          [[ 6.,  8.],
           [14., 16.]]]])

总结:

  • 对于给定输入元素,最大池化层会输出该窗口内的最大值,平均池化层会输出该窗口内的平均值。

  • 池化层的主要优点之一是减轻卷积层对位置的过度敏感

  • 我们可以指定池化层的填充和步幅。

  • 使用最大池化层以及大于1的步幅,可减少空间维度(如高度和宽度)。

  • 池化层的输出通道数与输入通道数相同。


网站公告

今日签到

点亮在社区的每一天
去签到