在使用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
或者作为等式:
hybrid_pooling(x, alpha_max) =
alpha_max * max_pooling(x) + (1 - alpha_max) * average_pooling(x)
既然看起来这样的东西不是现成的,那怎么能以有效的方式实现呢?
答案 0 :(得分:2)
我现在使用不同的解决方案来组合两种池变体。
这种方法当然具有更高的计算成本,但也更灵活。 连接后的转换层可以学习简单地将两个合并结果与alpha混合,但它最终也可以使用不同的alpha来表示不同的功能,当然 - 就像转换层一样 - 以全新的方式组合合并的功能
代码(Keras功能API)如下所示:
def hybrid_pool_layer(x, pool_size=(2,2)):
return Conv2D(int(x.shape[-1]), (1, 1))(
keras.layers.concatenate([
MaxPooling2D(pool_size)(x),
AveragePooling2D(pool_size)(x)]))
当然,也可以省略Conv2D
并返回两个池的连接,让下一层进行合并工作。但是上面的实现确保了由此混合池产生的张量具有人们对正常单池操作所期望的形状。
答案 1 :(得分: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]