目标检测:3.SPP-Net

Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

arXiv

现有的卷积深度神经网络需要固定尺寸的图像输入,这可能会降低图像或子图像识别准确率。本文提出了新的池化策略—“空间金字塔池化”,用来消除对固定尺寸的依赖。SPP-net能够生成与图像尺寸无关的固定长度的表征。该方法能够有效提高分类准确率。在目标检测任务中,仅从整个图像计算一次特征图,然后对任意区域进行池化,生成固定长度的表征用于训练检测器,该方法能够有效避免重复计算卷积特征

在这里插入图片描述

常见的网络结构中大多为卷积-全连接结构,全连接层要求输入维度固定,这使得卷积层的输入也需要固定,为了输入固定尺寸大小的图像,通常采用裁剪或扭曲方法,前者会丢失目标信息,后者会导致几何畸变,降低识别准确率。SPP层位于最后一个卷积层的后面,将特征映射到固定长度的表征,然后再输入到全连接层,以此来避免对固定尺寸的输入。SPP在CNN中的三个特性:

  • 生成固定长度的输出不管输入尺寸
  • 使用多层空间窗口进行池化,而传统的滑动窗口池化仅使用一种,对目标变形更具有鲁棒性
  • 由于输入尺度的灵活性,SPP能够以不同的尺度池化提取的特征。

SPP-net可以在训练阶段输入不同的尺寸,使用多尺度图像训练可以增减尺度不变性、降低过拟合。卷积层使用权值共享,在不同的epoch使用不同的输入尺寸图像。实验显示该训练方法能够提高测试准确率。


在这里插入图片描述

SPP能过保持空间信息通过在局部空间范围内池化,池化区域的大小与图像尺寸成比例,因此池化核的数量也是固定的。如图所示,在每一个spatial bin中,对每个核进行池化,spp层输出 k M kM kM维向量,其中 M M M是bin(池化核)的数量, k k k是最后一层卷积层的filters数量(图像通道数)。然后将固定维度的特征向量输入到全连接层。

使用SPP,网络输入图像大小可以任意,可以将输入图像缩放到任意尺寸,然后提取不同此村的特征,这有助于提高深度网络的准确率。

最粗糙的金字塔层使用一个bin覆盖全图,相当于全局池化。

单尺寸训练:对于一张给定大小的图像,可以预先计算出用于spp的bin大小。假设特征图大小维 a × a a\times a a×a,其中一个金字塔层有 n × n n\times n n×n个bins,使用滑动窗口池化对该层进行池化,其中池化窗口的大小为 w i n = ⌈ a / n ⌉ win=\lceil{a/n}\rceil win=a/n,步长为 s t r = ⌊ a / n ⌋ str=\lfloor{a/n}\rfloor str=a/n。全连接层将所有金字塔层的池化结果进行拼接作为输入。

多尺寸训练:SPP可以用任何尺寸的图像,通过切换输入图像的尺寸大小可以进行多尺度训练。

假设特征图的大小为 w × h w\times h w×h,对于一个金字塔层为 n × n n\times n n×n个bin,第 ( i , j ) (i,j) (i,j)个bin的池化作用范围为 [ ⌊ i − 1 n w ⌋ , ⌈ i n w ⌉ ] × [ ⌊ j − 1 n h ⌋ , ⌈ j n h ⌉ ] [\lfloor{\frac{i-1}{n}w}\rfloor, \lceil{\frac{i}{n}w}\rceil]\times[\lfloor{\frac{j-1}{n}h}\rfloor, \lceil{\frac{j}{n}h}\rceil] [ni1w,niw]×[nj1h,njh]

注[1]:求解步长和池化核大小的公式有误,如当 a = 7 , n = 4 a=7,n=4 a=7,n=4时,按照原公式计算 w i n = 2 , s t r = 1 win=2,str=1 win=2,str=1,此时计算出来的输出特征图大小为 o u t = ⌊ a − w i n s t r ⌋ + 1 = 6 out=\lfloor{\frac{a-win}{str}}\rfloor+1=6 out=strawin+1=6,原因在于未考虑padding,实际上应为 w i n = ⌈ a / n ⌉ , s t r = ⌈ a / n ⌉ , p a d d i n g = ⌊ n ∗ w i n − a + 1 2 ⌋ win = \lceil{a/n}\rceil,str=\lceil{a/n}\rceil,padding=\lfloor{\frac{n*win-a+1}{2}}\rfloor win=a/nstr=a/n,padding=2nwina+1,此时 w i n = s t r = 2 , p a d d i n g = 1 win=str=2,padding=1 win=str=2,padding=1,计算出来的输出特征图大小为 4 4 4

import math
import torch
import torch.nn.functional as F

class SPPLayer(torch.nn.Module):
    def __init__(self, f_sizes=(1, 2, 4), pool_type='max_pool'):
        super(SPPLayer, self).__init__()
        self.f_sizes = f_sizes
        self.pool_type = pool_type

    def forward(self, x):
        batch, channel, h, w = x.size()
        res = None
        for i in range(len(self.f_sizes)):
            k_size = (math.ceil(h / self.f_sizes[i]), math.ceil(w / self.f_sizes[i]))
            stride = k_size
            padding = (math.floor((k_size[0]*self.f_sizes[i]-h+1)/2), math.floor((k_size[1]*self.f_sizes[i]-w+1)/2))
            if self.pool_type == 'max_pool':
                tensor = F.max_pool2d(x, kernel_size=k_size, stride=stride, padding=padding).view(batch, -1)
            else:
                tensor = F.avg_pool2d(x, kernel_size=k_size, stride=stride, padding=padding).view(batch, -1)
            if res is None:
                res = tensor
            else:
                res = torch.cat((res, tensor), dim=1)
        return res

R-CNN重复对2000个候选窗口进行卷积操作,导致十分耗时。SPP仅从整个图像提取一次特征图,然后对每一个候选窗口的特征图进行空间金字塔池化,将其池化为固定大小的窗口,能够大大运行时间。

过程:

  1. SS方法生成2000个候选窗口,对图像进行缩放至最小边满足 min ⁡ ( h , w ) = s \min(h,w)=s min(h,w)=s,从图像中提取特征。
  2. 对每一个候选窗口使用空间金字塔池化( 1 × 1 , 2 × 2 , 3 × 3 , 6 × 6 1\times1,2\times2,3\times3,6\times6 1×1,2×2,3×3,6×6,共50个bins),生成一个12800( 256 × 50 256\times50 256×50)维表征向量,然后输入到全连接层。
  3. 使用这些特征训练一个二类线性SVM,使用GT窗口生成正样本,负样本与正样本IoU不超过0.3,将与其他负样本IoU超过0.7的负样本移除,使用硬负样本挖掘训练SVM。在测试时,SVM 对每个候选窗口进行打分,然后用非极大值抑制(30%)进行删减。

使用多尺度特征能够改善检测性能,将图像缩放至 min ⁡ ( h , w ) = s , s ∈ { 480 , 576 , 688 , 846 , 1200 } \min(h,w)=s, s\in\{480, 576, 688, 846, 1200\} min(h,w)=s,s{480,576,688,846,1200},然后计算每个尺度的特征图,对于每一个候选窗口,选择一个单一尺度 s ∈ S s\in S sS,使得缩放后的候选窗口接近 224 × 224 224\times 224 224×224,仅使用该尺度特征图计算该窗口的特征。

候选窗口是给定在图像域上,使用它来对卷积特征图进行裁剪,所以需要在特征图上对候选窗口进行对齐。将候选窗口的角点坐标投影到特征图上,使得该角点接近于特征图像素感受野中心。由于卷积层和池化层使用填充使得该映射变得困难。特征图坐标为 ( x ′ , y ′ ) (x',y') (x,y),对应在图像域内的感受野中心为 ( x , y ) = ( S x ′ , S y ′ ) (x,y)=(Sx',Sy') (x,y)=(Sx,Sy),其中 S S S是步长的乘积。对于一个在图像域内的候选窗口,投影其left(top)边界: x ′ = ⌊ x / S ⌋ + 1 x'=\lfloor{x/S}\rfloor+1 x=x/S+1,right(bottom)边界: x ′ = ⌈ x / S − 1 ⌉ x'=\lceil{x/S}-1\rceil x=x/S1

[1]. https://www.cnblogs.com/marsggbo/p/8572846.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值