R-CNN Series
RCNN
1 |
|
R-CNN 算法流程分四个步骤:
一张图像生成1k~2k个候选区域(使用 Selective Search 方法) [https://zhuanlan.zhihu.com/p/485727819]
候选区域生成 (Selective Search) 的主要思想:图像中物体可能存在的区域应该是有某些相似性或者连续性区域的。
- 首先,对输入图像进行分割算法产生许多小的子区域。
- 其次,根据这些子区域之间相似性(相似性标准主要有颜色、纹理、大小等等)进行区域合并,不断的进行区域迭代合并。每次迭代过程中对这些合并的子区域做bounding boxes(外切矩形),这些子区域外切矩形就是通常所说的候选框。
对每个候选区域,使用深度网络(图片分类网络)提取特征
- 通过SS算法可以在一张图片中生成大概2000个候选区域,将候选区域送到CNN网络之前先进行resize处理,将2000候选区域缩放到 227 × 227 (原文是不管候选框多大都resize到 227 × 227)
- 接着将候选区域输入事先训练好的AlexNet / VGG CNN网络获取4096维的特征,得到2000×4096维矩阵。
特征送入每一类SVM分类器,判断是否属于该类
将
2000×4096
维特征与20
个SVM组成的权值矩阵4096×20
相乘,获得2000×20
维矩阵表示每个建议框是某个目标类别的得分分别对上述
2000×20
维矩阵中每一列即每一类进行**NSM(非极大值抑制)**剔除重叠建议框,得到该列即该类中得分最高的一些建议框。
使用回归器精细修正候选框位置。(使用 Selective Search 算法得到的候选框并不是框得那么准)
- 对NMS处理后剩余的建议框进一步筛选
- 分别用20个回归器对上述20个类别中剩余的建议框进行回归操作,最终得到每个类别的修正后的得分最高的bounding box
(原文):
- 保留与真实目标比IoU大于某一阈值的预测框,不满足的直接删除
- 接着再分别使用20个回归器对剩余的预测框进行回归操作,最终得到每个类别的修正后得分最高的预测框。这里的实现方法跟上面的SVM分类差不多,依旧是对卷积神经网络输出的特征向量进行预测,利用每个边界框得到4096维特征向量来预测的。通过回归分类器之后会得到四个参数分别对应着目标建议框的中心点的x,y偏移量和目标边界框的宽高缩放因子。通过预测的四个值对得到的建议框进行调整得到最终的预测边界框。
RCNN存在的问题
- 检测速度慢,测试一张图片约53s (CPU)。用Selective Search算法提取候选框用时约2秒,一张图像内候选框之间存在大量重叠,提取特征操作冗余。
- 训练速度慢,并且训练过程极其复杂。
- 训练所需空间大,对于SVM和bbox回归训练,需要从每个图像中的每个目标候选框提取特征,并写入磁盘。对于非常深的网络,如VGG16,从VOC07训练集上的5k图像上提取的特征需要数百GB的存储空间。
SPPNet
1 |
|
针对R-CNN的缺点:
1).对每个候选区域提取特征。2).输入CNN的候选区域大小固定,要经过Resize。SPPNet做出了以下改进,具体内容看表格:
SPPNet让SS算法得到候选区域与feature map直接映射,得到候选区域的映射特征向量(这是映射来的,不需要每个候选区域都再经过CNN的计算,极大的减少了计算量)。
SPPNet引入一种空间金字塔池化( spatial pyramid pooling,SPP)层以移除网络对固定尺寸的限制(不需要候选区域经过crop/wrap等操作变换成固定大小的图像)。
R-CNN模型 SPPNet模型 1.R-CNN让每个候选区域经过crop/wrap等操作变换成固定大小的图像. 2. 固定大小的每个候选区域塞给CNN 传给后面的层做训练回归、分类操作 1.SPPNet把全图塞给CNN得到全图的feature map. 2.让SS算法得到候选区域与feature map直接映射,得到候选区域的映射特征向量(这是映射来的,不需要过CNN). 3.映射过来的特征向量大小不固定,所以这些特征向量塞给SPP层(空间金字塔变换层),SPP层接收任何大小的输入,输出固定大小的特征向量,再塞给FC层. 4.经过映射+SPP转换,简化了计算,速度/精确度也上去了
两个关键问题:
SPP层怎么可以接收任意大小的输入,输出固定的向量?
spp layer会将每个候选区域分成1x1,2x2,4x4三张子图,对每个子图的每个区域作max pooling,得出的特征再连接到一起就是(16+4+1)x256=21x256=5376维向量,接着给全连接层做进一步处理。
SPPNet怎么就能把候选区域从全图的feature map 直接得到特征向量?
整个映射过程有具体的公式:$(x,y)=(Sx’,Sy’)$ $(x’,y’)=([x/S]+1,[y/S]+1)$(左上角+,右下角-)
其中 S 就是CNN中所有的strides的乘积,包含了池化、卷积的stride。论文中使用S的计算出来为2x2x2x2=16,在ZF-5结构中。
Fast R-CNN
1 |
|
参考文章:
Fast R-CNN 算法流程分四个步骤:
一张图像生成1k~2k个候选区域(使用 Selective Search 方法)
将图像输入网络得到相应的特征图,将 Selective Search 算法生成的候选框投影到特征图上获得相应的特征矩阵
将每个特征矩阵通过 ROI pooling层缩放为$ 7 \times 7$大小的特征图
ROI「region of interests」:指的是矩形框框出的区域,可能是有目标的也可能没目标,概念上等价于proposal region。
ROI Pooling层的具体做法是:
对候选框所对应的特征矩阵,将其划分为7*7,也就是49等份。划分之后,对每一个区域做一个最大池化下采样操作,也就是MaxPooling操作。如此对49等分的候选区域操作,便得到了一个7*7的特征矩阵。
也就是说,无论候选框的特征矩阵是怎么样的尺寸,都被缩放到一个7*7的大小,这样就可以不去限制输入图像的尺寸了。
接着将特征图展平通过一系列全连接层获得预测结果
最后并联了两个全连接层分别对分类和bbox进行预测。
分类结点数为 N+1,因为需要增加上背景。bbox预测的全连接层则是$4*(N+1)$个结点,对每一类都要预测出来边界框回归参数。
损失函数
Fast RCNN将分类与回归做到了一个网络里面,因此损失函数必定是多任务的:
$$
L(p,u,t^u,v)=L_{cls}(p,u)+\lambda[u\geq1]L_{loc}(t^u,v)
$$分类损失:$L_{cls}(p,u) $
使用交叉熵损失,
p
为预测结果的向量表示,u
为真实类别的标签数据。bbox回归器损失:$\lambda[u>=1]L_{loc}(t^u,v)$ :
$\lambda$: 用于调节两部分损失函数的比例,一般取1
$[u\geq1]$: 是因为将
u
定义成了真实类别的索引,而且将background这一类定义成了0。所以如果标签是0的时候,这部分是不需要计算bbox的损失函数的,因为background不需要bbox。$L_{loc}(t^u,v)$
$$
L_{loc}(t^u,v)=\sum_{i\in{x,y,w,h}}smooth_{L1}(t_i^u-v_i)
$$$$
smooth_{L1}(x)=
\begin{cases}
0.5x^2 &if\space|x|<1\
|x|-0.5 &otherwise
\end{cases}
$$这一部分就是把预测框与groud truth中的x, y, w, h都单独拿出来进行相减(实际上就是L1的损失函数),然后计算smooth函数($Smooth_{L1}$),最后把这四个的smooth进行相加就是bbox回归器的损失函数。
1
2
3
4
5
6def smooth_l1(y_true, y_pred):
# y_true和y_pred是特征位置的真实值和预测值
abs_diff = K.abs(y_true - y_pred)
less_than_one = K.cast(K.less(abs_diff, 1.0), "float32")
loss = (0.5 * abs_diff**2) * less_than_one + (abs_diff - 0.5) * (1 - less_than_one)
return loss
Faster R-CNN
1 |
|
这篇文章介绍Faster R-CNN写的非常非常详细!
Faster R-CNN 算法流程分三个步骤:
- 将图像输入网络得到相应的特征图-feature map
- 使用RPN网络(Region Proposal Network)生成候选框,将 RPN 生成的候选框投影到特征图上获得相应的特征矩阵
- 将每个特征矩阵通过 ROI pooling 层缩放为$7 \times 7$大小的特征图,接着将特征图展平通过一系列全连接层获得预测结果
RPN 网络结构
滑动窗口生成anchors -> softmax分类器提取positvie anchors -> bbox reg回归positive anchors -> Proposal Layer生成proposals
流程细节:
在经过backbone之后生成Feature Map大小为:H*W*N
N是根据使用backbone的通道数来定的,比如VGG16为512个通道,而使用ZF网络则是256个通道。
对特征图做了3x3卷积,但输出层数保持不变(N),相当于每个点又融合了周围3x3的空间信息(猜测这样做也许更鲁棒?反正我没测试)
在上一步的结果上使用滑动窗口,每滑动到一个位置生成一个一维的向量, 在向量的基础上通过两个全连接层去输出目标概率(背景/非背景)和边界框回归参数。
256-d是指使用ZF model作为backbone,最终每个点都用一个256维的向量表示,即
N=256
。1*1卷积+Cls layer + Reg layer:
在分类任务「Cls layer」中,经过1*1卷积后,输出图像大小为:H*W*18,正好对应9个anchor boxes的2分类结果。为何要在softmax前后都接一个reshape layer?其实只是为了便于softmax分类,具体原因这就要从caffe的实现形式说起。
在回归任务「Reg layer」,经过1*1卷积后,输出图像大小为:H*W*36,正好对应9个anchor boxes的边界框。
2k 中的 k 指的是 k 个 anchor boxes,2是指为背景的概率和为前景的概率。
4k 中的 k 指的是 k 个 anchor boxes,4是指每个 anchor 有 4 个边界框回归参数。
Proposal层
Proposal层共有三个输入:分类器结果【1,2*9,H,W】、边界框回归参数【1,4*9,H,W】、img_info
Proposal Layer forward(caffe layer的前向函数)按照以下顺序依次处理:
生成anchors,利用$d_x(A),d_y(A),d_w(A),d_h(a)$对所有的anchors做bbox regression回归(这里的anchors生成和训练时完全一致)
按照输入的positive softmax scores由大到小排序anchors,提取前pre_nms_topN(e.g. 6000)个anchors,即提取修正位置后的positive anchors
判定超出图像边界的positive anchors为图像边界,防止后续roi pooling时proposal超出图像边界
剔除尺寸非常小的positive anchors
对剩余的positive anchors进行NMS(nonmaximum suppression)
对应的bbox reg的结果作为proposal输出
由于在第三步中将anchors映射回原图判断是否超出边界,所以这里输出的proposal是对应MxN输入图像尺度的,这点在后续网络中有用。另外我认为,严格意义上的检测应该到此就结束了,后续部分应该属于识别了。
ROI Pooling层
同Fast R-CNN中的ROI层作用和用法
FC层
同Fast R-CNN中的FC层作用和用法
损失函数
RPN的损失也分为两个部分:分类损失和边界框回归损失
$$
L({p_i},{t_i})=\frac{1}{N_{cls}}\sum_{i}L_{cls}(p_i,p_i^*)+\lambda\frac{1}{N_{reg}}\sum_{i}{p_i^*}L_{reg}(t_i,t_i^*)
$$
补充材料
Faster R-CNN
实际上生成的那么多 anchors 并不是每个都用来训练 RPN 网络。对于每张图片我们从上万个 anchor 当中采样 256 个 anchor,这些 anchor 由正样本和负样本 1:1 组成的。如果正样本不足 128,就用负样本进行填充。两种定义正样本的方式:(1)anchor 与 ground-truth 的 iou 超过 0.7,(2)某个 anchor 与 ground-truth 拥有最大的 iou。负样本是与所有的 ground-truth 的 iou 都小于 0.3 的。
感受野