Mask R-CNN代码分析(一)

Mask R-CNN的源码是随着FAIR的物体检测平台detectron公布的,detectron囊括了从Fast R-CNN到Mask R-CNN所有重要的物体检测算法,整个平台基于caffe2实现。本文主要从代码层面介绍Mask R-CNN具体的实现过程。

一、caffe2介绍

caffe2是在caffe的基础上的进化版,最大的特色就是引入了operator的概念,取代了caffe中layer作为net的基本构造单位。

Mask R-CNN代码分析(一)_第1张图片

由于operator定义很基础,很抽象,因此caffe2中的权值初始化、前传、反传、梯度更新都可以用operator实现,所以solver、layer类在caffe2中都不是必要的。在caffe2中,对应的基础组成有:

  • blob:存储数据
  • operator:输入blob,输出blob,定义了计算规则
  • 网络:net,由多个operator组合实现
  • workspace:caffe中没有,可以理解成变量的空间,便于管理网络和变量

所以在使用caffe2之前,需要先将caffe2.python.core和caffe2.python.workspace导入,这里边有常用的一些类和函数。

from caffe2.python import core, workspace

下面介绍caffe2比较重要的几个点:

1.workspace

workspace是caffe2新引入的一个概念,顾名思义就是工作区的意思,类似于Matlab中管理变量的工作区,caffe2里的变量一般就是指blob里存储的变量。

对模型的训练测试等操作都是在workspace中进行的,如运行一个网络,即调用workspace中的RunNet方法,输入参数为网络的名字和迭代轮数。具体的workspace中的方法可以查阅官方文档。

2.operator

在caffe2中创建一个operator的一般方法是使用core.CreateOperator,但在实际情况下,我们创建网络时不会直接创建每个operator,这样太麻烦,一般使用modelhelper来帮忙我们创建网络。

以创建一个relu operator举例:

# Create an operator. 
op = core.CreateOperator( 
    "Relu", # The type of operator that we want to run 
    ["X"],  # A list of input blobs by their names 
    ["Y"],  # A list of output blobs by their names 
) 
# and we are done!

这里我们创建了一个relu运算符。值得注意的是,这里我们仅是定义了一个relu运算符,却没有运行它。如果要运行这个运算符,需要先在当前工作区内添加一个输入的变量(一个blob变量),然后运行这个运算符,这里就需要用到workspace中的方法。

workspace.FeedBlob("X", np.random.randn(2, 3).astype(np.float32)) # add a Blob called X
workspace.RunOperatorOnce(op) # run the operator once

3.nets

Nets是一系列operator的集合,从本质上,是由operator构成的计算图。Caffe2中core.net 封装了源码中 NetDef 类。

同样,定义一个网络的工作完成后,实际上并没有进行net的计算。

当我们在python运行网络时,实际上在c++层面做了两件事情:

  • 由protobuf定义初始化c++的net对象
  • 调用初始化了的net的run函数

在python中有两种方法来运行一个net:

  • 方法1:使用workspace.RunNetOnce,初始化网络,运行网络,然后销毁网络。
  • 方法2:先使用workspace.CreateNet初始化网络,然后使用workspace.RunNet来运行网络。

4.modelhelper & brew

在operator的介绍中提到,一般来说我们是不用operator来直接创建网络的,每一层(包括数据输入权值初始化等)都要创建一个operator并为它设置初值,过于麻烦了。于是就有了用modelhelper来创建网络。

在caffe中所说的一个模型,其实就是一个网络,一个net。而在caffe2中,通常使用modelhelper来表示一个模型,这个模型里可以包含多个网络。一般来说一个模型包含一个param_init_net和一个net两个网络。modelhelper是在caffe2\python\model_helper.py中定义的一个类。详细说明如下:

class ModelHelper(object):
    """A helper model so we can manange models more easily. It contains net def
    and parameter storages. You can add an Operator yourself, e.g.

        model = model_helper.ModelHelper(name="train_net")
        # init your weight and bias as w and b
        w = model.param_init_net.XavierFill(...)
        b = model.param_init_net.ConstantFill(...)
        fc1 = model.FC([input, w, b], output, **kwargs)

    or you can use helper functions in brew module without manually
    defining parameter initializations and operators.

        model = model_helper.ModelHelper(name="train_net")
        fc1 = brew.fc(model, input, output, dim_in, dim_out, **kwargs)

    """

 ModelHelper包含了网络的定义和参数的存储,并且可以在此基础上自行添加operator。

比较有趣的是,在上面代码段说明的下半段,开发者提供了另一种建立模型的方式,即使用brew这个包。在caffe2中,为了便于开发者搭建网络,caffe2在python/helpers中提供了许多help函数,像上面例子中的FC层,使用python/helpers/fc.py来构造,非常简单就一行代码:

fc1 = brew.fc(model, input, output, dim_in, dim_out, **kwargs)
# returns a blob reference

这里面help函数能够帮助我们将权值初始化和计算网络自动分开到两个网络,这样一来就简单多了。caffe2为了更方便调用和管理,把这些帮助函数集合到一起,放在brew这个包里面。可以通过导入brew这个包来调用这些帮助函数。

两种方法来构造网络的原理是一样的,只是使用brew这个包能使网络建立的过程大大简化,所以目前官方给出的建议是尽量使用brew来构造网络。

 

对于caffe2的介绍到这里就结束了,下篇将开始详细分析detectron中Mask R-CNN的代码执行过程。

Reference:

1. caffe2官网:https://caffe2.ai/

2. caffe2 教程入门(python版)

3. Caffe2 - (十四) 网络构建API之 brew

你可能感兴趣的:(代码分析)