一、最大池的作用:最大池化的目的在于保留原特征的同时减少神经网络训练的参数,使得训练时间减少。相当于输入1080p的视频,经过池化后变为了720p
二、最大池参数:
1、kernel_size:最大取值窗口,类似于卷积中的卷积核,当传入一个整形时,最大取值窗口为一个正方形,当传入一个列表时,则一个是长,一个是宽
2、stride:步径,与卷积层不同的是,他的默认值为kernel_size的大小
3、padding:与卷积层中padding用法相同,为输入的边缘填充大小。可以是一个整数或元组。填充通常用于控制输出特征图的大小。
4、dilation:控制kernel_size中元素步幅的参数,即可以使得元素两两之间有间隙
为0时:
为1时:
5、ceil_module:设置 ceil 模式和 floor 模式:
例如:当输入一个矩阵时:
设置kernel_size = 3:
第一次匹配:
挑选出9个数中最大的那个数:2,然后向右移动stride个格子
此时数据无法填满kernel_size中的格子,就涉及到取舍问题,当ceil_module=T时,保留 剩余的6个数,并取出最大值:3,如果为False,则将这6个数舍去
因此造成的结果也不同:
ceil_module=True时,结果:
ceil_module=False时,结果:
由此结果可以看出最大池化的功能:我们输入的图片时5*5的,可输出的图片会变成2*2或1*1,经过这样的处理,使得数据量变少,当训练模型时就会训练的更快
代码展示:
import torch
from torch import nn
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=float) # 使用dtype的原因:因为神经网络中经常使用的数据类型是浮点型,不支持长整形,因此需要把输入的二维矩阵(模拟图像)中的数字变成浮点型
# 将输入的二维矩阵转化格式
input = torch.reshape(input,[-1,1,5,5])
# 将shape中第一个参数batch_size设置成-1,编译环境会自动根据后面三个数计算图像大小
# 因为二维矩阵只有一层,因此shape中第二个参数channel为1
# shape后面两个参数分别为高和宽,都为5,因为矩阵是5*5矩阵
# 开始搭建神经网络——池化层
class MyModule(nn.Module):
def __init__(self):
super().__init__()
self.maxpool1 = nn.MaxPool2d(kernel_size=3,ceil_mode=False)
def forward(self,img):
img = self.maxpool1(img)
return img
module = MyModule()
input = module(input)
print(input)
最大池化处理真正的图片代码:
from torch import nn
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from torch.utils.data import DataLoader
import torchvision
tensor_trans = transforms.ToTensor()
test_data = torchvision.datasets.CIFAR10(root="./dataloader",train=False,transform=tensor_trans,download=True)
dataloader = DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0,drop_last=False)
# 创建一个神经网络
class MyModule(nn.Module):
def __init__(self):
super().__init__()
self.maxpool1 = nn.MaxPool2d(kernel_size=3,stride=3,padding=0,ceil_mode=True)
def forward(self,imgs):
imgs = self.maxpool1(imgs)
return imgs
writer = SummaryWriter("log")
maxpool1 = MyModule()
step = 0
for each in dataloader:
imgs,labels = each
writer.add_images("未池化",imgs,step)
# 用未池化的原图进行对比
imgs = maxpool1(imgs)
# 与卷积不同的是,卷积过后图片的通道数可能会变化,而池化过后图片通道数不会变化,因此不需要重新设置通道数
writer.add_images("池化",imgs,step)
step += 1
writer.close()
输出结果:
可明显看出,图片经过池化后清晰度明显降低