目前网上看到的源码解析都主要在写mask-Rcnn,包括backbone,rpn head, loss之类的,但是关于maskrcnn-benchmark本身的组织形式,config是如何调用的,目标检测的data是如何prepare的都没有解读,于是本文承接另一位博主的介绍
https://blog.csdn.net/francislucien2017/article/details/102584847?spm=1001.2014.3001.5506
开始介绍源码的其他细节部分,先讲讲config。
源码来自:https://github.com/yukang2017/Stitcher/tree/master/maskrcnn_benchmark
上回书说到,benchmark的训练脚本train_net.py
#from maskrcnn_benchmark.config import cfg
def main():
# 定义参数列表
parser = argparse.ArgumentParser(description="PyTorch Object Detection Training")
***
#省略内容
***
cfg.merge_from_file(args.config_file)
cfg.merge_from_list(args.opts)
cfg.freeze()
output_dir = cfg.OUTPUT_DIR
if output_dir:
mkdir(output_dir)
***
#省略内容
***
# 训练模型
model = train(cfg, args.local_rank, args.distributed)
# 是否测试模型
if not args.skip_test:
run_test(cfg, model, args.distributed)
首先,这个from maskrcnn_benchmark.config import cfg的cfg是啥?
看看config目录下的文件
合并到一起看
#__init__.py
from .defaults import _C as cfg
'''
从default.py导入_C对象,并重命名为cfg,即上面的from maskrcnn_benchmark.config import cfg
'''
#default.py
import os
from yacs.config import CfgNode as CN
'''
超参设置文件,以yacs来管理超参,CfgNode()为config节点,同时也能创建子节点
'''
_C = CN()#创建一个节点_C
_C.MODEL = CN()#创建_C的子节点MODEL
_C.MODEL.RPN_ONLY = False#设置子节点的一个参数RPN_ONLY为False
_C.MODEL.MASK_ON = False
_C.MODEL.RETINANET_ON = False
_C.MODEL.KEYPOINT_ON = False
_C.MODEL.DEVICE = "cuda"
_C.MODEL.META_ARCHITECTURE = "GeneralizedRCNN"
_C.MODEL.CLS_AGNOSTIC_BBOX_REG = False
_C.MODEL.WEIGHT = ""
_C.MODEL.BACKBONE = CN()
_C.MODEL.BACKBONE.CONV_BODY = "R-50-C4"
_C.MODEL.BACKBONE.FREEZE_CONV_BODY_AT = 2
###以下省略剩余相似内容
#paths_catlog.py
"""Centralized catalog of paths."""
import os
'''
存放各种数据、模型的位置,后面再讲
'''
class DatasetCatalog(object):
DATA_DIR = "datasets"
DATASETS = {
"coco_2017_train": {
"img_dir": "coco/train2017",
"ann_file": "coco/annotations/instances_train2017.json"
},
"coco_2017_val": {
"img_dir": "coco/val2017",
"ann_file": "coco/annotations/instances_val2017.json"
},
###以下省略剩余相似内容
顺便讲一下python中的包调用方式
1、train_net.py里
from maskrcnn_benchmark.config import cfg
会去看maskrcnn_benchmark/config文件夹下,找cfg对象
2、config文件夹下
有一个__init__.py
init.py的作用:让一个呈结构化分布(以文件夹形式组织)的代码文件夹变成可以被导入import的软件包。
参考https://blog.csdn.net/yucicheung/article/details/79445350
而在导入config时,会先执行__init__.py的内容
from .defaults import _C as cfg
从兄弟节点defaults.py文件中导入_C对象,并重命名为cfg
于是maskrcnn_benchmark.config里就有了cfg这个对象
便可以执行from maskrcnn_benchmark.config import cfg
default config是一个默认的config,maskrcnn_benchmark的就是maskrcnn的参数,而Stitcher模型则是直接在这里加上了一些参数。当要使用其他模型时,就将其他模型的yaml文件读取,并和"default config" merge在一起,其他模型的config会覆盖default config的相同部分。
cfg.merge_from_file(args.config_file)
cfg.merge_from_list(args.opts)
这里cfg=_C=CN()=yacs.config.CfgNode()
调用yacs.config.CfgNode()的merge_from_file方法,用一个新的yaml文件里的config继承default config。
eg.
#e2e_faster_rcnn_fbnet.yaml
MODEL:
META_ARCHITECTURE: "GeneralizedRCNN"
BACKBONE:
CONV_BODY: FBNet
FBNET:
ARCH: "default"
BN_TYPE: "bn"
WIDTH_DIVISOR: 8
DW_CONV_SKIP_BN: True
DW_CONV_SKIP_RELU: True
相当于查找MODEL节点:_C.MODEL = CN()
,子节点_C.MODEL.BACKBONE=CN()
并替代里面相同属性的内容CONV_BODY