Mask R-CNN是一个实例分割(Instance segmentation)算法,可以用来做目标检测,目标实例分割,目标关键点检测。
实例分割的难度在于要先对一张图所有的目标进行正确的检测同时还要对每个实例进行分割。
检测的目的是把每一个单个目标分类然后用bounding box标定出来,而实例分割的目的是区分每一个像素为不同的分类。
整个Mask R-CNN算法的思路很简单,就是在原始Faster-rcnn算法的基础上面增加了对应的MASK分支(完成图像分割任务)。Faster-rcnn笔记
原始图片输入进CNN(可以是任意的主干网络),得到特征图;
特征图经过RPN层生成候选区域(anchor),对anchor进行回归和分类;再经过ROIAlign层(把不同候选区域anchor对应的特征图变成相同的维度);
图片经过主干网络,提取到特征图;经过RPN,生成候选区域;经过RoI Align,把候选区域变成相同的大小;传到head 层进行分类,回归,Mask任务
Align之后有一个“head”部分,主要作用是使用转置卷积将Rol Align的输出特征图扩大,这样在预测Mask时会更加精确。
(1)有分类,回归,mask三个分支。对于mask分支
14x14x256经过4次卷积,还是14x14x256;通过转置卷积上采样,得到28x28x256;再卷积得到28x28x80(80对应的是Coco数据集的80个类别,每1个分类都有1个Mask与之对应)
(2)双线性插值把28×28mask变换到原图中box的大小,mask在这里做变换的时候有一个形变
(3)每一个类都输出一个mask,激活函数为sigmoid,取0.5阈值,得到二值化mask。
注:双线性插值是常用的resize算法,这里相当于将28×28的小图片resize成大图片
在Faster-RCNN中,ROI Pooling的作用是根据预选框的位置坐标在特征图中将相应区域池化为固定尺寸的特征图,以便进行后续的分类和候选框回归操作。 由于候选框的位置通常是由模型回归得到的,一般来讲是浮点数,而池化后的特征图要求尺寸固定。 故ROI Pooling这一操作存在两次量化的过程: 1.将候选框边界量化为整数点坐标值。 2.将量化后的边界区域平均分割成kxk个单元(bin),(举个栗子,假设用k=5,5x5去平均分割长宽为9的边界区域,分割后的单元长宽就不是整数了),还要对每一个单元的边界进行量化。
事实上,经过上述两次量化,此时的候选框已经和最开始回归出来的位置有一定的偏差,这个偏差会影响检测或者分割的准确度。在论文里,作者把它总结为“不匹配问题(misalignment)。
800x800的原始图片,里面有一个665x665的预测框;
用Vgg6对原始图片卷积,最后的结果是缩小32倍的。预测框缩小32倍尺寸为20.78,要转换为整数20;
RoI pooling,20/7=2.86,再次量化向下取整为2。
最后的特征图上产生1个像素点的误差,就会在原始图片上产生32个像素点的误差
如上面的相差了0.86个像素点,最终在原始图片上相差了0.86x32约等于27个像素点。对于图像分割任务来说,这个偏差还是挺大的。
虽然misalignment在分类问题上影响并不大,但在Pixel级别的Mask 上会存在较大误差。
ROI Align 是在Mask-RCNN这篇论里提出的一种区域特征聚集方式(用来优化ROI pooling),很好地解决了ROI Pooling操作中两次量化造成的区域不匹配(misalignment)的问题。实验显示,在检测任务中将ROI Pooling 替换为ROI Align 可以提升检测模型的准确性。
为了解决ROI Pooling的上述缺点,作者提出了ROl Align这一改进的方法。ROI Align的思路很简单:取消量化操作,使用双线性插值法的方法获得坐标为浮点数的像素点上的图像数值,从而将整个特征聚集过程转化为一个连续的操作。值得注意的是,在具体的算法操作上,ROIAlign并不是简单地补充出候选区域边界上的坐标点,然后将这些坐标点进行池化,而是重新设计了一套流程:
1.遍历每一个候选区域,保持浮点数边界不做量化。(第1次量化取整没用做)
2.将候选区域分割成kxk个单元,每个单元的边界也不做量化。(第2次量化取整没用做)
3.在每个单元中计算固定四个坐标位置(把这个单元平均分割成四个小方块以后再取它们分别的中心点),用双线性插值的方法计算出这四个位置的值,然后进行最大池化操作。
1、800x800的原始图片,里面有一个665x665的预测框;
用Vgg6对原始图片卷积,最后的结果是缩小32倍的。预测框缩小32倍尺寸为20.78;
2、RoI pooling,分成7x7=49份,每份长度20.78/7=2.97;
3、假设对于第一个单元,取4个点,计算坐标位置(把这个单元平均分割成四个小方块以后再取它们分别的中心点),用双线性插值的方法计算出这四个位置的值,然后进行最大池化操作。这样就求出来了第一个单元值;
4、依次类推,就求出了49个单元格的值
和
都是对正样本才会起作用的。而且在Mask R-CNN中,相较于Faster R-CNN还有些略微的调整,比如正样本被定义成了与Ground truth的loU大于0.5的(Faster R-CNN中是0.7)。
在mask 分支中对每个Rol的输出是,表示K个尺寸为
的二值mask,K是物体类别数目。
作者没有采用FCN式的Softmax Loss,反而是输出了K个Mask预测图(每一个类都输出一个mask),通过逐像素的用激活函数Sigmoid 计算得到,所有代价函数为sigmoid对应的交叉熵,也叫平均二值交叉熵(aver age binary cross-entropy)。