利用配置文件来组合各部分内容
cfg = Config.fromfile(args.config) (args.config其实就是命令行传入的配置文件的地址)
在利用mmdet3d框架进行训练时,核心在于一个配置文件。在train.py中,会将传入的配置文件地址生成一个cfg对象,这个cfg就相当于一个嵌套字典结构,字典中储存着配置文件中关于data,model,runner(用于执行训练),优化器等内容。
mmdet总体是用字典来储存配置文件的信息,生成cfg对象后,继承了DIctAction后用cfg.model.xxx就可以访问字典里的内容。不同model并列关系是用列表储存。也就是总体上是大字典套小字典,中间可能有list的结构。(相当于可以用cfg.xxx.xxx来访问字典中储存的不同层级的内容)
一般来说配置文件可以利用_base_=[mmdet3d中写好的config文件地址] 继承已经写好的配置文件,相当于把之前写好的内容直接复制过来,可以省去很多靠自己写的步骤。
_base_ = [
'../../../configs/_base_/default_runtime.py'
]
当然,可以在此基础上增加新的内容,若有名字和之前内容重合,则会进行覆盖。若是直接写dict()只写其中一个元素,则会求同存异,把不一样的进行修改,其他没写的仍按之前的值。
mmdet3d的注册器机制——更加便于从配置文件中读取model
MODELS = Registry('models', parent=MMCV_MODELS)
BACKBONES = MODELS
NECKS = MODELS
ROI_EXTRACTORS = MODELS
SHARED_HEADS = MODELS
HEADS = MODELS
LOSSES = MODELS
DETECTORS = MODELS
VOXEL_ENCODERS = MODELS
MIDDLE_ENCODERS = MODELS
FUSION_LAYERS = MODELS
SEGMENTORS = MODELS
在mmdet3d/model/builder.py中,实现了注册器机制,把各组件注册上去。
后面对于各个组件具体的类的实现:
用@相应前面注册器的名字.register_module() ,在下面具体定义类的实现,之后就可以用相应的方法直接通过访问字符串就能访问到这个被注册的类。因此在mmdet3d的配置文件中,只要给定好type=“类名”,就可以理解为在配置文件中引入了这个类的定义过程。(只不过我们在配置文件会在此基础上进行覆盖和组合,以及把各组件拼成一整个model)
注意,如果自己在此框架中通过注册器机制写好了一个网络,经过上述注册后,记得在相应模块的_init_.py的_all_=[]中加入该类,且在写这个类的导入模块要模仿其他已经存在的同类别的网络类。
补充:_init_.py的_all_=[]即如果使用from xxx import *导入xxx功能包所有的内容,实际上只会导入_all_=[]中的字符串对应的xxx包中定义好的类或函数。
综上所述,对于model部分,我们在配置文件中通过type=“”,可以引入已经定义好的网络结构(利用注册器机制),并可以在此基础上进行补充覆盖,组装成一个完整的model。最后,我们通过cfg.model可以访问配置文件中的model,利用框架中写好的函数build_model,创造实例化model=build_model(cfg.model),就可以进行最后的训练)。
model = build_model(
cfg.model,
train_cfg=cfg.get('train_cfg'),
test_cfg=cfg.get('test_cfg'))
#在使用cfg.get()函数时,你需要将相应配置文件中的元素用引号括起来
一般还得加上配置文件中的train_cfg和test_cfg,因为训练和预测的网络往往存在一些设置的不同。