spp
基于空间金字塔池化的卷积神经网络物体检测
原文地址:http://blog.csdn.net/hjimce/article/details/50187655
作者:hjimce
一、相关理论
本篇博文主要讲解大神何凯明2014年的paper:《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》,这篇paper主要的创新点在于提出了空间金字塔池化。paper主页:http://research.microsoft.com/en-us/um/people/kahe/eccv14sppnet/index.html 这个算法比R-CNN算法的速度快了n多倍。
我们知道在现有的CNN中,对于结构已经确定的网络,需要输入一张固定大小的图片,比如224*224,32*32,96*96等。这样对于我们希望检测各种大小的图片的时候,需要经过裁剪,或者缩放等一系列操作,这样往往会降低识别检测的精度,于是paper提出了“空间金字塔池化”方法,这个算法的牛逼之处,在于使得我们构建的网络,可以输入任意大小的图片,不需要经过裁剪缩放等操作,只要你喜欢,任意大小的图片都可以。不仅如此,这个算法用了以后,精度也会有所提高,总之一句话:牛逼哄哄。
空间金字塔池化,又称之为“SPP-Net”,记住这个名字,因为在以后的外文文献中,你会经常遇到,特别是物体检测方面的paper。这个就像什么:OverFeat、GoogleNet、R-CNN、AlexNet……为了方便,学完这篇paper之后,你就需要记住SPP-Net是什么东西了。空间金子塔以前在特征学习、特征表达的相关文献中,看到过几次这个算法。
既然之前的CNN要求输入固定大小的图片,那么我们首先需要知道为什么CNN需要输入固定大小的图片?CNN大体包含3部分,卷积、池化、全连接。
首先是卷积,卷积操作对图片输入的大小会有要求吗?比如一个5*5的卷积核,我输入的图片是30*81的大小,可以得到(26,77)大小的图片,并不会影响卷积操作。我输入600*500,它还是照样可以进行卷积,也就是卷积对图片输入大小没有要求,只要你喜欢,任意大小的图片进入,都可以进行卷积。
池化:池化对图片大小会有要求吗?比如我池化大小为(2,2)我输入一张30*40的,那么经过池化后可以得到15*20的图片。输入一张53*22大小的图片,经过池化后,我可以得到26*11大小的图片。因此池化这一步也没对图片大小有要求。只要你喜欢,输入任意大小的图片,都可以进行池化。
全连接层:既然池化和卷积都对输入图片大小没有要求,那么就只有全连接层对图片结果又要求了。因为全连接层我们的连接劝值矩阵的大小W,经过训练后,就是固定的大小了,比如我们从卷积到全连层,输入和输出的大小,分别是50、30个神经元,那么我们的权值矩阵(50,30)大小的矩阵了。因此空间金字塔池化,要解决的就是从卷积层到全连接层之间的一个过度。
也就是说在以后的文献中,一般空间金子塔池化层,都是放在卷积层到全连接层之间的一个网络层。
二、算法概述
OK,接着我们即将要讲解什么是空间金字塔池化。我们先从空间金字塔特征提取说起(这边先不考虑“池化”),空间金字塔是很久以前的一种特征提取方法,跟Sift、Hog等特征息息相关。为了简单起见,我们假设一个很简单两层网络:
输入层:一张任意大小的图片,假设其大小为(w,h)。
输出层:21个神经元。
也就是我们输入一张任意大小的特征图的时候,我们希望提取出21个特征。空间金字塔特征提取的过程如下:
图片尺度划分
如上图所示,当我们输入一张图片的时候,我们利用不同大小的刻度,对一张图片进行了划分。上面示意图中,利用了三种不同大小的刻度,对一张输入的图片进行了划分,最后总共可以得到16+4+1=21个块,我们即将从这21个块中,每个块提取出一个特征,这样刚好就是我们要提取的21维特征向量。
第一张图片,我们把一张完整的图片,分成了16个块,也就是每个块的大小就是(w/4,h/4);
第二张图片,划分了4个块,每个块的大小就是(w/2,h/2);
第三张图片,把一整张图片作为了一个块,也就是块的大小为(w,h)
空间金字塔最大池化的过程,其实就是从这21个图片块中,分别计算每个块的最大值,从而得到一个输出神经元。最后把一张任意大小的图片转换成了一个固定大小的21维特征(当然你可以设计其它维数的输出,增加金字塔的层数,或者改变划分网格的大小)。上面的三种不同刻度的划分,每一种刻度我们称之为:金字塔的一层,每一个图片块大小我们称之为:windows size了。如果你希望,金字塔的某一层输出n*n个特征,那么你就要用windows size大小为:(w/n,h/n)进行池化了。
当我们有很多层网络的时候,当网络输入的是一张任意大小的图片,这个时候我们可以一直进行卷积、池化,直到网络的倒数几层的时候,也就是我们即将与全连接层连接的时候,就要使用金字塔池化,使得任意大小的特征图都能够转换成固定大小的特征向量,这就是空间金字塔池化的奥义(多尺度特征提取出固定大小的特征向量)。具体的流程图如下:
三、算法源码实现
可能看完上面的过程,你还不是对算法的源码实现有信心,为了证明自己的理解是否有误,那么我们就需要去阅读源码的实现,下面是caffe对于空间金字塔池化实现的源码:
未完待续,敬请期待……
四、算法应用之物体检测
在SPP-Net还没出来之前,物体检测效果最牛逼的应该是RCNN算法了,下面跟大家简单讲一下R-CNN的总算法流程,简单回顾一下:
1、首先通过选择性搜索,对待检测的图片进行搜索出2000个候选窗口。
2、把这2k个候选窗口的图片都缩放到227*227,然后分别输入CNN中,每个候选窗台提取出一个特征向量,也就是说利用CNN进行提取特征向量。
3、把上面每个候选窗口的对应特征向量,利用SVM算法进行分类识别。
可以看到R-CNN计算量肯定很大,因为2k个候选窗口都要输入到CNN中,分别进行特征提取,计算量肯定不是一般的大。
OK,接着回归正题,如何利用SPP-Net进行物体检测识别?具体算法的大体流程如下:
1、首先通过选择性搜索,对待检测的图片进行搜索出2000个候选窗口。这一步和R-CNN一样。
2、特征提取阶段。这一步就是和R-CNN最大的区别了,同样是用卷积神经网络进行特征提取,但是SPP-Net用的是金字塔池化。这一步骤的具体操作如下:把整张待检测的图片,输入CNN中,进行一次性特征提取,得到feature maps,然后在feature maps中找到各个候选框的区域,再对各个候选框采用金字塔空间池化,提取出固定长度的特征向量。而R-CNN输入的是每个候选框,然后在进入CNN,因为SPP-Net只需要一次对整张图片进行特征提取,速度是大大地快啊。江湖传说可一个提高100倍的速度,因为R-CNN就相当于遍历一个CNN两千次,而SPP-Net只需要遍历1次。
3、最后一步也是和R-CNN一样,采用SVM算法进行特征向量分类识别。
算法细节说明:看完上面的步骤二,我们会有一个疑问,那就是如何在feature maps中找到原始图片中候选框的对应区域?因为候选框是通过一整张原图片进行检测得到的,而feature maps的大小和原始图片的大小是不同的,feature maps是经过原始图片卷积、下采样等一系列操作后得到的。那么我们要如何在feature maps中找到对应的区域呢?这个答案可以在文献中的最后面附录中找到答案:APPENDIX A:Mapping a Window to Feature Maps。这个作者直接给出了一个很方便我们计算的公式:假设(x’,y’)表示特征图上的坐标点,坐标点(x,y)表示原输入图片上的点,那么它们之间有如下转换关系:
(x,y)=(S*x’,S*y’)
其中S的就是CNN中所有的strides的乘积。比如paper所用的ZF-5:
S=2*2*2*2=16
而对于Overfeat-5/7就是S=12,这个可以看一下下面的表格:
需要注意的是Strides包含了池化、卷积的stride。自己计算一下Overfeat-5/7(前5层)是不是等于12。
反过来,我们希望通过(x,y)坐标求解(x’,y’),那么计算公式如下:
因此我们输入原图片检测到的windows,可以得到每个矩形候选框的四个角点,然后我们再根据公式:
Left、Top:
Right、Bottom:
相关阅读
这篇文章翻译至denny britz的博客。 一、数据预处理 这个情感分析的数据集来自Rotten Tomatoes的电影评论,总共10662个样本,一半
每次请回顾: Faster RCNN 学习笔记 faster rcnn源码解析 Faster RCNN:RPN,anchor,sliding windows https://zhuanlan.zhihu.com/p/32
深度学习(二)—图像检测算法(faster R-cnn)简单易懂的思路
基础知识掌握情况决定研究的高度,我们刚开始接触深度学习时,一般都是看到别人的概括,这个方法很好能让我们快速上手,但是也有一个很大
如何利用Q哥Q妹图标来看加密的QQ空间和相册 大家看详细操作 假如对方的QQ空间加了密 而你又很想看 那你就让对方点他的Q哥Q妹图标
社交是人与人之间的交际来往,六度空间理论作为一个数学领域的猜想,由于其本质是围绕人与人的关系来进行实验的,在我们所见到的社交产