6

在使用 Keras(使用 TensorFlow 后端)调整深度卷积网络时,我想尝试在 和 之间进行混合MaxPooling2DAveragePooling2D因为这两种策略似乎都改善了关于我的目标的两个不同方面。

我正在考虑这样的事情:

    -------
    |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

或者作为一个等式:

hybrid_pooling(x, alpha_max) =
    alpha_max * max_pooling(x) + (1 - alpha_max) * average_pooling(x)

既然这样的东西看起来不是现成的,那如何才能有效地实施呢?

4

2 回答 2

5

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

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

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

代码(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')

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

于 2017-08-10T09:06:46.337 回答
0

这里有一个简单的实现alpha * average_pooling(x) + (1 - alpha) * max_pooling(x)放在网络中......

x = Conv2D(32, 3, activation='relu')(...)
a = AveragePooling2D()(x)
a = Lambda(lambda xx : xx*alpha)(a)
m = MaxPooling2D()(x)
m = Lambda(lambda xx : xx*(1-alpha))(m)
x = Add()([a,m])

alpha = 0.xx[0,1] 范围内

于 2020-07-09T10:33:02.290 回答