Pool池化下采样层详解(二)

池化过程类似于卷积过程。
在这里插入图片描述

上图表示的就是对一个图片邻域内的值,用一个 2x2 的池化kernel,步长为2进行扫描,选择最大值输出,称为最大池化。

最大池化 MaxPool 常用的参数为 kernel = 2, stride = 2 ,这样的参数处理效果就是输出图片的高度、宽度减半,通道数不变。还有一种叫平均池化,和最大池化类似,就是将取区域内最大值改为求这个区域的平均值。

引用自:https://zhuanlan.zhihu.com/p/545293528
与卷积层相比,池化操作也有一个核(kernel),但它不是卷积核。池化的核只负责框定某次池化计算需要的图片的范围,核里面并没有数据参与计算,也就是说,在训练过程中,池化层不像卷积层那样,需要学习权重,另一个与卷积不同的是,在卷积的计算中,需要channel维度的数据累加,而池化层的channel维度的数据不需要累加,每个channel中的数据是独立的,这也导致,池化的运算复杂度比卷积简单很多。

⭐torch.nn.MaxPool2d()详解

最大池化操作:将 n x n 尺寸内所有像素值取最大值作为输出通道的像素值。
在这里插入图片描述

函数原型:
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

关键参数说明:
● kernel_size:最大的窗口大小,可以是单值也可以是tuple元组
● stride:窗口的步幅(步长),默认值为kernel_size,可以是单值也可以是tuple元组
● padding:填充值,默认为0,可以是单值也可以是tuple元组
● dilation:控制窗口中元素步幅的参数,默认为1
● return_indices: 布尔类型,返回最大值位置索引
● ceil:布尔类型,为Ture,用向上取整的方法,计算输出形状,默认是向下取整

*kernel_size理解(必选):此处不是卷积核,kernel_size可以看做是一个滑动窗口,这个窗口的大小由自己指定,如果输入是一个单值,例如3,那么窗口的大小为3 X 3,此时的最大池化窗口是方形。还可以是元胞数组,例如(3,2),那么窗口大小就是32,此时的最大窗口不是方形。

stride理解(可选): stride 是用来确定kernel_size如何进行滑动。如果不指定这个参数,那么默认步长跟最大池化窗口大小一致。如果指定了参数,那么将按照我们指定的参数进行滑动。例如stride = (2,3),那么窗口将每次向右滑动三个元素位置或者向下滑动两个元素位置。

padding理解(可选):*padding参数控制如何进行填充,填充值默认为0。如果是单个值,例如1,那么将在周围填充一圈0。还可以用元组制定能够如何填充,例如padding = (2,1),表示在上下两个方向各填充两行0,左右两个方向各填充一列0。

*dilation理解(可选):*控制窗口中元素步幅的参数。

return_indices理解(可选): 布尔类型值,表示返回值中是否包含最大值位置的索引,注意这个最大值指的是在所有窗口中产生的最大值,如果窗口产生的最大值总共有 5个,就会有5个返回值。如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助。

ceil_mode=False理解(可选):布尔类型值,它决定的是在计算输出结果形状的时候,是使用向上取整还是向下取整。怎么计算输出形状,下式为最大池化层输出形状计算:

📐池化层计算公式:
● Input:(N, C, Hin, Win) or (C, Hin, Win)
● Output:(N, C, Hout, Wout) or (C, Hout, Wout)
其中,N代表数量, C代表channel,H代表高度,W代表宽度.池化层计算

🔍案例1

输入:

import torch
import torch.nn as nn

m       = nn.MaxPool2d(2)
input_x = torch.randn(3, 32, 32)
print("输入数据input_x.shape:",input_x.shape)
output  = m(input_x)
print("输出数据output.shape:",output.shape)

输出

输入数据input_x.shape: torch.Size([3, 32, 32]) 
输出数据output.shape: torch.Size([3, 16, 16])

📏推导分析:
输入的数据格式是:[3, 32, 32] 即 [C X Hin X Win]

在这里插入图片描述
其中Hin=32,padding=0,dilation=1,kernel_size=2,stride=2,代入上面的公式可得Hout=16
同理,Wout=16,C保持不变,故而output.shape为 [3, 16, 16] 输出的数据格式即 [C X Hout X Wout]。

🔍案例2

输入

m       = nn.MaxPool2d(3)
input_x = torch.randn(3, 32, 32)
print("输入数据input_x.shape:",input_x.shape)
output  = m(input_x)
print("输出数据output.shape:",output.shape)

输出

输入数据input_x.shape: torch.Size([3, 32, 32]) 
输出数据output.shape: torch.Size([3, 10, 10])

为什么需要池化层?

  • 特征不变性

汇合操作使模型更关注是否存在某些特征而不是特征具体的位置,可看作是一种很强的先验,使特征学习包含某种程度自由度,能容忍一些特征微小的位移。即池化层支持了一定的平移、旋转、拉伸不变性,这个特性就是有点抽丝剥茧的意思,不断用小特征对大特征进行精简。

如下图,通过池化操作,图片中的黑色特征在输出图片中,仍然被保留了下来,虽然有些许的误差。
在这里插入图片描述

  • 降维

如上的例子,图片经过池化的操作,可以减小图片的尺寸,同时又可以保留相应特征,所以主要用来降维。

  • 防止过拟合

由于池化层没有需要学习的参数,因此,在训练的过程中,可以在一定程度上防止过拟合的发生。

  • 降低模型计算量

池化的操作,会在保留原始图片特征不变的情况下,将图片尺寸缩小,从而减少整个模型的计算量。

在神经网络的训练和推理过程中,一个维度的计算量减倍,往往会带来一个数量级的性能提升,尤其是在训练过程动辄迭代成千上万次的训练场景中。

使用池化算法,在减少图片的宽和高尺寸的同时,也会给模型的训练和推理带来更优异的性能提升。

  • One More Thing

除了上述最大池化和平均池化外,池化还有很多变种。最常见的一种变体就是全局池化。

全局池化的kernel大小和图片大小一样,因此最终输出的图片大小就是一个点。这种全局池化操作,后面一般用来接全连接层,从而进行分类。如Resnet50最后一层全连接层前,就是一个全局平均池化层。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦在黎明破晓时啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值