PyTorch—Mask RCNN(概述)


图像分割与识别平台,10个月前Facebook曾发布过一款,名叫 Detecron的项目。其中也包含Mask R-CNN。不过它是基于Caffe 2深度学习框架编写的。Detectron 目前包含以下目标检测算法的实现:Mask R-CNN 、RetinaNet、Faster R-CNN、RPN、Fast R-CNN、R-FCN。(本人一直期待基于PyTorch版本)这一次,Facebook换上了更受欢迎的PyTorch框架。除了更改框架,Mask R-CNN Benchmark相比它的“前辈”Detectron,训练速度提高了一倍(这才是重点)。

另外,商汤和香港中文大学的多媒体实验室也开源了一个类似项目:mmdetection。它支持Faster R-CNN、Mask R-CNN、RetinaNet等等,相比Facebook的Detecron有5%到20%的性能提升。这个模型还在2018年的COCO Detection竞赛中拿下了冠军。

但是此次Pytorch有如下优点:
PyTorch 1.0编写:RPN、Faster R-CNN和Mask R-CNN均可实现,达到甚至超出Detectron的准确度
快速:训练速度是Detectron的2倍,比mmdetection高30%。
显存效率更高:大约比mmdetection少使用500MB显存
支持多GPU训练与推断
支持以CPU进行推断
支持图像批处理:可分批分GPU对多图进行推断
提供预训练模型:针对几乎所有引用Faster RCNN和Mask RCNN的架构

使用Mask R-CNN Benchmark需要安装以下组件:

PyTorch 1.0
torchvision
cocoapi
yacs
matplotlib
opencv-python
  • R-CNN发展历史
    R-CNN是卷积神经网络(CNN)在图像识别领域的应用,Facebook AI研究团队在这条到道路上做出了颇多贡献,其中不得不提一位大神:Ross Girshick。他发明了RCNN,又提出速度更快的Fast R-CNN。
    2016年,微软研究院提出了Faster R-CNN,降低了在边框搜索上的运算量,进一步提高了算法的速度。
    2017年,Facebook AI研究团队又再次提出了Mask R-CNN:通过添加与现有分支并行的对象掩码(object mask)分支,以增强Faster RCNN在边框识别上的性能。

  • 传送门
    Mask R-CNN Benchmark项目地址:https://github.com/facebookresearch/maskrcnn-benchmark
    印度小哥Mask R-CNN项目地址:https://github.com/wannabeOG/Mask-RCNN
    Detecron项目地址:https://github.com/facebookresearch/Detectron
    mmdetection项目地址:https://github.com/open-mmlab/mmdetection
    代码演示:https://blog.csdn.net/wsp_1138886114/article/details/103011856

一、Mask-RCNN整体框架

Mask-RCNN 是何凯明大神继Faster-RCNN后的又一力作,集成了物体检测和实例分割两大功能,整体框架:
在这里插入图片描述
关于faster-RCNN框架及详情 【请点击】

Mask-RCNN,在Faster-RCNN的基础之上,主要有以下几点改进:

  • 提取feature maps的主干conv layers中引入了FPN网络【请点击】
  • 加入了Mask branch(FCN)用于生成物体的掩模(object mask),
  • 把RoI pooling 修改成为了RoI Align 用于处理mask与原图中物体不对齐的问题。

二、主要网络模块

模块流程图:
在这里插入图片描述
遵循自下而上的原则,依次的从backbone,FPN,RPN,anchors,RoIAlign,classification,box regression,mask这几个方面讲解。

backbone

backbone是一系列的卷积层用于提取图像的feature maps,比如可以是VGG16,VGG19,GooLeNet,ResNet50,ResNet101等,这里粗略讲解的是ResNet的网络结构。详情 【请点击】

ResNet(深度残差网络)主要解决了深层的网络训练退化的问题。ResNet使用了跨层连接,使得训练更加容易。
在这里插入图片描述

FPN(Feature Pyramid Network)

FPN网络【请点击】。FPN的提出是为了实现更好的feature maps融合,一般的网络都是直接使用最后一层的feature maps,虽然最后一层的feature maps 语义强,但是位置和分辨率都比较低,容易检测不到比较小的物体。FPN的功能就是融合了底层到高层的feature maps ,从而充分的利用了提取到的各个阶段的Z征(ResNet中的C2-C5 )。
在这里插入图片描述
左边的底层特征层通过 1X1 的卷积得到与上一层特征层相同的通道数;
上层的特征层通过上采样得到与下一层特征层一样的长和宽再进行相加,从而得到了一个融合好的新的特征层。
举个例子:C4层经过 1X1 卷积得到与P5相同的通道,P5经过上采样后得到与C4相同的长和宽,最终两者进行相加,得到了融合层P4,其他的以此类推。

anchors

anchors英文翻译为锚点、锚框,是用于在feature maps的像素点上产生一系列的框,各个框的大小由scale和ratio这两个参数来确定的,比如scale =[128],ratio=[0.5,1,1.5] ,则每个像素点可以产生3个不同大小的框。这个三个框是由保持框的面积不变,来通过ratio的值来改变其长宽比,从而产生不同大小的框。
由于使用到了FPN,在论文中也有说到每层的feature map 的scale是保持不变的,只是改变每层的ratio,且越深scale的值就越小,因为越深的话feature map就越小。论文中提供的每层的scale为(32, 64, 128, 256, 512),ratio为(0.5, 1, 2),所有每一层的每一个像素点都会产生3个锚框,而总共会有15种不同大小的锚框。

RPN(Region Proposal Network)

RNP(区域推荐网络):用于帮助网络推荐感兴趣的区域,也是Faster-RCNN中重要的一部分。

  1. conv feature map:上文中的P2-P6
  2. k*k anchor boxes:在每个sliding window的点上的初始化的参考区域。每个sliding window的点上取得anchor boxes都一样。只要知道sliding window的点的坐标,就可以计算出每个anchor box的具体坐标。每个特征层的k=3k,先确定一个base anchor,如P6大小为32×3216×16,保持面积不变使其长宽比为(0.5,1,2)(0.5,1,2),得到3个anchors。
  3. intermediate layer:作者代码中使用的是512d的conv中间层,再通过1×1的卷积获得2k*2k scores和4k*4k cordinates。作者在文中解释为用全卷积方式替代全连接。
  4. 2k*2k scores:对于每个anchor,用了softmax layer的方式,会或得两个置信度。一个置信度是前景,一个置信度是背景
  5. 4k*4k cordinates:每个窗口的坐标。这个坐标并不是anchor的绝对坐标,而是与ground_truth偏差的回归。
RoIAlign 及反向传播

Mask-RCNN中提出了RoIAlign,改进了RoI pooling像素对齐的问题
在这里插入图片描述
以看出来在RoI pooling中出现了两次的取整,虽然在feature maps上取整看起来只是小数级别的数,但是当把feature map还原到原图上时就会出现很大的偏差,
比如第一次的取整是舍去了0.78,还原到原图时是0.78*32=25,第一次取整就存在了25个像素点的偏差,在第二次的取整后的偏差更加的大。对于分类和物体检测来说可能这不是一个很大的误差,但是对于实例分割而言,这是一个非常大的偏差,因为mask出现没对齐的话在视觉上是很明显的。而RoIAlign的提出就是为了解决这个问题,解决不对齐的问题。

RoIAlign的思想其实很简单,就是取消了取整的这种粗暴做法,而是通过双线性插值来得到固定四个点坐标的像素值,从而使得不连续的操作变得连续起来,返回到原图的时候误差也就更加的小。
在这里插入图片描述

  1. 划分7*7的bin(可以直接精确的映射到feature map上来划分bin,不用第一次ROI的量化)(上图左)
  2. 接着是对每一个bin中进行双线性插值,得到四个点(在论文中也说到过插值一个点的效果其实和四个点的效果是一样的,在代码中作者为了方便也就采用了插值一个点)(上图右)
  3. 通过插完值之后再进行max pooling得到最终的7*7的ROI,即完成了RoIAlign的过程。

ROI Align 的反向传播
常规的ROI Pooling的反向传播公式如下:
∂ L ∂ x i = ∑ r ∑ j [ i = i ∗ ( r , j ) ] ∂ L ∂ y r j \frac{\partial L}{\partial x_{i}}=\sum_{r}\sum_{j}[i= i^*(r,j)]\frac{\partial L}{\partial y_{rj}} xiL=rj[i=i(r,j)]yrjL

这里, x i x_i xi 代表池化前特征图上的像素点;yrj代表池化后的第r个候选区域的第j个点; i ∗ ( r , j ) i^*(r,j) i(r,j) 代表点 y r j y_{rj} yrj像素值的来源(最大池化的时候选出的最大像素值所在点的坐标)。由上式可以看出,只有当池化后某一个点的像素值在池化过程中采用了当前点Xi的像素值(即满足 i = i ∗ ( r , j ) i = i^*(r,j) i=i(r,j) ),才在xi处回传梯度。

类比于ROIPooling,ROIAlign的反向传播需要作出稍许修改:在ROIAlign中, x i ∗ ( r , j ) x_i^*(r,j) xi(r,j) 是一个浮点数的坐标位置(前向传播时计算出来的采样点),在池化前的特征图中,每一个与 x i ∗ ( r , j ) x_i^*(r,j) xi(r,j) 横纵坐标均小于1的点都应该接受与此对应的点yrj回传的梯度,故ROI Align 的反向传播公式如下:
∂ L ∂ x i = ∑ r ∑ j [ d ( i , i ∗ ( r , j ) ) < 1 ] ( 1 − Δ h ) ( 1 − Δ w ) ∂ L ∂ y r j \frac{\partial L}{\partial x_{i}}=\sum_{r}\sum_{j}[d(i,i^*(r,j))<1](1-\Delta h)(1-\Delta w)\frac{\partial L}{\partial y_{rj}} xiL=rj[d(i,i(r,j))<1](1Δh)(1Δw)yrjL
上式中, d ( . ) d(.) d(.) 表示两点之间的距离, Δ h Δh Δh Δ w Δw Δw 表示 x i xi xi x i ∗ ( r , j ) x_i^*(r,j) xi(r,j) 横纵坐标的差值,这里作为双线性内插的系数乘在原始的梯度上。

classifier 与 Loss 函数

其中包括了物体检测最终的classes和bounding boxes。该部分是利用了之前检测到了ROI进行分类和回归(是分别对每一个ROI进行)。

训练时,对每个采样的 RoI 的 multi-task loss 为:

L = L c l s + L b o x + L m a s k L=L_{cls}+L_{box}+L_{mask} L=Lcls+Lbox+Lmask

Lcls - 分类 loss
Lbox - bounding-box 回归 loss
Lmask - mask 分割 loss
mask 网络分支采用 FCN 对每个 RoI 的分割输出维数为 Km2,即 K 个类别的 m×m 的二值 mask. 采用像素级 Sigmoid,定义 Lmask为平均二值交叉熵损失函数(average binary cross-entropy loss). 一个 RoI 仅与 ground-truth 类别 kk 相关,LmaskLmask 只与第 ​k​ 个 mask 相关,不受其它的 mask 输出的影响.

Lmask 使得网络能够输出每一类的 mask,且不会有不同类别 mask 间的竞争. 分类网络分支预测 object 类别标签,以选择输出 mask,解耦了 mask 和 class 预测间的关系.

传统 FCNs 采用 per-pixel 的 softmax 和 multinomial cross-entropy loss,会造成不同类别的 mask 间的相互影响;

Lmask 采用 per-pixel sigmoid 和 binary loss,避免了不同类别的 mask 间的影响. 有效的提升了 instance segmentation 效果.

其中分类回归损失函数见 【请点击】

关于该框架的使用请查看以后的文章
https://blog.csdn.net/remanented/article/details/79564045
https://blog.csdn.net/horizonheart/article/details/81188161

sigmoid函数解释如下http://blog.163.com/liyanhua_08/blog/static/1172002772009927111741738/
softmax函数解释如下: https://www.zhihu.com/question/23765351
交叉熵损失函数的解释如下: http://blog.csdn.net/u012162613/article/details/44239919
各种损失函数的解释如下: http://blog.csdn.net/u014114990/article/details/47802993

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页