大数据,机器学习,人工智能大数据 爬虫Python AI SqlArtificial Intelligence

R-CNN系列其二:SPP-Net

2018-06-09  本文已影响8人  manofmountain

介绍

我们平时用于做物体分类或检测的CNN网络多是由两部分来组成,前端的CNN层构成的网络用于图片特征的抽象化提取与后端的FC层构成的网络用于具体的问题处理如分类或物体位置识别。因为模型中后端FC层的存在,意味着它只能接受固定大小的输入即每次输入tensor的维数必须相同。这带来一个问题即我们只能使用统一大小的图片作为网络输入,如此才能在前端CNN网络层的最后输出具有一致维数大小的数据特征集合(feature map)给接下来的网络层使用。为此很多时候,我们的网络在图片输入之前不得不对其进行一些处理如剪切(crop)或失真式变行(Warp),这些处理或会导致图片分辨率有变化,甚至可能使得输入图像有内容损失。

来自微软Sun, Jian老师的团队想到了一种可对任意大小的feature map输入进行Pooling处理来生成固定大小的空间金字塔式层化方法(Spatial pyramid pooling,简称SPP)。此种SPP层化方法被加在前端CNN层网络的最后一级feature map输出后可生成固定大小的特征来。这样就实现了CNN网络结构与图片输入大小之间的解耦。。理论上我们可以使用任意大小的图片作用CNN网络的输入了即使在网络的最后我们有FC层。

如下图中可以看到使用此层所能解决的CNN网络对输入图片大小存在依赖的问题。

CNN网络使用SPP层前后对输入图片所进行的处理

金字塔式池化层(Spatial Pyramid Pooling)

如以上介绍本质上金字塔式池化层也是一种池化层结构,只是它被巧妙的设计用来处理任意维度的输入Tensor,这样最终经过此层处理后,我们能够得到固定长度的结果向量。下图中我们能清晰地看到它是如何实现的。

带有金字塔式池化层的CNN网络

训练带有金字塔式池化层的CNN网络

理论上有了金字塔式池化层后,我们训练CNN网络模型将可以使用做任意大小(Size)的图片数据了。可因为当下像Caffe / Tensorflow等流行深度学习框架在设计之初都对固定大小的输入图片有假设,因此它们处理起来固定大小输入的模型训练更加友好。作者也先尝试使用了固定大小的输入图片来进行训练。但为了发挥其能使用多种大小图片进行模型训练的优势,他们使用迁移学习或者说多阶段学习的办法来进行模型训练。即使用180x180与224x224大小的图片交叉着训练CNN网络。。最终得到了与只使用单一大小图片输入一致的收敛速率。

SPP层在CNN检测网络中的应用

根据我们上篇对R-CNN网络的了解可以知道,我们的前端CNN网络需要对不同大小的ROI窗口进行特征提取。而为了保证最终得到一样大小的特征向量(因为接下来的SVM分类器与要对目标框进行位置较正的逻辑回归模型都需要固定大小的输入),我们一般会将原本具有不同大小的ROI强制转换为固定的大小(如180x180或224x224),如此以来可能会对ROI的输入对比度等造成破化,极有可能因此而影响我们分类器对正确物体的特征认识。
若将SPP层来代替普通的MaxPool或AvgPool层来使用,则可完美地解决输入的ROI窗口大小不一致的问题,从而有可能提高我们CNN模型+SVM 目标检测框架的准确性。下图中可看出SPP层是如何应用在此CNN网络+SVM分类模型的目标检测框架中的。

SPP层在目标检测框架中的应用

SPP层对CNN检测网络带来的好处

以下表格中可看到SPP层的使用所能给我们的R-CNN检测框架带来的模型准确率与速度上的好处。

SPP层的使用对R-CNN检测框架带来的提升

SPP在Caffe中的实现

--------------------------layer spm------------------------

layer {
name: "pool5_spm6"
type: "pool"
pool_param{
kernel_size: 3
stride: 2
pool: MAX
}
bottom: "conv5"
top: "pool5_spm6"
}

layer {
name: "pool5_spm6_flatten"
type: "flatten"
bottom: "pool5_spm6"
top: "pool5_spm6_flatten"
}

layer {
name: "pool5_spm3"
type: "pool"
pool_param{
kernel_size: 5
stride: 4
pool: MAX
}
bottom: "conv5"
top: "pool5_spm3"
}

layer {
name: "pool5_spm3_flatten"
type: "flatten"
bottom: "pool5_spm3"
top: "pool5_spm3_flatten"
}

layer {
name: "pool5_spm2"
type: "pool"
pool_param{
kernel_size: 7
stride: 7
pool: MAX
}
bottom: "conv5"
top: "pool5_spm2"
}

layer {
name: "pool5_spm2_flatten"
type: "flatten"
bottom: "pool5_spm2"
top: "pool5_spm2_flatten"
}

layer {
name: "pool5_spm1"
type: "pool"
pool_param{
kernel_size: 13
stride: 13
pool: MAX
}
bottom: "conv5"
top: "pool5_spm1"
}

layer {
name: "pool5_spm1_flatten"
type: "flatten"
bottom: "pool5_spm1"
top: "pool5_spm1_flatten"
}

layer {
name: "pool5_spm"
type: "concat"
concat_param{
concat_dim: 1
}
bottom: "pool5_spm1_flatten"
bottom: "pool5_spm2_flatten"
bottom: "pool5_spm3_flatten"
bottom: "pool5_spm6_flatten"
top: "pool5_spm"
}

参考文献

上一篇下一篇

猜你喜欢

热点阅读