从今天开始,我将为大家逐步介绍Mask RCNN这个将检测和分割统一起来的框架的具体原理以及详细代码解读,项目地址为https://github.com/matterport/Mask_RCNN
,基于TensorFlow1.x和Keras框架实现。
Mask-RCNN是一个实例分割(Instance segmentation)框架,通过增加不同的分支可以完成目标分类,目标检测,语义分割,实例分割,人体姿态估计等多种任务。对于实例分割来讲,就是在Faster-RCNN的基础上(分类+回归分支)增加了一个分支用于语义分割,其抽象结构如Figure1所示:
稍微描述一下这个结构:
下图更清晰的展示了Mask-RCNN的整体框架,来自知乎用户vision
:
来自知乎用户vision的Mask RCNN结构图
在Faster-RCNN中ROI Pooling的过程如下图所示:
ROI Pooling过程
输入图片的大小为
,其中狗这个目标框的大小为
,经过VGG16网络之后获得的特征图尺寸为
,其中
代表VGG16中的
次下采样(步长为2)操作。同样,对于狗这个目标,我们将其对应到特征图上得到的结果是
,因为坐标要保留整数所以这里引入了第一个量化误差即舍弃了目标框在特征图上对应长宽的浮点数部分。
然后我们需要将这个
的ROI区域映射为
的ROI特征图,根据ROI Pooling的计算方式,其结果就是
,同样执行取整操作操作后ROI特征区域的尺寸为
,这里引入了第二次量化误差。
从上面的分析可以看出,这两次量化误差会导致原始图像中的像素和特征图中的像素进行对应时出现偏差,例如上面将
量化为
的时候就引入了
的偏差,这个偏差映射回原图就是
,可以看到这个像素偏差是很大的。
为了缓解ROI Pooling量化误差过大的缺点,本论文提出了ROIAlign,ROIAligin没有使用量化操作,而是使用了双线性插值。它充分的利用原图中的虚拟像素值如
四周的四个真实存在的像素值来共同决定目标图中的一个像素值,即可以将和
类似的非整数坐标值像素对应的输出像素值估计出来。这一过程如下图所示:
ROIAlign的实现过程
其中feat.map就是VGG16或者其他Backbone网络获得的特征图,黑色实线表示的是ROI划分方式,最后输出的特征图大小为
,然后就使用双线性插值的方式来估计这些蓝色点的像素值,最后得到输出,然后再在橘红色的区域中执行Pooling操作最后得到
的输出特征图。可以看到,这个过程相比于ROI Pooling没有引入任何量化操作,即原图中的像素和特征图中的像素是完全对齐的,没有偏差,这不仅会提高检测的精度,同时也会有利于实例分割。
为了证明次网络的通用性,论文构造了多种不同结构的Mask R-CNN,具体为使用不同的Backbone网络以及是否将用于边框识别和Mask预测的上层网络分别应用于每个ROI。对于Backbone网络,Mask R-CNN基本使用了之前提出的架构,同时添加了一个全卷积的Mask(掩膜)预测分支。Figure3展示了两种典型的Mask R-CNN网络结构,左边的是采用
或者
做网络的backbone提取特征,右边的网络采用FPN网络做Backbone提取特征,最终作者发现使用ResNet-FPN作为特征提取的backbone具有更高的精度和更快的运行速度,所以实际工作时大多采用右图的完全并行的mask/分类回归。
Mask RCNN的两种经典结构
Mask分支针对每个ROI区域产生一个
的输出特征图,即
个
的二值掩膜图像,其中
代表目标种类数。Mask-RCNN在Faster-RCNN的基础上多了一个ROIAligin和Mask预测分支,因此Mask R-CNN的损失也是多任务损失,可以表示为如下公式:
其中
表示预测框的分类损失,
表示预测框的回归损失,
表示Mask部分的损失。对于预测的二值掩膜输出,论文对每一个像素点应用sigmoid
函数,整体损失定义为平均二值交叉损失熵。引入预测K个输出的机制,允许每个类都生成独立的掩膜,避免类间竞争。这样做解耦了掩膜和种类预测。不像FCN的做法,在每个像素点上应用softmax
函数,整体采用的多任务交叉熵,这样会导致类间竞争,最终导致分割效果差。
下图更清晰的展示了Mask-RCNN的Mask预测部分的损失计算,来自知乎用户vision
:
Mask-RCNN的Mask预测部分的损失计算
在Faster-RCNN中,如果ROI区域和GT框的IOU>0.5
,则ROI是正样本,否则为负样本。
只在正样本上定义,而Mask的标签是ROI和它对应的Ground Truth Mask的交集。其他的一些训练细节如下:
mini-batch=2
,每张图片有个采样ROIs,其中正负样本比例为1:3
。
batch_size=2
,迭代160k
次,初始学习率0.02
,在第120k
次迭代时衰减10倍,weight_decay=0.0001
,momentum=0.9
。测试阶段,采用的proposals
的数量分别为
(Faster-RCNN)和
(FPN)。在这些proposals
上,使用bbox
预测分支配合后处理nms
来预测box
。然后使用Mask预测分支对最高score
的100个检测框进行处理。可以看到这里和训练时Mask预测并行处理的方式不同,这里主要是为了加速推断效率。然后,Mask网络分支对每个ROI预测
个掩膜图像,但这里只需要使用其中类别概率最大的那个掩膜图像就可以了,并将这个掩膜图像resize
回ROI大小,并以0.5
的阈值进行二值化。
当时的SOTA,Mask R-CNN打败了上界冠军FCIS(其使用了multi-scale训练,水平翻转测试,OHEM等),具体结果如Table1所示:
在COCO数据集上的Mask RCNN的结果
再来一些可视化结果看看,如Figure5所示。
一些可视化结果
Table2展示了Mask-RCNN的消融实验,(a)
显示网络越深,效果越好。并且FPN效果要好一些。而(b
)显示sigmoid
要比softmax
效果好一些。(c)
和(d)
显示ROIAligin效果有提升,特别是AP75提升最明显,说明对精度提升很有用。(e)
显示mask banch采用全卷积网络效果较好(因为全卷积网络没有破坏空间关系)。
Mask-RCNN的消融实验
从Table3可以看出,在预测的时候即使不使用Mask分支,结果精度也是很高的。可以看到ROIAlign直接使用到Faster-RCNN上相对于ROI Pooling提高了0.9个点,但比Mask-RCNN低0.9个点。作者将其归结为多任务训练的提升,由于加入了mask分支,带来的loss改变,间接影响了主干网络的效果。
和Faster RCNN的目标检测结果
和Mask-RCNN相比,关键点检测就是将Mask分支变成heatmap
回归分支,需要注意的是最后的输出是
形式的softmax
, 不再是sigmoid
,论文提到这有利于单独一个点的检测,并且最后的Mask分辨率是
,不再是
。
关键点检测
我要解析的Mask RCNN就是官方提供的代码,使用Keras框架实现的,地址为:
https://github.com/matterport/Mask_RCNN
下面先对项目的README.md进行一个翻译。
这是Mask RCNN使用Python3,Keras,TensorFlow的实现。该模型为图像中的每个实例物体生成边界框和掩膜。它基于特征金字塔网络(FPN)和ResNet101骨干网络。
street.png
工程包括:
下面三个脚本是模型主体文件。
下面三个脚本是观察理解模型用到。
为了帮助调试和理解模型,这里有3个笔记本(inspect_data.ipynb,inspect_model.ipynb,inspect_weights.ipynb)提供了很多可视化效果,并允许逐步运行模型以检查每个点的输出。这里有一些例子:
可视化RPN网络中的每一个步骤并且展示正负Anchor以及精炼后的Anchor。
detection_anchors.png
这是第二阶段最终检测框(虚线)的示例并对其进行了精炼(实线)。
detection_refinement.png
生成的掩膜示例。然后将它们缩放并放置在正确位置的图像上。
detection_masks.png
通常,检查不同层的激活以查找故障迹象(全零或随机噪声)通常很有用。
detection_activations.png
另一个有用的调试工具是检查权重直方图。这包含在inspect_weights.ipynb笔记本中。
detection_histograms.png
TensorBoard是另一个出色的调试和可视化工具。该模型配置为在每个epoch结束时记录损失并保存权重。
detection_tensorboard.png
detection_final.png
我们提供了MS COCO训数据集的预训练模型让训练更加简单。你可以使用这些权重作为起点去训练你自己的网络变体。训练和评价代码在samples/coco/coco.py
里面。您可以在Jupyter笔记本中导入此模块(请参阅提供的笔记本例子),也可以直接从命令行运行它:
# Train a new model starting from pre-trained COCO weights
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=coco
# Train a new model starting from ImageNet weights
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=imagenet
# Continue training a model that you had trained earlier
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=/path/to/weights.h5
# Continue training the last model you trained. This will find
# the last trained weights in the model directory.
python3 samples/coco/coco.py train --dataset=/path/to/coco/ --model=last
你可以执行COCO的评价代码:
# Run COCO evaluation on the last trained model
python3 samples/coco/coco.py evaluate --dataset=/path/to/coco/ --model=last
训练设置,学习率和其他超参数都应该在samples/coco/coco.py
中设置。
阅读这个例子作为开始:https://engineering.matterport.com/splash-of-color-instance-segmentation-with-mask-r-cnn-and-tensorflow-7c761e238b46?gi=468916310fd5
。它涵盖了从标注图像到训练再到在一个示例应用程序中获得结果的过程。
总之,要在自己的数据集上训练模型,你需要扩展两个类:
Config
这个类包含了默认配置. 继承这个类并修改你想修改的信息。Dataset
这个类似提供了处理任意数据集的一致方式。它允许你使用新的数据集进行训练,而无需更改模型的代码。它还支持同时加载多个数据集,如果要检测的目标不是在一个数据集中都可用,则此功能非常有用 。
查看samples/shapes/train_shapes.ipynb
, samples/coco/coco.py
, samples/balloon/balloon.py
, 和samples/nucleus/nucleus.py
中的例子。
这个实现在很大程度上遵循了Mask-RCNN的论文,但是在一些情况下,我们偏向于代码的简单性和泛化。下面是我们意识到的一些差异。如果你遇到其他分歧,请务必通知我们。下面的px代表像素。
。我们保留长宽比,所以如果图像不是正方形,我们用零填充它。在论文中,调整尺寸时,最小边为800px,最大边为1000px。
为了验证这种方法,我们将计算出的边界框与COCO数据集提供的边界框进行了比较。我们发现约2%的边界框相差1px或更多,约0.05%的边界框相差5px或更多,只有0.01%的边界框相差10px或更多。
使用此bibtex引用此代码库:
@misc{matterport_maskrcnn_2017,
title={Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow},
author={Waleed Abdulla},
year={2017},
publisher={Github},
journal={GitHub repository},
howpublished={\url{https://github.com/matterport/Mask_RCNN}},
}
欢迎对此代码库做出贡献。你可以做出贡献的例子为:
Python 3.4, TensorFlow 1.3, Keras 2.0.8以及在requirements.txt
中列出的其它包。
为了在MS COCO数据集上训练和测试,你需要:
http://cocodataset.org/#home
https://github.com/rbgirshick/py-faster-rcnn/blob/master/data/README.md
)如果你使用Docker,你可以拉取这个Docker容器:https://hub.docker.com/r/waleedka/modern-deep-learning/
。
pip3 install -r requirements.txt
python3 setup.py install
https://github.com/matterport/Mask_RCNN/releases
下载COCO的预训练模型(mask_rcnn_coco.h5)。pycocotools
。它们是Python3和Windows(官方repo似乎不再活跃)的原始pycocotools的分支。如果您将此模型扩展到其他数据集或构建使用它的项目,我们将很高兴收到您的来信。
4K Video Demo by Karol Majek。(https://www.youtube.com/watch?v=OOT3UIXZztE
).
4K Video Demo
Images to OSM: Improve OpenStreetMap by adding baseball, soccer, tennis, football, and basketball fields.(https://github.com/jremillard/images-to-osm
)
Images to OSM
Splash of Color. A blog post explaining how to train this model from scratch and use it to implement a color splash effect.(https://engineering.matterport.com/splash-of-color-instance-segmentation-with-mask-r-cnn-and-tensorflow-7c761e238b46
)
Splash of Color
Segmenting Nuclei in Microscopy Images (https://github.com/matterport/Mask_RCNN/tree/master/samples/nucleus
). Built for the 2018 Data Science Bowl(https://www.kaggle.com/c/data-science-bowl-2018
)。
代码在samples/nucleus
文件夹。
Segmenting Nuclei in Microscopy Images
Detection and Segmentation for Surgery Robots by the NUS Control & Mechatronics Lab.(https://github.com/SUYEgit/Surgery-Robot-Detection-Segmentation
)
Surgery-Robot-Detection-Segmentatio
Reconstructing 3D buildings from aerial LiDAR
A proof of concept project by Esri(https://www.esri.com/zh-cn/home
), in collaboration with Nvidia and Miami-Dade County. Along with a great write up and code by Dmitry Kudinov, Daniel Hedges, and Omar Maher.
Reconstructing 3D buildings from aerial LiDAR
Usiigaci: Label-free Cell Tracking in Phase Contrast Microscopy(https://github.com/oist/usiigaci
)
A project from Japan to automatically track cells in a microfluidics platform. Paper is pending, but the source code is released.
显微镜中无标记细胞追踪原图
显微镜中无标记细胞追踪结果图
Characterization of Arctic Ice-Wedge Polygons in Very High Spatial Resolution Aerial Imagery(https://www.mdpi.com/2072-4292/10/9/1487
)
了解北极退化与气候变化之间复杂过程的研究项目。By Weixing Zhang, Chandi Witharana, Anna Liljedahl, and Mikhail Kanevskiy.
北极退化与气候变化之间复杂过程
Mask-RCNN Shiny(https://github.com/huuuuusy/Mask-RCNN-Shiny
)
A computer vision class project by HU Shiyu to apply the color pop effect on people with beautiful results.
Mask-RCNN Shiny
Mapping Challenge: Convert satellite imagery to maps for use by humanitarian organisations.(https://github.com/crowdAI/crowdai-mapping-challenge-mask-rcnn
)
将卫星图像转换成地图供人道主义组织使用。
GRASS GIS Addon (https://github.com/ctu-geoforall-lab/i.ann.maskrcnn
)to generate vector masks from geospatial imagery. Based on a Master's thesis(https://github.com/ctu-geoforall-lab-projects/dp-pesek-2018
) by Ondřej Pešek.
从地理空间图像生成矢量遮罩
第一节就讲到这里了。
本文分享自 GiantPandaCV 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!