首页 > 其他 > 详细

SPP

时间:2020-09-20 08:42:53      阅读:60      评论:0      收藏:0      [点我收藏+]

 

 

想直接看公式的可跳至第三节 3.公式修正

1|0一、为什么需要SPP


首先需要知道为什么会需要SPP。

我们都知道卷积神经网络(CNN)由卷积层和全连接层组成,其中卷积层对于输入数据的大小并没有要求,唯一对数据大小有要求的则是第一个全连接层,因此基本上所有的CNN都要求输入数据固定大小,例如著名的VGG模型则要求输入数据大小是 (224*224) 。

固定输入数据大小有两个问题:

1.很多场景所得到数据并不是固定大小的,例如街景文字基本上其高宽比是不固定的,如下图示红色框出的文字。

技术分享图片 技术分享图片

2.可能你会说可以对图片进行切割,但是切割的话很可能会丢失到重要信息。

综上,SPP的提出就是为了解决CNN输入图像大小必须固定的问题,从而可以使得输入图像高宽比和大小任意。

2|0二、SPP原理


更加具体的原理可查阅原论文:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition

技术分享图片

上图是原文中给出的示意图,需要从下往上看:
  • 首先是输入层(input image),其大小可以是任意的
  • 进行卷积运算,到最后一个卷积层(图中是????????5conv5)输出得到该层的特征映射(feature maps),其大小也是任意的
  • 下面进入SPP层
    • 我们先看最左边有16个蓝色小格子的图,它的意思是将从????????5conv5得到的特征映射分成16份,另外16X256中的256表示的是channel,即SPP对每一层都分成16份(不一定是等比分,原因看后面的内容就能理解了)。
    • 中间的4个绿色小格子和右边1个紫色大格子也同理,即将特征映射分别分成4X2561X256

那么将特征映射分成若干等分是做什么用的呢? 我们看SPP的名字就是到了,是做池化操作,一般选择MAX Pooling,即对每一份进行最大池化。

我们看上图,通过SPP层,特征映射被转化成了16X256+4X256+1X256 = 21X256的矩阵,在送入全连接时可以扩展成一维矩阵,即1X10752,所以第一个全连接层的参数就可以设置成10752了,这样也就解决了输入数据大小任意的问题了。

注意上面划分成多少份是可以自己是情况设置的,例如我们也可以设置成3X3等,但一般建议还是按照论文中说的的进行划分。

 

这里我使用的是PyTorch深度学习框架,构建了一个SPP层,代码如下:

#coding=utf-8 import math import torch import torch.nn.functional as F # 构建SPP层(空间金字塔池化层) class SPPLayer(torch.nn.Module): def __init__(self, num_levels, pool_type=‘max_pool‘): super(SPPLayer, self).__init__() self.num_levels = num_levels self.pool_type = pool_type def forward(self, x): num, c, h, w = x.size() # num:样本数量 c:通道数 h:高 w:宽 for i in range(self.num_levels): level = i+1 kernel_size = (math.ceil(h / level), math.ceil(w / level)) stride = (math.ceil(h / level), math.ceil(w / level)) pooling = (math.floor((kernel_size[0]*level-h+1)/2), math.floor((kernel_size[1]*level-w+1)/2)) # 选择池化方式 if self.pool_type == ‘max_pool‘: tensor = F.max_pool2d(x, kernel_size=kernel_size, stride=stride, padding=pooling).view(num, -1) else: tensor = F.avg_pool2d(x, kernel_size=kernel_size, stride=stride, padding=pooling).view(num, -1) # 展开、拼接 if (i == 0): x_flatten = tensor.view(num, -1) else: x_flatten = torch.cat((x_flatten, tensor.view(num, -1)), 1) return x_flatten
 

上述代码参考: sppnet-pytorch

为防止原作者将代码删除,我已经Fork了,也可以通过如下地址访问代码:
marsggbo/sppnet-pytorch

 

 

 

--> 能否直接输入 hierarchy ?

S: w * h 有 hierarchy 

T (和S的交互):是不是也有?

--> concat 有多 powerful?直接增加一个维度又如何呢?

--> 池化参数的影响(16->4->1 是一种,多取几种呢?--> deformable?--> adaptive?--> ImageNet 特征提取,相机和人眼感知的区别?--> 用各个视角的相片拼接人眼感知?

 

SPP

原文:https://www.cnblogs.com/cx2016/p/13698656.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!