目前網上看到的源碼解析都主要在寫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目錄下的檔案
合并到一起看
#__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