[Pytorch] SPP-Net 3D版本原理与实现

代码参考2d的 spp-net code Github

1.SPP 插入位置

在分类之前,FC要求输入特定尺寸的feature。当输入中包含不同size的图像时,传统的fc就不可以了。此时kaiming提出了SPP-Net,解决了这个问题。
[Pytorch] SPP-Net 3D版本原理与实现_第1张图片

2. SPP module 细节

输入任意大小的feature,使用maxpooling/average pooling等方法得到4x4xc,2x2xc, 1x1xc的三个固定大小feature。
[Pytorch] SPP-Net 3D版本原理与实现_第2张图片

3.代码实现

class SpatialPyramidPool3D(nn.Module):
    """
    Args:
        out_side (tuple): Length of side in the pooling results of each pyramid layer.

    Inputs:
        - `input`: the input Tensor to invert ([batch, channel, width, height])
    """

    def __init__(self, out_side):
        super(SpatialPyramidPool3D, self).__init__()
        self.out_side = out_side

    def forward(self, x):
        out = None
        for n in self.out_side:
            d_r, w_r, h_r = map(lambda s: math.ceil(s / n), x.size()[2:])  # Receptive Field Size
            s_d, s_w, s_h = map(lambda s: math.floor(s / n), x.size()[2:])  # Stride
            max_pool = nn.MaxPool3d(kernel_size=(d_r, w_r, h_r), stride=(s_d, s_w, s_h))
            y = max_pool(x)
            if out is None:
                out = y.view(y.size()[0], -1)
            else:
                out = torch.cat((out, y.view(y.size()[0], -1)), 1)
        return out

用的时候这么用,如果feature本身大小小于4*4,那肯定不行,4去掉就行。

self.spp = SpatialPyramidPool3D(out_side=(1,2,4))

4.输入输出维度

  • 输入必须大于stride
  • 这里注意下,3d的spp module计算输出的size 和2d的有一点差异。具体来说,比如设置out_side=(1,2),那么输出的维度是
    c h a n n e l × ( 1 + 2 × 2 × 2 ) = 90 × c h a n n e l channel\times(1+2\times2\times2)=90\times channel channel×(1+2×2×2)=90×channel

你可能感兴趣的:(deep,learning,torch)