空间⾦字塔池化(SpatialPyramidPooling,SPP)原理及代码实现(Pyt。。。
空间⾦字塔池化(SpatialPyramidPooling,SPP)原理及代码实现(Pytorch)
卷积神经⽹络(CNN)由卷积层和全连接层组成,其中卷积层对于输⼊数据的⼤⼩并没有要求,唯⼀对数据⼤⼩有要求的则是第⼀个全连接
层,因此基本上所有的CNN都要求输⼊数据固定⼤⼩,例如著名的VGG模型则要求输⼊数据⼤⼩是(224*224)。
固定输⼊数据⼤⼩有两个问题:
1.很多场景所得到数据并不是固定⼤⼩的,例如街景⽂字基本上其⾼宽⽐是不固定的。
2.可能你会说可以对图⽚进⾏切割,但是切割的话很可能会丢失到重要信息。
综上,SPP的提出就是为了解决CNN输⼊图像⼤⼩必须固定的问题,从⽽可以使得输⼊图像⾼宽⽐和⼤⼩任意。
1、SPP原理
上图是原⽂中给出的⽰意图,需要从下往上看:
⾸先是输⼊层(inputimage),其⼤⼩可以是任意的进⾏卷积运算,到最后⼀个卷积层(图中是conv5)输出得到该层的特征映射(feature
maps),其⼤⼩也是任意的。
下⾯进⼊SPP层
我们先看最左边有16个蓝⾊⼩格⼦的图,它的意思是将从conv5得到的特征映射分成16份,另外16X256中的256表⽰的是channel,即
SPP对每⼀层都分成16份(不⼀定是等⽐分,原因看后⾯的内容就能理解了)。
中间的4个绿⾊⼩格⼦和右边1个紫⾊⼤格⼦也同理,即将特征映射分别分成4X256和1X256份。
那么将特征映射分成若⼲等分是做什么⽤的呢?我们看SPP的名字就是到了,是做池化操作,⼀般选择MAXPooling,即对每⼀份进⾏最
⼤池化。
我们看上图,通过SPP层,特征映射被转化成了16X256+4X256+1X256=21X256的矩阵,在送⼊全连接时可以扩展成⼀维矩阵,即
1X10752,所以第⼀个全连接层的参数就可以设置成10752了,这样也就解决了输⼊数据⼤⼩任意的问题了。
注意上⾯划分成多少份是可以⾃⼰是情况设置的,例如我们也可以设置成3X3等,但⼀般建议还是按照论⽂中说的的进⾏划分。
2、SPP公式
3、代码实现
```python
#coding=utf-8
importmath
importtorch
onalasF
#构建SPP层(空间⾦字塔池化层)
classSPPLayer():
def__init__(lf,num_levels,pool_type='max_pool'):
super(SPPLayer,lf).__init__()
_levels=num_levels
_type=pool_type
defforward(lf,x):
num,c,h,w=()#num:样本数量c:通道数h:⾼w:宽
foriinrange(_levels):
level=i+1
kernel_size=((h/level),(w/level))
stride=((h/level),(w/level))
pooling=(((kernel_size[0]*level-h+1)/2),((kernel_size[1]*level-w+1)/2))
#选择池化⽅式
_type=='max_pool':
tensor=_pool2d(x,kernel_size=kernel_size,stride=stride,padding=pooling).view(num,-1)
el:
tensor=_pool2d(x,kernel_size=kernel_size,stride=stride,padding=pooling).view(num,-1)
#展开、拼接
if(i==0):
x_flatten=(num,-1)
el:
x_flatten=((x_flatten,(num,-1)),1)
returnx_flatten
参考代码:
/marsggbo/sppnet-pytorch/blob/master/spp_
本文发布于:2022-12-02 17:20:49,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/88/39186.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |