import yaml
from experiment import ExperimentStage
if __name__ == '__main__':
with open('./configs/common.yaml', 'r') as f:
common_config = yaml.load(f, Loader=yaml.Loader)
print(type(common_config))
print(common_config)
if not isinstance(common_config['device'], list):
common_config['device'] = [common_config['device']]
experiment_configs = []
# for experiment_path in args['experiments']:
experiment_path='./configs/basis_exp/experiment_fedstil.yaml'
with open(experiment_path, 'r') as f:
exp_config = dict(common_config['defaults'])
exp_config.update(yaml.load(f, Loader=yaml.Loader))
experiment_configs.append(exp_config)
with ExperimentStage(common_config, experiment_configs) as exp_stage:
exp_stage.run()
class ExperimentStage(object):
def __init__(self, common_config: Dict, exp_configs: Union[Dict, Tuple[Dict]]):
self.common_config = common_config
self.exp_configs = [exp_configs] if isinstance(exp_configs, Dict) else exp_configs
self.logger = Logger('stage')
self.container = VirtualContainer(self.common_config['device'], self.common_config['parallel'])
def __enter__(self):
self.check_environment()
return self
def __exit__(self, type, value, trace):
if type is not None and issubclass(type, Exception):
self.logger.error(value)
raise trace
return self
def check_environment(self):
# check runtime device
devices = self.common_config['device']
for device in devices:
try:
torch.Tensor([0]).to(device)
except Exception as ex:
self.logger.error(f'Not available for given device {device}:{ex}')
exit(1)
# check dataset base path
datasets_dir = self.common_config['datasets_dir']
if not os.path.exists(datasets_dir):
self.logger.error(f'Datasets base directory could not be found with {datasets_dir}.')
exit(1)
# check dataset base path
checkpoints_dir = self.common_config['checkpoints_dir']
if os.path.exists(checkpoints_dir):
self.logger.warn(f'Checkpoint directory {checkpoints_dir} is not empty.')
self.logger.info('Experiment stage build success.')
对于上面这个代码,我不理解的是with的使用与yaml文件是怎样读取,怎样编写的。
参考文章:
Python with理解
Python----魔法函数__enter__/__exit__的用法
上面这段代码中with用于读取文件common.yaml与experiment_fedstil.yaml
在平时读取文件的时候我会这样读取:
file = open("/tmp/foo.txt")
data = file.read()
file.close()
这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。
with open("/tmp/foo.txt") as file:
data = file.read()
与with语句配套的是__enter__与__exit__,在执行with语句之前,先实例化ExperimentStage类,运行init方法,然后运行__enter__方法,将__enter__的返回值赋值给as后面的变量,接着运行with-as后面的语句,运行完之后,最后运行__exit__方法。
参考文章:
python yaml用法详解
YAML是一种直观的能够被电脑识别的的数据序列化格式,容易被人类阅读,并且容易和脚本语言交互。YAML类似于XML,但是语法比XML简单得多,对于转化成数组或可以hash的数据时是很简单有效的。
import yaml
if __name__ == '__main__':
with open('test.yaml', 'r') as f:
common_config = yaml.load(f, Loader=yaml.Loader)
print(type(common_config))
print(common_config)
test.yaml
name: Tom Smith age: 37 spouse: name: Jane Smith age: 25 children: - name: Jimmy Smith age: 15 - name1: Jenny Smith age1: 12
运行结果:
{'name': 'Tom Smith', 'age': 37, 'spouse': {'name': 'Jane Smith', 'age': 25}, 'children': [{'name': 'Jimmy Smith', 'age': 15}, {'name1': 'Jenny Smith', 'age1': 12}]}
children这里是列表:
1. 大小写敏感
2. 使用缩进表示层级关系
3. 缩进时不允许使用Tab,只允许使用空格
4. 缩进的空格数目不重要,只要相同层级的元素左对齐即可
5. # 表示注释,从它开始到行尾都被忽
2、yaml转字典
3、yaml转列表
4、如果字符串没有空格或特殊字符,不需要加引号,但如果其中有空格或特殊字符,则需要加引号了
import yaml
aproject = {'name': 'Silenthand Olleander',
'race': 'Human',
'traits': ['ONE_HAND', 'ONE_EYE']
}
with open('test.yaml', 'w') as f:
yaml.dump(aproject,f)