天天看點

maskrcnn-benchmark源碼解析-config篇

目前網上看到的源碼解析都主要在寫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)
           

<一>default cfg的導入

首先,這個from maskrcnn_benchmark.config import cfg的cfg是啥?

看看config目錄下的檔案

maskrcnn-benchmark源碼解析-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 cfg與不同模型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

繼續閱讀