Faster-rcnn论文笔记

Faster-rcnn论文笔记

整体的思路

faster-rcnn 是一个很好的paper,里面有许多的思想非常值得借鉴,之前细读过好几遍,代码也研究了一下,觉得越清晰越幸福的感觉,哈哈。不过时间久了还是很容易忘记的,准备记录一下里面主要的部分。

原始的faster-rcnn是用vgg来作为base的网络,然后分为两个支路,其中一支是RPN,另一支是RCNN,其中RPN的输入是从base网络中提出的feature,RPN的主要作用是产生一些rois,然后送入到后面的RCNN中去采样,再做最后的分类和回归的任务。

这些rois是如何得来的?

  • 第一步

rois是在anchor的基础上再”加上” 网络预测的“位置信息”,而得到的,这里的位置信息指的是paper里面的“dx,dy,dw,dh”,anchor需要在这些变换的基础之上才能够得到真正的相对于网络的输入大小的框,这些框经过clip之后才能够被用。

  • 第二步

RPN中除了对每个anchor预测4个关于位置的信息,还预测了两个概率信息,分别代表其是fg还bg的概率。(注意是经过softmax之后才理解成是概率), 然后要根据fg的得分做一个排序,然后把TOP N1的rois取出来。 这一步叫做nms的前期处理, 比如N1=6000

  • 第三步

上一步的处理之后仍然会是有很多的rois的,所以这一步是做NMS的,注意是rois之间的NMS, 不是anchors,这里的rois是变换到相对于网络输入大小并做了clip之后的rois。

  • 第四步

NMS之后仍可能会有很多的框,然后再从经过NMS里面的取出TOP N2数量的rois,这里的top仍是基于前景的概率排序的,还是第二步中的那个排序。 这一步之后得到的rois就是RCNN的输入。 但是要注意,这时候返回的rois可能会有很多比如2000个,而真正在RCNN中用的可以有是256个.从2000个到256个这一步经过了”proposal_target_layer”, 其实在RPN的loss中,也是从2000个中选择一部分去做的rpn的loss,比如说256个。.

如何保障RPN输出的rois比较好呢?

这就要优化RPN了,RPN要是好的话,就是能够区分 fg/bg,还有预测的关于位置的信息使得anchor经过其变换之后能够与gt-bbox要很接近,所以就要搞清晰RPN优化的是什么?

  • RPN的loss

RPN的loss有两个组成部分,一是关于fg/bg的bce,二是关于预测与其target之间的smoothL1,即回归的loss,

  • 整体的来看,就是RPN的网络的输出的cls_pred和loc_pred,其中loc_pred copy一份去做了rois,另一份去做了回归的损失。

rois 作为RPN的一个输出会送到下面的网络中去采样,这里能够显示出one-stage与two-stage的一个很大的区别之处,比如和SSD的差别, 这里得到一些rois之后,就会根据rois去扣图,扣完图之后,把扣出来的图(即采样得到的图)送到后面的网络中去。 而在one-stage的里面,并没有这个扣图的动作,哪怕一张图里面有多个物体,也是基本上是以全局的feature放进去的,而不是部分。

这两者的区别还是很大的,个人觉得如果一张图里的目标比较少的情况下用two-stage的办法会比较好,因为分类的时候比较有针对性,即针对roi这个区域里的进行分类,如果用one-stage的话,可能其他地方有变化,但是不是关心的任务的话,网络会以为那个地方是要学习的呢,比如区别一个盘子里的水果是什么,只有一个水果的话,如果盘子的形状,盘子的颜色变的话,还有底下垫的东西也变的话,网络会以为这些因素是主导因素,可能不会把精力集中的bbox里面去。

如果除了关心的目标之外其他的地方都不动的话,比如检测一个产品上面有没有一个零件,而在生产线的时候,图片几乎完全一样,除了关心的那个地方外,这时候的话,用one-stage的时候也是可以的,因为图之间除了关心的区域之外其他地方完全一样,那么这时候以整个featuremap 输入进去的话,网络就会注意到是哪些地方的改变引起了类别的变化,即会把注意力放在目标区域里去。

所以还是要具体的问题具体的分析。

RCNN 中的分类和回归

我在没看代码的时候只看论文的时候不清晰后面到底是怎么处理的,比如前段的RPN提出了rois, 输入给后面的网络了,后面的分类比较好理解,就是一个多分类问题,注意前面RPN里面也有一次分类,RPN中的分类的gt是1或者是0,-1是无效的,这个label是anchor与gt-bbox的IOU来决定的,而在RCNN阶段分类的gt是物体的真实的类别,比如dog or cat, 是这样的一个分类。

而回归呢,前一次回归是预测与target之间的,这次呢?这次的target和上次的不一样了,上次的target是anchor的位置与gt-bbox之间的一个变换,而这次的target是rois与gt-bbox之间的变换,而且这次进入网络的是从rois里面扣出的feature。也就是分类和预测位置参数都是从这个roi里面去做的。分类从roi里面去做可以理解,但是位置信息从这里面预测感觉不是很合理,因为网络可能没有看到全局的信息。

所以整个过程下来做了两次NMS, 打了两次label, 一次是打fg/bg的label 另外一次是打多分类中的label,建立了两次target,第一次是的target是anchor与gt之间的变换,第二次是rois与gt-bbox之间的。

更正

其实在训练的时候只做了一次NMS,即所有的框经过变换得到所有的rois之间的一次NMS,在head部分并没有用NMS,不过在测试的时候,后面得到最终的框的时候也还是用了NMS的。

如何训练的

其实训练有两种方式,paper上面也介绍了两种方式,一种是当成one-stage的进行end-to-end的训练,一种是分步训练,这里复习一下分步训练。 为了接下来叙述方便,将整个网络分成三个部分,共有的base网络,提proposals的rpn网络和后面分类的head部分。

  1. 训练rpn网络,这个过程是将pre_trained的模型上进行训练,对应stage1_rpn_train. 这步训练完的部分暂时叫做base1+rpn1.

  2. 利用1步训练好的base1+rpn1网络,收集proposals,供后面用,这一步对应于 rpn_test

  3. 第一次训练fast-rcnn(注意没有加er),即base+head部分,用的proposals就是上一步针对每张训练图产生的proposals.

注意这一步训练的时候和第一次一样,也是从pre_trained的模型开始训练,这一步训练好的叫base2+head1.(注意base2并不是在base1的基础上训练的.) 这一步叫stage1_fast_rcnn_train

  1. 第二次训练rpn网络,注意这次用的base是base2,而且base2没有学习,得到base2+rpn2.

  2. 用上一步得到的base2+rpn2产生proposals,这一步也叫rpn_test

  3. 第二次训练fast-rcnn(注意没加er),这一步实际上是finetune,因为用的仍是base2,训练的是head部分,得到的是head2.这一步叫stage2_fast_rcnn_train.

至此就得到了base2,rpn2, head2.

其他细节

由RPN提出的proposals即rois是相对于进入网络的shape(假设这个shape为(M, N),注意这个(M,N)是由原图像经过变换得到的。) 然后在后序采样之前,需要先把proposals转化为对应于(M/16, N/16),这个shape是base的网络出来的大小,然后从这个feature map上面得到对应的rois, 这个过程用的是roi-pooling,也就是把大小可能都不相同的rois全部都转化成为(pooled_w,pooled_h)那么大的,比如(7,7),即将roi-feature分成网格,然后每个网格里面用max-pooling.这样就可以实现固定长度的输出。

  • rpn过程中分类的anchor的类别gt.

这时候要看anchor与gt之间的IOU,判定为正anchor的情况有两种: 固定一个gt-bbox,算其他anchor与这个gt-bbox的IOU,具有最大IOU的那个anchor或者那些anchor就标记为正例(这时候这个最大的IOU有可能比较小); 因定一个anchor, 算每个gt-bbox与这个anchor的IOU,只要有一个IOU大于0.7,就把这个anchor标记为正例。如果这个anchor与每个gt-bbox的IOU都小于0.3,就把这个anchor标记为负例。而其他情况的anchor不参与训练。

备注

有些地方和原paper中并不太一样,比如原paper中可能用的是300个rois,我这里用的是256个rois.

打赏,谢谢~~

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,多谢支持~

打开微信扫一扫,即可进行扫码打赏哦