中值池化
中值池化是参考图像处理中的中值滤波而引申的一种池化方式。在目前CNN架构中极为少见,仅发现一篇论文:基于卷积神经网络和中值池化的人脸识别,不确定是否为水文。
在前向与反向传播过程中,中值池化类似于最大值池化,故不再赘述。
中值池化同样具有学习边缘和纹理结构的特性,同时具有抗噪性。代码描述参考:
# 代码摘自开源项目:pytorch-image-models
class MedianPool2d(nn.Module):
""" Median pool (usable as median filter when stride=1) module.
Args:
kernel_size: size of pooling kernel, int or 2-tuple
stride: pool stride, int or 2-tuple
padding: pool padding, int or 4-tuple (l, r, t, b) as in pytorch F.pad
same: override padding and enforce same padding, boolean
"""
def __init__(self, kernel_size=3, stride=1, padding=0, same=False):
super(MedianPool2d, self).__init__()
self.k = _pair(kernel_size)
self.stride = _pair(stride)
self.padding = _quadruple(padding) # convert to l, r, t, b
self.same = same
def _padding(self, x):
if self.same:
ih, iw = x.size()[2:]
if ih % self.stride[0] == 0:
ph = max(self.k[0] - self.stride[0], 0)
else:
ph = max(self.k[0] - (ih % self.stride[0]), 0)
if iw % self.stride[1] == 0:
pw = max(self.k[1] - self.stride[1], 0)
else:
pw = max(self.k[1] - (iw % self.stride[1]), 0)
pl = pw // 2
pr = pw - pl
pt = ph // 2
pb = ph - pt
padding = (pl, pr, pt, pb)
else:
padding = self.padding
return padding
def forward(self, x):
x = F.pad(x, self._padding(x), mode='reflect')
x = x.unfold(2, self.k[0], self.stride[0]).unfold(3, self.k[1], self.stride[1])
x = x.contiguous().view(x.size()[:4] + (-1,)).median(dim=-1)[0]
return x
分数阶最大值池化
分数阶最大值池化(Fractional Max Pooling)见诸于ARXIV。本文查阅Pytorch代码时发现的,先前未曾了解过,也未曾用过。感兴趣者可以参见原文或者用pytorch代码试玩几把,这里提供一个pytorch试玩deme:
import torch
import torch.nn as nn
inputs = torch.rand(20, 16, 50, 32)
fmp = nn.FractionalMaxPool2d(3, output_ratio=(0.8, 0.8))
output = fmp(inputs)
print(output.size())
# 此时output的尺寸为:20X16X40X25.
组合池化
组合池化则是同时利用最大值池化与均值池化两种的优势而引申的一种池化策略。常见组合策略有两种:Cat与Add。其代码描述如下:
def add_avgmax_pool2d(x, output_size=1):
x_avg = F.adaptive_avg_pool2d(x, output_size)
x_max = F.adaptive_max_pool2d(x, output_size)
return 0.5 * (x_avg + x_max)
def cat_avgmax_pool2d(x, output_size=1):
x_avg = F.adaptive_avg_pool2d(x, output_size)
x_max = F.adaptive_max_pool2d(x, output_size)
return torch.cat([x_avg, x_max], 1)