池化层的基本定义
池化层(Pooling Layer)是神经网络中的一种重要层结构,特别是在卷积神经网络(CNN)中扮演着至关重要的角色。其基本定义是通过对输入特征图进行下采样操作,以减少特征图的空间尺寸,同时保留关键信息。这种操作有助于降低计算复杂度,提高模型的运行效率,并且能够在一定程度上增强模型的鲁棒性。池化层通常位于卷积层之后,作为特征提取过程中的一个关键步骤。
池化层作用
池化层的作用包括降维、减少参数、防止过拟合、增强鲁棒性、保留显著特征、提高计算效率以及实现空间不变性。
池化层的主要类型
池化层根据下采样操作的不同,主要分为以下几种类型:
- 最大池化(Max Pooling):在设定的池化窗口内,选择最大值作为输出。最大池化能够保留区域内最显著的特征,对于分类和识别任务特别有效。
- 平均池化(Average Pooling):计算池化窗口内所有像素的平均值作为输出。平均池化能够平滑特征图,减少噪声的影响。
- 全局池化(Global Pooling):对整个特征图进行池化操作,通常用于减少特征图的维度至一维,便于后续的全连接层处理。
此外,还有一些特殊的池化方式,如L2池化、重叠池化等,它们根据不同的应用场景和需求进行选择和调整。
二维最大池化层
同卷积层一样,池化层每次对输入数据的一个固定形状窗口(又称池化窗口)中的元素计算输出。不同于卷积层里计算输入和核的互相关性,池化层直接计算池化窗口内元素的最大值或者平均值。该运算也分别叫做最大池化或平均池化。在二维最大池化中,池化窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。当池化窗口滑动到某一位置时,窗口中的输入子数组的最大值即输出数组中相应位置的元素。
图1 池化窗口形状为 2 x 2 的最大池化
图1展示了池化窗口形状为2×22×22×2的最大池化,阴影部分为第一个输出元素及其计算所使用的输入元素。输出数组的高和宽分别为2,其中的4个元素由取最大值运算maxmaxmax得出:
max(0,1,3,4)=4,
max(1,2,4,5)=5,
max(3,4,6,7)=7,
max(4,5,7,8)=8.
二维最大池化可参考官方文档:
MaxPool2d — PyTorch 2.6 documentation
代码演示1
import torch
from torch.nn import MaxPool2d,Module
input = torch.tensor([
[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]],dtype=torch.float32)
input = torch.reshape(input,[-1,1,5,5]) # 转换为NCHW四维数据
print(input)
print(input.shape)
class Maxpoll_nn(Module):
def __init__(self,mode):
super().__init__()
self.maxpool = MaxPool2d(3,ceil_mode=mode)
def forward(self,x):
x = self.maxpool(x)
return x
testnn1 = Maxpoll_nn(False)
testnn2 = Maxpoll_nn(True)
output1 = testnn1(input)
output2 = testnn2(input)
print(output1)
print(output1.shape)
print(output2)
print(output2.shape)
输出:
tensor([[[[1., 2., 0., 3., 1.],
[0., 1., 2., 3., 1.],
[1., 2., 1., 0., 0.],
[5., 2., 3., 1., 1.],
[2., 1., 0., 1., 1.]]]])
torch.Size([1, 1, 5, 5])
tensor([[[[2.]]]])
torch.Size([1, 1, 1, 1])
tensor([[[[2., 3.],
[5., 1.]]]])
torch.Size([1, 1, 2, 2])
代码演示2
import torch
from torch.nn import MaxPool2d,Module
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision.transforms import ToTensor
# 加载本地图片
img = Image.open(r'pic/cat.jpeg')
# 转换图片为NCHW tensor数据格式
img = ToTensor()(img)
img = torch.reshape(img,[1,img.shape[0],img.shape[1],img.shape[2]])
print(img.shape)
# 自定义一个简单的池化层神经网络
class Maxpoll_nn(Module):
def __init__(self,ksize,mode):
super().__init__()
self.maxpool = MaxPool2d(ksize,ceil_mode=mode)
def forward(self,x):
x = self.maxpool(x)
return x
testnn1 = Maxpoll_nn(3,False)
testnn2 = Maxpoll_nn(7,False)
outimg1 = testnn1(img)
outimg2 = testnn2(img)
print(outimg1.shape)
print(outimg2.shape)
# 通过tensorboard加载池化后的图片
writer = SummaryWriter('logs_pool')
writer.add_image('原始图片',img,1,dataformats="NCHW")
writer.add_image('池化处理1',outimg1,1,dataformats="NCHW")
writer.add_image('池化处理2',outimg2,1,dataformats="NCHW")
writer.close()
输出:
torch.Size([1, 3, 1280, 1533])
torch.Size([1, 3, 426, 511])
torch.Size([1, 3, 182, 219])
从输出结果可以看到,原始图片尺寸1280*1533,经过大小为3的池化核处理后图片尺寸变为426*511,经过大小为7的池化核处理后图片尺寸变为182*219。
运行程序后会生成tensorboard日志文件,在终端输入tensorboard --logdir=logs_pool指令可打开原始及池化处理后的图片。