Mask R-CNN

论文就不多讲了(一搜一大堆),这里主要记录读源代码时想记下来的东西。

1.网络结构

首先Mask R-CNN属于TwoStageDetector,结构组成有:

  • neck:基于ResNet的FPN结构,主要用来提取5个不同level的feature maps(分辨率分别是原图的1/4,1/8,1/16,1/32和1/64),其中1/64的feature map是对1/32做stride=2的max_pooling得到。
  • rpn_head:最经典的RPN了。。对5个不同level的feature maps逐个先过3x3的conv和relu,再经过不同的1x1 conv分别得到(N,3,H,W)的rpn_cls_score和(N,12,H,W)的rpn_bbox_pred,N为batch size,3是指每个点3个anchors(下面会提到)。
  • bbox_head:先用bbox_roi_extractor对proposals提取到7x7x256的roi特征,然后经过2层shared fc,再经过不同的1层fc分别得到81类的cls_score(cls branch)和bbox_pred(box branch)。
  • mask_head:先用mask_roi_extractor提取得到14x14x256的roi特征,然后经过4层conv/deconv的小型FCN,最终得到28x28x80的mask map。

bbox_head和mask_head具体网络结构可以看paper的Figure 4。

2.数据加载

CocoDataset继承了CustomDataset

这里主要是做了random fliprandom scale。若想真正地开启random scale training的话,需要在cfg设置多个scale,目前支持“value”和“range”两种scale采样的方式,最后通过pad确保scale后图片的长宽都能被32整除。

还有一个值得注意的问题是由于coco数据集图片的长宽不一致,所以把同一个batch但不同大小的图片cat一起送进torch的网络之前,会对小图做pad

3.训练阶段

下面进入训练

3.1 rpn_head

先用AnchorGenerator为每个level的feature map获取anchors,每个点3个(1:1,2:1,1:2),并进行anchor的过滤

之后通过MaxIoUAssigner为每个anchor分配gt bbox或者background,原则是阈值pos_iou_thr=0.7最大iou。然后采样num=256个正负anchors,正负比例最好是1:1,去训rpn。正anchor和对应的gt bbox之间的回归量通过bbox2delta计算。

最终loss由cls和reg组成

3.2 bbox_head和mask_head

rpn_head和bbox_head、mask_head可以joint training。在计算好rpn_head的loss之后,rpn_head进入“前向测试”状态,获取bbox_head和mask_head需要的proposals,具体来说:rpn_head还是先生成anchors,然后根据rpn_cls_score去排序anchors,选择前cfg.nms_pre=2000个anchors,把回归量rpn_bbox_pred计算在anchors上得到proposals,再经由nms(nms_thr=0.7)得到最多2000个proposals。

拿到proposals之后,rcnn根据之前的rpn的规则(这里pos_iou_thr=0.5)为每个proposals分配gt bbox,并采样num=512个正负proposals,正负比例1:3

有了proposals,后面不管什么head/branch,就简单了。

bbox_head针对正负proposals,训练分类(81类)和回归任务(box refine)。

mask_head只针对正proposals准备对应的mask gt,去训练mask任务。

4.测试阶段

Kai Su /
Published under (CC) BY-NC-SA in categories Research