池化是什么?它有什么作用?
还是草地的场景,把草地分成一块块的网格,数量还是太多了,如何继续简化输入数据呢?
这时候可以只取一块网格中所有的小草的大小形状的平均值或者最大值作为一个输入数据,这样就大大简化了数据数量。
池化(Pooling)是卷积神经网络中的一种常用操作,其目的是通过减小特征图的空间大小来降低模型的复杂度。在池化操作中,我们将特征图划分为多个子区域,然后对每个子区域进行聚合操作,生成一个较小的特征图。
通常,池化操作的聚合操作可以是取最大值(Max Pooling)、取平均值(Average Pooling)等,其中最大值池化是最常用的一种。
池化的作用有以下几点:
-
减小特征图的空间大小,降低模型复杂度,减少计算量。
-
增强模型对平移不变性的学习能力,即使目标在图像中稍微移动一点,也能保持对它的识别能力。
-
缓解过拟合,减少模型对噪声的敏感性,提高模型的泛化能力。
在实际应用中,池化操作通常会与卷积操作交替进行,以构建一个完整的卷积神经网络。同时,由于池化操作的缩小特征图的空间大小,因此在池化操作之前,可以通过增加卷积层的数量或通道数来提高模型的表达能力,从而保持对目标的识别能力。
Pytorch中常用的池化操作的函数
还是上一篇的例子,我们把每一个卷积核的结果进行最大值或平均值池化,可得到如下结果
这样数据量明显减小。以下是python代码
import numpy as np
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image# 读取图像并将其转换为灰度图
img = Image.open("/home/cbc/图片/2.png")
imgGray = np.array(img.convert("L"), dtype=np.float32) # convert("L") 转换为单通道图片imh,imw = imgGray.shape
# 将二维的灰度图像转换成四维的张量,维度为(1, 1, imh, imw),表示一个batch,一个通道,高为imh,宽为imw
imgGray_torch = torch.from_numpy(imgGray.reshape((1,1,imh,imw)))
print(imgGray_torch.shape)
# 定义卷积核大小和卷积核矩阵,其中心为24,其余为-1
kersize = 5
ker = torch.ones(kersize, kersize, dtype=torch.float32) * -1
ker[2, 2] = 24
ker = ker.reshape((1, 1, kersize, kersize))# 将卷积核矩阵转换成张量,维度为(1, 1, kersize, kersize),表示一个batch,一个通道,卷积核的高和宽分别为kersize
ker = ker.reshape((1, 1, kersize, kersize))# 定义一个2D卷积层,输入通道数为1,输出通道数为2,卷积核的大小为(kersize,kersize),不使用偏置项
conv2d = nn.Conv2d(1, 2, (kersize, kersize), bias=False)# 将卷积核张量赋值给卷积层的权重,第一个通道的权重为ker
conv2d.weight.data[0] = ker# 对灰度图像进行卷积操作
imconv2dout = conv2d(imgGray_torch)
maxpoll2 = nn.MaxPool2d(2,stride=2)
pool2_out = maxpoll2(imconv2dout)# 将卷积和池化的结果的张量降维成二维数组
imconv2dout_im = pool2_out.data.squeeze()# 打印卷积结果的形状
print("卷积后的尺寸:", imconv2dout_im.shape)# 绘制卷积结果的两个通道
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.imshow(imconv2dout_im[0], cmap=plt.cm.gray)
plt.axis(False)
plt.subplot(1, 2, 2)
plt.imshow(imconv2dout_im[1], cmap=plt.cm.gray)
plt.axis(False)
plt.show()
可以看出,由于池化后的输入数据量减少,图像也变得模糊了。