最大池和平均池的混合

Tob*_*ann 5 python-3.x keras tensorflow max-pooling spatial-pooling

在使用Keras(带有TensorFlow后端)调整深层卷积网络时,我想尝试一下MaxPooling2D和之间的混合AveragePooling2D,因为这两种策略似乎都可以改善我的目标的两个不同方面。

我正在考虑这样的事情:

    -------
    |8 | 1|
x = ---+---
    |1 | 6|
    -------

average_pooling(x)                ->   4
max_pooling(x)                    ->   8
hybrid_pooling(x, alpha_max=0.0)  ->   4
hybrid_pooling(x, alpha_max=0.25) ->   5
hybrid_pooling(x, alpha_max=0.5)  ->   6
hybrid_pooling(x, alpha_max=0.75) ->   7
hybrid_pooling(x, alpha_max=1.0)  ->   8
Run Code Online (Sandbox Code Playgroud)

或等式:

hybrid_pooling(x, alpha_max) =
    alpha_max * max_pooling(x) + (1 - alpha_max) * average_pooling(x)
Run Code Online (Sandbox Code Playgroud)

既然看起来好像没有现成的东西,那么如何以有效的方式实现它呢?

Tob*_*ann 5

我现在使用不同的解决方案来组合两种池化变体。

  • 将张量提供给两个池化函数
  • 连接结果
  • 使用一个小的conv层来学习如何组合

当然,这种方法具有更高的计算成本,但也更灵活。连接后的 conv 层可以学习简单地将两个池化结果与 alpha 混合,但它最终也可以为不同的特征使用不同的 alpha,当然 - 正如 conv 层所做的那样 - 以一种全新的方式组合池化的特征。

代码(Keras 函数式 API)如下所示:

import numpy as np
from tensorflow.keras.layers import Input, MaxPooling2D, Conv2D
from tensorflow.keras.layers import Concatenate, AveragePooling2D
from tensorflow.keras.models import Model

# implementation of the described custom pooling layer
def hybrid_pool_layer(pool_size=(2,2)):
    def apply(x):
        return Conv2D(int(x.shape[-1]), (1, 1))(
            Concatenate()([
                MaxPooling2D(pool_size)(x),
                AveragePooling2D(pool_size)(x)]))
    return apply

# usage example
inputs = Input(shape=(256, 256, 3))
x = inputs
x = Conv2D(8, (3, 3))(x)
x = hybrid_pool_layer((2,2))(x)
model = Model(inputs=inputs, outputs=x)
model.compile(loss='categorical_crossentropy', optimizer='nadam')
Run Code Online (Sandbox Code Playgroud)

当然,也可以省略Conv2D,只返回两个池的串联,让下一层进行合并工作。但是上面的实现确保了这种混合池化产生的张量具有正常的单一池化操作所期望的形状。