2025-10-23
点 赞
0
热 度
20
评 论
0

Pytorch最大池化(MaxPool2d)篇

  1. 首页
  2. 深度学习
  3. Pytorch最大池化(MaxPool2d)篇

1.什么是最大池化?

最大池化从某种程度上来说跟卷积有些相似,他们都属于减少参数量的操作,但是最大池化明显更加迅速。最大池化的运算逻辑如下:

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

假设上表是一个 5*5 的输入矩阵,在核(kernel_size)为 3、ceil_mode 为 true 的情况下,其输出为:

2

3

5

1

核大小可以理解为滑动的窗口,默认的步长即为核大小,窗口每到一个位置就会将窗口内数据的最大值作为这一步的输出。这样的操作可以迅速减少数据量,既能防止过拟合,又最大程度地保留了原始特征。

2.参数

class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

常用的参数还是卷积里的几个老熟人了:

kernel_size 是指计算时滑动窗口的大小,依然是可以选择使用 int 或者 tuple 类型,含义与卷积中的相同。

stride 是步长,与卷积不同的是最大池化的步长默认就是核的大小(kernel_size),这样可以大幅减少参数量。

padding 依然是填充,不过这里就不需要搭配 padding_mode 来使用了,在官方文档的描述里,这个 padding 会直接填充为隐式的负无穷大。

ceil_mode 这个东西很有意思,依然用 1. 中的输入矩阵和 kernel_size 举例,如果 ceil_mode 按默认的 False 设置,其输出为 2(这是个 1*1 的矩阵)。这个东西的含义来自于向上取整和向下取整,在 C 语言中函数 floor()是向下取整(又称地板函数),函数 ceil() 是向上取整(即天花板函数),这里也借用了其含义来描述这个行为。因为输入矩阵是 5*5,卷积核是 3*3,在无填充(padding=0)的情况下核按默认步长 3 滑动时,计算完第一个窗口的数据后就无法再滑动了(因为横向滑动和纵向滑动都使窗口超出了输入矩阵的范围),ceil_mode 设置为 true 则允许超出的情况出现(类似 padding 填充了隐式负无穷大),使第一个窗口右侧的 3*2 区域和下侧的 2*3、2*2 区域均可继续计算最大池化。

不常用的参数中也有一个老熟人:

dilation,也就是卷积中那个控制核间元素距离的参数,这里含义与卷积的 dilation 相同,主要目的是增加感受野减少更多的数据。

另一个新朋友是 return_indices,听名字就很好理解,它为 true 时会返回最大元素的索引和输出,在某些场景中可以用于后续操作。

3.具象化显示

这步演示我使用 CIFAR10 数据集,构建一个最简化的模型来演示最大池化的实际效果,图 1 是原始图像,图 2 是最大池化后的结果,这里取一个 batch 做演示:

图 1 原始图像

图 2 最大池化后的结果

下面是测试代码:

import torchvision
from torch import nn
from torch.nn import MaxPool2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

test_data = torchvision.datasets.CIFAR10(root="./dataset", train=False, download=True, transform=torchvision.transforms.ToTensor())
data_loader = DataLoader(dataset=test_data, batch_size=64)

class Example(nn.Module):
    def __init__(self):
        super(Example, self).__init__()
        self.maxpool1 = MaxPool2d(kernel_size=3, ceil_mode=False)

    def forward(self, input):
        output = self.maxpool1(input)
        return output

example = Example()
writer = SummaryWriter("./maxpool_log")
step = 0
for data in data_loader:
    imgs, targets = data
    # print(F"imgs = {imgs}")
    # print(F"imgs.shape =  {imgs.shape}")
    # print(F"imgs.type = {type(imgs)}")
    writer.add_images("maxpool_input", imgs, step)
    # print(" " * 111)
    output = example(imgs)
    # print(F"output = {output}")
    # print(F"output.shape = {output.shape}")
    # print(F"output.type = {type(output)}")
    writer.add_images("maxpool_output", output, step)
    step += 1

writer.close()


我自己用的账号

enfj 主人公

不具版权性
不具时效性

文章内容不具时效性。若文章内容有错误之处,请您批评指正。

目录

欢迎来到Henry的站点,为您导航全站动态

18 文章数
4 分类数
1 评论数
5标签数