cnn中池化层作用

一、池化层概述

在卷积神经网络中,池化层是核心组件之一,主要作用是逐步降低特征图的空间尺寸即宽和高,从而减少计算量、控制过拟合并增强模型的鲁棒性。

核心作用

  1. 降维与减少计算量
    压缩特征图的尺寸,显著减少后续层的参数数量和计算负担。
  2. 引入平移不变性
    对微小位置变化不敏感。如输入图像中目标物体稍微移动后,池化层仍能提取相同特征。
  3. 抑制噪声与保留主要特征
    通过取局部区域的最大值或平均值,保留显著特征并过滤细节噪声。
  4. 扩大感受野
    使后续层能融合更广阔区域的上下文信息。

1. 最大池化

原理:取滑动窗口内的最大值。
例子:对 4×4 特征图进行 2×2 窗口 + 步长2 的最大池化:

可以使用torch.nn.MaxPool2d构造最大池化层:

maxpool_layer = torch.nn.MaxPool2d(
    kernel_size, # 池化窗口的大小
    stride=None, # 池化操作的步长,默认等于窗口大小
    padding=0,   # 零像素的边缘填充数量
    dilation=1,  # 扩张元素的数量
    return_indices=False, # 返回池化取值的索引,并通过nn.MaxUnpool2d()进行反池化
    ceil_mode=False # 在输出尺寸中是否使用向上取整代替向下取整
    )

输入特征图(4×4):
[[1, 2, 5, 3],
 [4, 9, 6, 8],
 [7, 1, 4, 2],
 [3, 5, 2, 6]]

池化操作:
| 1  2 | 5  3 |   → 取 max(1,2,4,9)=9    | 取 max(5,3,6,8)=8
| 4  9 | 6  8 |
-------------------
| 7  1 | 4  2 |   → 取 max(7,1,3,5)=7    | 取 max(4,2,2,6)=6
| 3  5 | 2  6 |

输出特征图(2×2):
[[9, 8],
 [7, 6]]

效果:保留边缘、纹理等显著特征。


2. 平均池化

原理:取滑动窗口内的平均值。
例子:相同输入,进行 2×2 平均池化:

可以使用torch.nn.AvgPool2d构造平均池化层:

avgpool_layer = torch.nn.AvgPool2d(
    kernel_size, # 池化窗口的大小
    stride=None, # 池化操作的步长,默认等于窗口大小
    padding=0,   # 零像素的边缘填充数量
    ceil_mode=False # 在输出尺寸中是否使用向上取整代替向下取整
    count_include_pad=True, # 计算均值时是否考虑填充像素
    divisor_override=None # 若指定将用作平均操作中的除数
    )

| 1  2 | 5  3 |   → 平均 = (1+2+4+9)/4 = 4   | (5+3+6+8)/4 = 5.5
| 4  9 | 6  8 |
-------------------
| 7  1 | 4  2 |   → 平均 = (7+1+3+5)/4 = 4   | (4+2+2+6)/4 = 3.5

输出特征图(2×2):
[[4.0, 5.5],
 [4.0, 3.5]]

适用场景:全局信息平滑如图像分类的背景区域。

应用:

  • 目标检测:最大池化保留物体的关键特征如猫的耳朵,即使位置轻微变化仍能被识别。
  • 减少过拟合:通过降低特征图尺寸,强制网络学习更泛化的模式。
  • 加速训练:减少全连接层的参数如将 200×200 特征图池化为 100×100,后续计算量减少75%。

改进:

  • 趋势:部分网络(如ResNet)用步长>1的卷积层替代池化层,在降维的同时学习特征。
  • 全局平均池化(Global Average Pooling):将整个特征图池化为一个值(替代全连接层),极大减少参数(如用于Inception、SqueezeNet)。

二、卷积层参数如何计算

2.1 参数数量计算

#例子
class CNN(nn.Module):
    def __init__(self, activation="relu"):
        super(CNN, self).__init__()
        self.activation = F.relu if activation == "relu" else F.selu
        #输入通道数,图片是灰度图,所以是1,图片是彩色图,就是3,输出通道数,就是卷积核的个数(32,1,28,28)
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1)
        #输入x(32,32,28,28) 输出x(32,32,28,28)
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=32, kernel_size=3, padding=1)
        
        self.pool = nn.MaxPool2d(2, 2) #池化核大小为2(2*2),步长为2
        
        
        self.conv3 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
        self.conv4 = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=3, padding=1)
        self.conv5 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1)
        self.conv6 = nn.Conv2d(in_channels=128, out_channels=128, kernel_size=3, padding=1)
        
        self.pool2 = nn.MaxPool2d(2, 2)   #输入(128,7,7) 输出(128,3,3)
        
        self.flatten = nn.Flatten()
        # input shape is (28, 28, 1) so the fc1 layer in_features is 128 * 3 * 3
        self.fc1 = nn.Linear(128 * 3 * 3, 128)
        self.fc2 = nn.Linear(128, 10) #输出尺寸(32,10)

        self.init_weights()
1. **卷积层 **

参数数量 = (in_channels × out_channels × kernel_height × kernel_width) + out_channels

  • 权重参数in_channels × out_channels × kernel_size²
  • 偏置参数out_channels(每个输出通道一个偏置)
2. **全连接层 **

参数数量 = (in_features × out_features) + out_features

  • 权重参数in_features × out_features
  • 偏置参数out_features
3. 池化层/ Flatten 层

参数数量 = 0(无训练参数)

以下是CNN模型中每一层的参数数量计算和输出尺寸变化的详细说明(输入为 (batch_size, 1, 28, 28)):

  1. Conv1 层
  • 输入尺寸(batch_size, 1, 28, 28)
  • 输出尺寸(batch_size, 32, 28, 28)
    • Padding=1 保持空间尺寸不变((28 + 2 - 3)/1 + 1 = 28)。
  • 参数数量
    • 权重:1 × 32 × 3 × 3 = 288
    • 偏置:32
    • 总计:288 + 32 = 320
  1. Conv2 层
  • 输入尺寸(batch_size, 32, 28, 28)
  • 输出尺寸(batch_size, 32, 28, 28)
    • Padding=1 保持尺寸不变。
  • 参数数量
    • 权重:32 × 32 × 3 × 3 = 9,216
    • 偏置:32
    • 总计:9,216 + 32 = 9,248

  1. Pool 层(MaxPool2d, kernel=2, stride=2)
  • 输入尺寸(batch_size, 32, 28, 28)
  • 输出尺寸(batch_size, 32, 14, 14)
    • 下采样公式:(28 - 2)/2 + 1 = 14
  • 参数数量0(池化层无参数)

  1. Conv3 层
  • 输入尺寸(batch_size, 32, 14, 14)
  • 输出尺寸(batch_size, 64, 14, 14)
    • Padding=1 保持尺寸不变。
  • 参数数量
    • 权重:32 × 64 × 3 × 3 = 18,432
    • 偏置:64
    • 总计:18,432 + 64 = 18,496

  1. Conv4 层
  • 输入尺寸(batch_size, 64, 14, 14)
  • 输出尺寸(batch_size, 64, 14, 14)
  • 参数数量
    • 权重:64 × 64 × 3 × 3 = 36,864
    • 偏置:64
    • 总计:36,864 + 64 = 36,928

  1. Pool 层(再次使用,kernel=2, stride=2)
  • 输入尺寸(batch_size, 64, 14, 14)
  • 输出尺寸(batch_size, 64, 7, 7)
    • 下采样:(14 - 2)/2 + 1 = 7
  • 参数数量0

  1. Conv5 层
  • 输入尺寸(batch_size, 64, 7, 7)
  • 输出尺寸(batch_size, 128, 7, 7)
    • Padding=1 保持尺寸不变。
  • 参数数量
    • 权重:64 × 128 × 3 × 3 = 73,728
    • 偏置:128
    • 总计:73,728 + 128 = 73,856

  1. Conv6 层
  • 输入尺寸(batch_size, 128, 7, 7)
  • 输出尺寸(batch_size, 128, 7, 7)
  • 参数数量
    • 权重:128 × 128 × 3 × 3 = 147,456
    • 偏置:128
    • 总计:147,456 + 128 = 147,584

  1. Pool2 层(MaxPool2d, kernel=2, stride=2)
  • 输入尺寸(batch_size, 128, 7, 7)
  • 输出尺寸(batch_size, 128, 3, 3)
    • 下采样:(7 - 2)/2 + 1 = 3(向下取整)。
  • 参数数量0

  1. Flatten 层
  • 输入尺寸(batch_size, 128, 3, 3)
  • 输出尺寸(batch_size, 128 × 3 × 3) = (batch_size, 1,152)
  • 参数数量0

  1. FC1 层(全连接层)
  • 输入尺寸(batch_size, 1,152)
  • 输出尺寸(batch_size, 128)
  • 参数数量
    • 权重:1,152 × 128 = 147,456
    • 偏置:128
    • 总计:147,456 + 128 = 147,584

  1. FC2 层(全连接层)
  • 输入尺寸(batch_size, 128)
  • 输出尺寸(batch_size, 10)
  • 参数数量
    • 权重:128 × 10 = 1,280
    • 偏置:10
    • 总计:1,280 + 10 = 1,290

完整计算流程(输入 (1, 28, 28))

输出尺寸参数计算参数数量
Conv1(32, 28, 28)(1×32×3×3) + 32320
Conv2(32, 28, 28)(32×32×3×3) + 329,248
Pool1(32, 14, 14)无参数0
Conv3(64, 14, 14)(32×64×3×3) + 6418,496
Conv4(64, 14, 14)(64×64×3×3) + 6436,928
Pool2(64, 7, 7)无参数0
Conv5(128, 7, 7)(64×128×3×3) + 12873,856
Conv6(128, 7, 7)(128×128×3×3) + 128147,584
Pool3(128, 3, 3)无参数0
Flatten(1152,)无参数0
FC1(128,)(1152×128) + 128147,584
FC2(10,)(128×10) + 101,290
总计--435,306

2.2 每层输出尺寸变换原理

卷积输出尺寸公式:

假设输入尺寸为 Hin×Win

卷积核尺寸 K,步长 S,填充 P,输出尺寸 Hout×Wout 为:
Hout=⌊Hin+2P−KS⌋+1 Hout= \left\lfloor \frac{H_{in} + 2P - K}{S} \right\rfloor + 1 Hout=SHin+2PK+1

Wout=⌊Win+2P−KS⌋+1 Wout=\left\lfloor \frac{W_{in} + 2P - K}{S} \right\rfloor + 1 Wout=SWin+2PK+1

默认设置(最常见):

  • kernel_size = 3
  • stride = 1
  • padding = 1
    则:

Hout=Hin,Wout=WinH

尺寸不变

当卷积核尺寸 K=2,步长 S=2.填充 P=1时

这个操作会让图像尺寸缩小一半:

简化为:
Hout=⌊HinS⌋ Hout= \left\lfloor \frac{H_{in} }{S} \right\rfloor Hout=SHin
例如:

  • 输入 28×2814×14
  • 输入 14×147×7
  • 输入 7×73×3

Flatten 展平层

将形如 (batch_size, C, H, W) 的张量展平成 (batch_size, C × H × W),准备送入全连接层。

总结

输入尺寸操作输出尺寸说明
conv11×28×28Conv2d(3, p=1)32×28×28尺寸不变,通道变为 32
conv232×28×28Conv2d(3, p=1)32×28×28尺寸不变
pool132×28×28MaxPool2d(2,2)32×14×14高宽缩小一半
conv332×14×14Conv2d(3, p=1)64×14×14通道增加
conv464×14×14Conv2d(3, p=1)64×14×14通道不变
pool264×14×14MaxPool2d(2,2)64×7×7再次缩小
conv564×7×7Conv2d(3, p=1)128×7×7通道增加
conv6128×7×7Conv2d(3, p=1)128×7×7通道不变
pool3128×7×7MaxPool2d(2,2)128×3×3尺寸变为最终
flatten128×3×3Flatten1152送入全连接层
fc11152Linear(1152→128)128隐藏层
fc2128Linear(128→10)10输出分类结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值