池化的思想

下采样:多取一

 
每四个格取一个
- 每隔一个取一个 :方式有些古板 
- 随机取一个 
- 平均值 :信息丢失最少 
- 最小值 
- 最大值 

这也是池化层的操作,
- 池化层无参数,只是一种计算方式 
- 池化不改变特征层/数,只是一种下采样方式,收缩的是特征图的大小 

 
池化无参数,也不改变层数 

stride默认与kernel_size相等

 
池化是从特征层中多中取少,所以它收缩特征图而不改变层数 

不涉及特征数,不需要像线性变换那样有 输入特征数in_features 输出特征数out_features之类的参数 

在实现时,是多取一,
所以最主要的参数是一次取多少数据 kernel_size,
以及相关的stride,padding,设计技巧dilation-膨胀系数 

其中,stride默认与kernel_size相等,不够步数时,默认舍弃 

池化经典用法

nn.MaxPool2d(kernel_size=2, stride=2, padding=0)

 
# 第 1 层, [B, 1, 32, 32] --  [B, 16, 16, 16]
self.layer1 = nn.Sequential(
    nn.Conv2d(in_channels=1, out_channels=6, kernel_size=3, stride=1, padding=1),
    nn.BatchNorm2d(num_features=6),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
)

 

    

 


 

  

 


平均池化

 
平均池化,取核覆盖数据的平均值,每个新值都包含原来所有元素的信息 

丢失信息最小

 
import torch
from torch import nn
pool_avg = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
X = torch.randn(32, 3, 256, 256)
pool_avg(X).shape
torch.Size([32, 3, 128, 128])

 
import torch
from torch import nn
images = torch.randn(32,3,30,30)

pool_avg = nn.AvgPool2d(kernel_size=3)
pool_avg(images).shape  # torch.Size([32, 3, 10, 10])

最大池化

 
但对于图像来说,最亮的像素 通常是有含义的部分,所以在图像中大多用最大池化
- 最开始的时候,是从理论出发的,图像中使用的也是avgpool
- 后来经实践验证,发现maxpool比avgpool效果更好
- maxpool是直接将次要的东西扔掉,不断扔掉无用的东西
- 而不是一直带着无用或不重要的东西

基于maxpool在图像中比avgpool效果好这个经验/事实,总结如下:

 
提取最重要的,丢掉不重要的
- 这是建立在特征层由少到多的情况下的
- 在这个提前下,不断重复这个过程
- 因为特征层变多了,如果每层的特征图还不丢弃信息,那么容易积重难返
- 中间很有可能将一些有用的信息丢弃了,产生的影响,需要评估,需要看最终的效果
- 但如果特征层变多,至少每一层上最重要的一批信息不会丢
- 但这是否会对最终结果产生严重的不良影响,要看业务要求的精度,看最终结果 
- 在现实中也应该不断丢掉之前的不重要的事务,比如,历史包袱,过去不行或没干的事,现在未必不行
- 新的阶段,应该重新去认识环境中的信息

回顾这个过程,先是从理论出发认为avgpool比maxpool效果好,结果在图像领域并非如此,
那么在其他领域呢?
要试一试... 

积重难返[jī zhòng nán fǎn]

 
积重难返(拼音:jī zhòng nán fǎn)是一个成语,最早出自于春秋·左丘明《国语·晋语》。 
    
积重难返(重:程度深;返:回转)指长期形成的不良习惯、弊端,不易改变。

主谓式结构,含贬义;

池化的作用

 
一个神经网络有多个组件,有的负责变换特征,池化负责:
- 减小/收缩 特征图 (将次要/无用的元素丢弃,丢掉不重要的信息)
- 特征图的shape不断缩小,1/2,1/2,1/2,... 

MAXPOOL 参数说明

取指定kernel_size内的一个最大值

 
nn.MaxPool1d()
"""
Init signature:
nn.MaxPool1d(
    kernel_size: Union[int, Tuple[int, ...]],
    stride: Union[int, Tuple[int, ...], NoneType] = None,
    padding: Union[int, Tuple[int, ...]] = 0,
    dilation: Union[int, Tuple[int, ...]] = 1,
    return_indices: bool = False,
    ceil_mode: bool = False,
) -> None

kernel_size: The size of the sliding window, must be > 0.
stride: The stride of the sliding window, must be > 0. Default value is :attr:`kernel_size`.
padding: Implicit negative infinity padding to be added on both sides, must be >= 0 and <= kernel_size / 2.
    
"""
MAXPOOL 调用示例

图像示例

 
import torch
from torch import nn
images = torch.randn(32,3,30,30)


pool_max = nn.MaxPool2d(kernel_size=3)
pool_max(images).shape # torch.Size([32, 3, 10, 10])

序列示例:5取3舍2

 
import torch
from torch import nn

input = torch.tensor([
        [0,1,2,3,4],
        [0,1,2,3,5]]).float()

m = nn.MaxPool1d(3)
output = m(input)
output
tensor([[2.],
        [2.]])

kernel_size=3,stride默认与kernel_size相等,也是3
如果跳一步的话,就过界了,maxpool的做法是不跳,然后舍弃 
所以,前三个数的最大值是2,尽量后面还有更大的数,但舍弃了 

舍弃的是边,通常边上没有重要信息 ; 若有,就真的舍弃了,不想舍弃就补 

 
import torch
from torch import nn

input = torch.tensor([
        [0,1,2,3,4],
        [0,1,2,3,5]]).float()

m = nn.MaxPool1d(kernel_size=3,padding=1)
output = m(input)
output
tensor([[1., 4.],
        [1., 5.]])
        
MAXPOOL 抽象描述

抽象描述

 
卷积通常不改变特征图shape
并不是说卷积没有改变特征图shape的能力,而是各个组件间功能划分清晰明确,

卷积被设计为 只提取特征,
随着卷积提取特征,单个维度信息量越来越少,其shape又不变,这张特征图上势必出现大量空白,无意义的区域
这时,MAXPOOL就被设计出来了,MAXPOOL(2,2),2行2列四方格选出一个最大的数值,
从特征图上这样一个个区域选择下来,提取的是原特征图的主要结构,丢弃的是不重要的信息

更准确地说,在只有黑与白的维度或者单一色彩的维度上,
比如,在白纸上写黑字,还是黑纸上写白字,或者电脑上白色背景黑色字体,还是黑色背景白色字体,对计算机都一样
255是白色,如果是黑色背景白色图像,这没什么问题,白色的图像就是想要的内容
那如果是白色背景黑色图像,即maxpool不就取的是白色背景吗?
这也没什么问题,在单一的特征层面上(比如,R,G,B各自有都一层特征),背景间的不同也能对比出图像差异

MAXPOOL多选一,丢失大量重要信息怎么办?
又不是只运算MAXPOOL,这是一个网络,各个组件间协同计算,
当它与卷积一起运算的时候,就是选择主脉络结构,丢弃不重要信息了

为什么不用MINPOOL

 
为简化问题,以黑白图片为例,从两个方面阐述:

角度一(行业主流观点):
在计算机中,黑白本无区别,图片形状是由 色差 体现,
光与堷 条纹交织就有了形状,
在一个全白底板画上黑色,与在一个全黑底板画上白色 对计算机来说完全一样 
所以, MINPOOL与MAXPOOL效果一样,但你总得选一个 
算法发展有源头,大家学的算法有共同的源头,源头用的是MAXPOOL,所以大家就都用了MAXPOOL 

角度二(纯个人推测,非行业主流观点,仅供参考):
在计算机中,0代表黑色,255代表白色,0代表消失,无,不计算,而非0数字通常与业务有对应关系
在现实中,黑色事物眼睛通常看不见,两眼一抹黑,啥也看不见,这样的图像对人来说没直接作用 
为简化问题,还是只谈黑白,
在相机照相或者录像时,有时为了突显重要部分,会进行补光,稍微亮点的,更容易进行区分 
这也可能是选择了MAXPOOL而非MINPOOL的原因之一

但不是说一切皆MAXPOOL了
MAXPOOL用于提取主要结构,在主次没有重大差异的情况下,也为排除高低带来的不稳定性,可以用平均池化AVGPOOL 
还有自适应平均池化AdaptiveAvgPool2d,合适的才是最好的

如果模型的精度不高,或者是依从科学严谨的态度,
可以尝试减少或去除MAXPOOL,以检测精度是否会有提升,
有时每层卷积后都跟一个MAXPOOL的话,舍弃的信息可能多了

光与暗的交织

 
既然光与暗交织形成结构,那么可以从三个维度去提取特征,max,min,avg,然后再合并成全连接
该想法未验证,纯属个人猜测,如有...纯属... 

参考