Object-Detection(五)

写在前面

常见计算机视觉的任务:

  1. 图像分类(image classification)
  2. 物体检测(object detection)
  3. 语义分割(Semantic Segmentation)
  4. 实例分割(Instance Segmentation)

pic1
图像分类就不做介绍了,就是输入一张图,输出该图的类别标签,可以是单个类别的也可以是多个类别的。
物体检测,前面介绍的RCNN,Fast RCNN,Faster RCNN都是属于物体检测,它需要你得到一个物体的位置并用一个框,框住该物体,同时还要给框内的物体打上类别标签.简而言之就是分类+定位。
语义分割,FCN就是属于语义分割,主要是通过给图上的每个像素打上标签归为一类.语义分割看上去和实例分割很像,但还是有一些区别的,在语义分割中同类物体的颜色是一样的,而不同类的物体的颜色是不同的,而实例分割则是即使同类,但是不同的实例仍是不同颜色的
下图的例子就能说明语义分割和实例分割的区别
pic2

而下面要介绍的Mask-RCNN,要实现的是object detection+classification+instance segmentation
显然这与我们之前介绍的RCNN系列有一些不同,即instance segmentation.

回顾:RCNN->Fast RCNN->Faster RCNN

RCNN

pic3

  1. 通过selective search找到一些region proposal
  2. 对这些region proposals warp 到固定大小
  3. 通过CNN,先分类后回归

Fast RCNN

pic4

  1. 先通过一个CNN提取特征
  2. 依然采用selective search,但是在feature map上做
  3. 用ROI pooling 代替原来的warp操作,缩放到固定大小
  4. 后用2个全连接层,一个分类+一个回归,Loss用multi-task形式,同时训练分类和回归

Faster RCNN

pic5

  1. 先通过CNN提取特征
  2. 用一个需要训练的RPN代替原来的Selective Search操作
  3. 继承Fast RCNN运用ROI pooling的操作
  4. 后用2个全连接层,一个分类+一个回归,Loss用multi-tasj形式,同时训练分类和回归

Mask RCNN

overview

pic6
从上图可以粗略地看出,Mask RCNN也只是在Faster RCNN上进行进一步的修改.
不同点:

  1. ROI pooling 替换成了ROIAlign layer
  2. 新增加了一个分支mask branch

    细节

    ROIAlign

    下图可以显示ROIPooling与ROIAlign的区别
    pic7
    简单来说:我们这里得到了一个框,但它的长宽与我们指定的长宽不同,所以需要将这个框先分割成我们指定长宽个bin.上面这步对于ROI Pooling和ROI Align都是一样的,不同的是对于ROI pooling 来说,它要进行一个量化操作,调整bin的分割,这里的量化操作可以理解为取整.然后再Pooling.而ROIAlign不进行量化操作,而是用双线性内插的方法然后再用Pooling.

  3. ROI Pooling
    pic8
    pic9
    pic10

引用何凯明演讲用的图片:
pic15

  • 在从原图到特征图上时会进行一次量化

  • ROI pooling时会进行一次量化
    这两次量化都会使框产生一定的偏倚.

ROI Pooling反向传播:

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

  1. ROI Align
    pic11
    pic12
    pic13
    pic14

引用何凯明演讲用的图片:
pic16

  • 原图上的坐标映射到特征图上时不进行量化(不取整,保持float形式)

  • 特征图进行Pooling,同样也不进行量化
    ROI Align的反向传播
    类比于ROI Pooling,ROIAlign的反向传播需要作出稍许修改:首先,在ROIAlign中,$x^ (r,j)$是一个浮点数的坐标位置,在池化前的特征图中,每一个与$x^\ (r,j)$横纵坐标均小于1的点都应该接收与此对应的点$y_{rj}$的回传的梯度,故ROI Align的反向传播公式如下:

上式,d(.)表示两点之间的距离,$\Delta h$和$\Delta w$表示$x_i$与$x_i^* (r,j)$横纵坐标的差值,这里作为双线性内插的系数乘在原始的梯度上.

为什么要将原来的ROI Pooling替换为ROI Align
我的理解是:现在的任务不再仅仅是原来Faster RCNN那种物体检测的粗略的任务,而是变为了需要实例分割(instance segmentation).实例分割需要给每个像素进行分类,因此其的精度要求比较高,而用ROI Pooling会在量化时造成一定的偏倚,从而导致misalignment的问题.值得一提的是,在做实验的时候发现,ROI Align在VOC2007数据集上提升效果并不如在COCO上明显.经过分析,造成这种区别的原因是COCO上小目标的数量更多,而小目标对misalignment问题的影响更为明显(比如,同样是0.5像素点的偏差,对于较大的目标而言显得微不足道,但是对于小目标,误差的影响就高很多)


附上双线性内插的内容:
pic17
pic18


Mask分支

除了将ROIPooling改为了ROI Align以外,Mask RCNN还增加了一个Mask 分支,很显然其作用就是为了实现它的实例分割.
Mask分支通过在ROI Align层后吐出的ROI特征上接上一个FCN,最终得到一个与ROI区域相对应的mask map出来(形式为:K×m×m,其中m表示ROI Align特征图的大小).这个mask map有K个channel.K在这里表示目标可能的类别数目.另外每个channel的mask map上面都是些二元信息,分别表示ROI区域上面的某位置点是前景还是背景(是否为该类别).这里采样二元信息的目的就是为了实现类间无竞争.(Softmax就会导致类间竞争此消彼长)

这里沿用FCN的特点,不以向量的形式输出是为了避免丢失空间信息,有效保留空间信息.

损失函数

MaskRCNN沿用之前的Multi-task loss的形式:由于新增了一个Mask分支,网络所使用的损失函数为:

其中$L_{cls}+L_{box}$与Faster RCNN中的一样,并且它们与新增的Mask 分支是独立的.
至于$L_{mask}$,我们知道 mask 分支输出的是一个K×m×m的形式.$L_{mask}$是对每一个像素使用二值的sigmoid交叉损失.
注意:这里Loss是只对groud-truth k层上得m×m个像素计算所有点得交叉熵,并求平均[For an Roi associated with ground-truth class k, LmaskLmask is only defined on the k-th mask(other mask outputs do not contributed to the loss)]

其他细节

在Mask RCNN的overview里我们看到,最一开始的特征提取层被称为backbone,也可以叫他共享基础网络.
文中尝试了多种基础网络:

  • ResNet
  • ResNeXt
  • FPN(Feature Pyramid Network)
  • RseNet+FPN

最终发现,ResNet+FPN的效果最好

目标检测正负样本的问题

正负样本的问题在目标检测任务中是普遍存在的,只不过之前没有重视到,这里再理解一遍.
我们拿到一张训练数据的图,图上的各个物体都是包含一个框的(称为ground truth).就一个物体一个框而言,只有ground truth的才为正例其他情况都为负例,这会导致正负样例不平衡的问题,所以需要我们生成一些正负样本,并平衡它们.这些正负样本就是为了我们更好的训练.例如在RCNN中,用Selective Search会找到一系列的proposal region,我们会将它们与ground truth做IOU操作,将一部分选为正样本,一部分选为负样本.最终重要的是还会进行正负样本的平衡,从上述分得的正负样本中选取出合适比例的样本参与训练.(对于Faster RCNN正负样本就是哪些anchor box)

参考文献

  1. https://blog.csdn.net/jiongnima/article/details/79094159
-------------本文结束感谢您的阅读-------------