下面会介绍基于ResNet50的Mask RCNN网络,其中会涉及到RPN、FPN、ROIAlign以及分类、回归使用的损失函数等python
介绍时所采用的MaskRCNN源码(python版本)来源于GitHub:https://github.com/matterport/Mask_RCNNgit
下面的介绍都是基于这部分源码进行的(少数地方会和原始论文中有差异,不过不影响整个网络的理解)github
一) 、总体框架结构算法
经过对代码的理解,从新绘制出一张MASKRCNN的总体架构图数组
二) 、分解各个节点网络
1) ResNet50网络简单介绍架构
ResNet50网络主要用来提取图片的特征。框架
MASKRCNN网络虽然对于输入图片的大小没有要求,可是在代码中存在IMAGE_MIN_DIM和IMAGE_MAX_DIM两个参数的定义,会将图片统一成设定的大小。设定的规则这里主要介绍两种经常使用的方式:函数
①‘squre’:先将图片较短边按照IMAGE_MIN_DIM进行等比例缩放,再将图片以零像素填充到IMAGE_MAX_DIM大小spa
②‘crop’:一样,先将图片较短边按照IMAGE_MIN_DIM进行等比例缩放,再从图片中随机剪裁一个IMAGE_MIN_DIM大小的子图片做为输入图片
这里,基于‘squre’这种方式介绍,即将参数IMAGE_MAX_DIM设定为1024,所以,网络的输入图片大小就是1024*1024
ResNet50网络比较简单,主要包括卷积、BN、RELU三步提取特征的操做,其中:
①C1:256*256*64表示特征图的大小为256*256,特征图的个数是64个
②C2:256*256*256表示特征图的大小为256*256,共有256个特征图
③C3:128*128*512表示特征图的大小为128*128,共有512个特征图
④C4:64*64*1024表示特征图的大小为64*64,共有1024个特征图
⑤C5:32*32*2048表示特征图的大小为32*32,共有2048个特征图
C1和C2的特征图大小是同样的,因此,FPN的创建也是基于从C2到C5这四个特征层上。
2) FPN网络的创建
经过ResNet50网络,获得图片不一样阶段的特征图,利用C2,C3,C4,C5创建特征图金字塔结构
①将C5通过256个1*1的卷积核操做获得:32*32*256,记为P5
②将P5进行步长为2的上采样获得64*64*256,再与C4通过的256个1*1卷积核操做获得的结果相加,获得64*64*256,记为P4
③将P4进行步长为2的上采样获得128*128*256,再与C3通过的256个1*1卷积核操做获得的结果相加,获得128*128*256,记为P3
④将P3进行步长为2的上采样获得256*256*256,再与C2通过的256个1*1卷积核操做获得的结果相加,获得256*256*256,记为P2
⑤将P5进行步长为2的最大池化操做获得:16*16*256,记为P6
结合从P2到P6特征图的大小,若是原图大小1024*1024,那各个特征图对应到原图的步长依次为[P2,P3,P4,P5,P6]=>[4,8,16,32,64]
3) Anchor锚框生成规则
基于上一步获得的特征图[P2,P3,P4,P5,P6],介绍下MASKRCNN网络中Anchor锚框的生成,根据源码中介绍的规则,与以前的Faster-RCNN中的生成规则有一点差异。
①遍历P2到P6这五个特征层,以每一个特征图上的每一个像素点都生成Anchor锚框
②以P2层为例,P2层的特征图大小为256*256,相对于原图的步长为4,这样P2上的每一个像素点均可以生成一个基于坐标数组[0,0,3,3]即4*4面积为16大小的Anchor锚框,固然,能够设置一个比例SCALE,将这个基础的锚框放大或者缩小,好比,这里设置P2层对应的缩放比例为16,那边生成的锚框大小就是长和宽都扩大16倍,从4*4变成64*64,面积从16变成4096,固然在保证面积不变的前提下,长宽比能够变换为32*128、64*64或128*32,这样以长、宽比率RATIO=[0.5,1,2]完成了三种变换,这样一个像素点均可以生成3个Anchor锚框。在Faster-RCNN中能够将SCALE也能够设置为多个值,而在MASKRCNN中则是每一特征层只对应着一个SCALE即对应着上述所设置的16。
③以P2层每一个像素点位中心,对应到原图上,则可生成256*256*3(长宽三种变换)=196608个锚框
④以P3层每一个像素点为中心,对应到原图上,则可生成128*128*3=49152个锚框
⑤以P4层每一个像素点为中心,对应到原图上,则可生成64*64*3=12288个锚框
⑥以P5层每一个像素点为中心,对应到原图上,则生成32*32*3=3072个锚框
⑦以P6层每一个像素点为中心,对应到原图上,则生成16*16*3=768个锚框
从P2到P6层一共能够在原图上生成261888个Anchor锚框
4) 生成RPN网络数据集
在上一步已经生成了26188个Anchor锚框,须要借助这些Anchors创建RPN网络训练时的正类和负类,
假设须要的正样本与负样本共计256个Anchor,即RPN_TRAIN_ANCHORS_PER_IMAGE这个参数所指定。源码中这步操做由如下几方面构成:
①先找到全部真实框中那些同时框住了多个物体的框,并排除掉
②计算每一个Anchors与该图片上标注的真实框ground truth之间的IOU
若是anchor box与ground truth的IoU值最大,标记为正样本,label=1
若是anchor box与ground truth的IoU>0.7,标记为正样本,label=1
若是anchor box与ground truth的IoU<0.3,标记为负样本,label=-1
剩下的既不是正样本也不是负样本,不用于最终训练,label=0
同时,保证正样本为128个,负样本为128个
除了对anchor box进行标记外,另外一件事情就是计算anchor box与ground truth之间的偏移量
令:
ground truth:标定的框也对应一个中心点位置坐标x*,y*和宽高w*,h*
anchor box:中心点位置坐标x_a,y_a和宽高w_a,h_a
因此,偏移量:
△x=(x*-x_a)/w_a △y=(y*-y_a)/h_a
△w=log(w*/w_a) △h=log(h*/h_a)
什么是IoU:
这样,通过这一步,共找到128个Anchor做为正样本和128个Anchor做为负样本, 同时,保存了这256个Anchor与真实框ground truth之间的偏移量
5) RPN网络的分类与回归
①前向传播计算分类得分(几率)和坐标点偏移量
RPN网络在分类和回归的时候,分别将每一层的每个Anchor分为背景和前景两类,以及回归四个位移量,好比P2层,特征图大小为256*256,即像素点有256*256个,每一个像素点有三种长宽比例变换,一共有256*256*3个Anchor,若是是分类则须要分别计算每一个Anchor为前景的得分(几率)或为背景的得分(几率),其数组可定义为[256*256*3,2],相应的若是是偏移量的回归则数组对应着形式为[256*256*3,4]
将从P2到P6的全部层进行一样的分类和回归操做,一共获得[261888,2]的分类信息和[261888,4]的回归信息。
②计算RPN网络损失值反向传播更新权重
在‘生成RPN网络数据集’这一步,在261888个Anchors中得到了256个正负样本且与真实框的偏移量。
分类:
从前向传播计算获得的全部Anchors得分数组中即上面所述的[261888,2]数组中找到这256个正样本和负样本所对应的得分,利用得分与正负样本的标签计算交叉熵损失值。
RPN分类使用的是基于Softmax函数的交叉熵损失函数,Softmax函数只要是将前向传播计算的得分归一化到0~1之间的几率值,同时,通过Softmax函数后,也能够保证各个分类的几率不会出现负数
Softmax函数公式:
其中,表示类别j通过网络前向传播计算出来的得分,
表示类别j通过Softmax函数后换算获得的几率
基于Softmax的交叉熵公式:
其中,表示的是真实标签,
表示几率,下面用
代替来表示几率
,看下L的求导结果:
所以假设一个5分类任务,一张图像通过Softmax层后获得的几率向量p是[0.1,0.2,0.25,0.4,0.05],真实标签y是[0,0,1,0,0],那么损失回传时该层获得的梯度就是p-y=[0.1,0.2,-0.75,0.4,0.05]。这个梯度就指导网络在下一次forward的时候更新该层的权重参数
回归:
从前向传播计算获得的全部Anchors偏移量数组中即上面所述的[261888,4]数组中找到这128个正样本所在索引对应的偏移量,利用此前向传播计算获得的偏移量与正样本与真实框之间计算的偏移量计算损失值,使用的是SmoothL1Loss
SmoothL1函数:
对应的损失函数:
其中,,
,
分别表示由前向传播计算的预测框的坐标值,Anchor锚框对应的坐标值,真实框对应的坐标值
SmoothL1函数的求导:
将预测框与真实框偏移量之间的差值带入上述公式后可获得损失函数求导后的结果,用此更新权重实现反向传播
6) 根据RPN调整生成ROI
这一部分对应着总网络图中的ProposalLayer层,取出必定量的Anchors做为ROI,这个量由源码中参数POST_NMS_ROIS_TRAINING肯定,假设这个参数在训练的时候设置为2000,则咱们这里须要从261888个Anchors中取出2000个做为ROI
首先,按照Anchors通过RPN网络前向传播计算得出的前景(或称为正样本)的得分从高到低排序,取出前2000个得分最高的Anchors,相对应的将2000个Anchors经RPN网络前向传播计算出的偏移量累加到Anchor box上获得较为准确的box坐标。
其中,红色的A框是生成的anchor box,而蓝色的G’框就是通过RPN网络训练后获得的较精确的预测框,绿色的G是ground truth box
最后在返回前,对2000个框再进行一次非最大值抑制NMS操做
用下图一个案例来对NMS算法进行简单介绍
如上图所示,一共有6个识别为人的框,每个框有一个置信率。
如今须要消除多余的:
进行非最大值抑制的目的主要是须要剔除掉重复的框,若是通过非最大值抑制操做后获得的ROI没有事先代码中设定的2000个,则用0填充。
7) 生成RCNN网络数据集
这一部分对应着总网络图中的DetectionTargetLayer层
在通过ProposalLayer层以后获得了2000个通过微调后的ROI,而在DetectionTargetLayer须要对2000个ROI作如下几步:
①首先剔除掉2000个ROI中不符合条件的ROI,主要是在ProposalLayer层最后返回的时候若是不足2000个会用0填充凑足,将这些用0填充的所有排除掉,避免参与没必要要的计算
②DetectionTargetLayer中会用到图片中的真实框信息,因此,在使用以前一样将全部真实框中那些同时框住了多个物体的框,并排除掉
③计算每一个ROI与真实框之间的IOU值
若是ROI与ground truth的IoU>0.5,标记为正样本
若是ROI与ground truth的IoU<0.5,标记为负样本
假定正样本个数只保留到100个,而负样本通常保持是正样本数的3倍,正负样本总数则就能够达到400个,这个400可有配置文件中TRAIN_ROIS_PER_IMAGE参数肯定
④对于每一个正样本,进一步计算与其相交最大即最接近的真实框ground truth box,将这个真实框所对应的类别即class_id赋予这个正样本,这样RCNN网络就能够区分具体哪一个类别
⑤一样,计算每一个正样本ROI与最接近的真实框ground truth box之间的偏移量,这RPN中的计算公式同样
⑥RCNN网络还须要保存与每一个正样本ROI最接近的真实框ground truth box的mask掩码信息,而且知道每一个mask大小为参数MASK_SHAPE所指定,通常为28*28,同时知道其所属于的类别即class_id,进行保存
最后DetectionTargetLayer层返回400个正、负样本,400个位移偏移量(其中300个由0填充),400个掩码mask信息(其中300个由0填充)
8) ROI 对齐操做
经过DetectionTargetLayer层,在原图上找到400个ROI,由于这些ROI多是有各个特征层产生的Anchor,因此,如今须要将这些ROI映射回特征图上
第一步,咱们须要知道每一个ROI如何和特征层对应上,论文中提到的方法是利用下面的公式:
对于公式而言:w,h分别表示ROI宽度和高度;k是这个RoI应属于的特征层level;是w,h=224,224时映射的level,通常取为4,即对应着P4,至于为何使用224,通常解释为是由于这是ImageNet的标准图片大小,好比如今有一个ROI是112*112,则利用公式能够计算获得k=3,即P3层
第二步,开始讨论对齐的方式
当完成每一个ROI能找到其对应的特征层后,就一样能够算出其对应的步长,步长只要用于解释ROI Align的原理,论文中提到的ROI Align,这个方法的思路:
①使用每一个ROI的长、宽除以步长,获得ROI映射到特征图上的图片大小,好比ROI为113*113,对应P3层,步长为8,则在特征图上的感兴趣区域则为14.13*14.13
②若是要将特征图上的感兴趣区域对齐到7*7,则须要将14.13*14.13这个区域分红49份,每一份的大小为:2.02*2.02
③再将每一个2.02*2.02的小区域,平分四份,每一份取其中心点位置,而中心点位置的像素,采用双线性插值法进行计算,这样,就会获得四个点的像素值,取四个像素值中最大值做为这个小区域(即:2.02*2.02大小的区域)的像素值,如此类推,一样是49个小区域获得49个像素值,组成7*7大小的feature map
以上介绍的是论文中的ROI Align方法,可是在这篇博文开头提供的代码连接中的源码并非这样处理的。对于ROI映射到特征图上的方法是同样的,但当每一个ROI找到对应的特征层厚,直接利用Crop and Resize操做,生成7*7大小的feature map
Mask掩码分支则是对齐成14*14大小的feature map
9) RCNN网络的类别分类、回归、mask掩码分类
①RCNN网络的类别分类和回归与RPN网络中的分类和回归是同样的,损失函数也都是基于Softmax交叉熵和SmoothL1Loss,只是RPN网络中只分前景(正类)、背景(负类),而RCNN网络中的分类是要具体到某个类别(多类别分类)
②mask掩码分类
在ROI 对齐操做中mask分支对齐成14*14大小的feature map,而且在‘生成RCNN网络数据集’操做中知道每一个正样本mask掩码区域对应的class_id
i) 前向传播:将14*14大小feature map经过反卷积变换为[28*28*num_class],即每一个类别对应一个mask区域,称之为预测mask
ii) 与‘生成RCNN网络数据集’操做中的返回的mask也是28*28,而且知道每一个mask区域的真实类别class_id,称之为真实mask
iii) 经过当前获得的真实mask中的类别class_id,遍历全部的预测mask,找到class_id类别所对应的预测mask(前向传播中介绍过每一个类别都有一个预测mask),比较真实mask与预测mask每一个像素点信息,用的是binary_cross_entropy二分类交叉熵损失函数
iv) binary_cross_entropy是二分类的交叉熵,实际是多分类softmax_cross_entropy的一种特殊状况,当多分类中,类别只有两类时,即0或者1,由于28*28大小的mask中只有0和1,便是像素和不是像素
这个是针对几率之间的损失函数,你会发现只有(预测几率)和
(真实标签)是相等时,loss才为0,不然loss就是为一个正数。并且,几率相差越大,loss就越大,根据Loss值更改权重实现反向传播
做为一枚技术小白,写这篇笔记的时候参考了不少博客论文,在这里表示感谢,同时,未经赞成,请勿转载....