【caffe】关于gempool层

近期由于又重新接触到pytorch转caffe的相关任务(gempool)。发现BN并不是caffe底层代码就已经写了一个BN的实现,而是在prototxt用一些不同的算子组合成BN层。

这一点仿佛为我打开了新世界的大门,觉得还挺神奇的,所以先写一篇来看看gempool公式,并进行对应的prototxt的实现吧。加深一下理解。

1.分析

Generalized Mean Pooling Explained | Papers With Codehttps://paperswithcode.com/method/generalized-mean-pooling看下面的公式,可能会云里雾里,但是会发现有相同的参数p,一个时power(p),一个是power(1/p)。

对应的代码(https://github.com/JDAI-CV/fast-reid/blob/master/fastreid/layers/pooling.py#L50),上面公式的代码表示:

class GeneralizedMeanPooling(nn.Module):
    r"""Applies a 2D power-average adaptive pooling over an input signal composed of several input planes.
    The function computed is: :math:`f(X) = pow(sum(pow(X, p)), 1/p)`
        - At p = infinity, one gets Max Pooling
        - At p = 1, one gets Average Pooling
    The output is of size H x W, for any input size.
    The number of output features is equal to the number of input planes.
    Args:
        output_size: the target output size of the image of the form H x W.
                     Can be a tuple (H, W) or a single H for a square image H x H
                     H and W can be either a ``int``, or ``None`` which means the size will
                     be the same as that of the input.
    """

    def __init__(self, norm=3, output_size=(1, 1), eps=1e-6, *args, **kwargs):
        super(GeneralizedMeanPooling, self).__init__()
        assert norm > 0
        self.p = float(norm)
        self.output_size = output_size
        self.eps = eps

    def forward(self, x):
        x = x.clamp(min=self.eps).pow(self.p)
        return F.adaptive_avg_pool2d(x, self.output_size).pow(1. / self.p)

    def __repr__(self):
        return self.__class__.__name__ + '(' \
               + str(self.p) + ', ' \
               + 'output_size=' + str(self.output_size) + ')'

2.实现

由上面知道基本是两个power与一个avgpool夹心饼干的组合。得到一个gempool。如果是固定参数的话,就计算好就行了,分数部分需要修改为小数。

那以上面的代码为例,p=3,则1/p≈0.3334。

layer {
  name: "gem_power1"
  type: "Power"
  bottom: "relu_blob1"
  top: "power_blob1"
  power_param {
    power: 2
    scale: 1
    shift: 0
  }
}
layer {
    name: "avgpool1"
    type: "Pooling"
    bottom: "power_blob1"
    top: "avgpool_blob1"
    pooling_param {
        pool: AVE
        global_pooling: true
    }
}
layer {
  name: "gem_power2"
  type: "Power"
  bottom: "avgpool_blob1"
  top: "power_blob2"
  power_param {
    power: 0.5
    scale: 1
    shift: 0
  }
}

猜你喜欢

转载自blog.csdn.net/qq_35975447/article/details/120787868