1.什么是最大池化?
最大池化从某种程度上来说跟卷积有些相似,他们都属于减少参数量的操作,但是最大池化明显更加迅速。最大池化的运算逻辑如下:
假设上表是一个 5*5 的输入矩阵,在核(kernel_size)为 3、ceil_mode 为 true 的情况下,其输出为:
核大小可以理解为滑动的窗口,默认的步长即为核大小,窗口每到一个位置就会将窗口内数据的最大值作为这一步的输出。这样的操作可以迅速减少数据量,既能防止过拟合,又最大程度地保留了原始特征。
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()
默认评论
Halo系统提供的评论