池化层

池化层

池化层的目标是对输入图像进行下采样(即缩小),以便减少计算量、内存使用量和参数数量(从而降低过拟合的风险)

池化层中的每个神经元都连接到位于一个小的矩形接受视野中的上一层中有限数量的神经元的输出。必须定义其大小、步幅和填充类型。但是,池化层没有权重。它所做的工作就是使用聚合函数(例如最大值或均值来聚合输入)

池化层通常独立地作用于每个输入通道,因此输出深度与输入深度相同

除减少计算量、内存使用量和参数数量之外,最大池化层还为小变化引入了一定程度的不变性。但是,最大池化也有一些缺点:首先,它显然是非常具有破坏性的,即使使用\(2\times2\)的小内核并且步幅为2,在两个方向上的输出也将减少到1/2(面积减少到1/4),丢弃了75%输入值。在某些应用中,不变性是不可取的

TensorFlow实现

在TensorFlow中实现最大池化层非常容易。以下代码使用\(2\times2\)内核创建一个最大池化层。步幅默认为内核大小,因此该层将使用步幅2(水平和垂直)。默认情况下,使用“valid”填充(即完全不填充):

from tensorflow import keras
max_pool = keras.layers.MaxPool2D(pool_size=2)

要创建平均池化层,只需要使用AvgPool2D而不是MaxPool2D。它的工作原理和最大池化层一样,只是它计算的是平均子而不是最大值。平均池化层曾经很受欢迎,但是现在通常使用最大池化层,因为它们通常表现更好。因为计算均值通常比计算最大值损失更少的信息,但是另外一方面,最大池化仅保留最强的特征,将所有无意义的特征都丢弃,因此下一层可获得更清晰的信号来使用。而且与平均池化相比,最大池化提供了更强的变换不变性,并且计算量略少于平均池化。

最大池化和平均池化可以沿深度维度而不是空间维度执行,尽管这不常见。这可以使CNN学习各种特征的不变性。例如,它可以学习多个滤波器,每个滤波器检测相同模式的不同旋转,并且深度最大池化层确保输出是相同的,而不考虑旋转。CNN可以类似地学会对其它任何东西的不变性:厚度、亮度、偏斜、颜色等等

Keras不包括深度最大池化层,但TensorFlow地底层深度学习API包括:只要使用tf.nn.max_pool()函数,并将内核大小和步幅指定为4元组(即大小为4的元组)。前三个值均为1:即内核大小、步幅和批量处理、高度和宽度应为1。最后一个值应为沿深度维度所需的内核大小和跨度。例如,3(这是必须输入深度的除数。如果上一层输出20个特征图,它将不起作用,因为20不是3的倍数):

import tensorflow as tf
output = tf.nn.max_pool(images, ksize=(1, 1, 1, 3),
                        strides=(1, 1, 1, 3), padding='valid')

如果要将其作为Keras模型中的一个层包括在内,将其包装在Lambda层中(或创建一个自定义的Keras层):

depth_pool = keras.layers.Lambda(lambda X: tf.nn.max_pool(
    X, ksize=(1, 1, 1, 3), strides=(1, 1, 1, 3), padding='valid'))

在现代架构中经常会看到最后一种类型的池化层是全局平均池化层。它的工作原理非常不同:它所做的是计算整个特征图的均值(这就像使用与输入有相同空间维度的池化内核的平均池化层)。这意味着它每个特征图和每个实例只输出一个单值。尽管这是极具破坏性的(特征图中的大多数信息都丢失了),但它可以用作输出层。要创建这样的层,只需要使用keras.layers.GlobalAvgPool2D类:

global_avg_pool=keras.layers.GlobalAvgPool2D()

它等效于此简单的Lambda层,该层计算空间维度(高度和宽度)上的平均值:

global_avg_pool=keras.layers.Lambda(lambda X:tf.reduce_mean(X,axis=[1,2]))
posted @ 2021-11-19 22:21  里列昂遗失的记事本  阅读(560)  评论(0编辑  收藏  举报