Global average pooling

本文介绍了Global Average Pooling(GAP),它首次出现在论文Network in Network中,可提高CNN效果。先阐述了深度网络中常见的池化方式及全连接层,指出全连接层易造成过拟合。而GAP可取代最后的全连接层,实现降维、减少参数,还能从结构上防止过拟合。

Golbal Average Pooling 第一次出现在论文Network in Network中,后来又很多工作延续使用了GAP,实验证明:Global Average Pooling确实可以提高CNN效果。

Traditional Pooling Methods

要想真正的理解Global Average Pooling,首先要了解深度网络中常见的pooling方式,以及全连接层。

众所周知CNN网络中常见结构是:卷积、池化和激活。卷积层是CNN网络的核心,激活函数帮助网络获得非线性特征,而池化的作用则体现在降采样:保留显著特征、降低特征维度,增大kernel的感受野。深度网络越往后面越能捕捉到物体的语义信息,这种语义信息是建立在较大的感受野基础上。已古人的例子来做解释,想必大家都知道盲人摸象这个成语的来历,每个盲人只能触摸到大象的一部分,也就是只能获得local response,基于这些local response,盲人们很难猜对他们到底在摸什么。即使是一个明眼人,眼睛紧贴这大象后背看,也很难猜到看的是什么。这个例子告诉我们局部信息很难提供更高层的语义信息,因此对feature map降维,进而增大后面各层kernel的感受野是一件很重要的事情。另外一点值得注意:pooling也可以提供一些旋转不变性。


Fully Connected layer

很长一段时间以来,全连接网络一直是CNN分类网络的标配结构。一般在全连接后会有激活函数来做分类,假设这个激活函数是一个多分类softmax,那么全连接网络的作用就是将最后一层卷积得到的feature map stretch成向量,对这个向量做乘法,最终降低其维度,然后输入到softmax层中得到对应的每个类别的得分。

全连接层如此的重要,以至于全连接层过多的参数重要到会造成过拟合,所以也会有一些方法专门用来解决过拟合,比如dropout。


Global Average Pooling

有了上面的基础,再来看看global average poolilng。既然全连接网络可以使feature map的维度减少,进而输入到softmax,但是又会造成过拟合,是不是可以用pooling来代替全连接。

答案是肯定的,Network in Network工作使用GAP来取代了最后的全连接层,直接实现了降维,更重要的是极大地减少了网络的参数(CNN网络中占比最大的参数其实后面的全连接层)。Global average pooling的结构如下图所示: 
gap-structure
每个讲到全局池化的都会说GAP就是把avg pooling的窗口大小设置成feature map的大小,这虽然是正确的,但这并不是GAP内涵的全部。GAP的意义是对整个网络从结构上做正则化防止过拟合。既要参数少避免全连接带来的过拟合风险,又要能达到全连接一样的转换功能,怎么做呢?直接从feature map的通道上下手,如果我们最终有1000类,那么最后一层卷积输出的feature map就只有1000个channel,然后对这个feature map应用全局池化,输出长度为1000的向量,这就相当于剔除了全连接层黑箱子操作的特征,直接赋予了每个channel实际的类别意义。

### Global Average Pooling 的概念 全局平均池化(Global Average Pooling, GAP)是一种用于减少特征图空间维度的技术,通常应用于卷积神经网络(Convolutional Neural Networks, CNNs)。它通过计算整个特征图上的像素值的平均值得到单一数值来替代传统的全连接层。这种方法不仅减少了参数数量,还降低了过拟合的风险。 GAP 的主要作用是在最后一个卷积层之后应用,将每个通道的空间尺寸压缩为单个值。这使得模型可以直接从局部响应中提取全局信息[^2]。 ```python import tensorflow as tf from tensorflow.keras.layers import GlobalAveragePooling2D # 假设输入张量形状为 (batch_size, height, width, channels) input_tensor = tf.random.normal(shape=(32, 7, 7, 512)) # 示例输入 # 应用全局平均池化 gap_layer = GlobalAveragePooling2D() output_tensor = gap_layer(input_tensor) print(output_tensor.shape) # 输出形状应为 (32, 512),即 batch size 和 channel 数不变 ``` 在这个例子中,`GlobalAveragePooling2D` 层接收一个四维张量作为输入 `(batch_size, height, width, channels)`,并返回二维张量 `(batch_size, channels)`。这意味着高度和宽度被完全压缩成单个值,而通道数保持不变。 ### 实现细节 在深度学习框架中,如 TensorFlow 或 PyTorch,可以通过内置函数轻松实现 GAP: #### 使用 TensorFlow/Keras TensorFlow 提供了 `tf.keras.layers.GlobalAveragePooling2D()` 来简化这一过程。该方法会自动处理不同大小的输入,并将其转换为固定长度的向量[^4]。 #### 自定义实现 如果需要手动实现 GAP,则可以利用 NumPy 或 TensorFlow 的基本操作完成相同功能: ```python def custom_global_average_pooling(x): """ 手动实现全局平均池化的函数。 参数: x: 输入张量,形状为 (batch_size, height, width, channels). 返回: y: 经过全局平均池化后的张量,形状为 (batch_size, channels). """ return tf.reduce_mean(x, axis=[1, 2]) # 测试自定义实现 custom_output = custom_global_average_pooling(input_tensor) print(custom_output.shape) # 验证输出形状是否一致 ``` 这段代码展示了如何不依赖于预定义的层接口,而是直接调用底层运算符执行相同的逻辑。 ### 总结 全局平均池化提供了一种有效的方法,在保留重要语义信息的同时显著降低模型复杂度。对于某些特定应用场景而言,比如图像分类任务中的最后几层设计阶段,采用 GAP 可能带来性能提升以及训练效率改善的效果[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值