小杰深度学习(seven)——卷积神经网络——池化
1.池化为什么能增强特征
1. 基础原理
什么是池化
池化(Pooling)是一种用于减少卷积神经网络(CNN)中特征图大小的操作。它通过将特征图上的局部区域进行聚合,得到一个更小的特征图。
池化操作
池化操作类似卷积操作,使用的也是一个很小的矩阵,叫做池化核,但是池化核本身没有参数,只是通过对输入特征矩阵本身进行运算,它的大小通常是2x2、3x3、4x4等,然后将池化核在卷积得到的输出特征图中进行池化操作,需要注意的是,池化的过程中也有Padding方式以及步长的概念,与卷积不同的是,池化的步长往往等于池化核的大小。
最常见的池化操作为最大值池化(Max Pooling)和平均值池化(Average Pooling)两种。
最大池化是从每个局部区域中选择最大值作为池化后的值,这样可以保留局部区域中最显著的特征。最大池化在提取图像中的纹理、形状等方面具有很好的效果。
平均池化是将局部区域中的值取平均作为池化后的值,这样可以得到整体特征的平均值。平均池化在提取图像中的整体特征、减少噪声等方面具有较好的效果。
特征输入
本实验中提供了一个5x5的特征输入矩阵,其中点击“格子”可以修改里面的值,仅限于0和1的切换,如下图所示:
卷积核
由于一般情况下,池化是在卷积之后,所以这里也做一次卷积后再跟池化。
在“卷积核”组件中定义卷积核的内容,这里固定卷积核的大小为3x3, 除此之外还可以修改卷积核的个数及卷积核中每个值的大小(通过单击“格子”修改值)。
卷积核个数为1 | 卷积核个数为2 |
卷积
在“卷积”组件中定义卷积核在卷积过程中的步长以及Padding方式,这里我们已经固定好Padding方式为“SAME”,并且步长为1。
池化结果
卷积操作结束后,就到了本章的重点知识,使用池化操作来增强特征。
使用“池化结果”组件将卷积的结果进行池化操作,在该组件中,固定了池化核的大小为2x2,这也是极为常用的一个池化核大小的参数, 除此之外,可以在该组件中设置池化核的步长与Padding方式以及池化类型,一般情况下,池化核大小是2的情况下,步长一般也就是2,如下图所示:
注意:图像中的“池化输出特征”暂未进行池化操作。
池化会对卷积后的输出特征进行池化操作,与卷积的过程类似, 根据池化的方式对池化区域进行池化操作,然后根据步长进行移动, 最大值池化就是将池化核所包围的原始输入特征的区域进行比大小,把最大的拿出来作为输出特征矩阵的数值,
如下图所示:
通过上图看到,通过池化操作后,降低特征图的尺寸,那么整体计算量就会降低,从而提升模型的运行效率。 并且,最大池化在降低特征图的尺寸的同时,保留卷积提取出来的比较大的值,去掉相对较小的值,保证特征的平移、旋转等不变性。
那平均池化就是将池化核所包围的原始输入特征的区域进行加和求平均,把平均值拿出来作为输出特征矩阵的数值,
如下图所示:
其中:池化的输出计算公式与卷积类似:
(图像尺寸-池化核尺寸 + 2*填充值)/步长+1,向下取整
池化也叫下采样
下采样原理:
对于一副图像Ⅰ尺寸为M*N,对其进行s倍下采样,即得到(M/s)*(N/s)尺寸的分辨率图像,当然,s应该是M和N的公约数才可以,s是不是相当于池化核。
池化的作用
池化操作的优势有:
1通过降低特征图的尺寸,池化层能够减少计算量(不是参数量,计算5*5池化后计算3*3的,参数量是卷积核还是3*3的没变化),从而提升模型的运行效率。
2池化操作可以带来特征的平移、旋转等不变性,这有助于提高模型对输入数据的鲁棒性(是指系统、模型或算法在面对输入数据、环境或参数的摄动(扰动)时,仍能保持其性能的稳定性和可靠性的能力)。
3池化层通常是非线性操作,例如最大值池化,这样可以增强网络的表达能力,进一步提升模型的性能。
但是池化也有缺点:
1池化操作会丢失一些信息,这是它最大的缺点;
代码实现
#导入包
import torch
import torch.nn as nn
#nn.Sequential 是容器 自带forward方法
conv1_pool_layer=nn.Sequential(nn.Conv2d(in_channels=3,out_channels=3,kernel_size=3,stride=1,padding='same',bias=False),# 窗口是2 步长为2nn.MaxPool2d(2, 2)
)# class convmodel(nn.Module):
# def __init__(self):
# super(convmodel,self).__init__()
# self.conv1_layer=nn.Conv2d(in_channels=3, out_channels=5, kernel_size=3, stride=1, bias=False)
# def forward(self,x):
# return self.conv1_layer(x)#仿真 1张3通道的图片
#torch.rand(2,3,30,30)中的第一个2表示样本数量=2,3表示通道数,长 宽为30x30
image=torch.rand(2,3,6,6)
#卷积进行计算后池化的结果
result1=conv1_pool_layer(image)# model=convmodel()
# result2=model(image)
print(result1.shape)
# print(result2.shape)