mmdetection源码笔记(二):创建网络模型之registry.py和builder.py解读(上)

引言:

在上篇文章中,讲了train.py训练文件,主要是读取命令行函数和主函数main。main主要先做了一些config,work_dir以及log等操作(这些操作都是从命令行获得的,或者从命令行带有的文件里得到的参数等。)。最主要的三个步骤就是调用build_detector()来创建模型,然后同样调用build_dataset()对数据集创建模型,然后在训练检测器train_detector()。
注:build_dataset()和build_detector()不在同一个builder.py中实现,所以以下的builder.py实现的是build_detector(),是在mmdet/model/下的py文件。
具体详情看

本篇文章主要就是讲一下,搭建模型的思路,以及registry.pybuilder.py中各个函数块的作用。

注:builder.py是在mmdet/model文件夹下,是用来创建BACKBONES、NECKS、ROI_EXTRACTORS、SHARED_HEADS、HEADS、LOSSES、DETECTORS的模型的。而关于build_dataset()(在mmdet/datasets/builder.py中),在后面讲到数据集的时候再来讲它。

在mmdet/utils文件夹下的registry.py为主要的实现过程,后面详细讲解。
先来看在mmdet/models文件夹下的registry.py,较简单,代码如下:

# -*- coding: utf-8 -*-  
from mmdet.utils import Registry

BACKBONES = Registry('backbone')
NECKS = Registry('neck')
ROI_EXTRACTORS = Registry('roi_extractor')
SHARED_HEADS = Registry('shared_head')
HEADS = Registry('head')
LOSSES = Registry('loss')
DETECTORS = Registry('detector') 
#类的实例化,Registry是一个类,传入的是一个字符串。该字符串为Registry类的name属性值

举个例子:DETECTORS为注册表Registry的实例化对象,DETECTORS .name = 'detector',Registry类的定义在mmdet/utils/文件中。

所以,根据上面代码,我们就应该知道了,不止一个名为DETECTORS的注册表Registry,后面还会有名为NECKS、ROI_EXTRACTORS 、SHARED_HEADS 、HEADS 、LOSSES 的注册表,这些注册表下的_module_dict属性,则是用来存对应的相同类对象的,举个例子:比如DETECTORS的_module_dict下就有可能有:Faster R-CNN、Cascade R-CNN、FPN、HTC等常见的检测器。到这或许你就明白了注册表的作用咯

而在mmdet/utils/Registry.py中,有一个类Registry的定义和一个方法:build_from_cfg()的实现。
build_from_cfg()方法的作用是从 congfig/py配置文件中获取字典数据,创建module(其实也就是一个class类),然后将这个module添加到之前创建的注册表Registry的属性_module_dict中(这是一个字典,key为类名,value为具体的类),返回值是一个实例化后的类对象。

所以,可以这样理解,从config/py配置文件中,将字典提取出来,然后为其映射成一个类,放进Registry对象的_module_dict属性中。(具体看下面的代码)

Registry.py文件

以下代码分三部分

Part one:

inspect模块是针对模块,类,方法,功能等对象提供些有用的方法。例如可以帮助我们检查类的内容,检查方法的代码,提取和格式化方法的参数等。

# -*- coding: utf-8 -*-  
import inspect
import mmcv

Part two:

通过前面第一段的代码段,我们知道DETECTORS = Registry('detector')
detector是干什么的 ???
其实,DETECTORS = Registry('detector') 只是注册了一个对象名为DETECTORS ,属性name为detector的对象。然后用属性_module_dict 来保存config配置文件中的对应的字典数据所对应的class类(看第三部分代码)。请看如下类Registry的定义代码:

class Registry(object):

    def __init__(self, name):		#此处的self,是个对象(Object),是当前类的实例,name即为传进来的'detector'值
        self._name = name
        self._module_dict = dict()  #定义的属性,是一个字典

    def __repr__(self):
    #返回一个可以用来表示对象的可打印字符串,可以理解为java中的toString()。
        format_str = self.__class__.__name__ + '(name={}, items={})'.format(
            self._name, list(self._module_dict.keys()))
        return format_str

    @property						#把方法变成属性,通过self.name 就能获得name的值。
    def name(self):
        return self._name 
        #因为没有定义它的setter方法,所以是个只读属性,不能通过 self.name = newname进行修改。
    @property
    def<
  • 60
    点赞
  • 146
    收藏
    觉得还不错? 一键收藏
  • 34
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值