pytorch mask rcnn_Mask RCNN-pytorch版本源码阅读(A)

95abab186c195aecf57ebef01d65526b.png

前言

找了很多关于源代码的解读 大部分是tf或者caffe版本的 pytorch的很少 下面是我结合自己看的文章以及对源码一步步的仔细阅读写的一个pytorch-mask-rcnn代码解读(代码源地址:https://github.com/wannabeOG/Mask-RCNN) 记录一下自己学习maskrcnn的心得收获,顺便抒发一下对何大大的仰慕之情:)第一次写文章竟还有点小激动~有语句不通顺的地方还请大家海涵。

另外:推荐我主要参考的两个大大的文章 关于原理:令人拍案称奇的Mask RCNN以及源码的解读:MASK_RCNN代码详解。讲的真的很仔细,很仔细,很仔细!重要的事情说三遍。大家在看代码前一定要大致明白原理,从原理理解代码,再利用代码加深对原理的理解,这样才算是成功的阅读了一篇顶级论文。

ok~接下来进入正题。

ResNet-FPN骨干网络

对Faster RCNN有了解,或是看过上面MaskRCNN原理讲解的童鞋应该清楚,在特征提取的阶段,Faster RCNN利用了VGG16模型中的结构(即13个conv layer+13个relu layer+4个max pooling),而MaskRCNN将其改进为了ResNet-FPN。Residual Neural Network(ResNet)的结构能够加快深层网络的训练并且保证了准确度的提升。Feature Pyramid Network (FPN)则是一种精心设计的多尺度检测方法,我们接下来也会讲解到。

下面我们首先看一下ResNet的整体结构(代码位于model.py):

class 

源码中作者是用了ResNet50、ResNet101两种形式的网络,我们可以任意选择只要显卡确实性能跟得上的话- -!这两种ResNet的结构如下图所示(对应于50-layer列与101-layer列):

379abb59eeb5ff6771cd311263650439.png

所以从图中数据我们也理所当然能够知道代码行

self

的由来了。至于为什么作者没有添加其他结构的网络,这个我也没有了解过,自我感觉是因为浅层网络的性能较差而太深层例如152-layer则在训练中要求的配置过高吧。

然后,ResNet类中最重要的的make_layer方法第一个输入block是BottleNeck或BasicBlock类(接下来会讲到),第二个输入是该blocks的输出channel即通道数,第三个输入是对于上图中每个convx_x(即blocks)中包含多少个residual子结构也就是上面设定的block。其中downsample的操作就是判断是否会保持输入输出的维度一致,如果不一致就需要downsample。

make_layer方法中比较重要的两行代码是:

#该部分是将每个convx_x的第一个residual子结构保存在layers列表中

在代码ResNet类前我们还可以看到作者实现的一个BottleNeck类,这个BottleNeck类是ResNet中的基础模块,也就是上面我们所提到的residual子结构。作者在论文中给出了两种residual block的设计,如下图所示:

0ebe41d9fc78b0f0d207029b357b0acd.png

在训练浅层网络的时候,我们选用前面这种,而如果网络较深(大于50层)时,会考虑使用后面这种(bottleneck),至于其中的原因,可以参考该作者的文章。源码中只添加了BottleNeck的结构,如下:

class 

是不是很简单,每个residual block都只是经过了三次conv、relu、bn,但是这个小小的设计却使得152层的丧心.病狂.神经网络训练的很好,对何大大的敬佩之情再一次油然而生。

好的,扯远了^^ 接下来讲解FPN之前,我再将Basicblock类的实现也贴上来,让大家做个对比,结合两个residual block的结构可能会对BottleNeck这个‘瓶颈’的意思能有更好的理解。

class 

接下来就要讲解FPN部分了,竟有些小雀跃怎么肥四?

37c6fea6878306dde2e39dcf23f575b4.png

相信大家当初在学习图像特征提取的时候都有听说过:高层特征含有丰富的语义信息,而底层特征则含有目标的更多细节,FPN就是由这个原理出发而设计的一种多尺度特征检测方法,与其他方法的不同之处在于,其他算法一般都是采用融合后的特征做检测,而FPN的检测则是在不同特征层中一起进行的,借用这位作者大大文章中所说到的:FPN结构中包括自下而上,自上而下和横向连接三个部分,如下图所示:

af0525cfcb646fcbc7aec9caf3c1d4c9.png

想要更深入了解FPN的原理的话,可以参考原论文以及这篇机器之心的翻译版。我们现在只要知道FPN从不同层次做预测就足够了,接下来就可以看一下MaskRCNN中的FPN部分(整体结构的话可以从开头介绍的那篇原理中找到):

(代码位于model.py)

class 

可以看到代码中我自己做了一个注释<P5 feature map经过max pooling操作得到了P6>,大部分结构图中都省略了这一分支,但在源码中作者实现了这一部分,说明P6还是有用的,至于起了什么作用呢?

。。。。(long long time)

看了大大的原理讲解。喔~~将其作为后序RPN的输入但不作为后序Fast RCNN的输入,通俗点就是讲P6依然作为roi提取的参考feature map,但不参加后面的分类、回归预测。

接着,我们在代码中可以看到,将featrue层与对应的上采样层求和的操作作者只用了很简单的+号以及conv实现,但同时作者也单独设计了一个TopDownLayer类,我认为他的意思大概是想突出这一部分的确切实现让大家能够有更深刻的理解吧,这个类目前我还没看到有真正被使用到,下面贴出了这段代码,大家可以参考上面的一起理解。

class 

我们看到,forward方法实现的确实是上面FPN类中类似代码段的作用

p4_out 

好啦,到目前为止,所有关于MaskRCNN的骨干网络的关键代码我们都通读了一遍,大家是否对ResNet-FPN这个阶段有了更深刻的理解了呢,下面我还会接着阅读RPN部分的代码,但是会更新的非常慢(拖延症患者晚期= =)文中有错误的地方希望大家能够提出~希望和大家一起进步!!!耶耶耶!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值