mmcv.Config 类
- 支持的配置文件类型包括:'.py', '.json', '.yaml', '.yml'
1,读取模型配置文件
from mmcv import Config
cfg = Config.fromfile(args.config)
2, Config.fromfile()
def fromfile(filename,
use_predefined_variables=True,
import_custom_modules=True):
# 将文件转换为字典
cfg_dict, cfg_text = Config._file2dict(filename,
use_predefined_variables)
# 加载预定的??
if import_custom_modules and cfg_dict.get('custom_imports', None):
import_modules_from_strings(**cfg_dict['custom_imports'])
return Config(cfg_dict, cfg_text=cfg_text, filename=filename)
3, Config._file2dict(filename, use_predefined_variables)
def _file2dict(filename, use_predefined_variables=True):
# 判断该文件是否存在
filename = osp.abspath(osp.expanduser(filename))
check_file_exist(filename)
# 判断该文件类型是否符合要求
fileExtname = osp.splitext(filename)[1]
if fileExtname not in ['.py', '.json', '.yaml', '.yml']:
raise IOError('Only py/yml/yaml/json type are supported now!')
#创建缓存配置文件
with tempfile.TemporaryDirectory() as temp_config_dir:
temp_config_file = tempfile.NamedTemporaryFile(
dir=temp_config_dir, suffix=fileExtname)
if platform.system() == 'Windows':
temp_config_file.close()
temp_config_name = osp.basename(temp_config_file.name)
# Substitute predefined variables
if use_predefined_variables:
Config._substitute_predefined_vars(filename,
temp_config_file.name)
else:
shutil.copyfile(filename, temp_config_file.name)
# Substitute base variables from placeholders to strings
base_var_dict = Config._pre_substitute_base_vars(
temp_config_file.name, temp_config_file.name)
if filename.endswith('.py'):
temp_module_name = osp.splitext(temp_config_name)[0]
sys.path.insert(0, temp_config_dir)
Config._validate_py_syntax(filename)
mod = import_module(temp_module_name)
sys.path.pop(0)
cfg_dict = {
name: value
for name, value in mod.__dict__.items()
if not name.startswith('__')
}
# delete imported module
del sys.modules[temp_module_name]
elif filename.endswith(('.yml', '.yaml', '.json')):
import mmcv
cfg_dict = mmcv.load(temp_config_file.name)
# close temp file
temp_config_file.close()
# check deprecation information
if DEPRECATION_KEY in cfg_dict:
deprecation_info = cfg_dict.pop(DEPRECATION_KEY)
warning_msg = f'The config file {filename} will be deprecated ' \
'in the future.'
if 'expected' in deprecation_info:
warning_msg += f' Please use {deprecation_info["expected"]} ' \
'instead.'
if 'reference' in deprecation_info:
warning_msg += ' More information can be found at ' \
f'{deprecation_info["reference"]}'
warnings.warn(warning_msg, DeprecationWarning)
cfg_text = filename + '\n'
with open(filename, 'r', encoding='utf-8') as f:
# Setting encoding explicitly to resolve coding issue on windows
cfg_text += f.read()
if BASE_KEY in cfg_dict:
cfg_dir = osp.dirname(filename)
base_filename = cfg_dict.pop(BASE_KEY)
base_filename = base_filename if isinstance(
base_filename, list) else [base_filename]
cfg_dict_list = list()
cfg_text_list = list()
for f in base_filename:
_cfg_dict, _cfg_text = Config._file2dict(osp.join(cfg_dir, f))
cfg_dict_list.append(_cfg_dict)
cfg_text_list.append(_cfg_text)
base_cfg_dict = dict()
for c in cfg_dict_list:
duplicate_keys = base_cfg_dict.keys() & c.keys()
if len(duplicate_keys) > 0:
raise KeyError('Duplicate key is not allowed among bases. '
f'Duplicate keys: {duplicate_keys}')
base_cfg_dict.update(c)
# Substitute base variables from strings to their actual values
cfg_dict = Config._substitute_base_vars(cfg_dict, base_var_dict,
base_cfg_dict)
base_cfg_dict = Config._merge_a_into_b(cfg_dict, base_cfg_dict)
cfg_dict = base_cfg_dict
# merge cfg_text
cfg_text_list.append(cfg_text)
cfg_text = '\n'.join(cfg_text_list)
return cfg_dict, cfg_text
最终返回值
#cfg_dict
{'model':
{'type': 'Recognizer2D',
'backbone': {...},
'cls_head': {...},
'train_cfg': None, 'test_cfg': {...}},
'optimizer':
{'type': 'SGD',
'constructor': 'TSMOptimizerConstructor',
'paramwise_cfg': {...},
'lr': 0.01,
'momentum': 0.9,
'weight_decay': 0.0001},
'optimizer_config':
{'grad_clip': {...}},
'lr_config':
{'policy': 'step', 'step': [...]},
'total_epochs': 50,
'checkpoint_config': {'interval': 5},
'log_config': {'interval': 20, 'hooks': [...]},
'dist_params': {'backend': 'nccl'},
'log_level': 'INFO',
'load_from': None, 'resume_from': None, 'workflow': [(...)],
'opencv_num_threads': 0,
'mp_start_method': 'fork', ...}
# cfg_text 返回配置文件的文本内容
4, Config中auto_argparser生成参数解析文件
Config (path: configs/recognition/tsm/tsm_r50_1x1x8_50e_kinetics400_rgb.py): {'model': {'type': 'Recognizer2D', 'backbone': {'type': 'ResNetTSM', 'pretrained': 'torchvision://resnet50', 'depth': 50, 'norm_eval': False, 'shift_div': 8}, 'cls_head': {'type': 'TSMHead', 'num_classes': 400, 'in_channels': 2048, 'spatial_type': 'avg', 'consensus': {'type': 'AvgConsensus', 'dim': 1}, 'dropout_ratio': 0.5, 'init_std': 0.001, 'is_shift': True}, 'train_cfg': None, 'test_cfg': {'average_clips': 'prob'}}, 'optimizer': {'type': 'SGD', 'constructor': 'TSMOptimizerConstructor', 'paramwise_cfg': {'fc_lr5': True}, 'lr': 0.01, 'momentum': 0.9, 'weight_decay': 0.0001}, 'optimizer_config': {'grad_clip': {'max_norm': 20, 'norm_type': 2}}, 'lr_config': {'policy': 'step', 'step': [20, 40]}, 'total_epochs': 50, 'checkpoint_config': {'interval': 5}, 'log_config': {'interval': 20, 'hooks': [{'type': 'TextLoggerHook'}]}, 'dist_params': {'backend': 'nccl'}, 'log_level': 'INFO', 'load_from': None, 'resume_from': None, 'workflow': [('train', 1)], 'opencv_num_threads': 0, 'mp_start_method': 'fork', 'dataset_type': 'RawframeDataset', 'data_root': 'data/kinetics400/rawframes_train', 'data_root_val': 'data/kinetics400/rawframes_val', 'ann_file_train': 'data/kinetics400/kinetics400_train_list_rawframes.txt', 'ann_file_val': 'data/kinetics400/kinetics400_val_list_rawframes.txt', 'ann_file_test': 'data/kinetics400/kinetics400_val_list_rawframes.txt', 'img_norm_cfg': {'mean': [123.675, 116.28, 103.53], 'std': [58.395, 57.12, 57.375], 'to_bgr': False}, 'train_pipeline': [{'type': 'SampleFrames', 'clip_len': 1, 'frame_interval': 1, 'num_clips': 8}, {'type': 'RawFrameDecode'}, {'type': 'Resize', 'scale': (-1, 256)}, {'type': 'MultiScaleCrop', 'input_size': 224, 'scales': (1, 0.875, 0.75, 0.66), 'random_crop': False, 'max_wh_scale_gap': 1, 'num_fixed_crops': 13}, {'type': 'Resize', 'scale': (224, 224), 'keep_ratio': False}, {'type': 'Flip', 'flip_ratio': 0.5}, {'type': 'Normalize', 'mean': [123.675, 116.28, 103.53], 'std': [58.395, 57.12, 57.375], 'to_bgr': False}, {'type': 'FormatShape', 'input_format': 'NCHW'}, {'type': 'Collect', 'keys': ['imgs', 'label'], 'meta_keys': []}, {'type': 'ToTensor', 'keys': ['imgs', 'label']}], 'val_pipeline': [{'type': 'SampleFrames', 'clip_len': 1, 'frame_interval': 1, 'num_clips': 8, 'test_mode': True}, {'type': 'RawFrameDecode'}, {'type': 'Resize', 'scale': (-1, 256)}, {'type': 'CenterCrop', 'crop_size': 224}, {'type': 'Normalize', 'mean': [123.675, 116.28, 103.53], 'std': [58.395, 57.12, 57.375], 'to_bgr': False}, {'type': 'FormatShape', 'input_format': 'NCHW'}, {'type': 'Collect', 'keys': ['imgs', 'label'], 'meta_keys': []}, {'type': 'ToTensor', 'keys': ['imgs']}], 'test_pipeline': [{'type': 'SampleFrames', 'clip_len': 1, 'frame_interval': 1, 'num_clips': 8, 'test_mode': True}, {'type': 'RawFrameDecode'}, {'type': 'Resize', 'scale': (-1, 256)}, {'type': 'CenterCrop', 'crop_size': 224}, {'type': 'Normalize', 'mean': [123.675, 116.28, 103.53], 'std': [58.395, 57.12, 57.375], 'to_bgr': False}, {'type': 'FormatShape', 'input_format': 'NCHW'}, {'type': 'Collect', 'keys': ['imgs', 'label'], 'meta_keys': []}, {'type': 'ToTensor', 'keys': ['imgs']}], 'data': {'videos_per_gpu': 8, 'workers_per_gpu': 2, 'test_dataloader': {'videos_per_gpu': 1}, 'train': {'type': 'RawframeDataset', 'ann_file': 'data/kinetics400/kinetics400_train_list_rawframes.txt', 'data_prefix': 'data/kinetics400/rawframes_train', 'pipeline': [{'type': 'SampleFrames', 'clip_len': 1, 'frame_interval': 1, 'num_clips': 8}, {'type': 'RawFrameDecode'}, {'type': 'Resize', 'scale': (-1, 256)}, {'type': 'MultiScaleCrop', 'input_size': 224, 'scales': (1, 0.875, 0.75, 0.66), 'random_crop': False, 'max_wh_scale_gap': 1, 'num_fixed_crops': 13}, {'type': 'Resize', 'scale': (224, 224), 'keep_ratio': False}, {'type': 'Flip', 'flip_ratio': 0.5}, {'type': 'Normalize', 'mean': [123.675, 116.28, 103.53], 'std': [58.395, 57.12, 57.375], 'to_bgr': False}, {'type': 'FormatShape', 'input_format': 'NCHW'}, {'type': 'Collect', 'keys': ['imgs', 'label'], 'meta_keys': []}, {'type': 'ToTensor', 'keys': ['imgs', 'label']}]}, 'val': {'type': 'RawframeDataset', 'ann_file': 'data/kinetics400/kinetics400_val_list_rawframes.txt', 'data_prefix': 'data/kinetics400/rawframes_val', 'pipeline': [{'type': 'SampleFrames', 'clip_len': 1, 'frame_interval': 1, 'num_clips': 8, 'test_mode': True}, {'type': 'RawFrameDecode'}, {'type': 'Resize', 'scale': (-1, 256)}, {'type': 'CenterCrop', 'crop_size': 224}, {'type': 'Normalize', 'mean': [123.675, 116.28, 103.53], 'std': [58.395, 57.12, 57.375], 'to_bgr': False}, {'type': 'FormatShape', 'input_format': 'NCHW'}, {'type': 'Collect', 'keys': ['imgs', 'label'], 'meta_keys': []}, {'type': 'ToTensor', 'keys': ['imgs']}]}, 'test': {'type': 'RawframeDataset', 'ann_file': 'data/kinetics400/kinetics400_val_list_rawframes.txt', 'data_prefix': 'data/kinetics400/rawframes_val', 'pipeline': [{'type': 'SampleFrames', 'clip_len': 1, 'frame_interval': 1, 'num_clips': 8, 'test_mode': True}, {'type': 'RawFrameDecode'}, {'type': 'Resize', 'scale': (-1, 256)}, {'type': 'CenterCrop', 'crop_size': 224}, {'type': 'Normalize', 'mean': [123.675, 116.28, 103.53], 'std': [58.395, 57.12, 57.375], 'to_bgr': False}, {'type': 'FormatShape', 'input_format': 'NCHW'}, {'type': 'Collect', 'keys': ['imgs', 'label'], 'meta_keys': []}, {'type': 'ToTensor', 'keys': ['imgs']}]}}, 'evaluation': {'interval': 5, 'metrics': ['top_k_accuracy', 'mean_class_accuracy']}, 'work_dir': './work_dirs/tsm_r50_1x1x8_100e_kinetics400_rgb/'}
5,cfg.merge_from_dict(args.cfg_options)
加载参数配置到py文件