import os import yaml import monopsr def config_dict_to_object(config_dict): """Recursively converts a dictionary to an object Args: config_dict: config dictionary to convert Returns: ConfigObj configuration object """ def convert(item): if isinstance(item, dict): return type('ConfigObj', (), {k: convert(v) for k, v in item.items()}) if isinstance(item, list): def yield_convert(list_item): for index, value in enumerate(list_item): yield convert(value) return list(yield_convert(item)) else: return item return convert(config_dict) def no_duplicates_constructor(loader, node, deep=False): """Check for duplicate keys https://gist.github.com/pypt/94d747fe5180851196eb """ mapping = {} for key_node, value_node in node.value: key = loader.construct_object(key_node, deep=deep) value = loader.construct_object(value_node, deep=deep) if key in mapping: raise ValueError('Found duplicate key in yaml' + key) mapping[key] = value return loader.construct_mapping(node, deep) def parse_yaml_config(yaml_path): """Parses a yaml config Args: yaml_path: path to yaml config Returns: config_obj: config converted to object """ # Add check for duplicate keys in yaml yaml.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, no_duplicates_constructor) with open(yaml_path, 'r') as yaml_file: config_dict = yaml.load(yaml_file) config_obj = config_dict_to_object(config_dict) config_obj.config_name = os.path.splitext(os.path.basename(yaml_path))[0] config_obj.exp_output_dir = monopsr.data_dir() + '/outputs/' + config_obj.config_name # Prepend data folder to paths paths_config = config_obj.train_config.paths_config if paths_config.checkpoint_dir is None: checkpoint_dir = config_obj.exp_output_dir + '/checkpoints' if not os.path.exists(checkpoint_dir): os.makedirs(checkpoint_dir) paths_config.checkpoint_dir = checkpoint_dir else: paths_config.checkpoint_dir = os.path.expanduser(paths_config.checkpoint_dir) paths_config.logdir = config_obj.exp_output_dir + '/logs' paths_config.pred_dir = config_obj.exp_output_dir + '/predictions' return config_obj