python用yaml装参数并支持命令行修改
效果:
- 将实验用的参数写入 yaml 文件,而不是全部用
argparse
传,否则命令会很长; - 同时支持在命令行临时加、改一些参数,避免事必要在 yaml 中改参数,比较灵活(如 grid-search 时遍历不同的 loss weights)。
最初是在 MMDetection 中看到这种写法,参考 [1] 中 --cfg-options
这个参数,核心是 DictAction
类,定义在 [2]。yaml 一些支持的写法参考 [3]。本文同时作为 python yaml 读、写简例。
Code
DictAction
类抄自 [2];parse_cfg
函数读 yaml 参数,并按命令行输入加、改参数(覆盖 yaml),用EasyDict
装;- 用 yaml 备份参数时,用
easydict2dict
将 EasyDict 递归改回 dict,yaml 会干净点。不用也行。
from argparse import Action, ArgumentParser, Namespace
import copy
from easydict import EasyDict
from typing import Any, Optional, Sequence, Tuple, Union
import yamlclass DictAction(Action):"""抄自 MMEngineargparse action to split an argument into KEY=VALUE formon the first = and append to a dictionary. List options canbe passed as comma separated values, i.e 'KEY=V1,V2,V3', or with explicitbrackets, i.e. 'KEY=[V1,V2,V3]'. It also support nested brackets to buildlist/tuple values. e.g. 'KEY=[(V1,V2),(V3,V4)]'"""@staticmethoddef _parse_int_float_bool(val: str) -> Union[int, float, bool, Any]:"""parse int/float/bool value in the string."""try:return int(val)except ValueError:passtry:return float(val)except ValueError:passif val.lower() in ['true', 'false']:return True if val.lower() == 'true' else Falseif val == 'None':return Nonereturn val@staticmethoddef _parse_iterable(val: str) -> Union[list, tuple, Any]:"""Parse iterable values in the string.All elements inside '()' or '[]' are treated as iterable values.Args:val (str): Value string.Returns:list | tuple | Any: The expanded list or tuple from the string,or single value if no iterable values are found.Examples:>>> DictAction._parse_iterable('1,2,3')[1, 2, 3]>>> DictAction._parse_iterable('[a, b, c]')['a', 'b', 'c']>>> DictAction._parse_iterable('[(1, 2, 3), [a, b], c]')[(1, 2, 3), ['a', 'b'], 'c']"""def find_next_comma(string):"""Find the position of next comma in the string.If no ',' is found in the string, return the string length. Allchars inside '()' and '[]' are treated as one element and thus ','inside these brackets are ignored."""assert (string.count('(') == string.count(')')) and (string.count('[') == string.count(']')), \f'Imbalanced brackets exist in {string}'end = len(string)for idx, char in enumerate(string):pre = string[:idx]# The string before this ',' is balancedif ((char == ',') and (pre.count('(') == pre.count(')'))and (pre.count('[') == pre.count(']'))):end = idxbreakreturn end# Strip ' and " characters and replace whitespace.val = val.strip('\'\"').replace(' ', '')is_tuple = Falseif val.startswith('(') and val.endswith(')'):is_tuple = Trueval = val[1:-1]elif val.startswith('[') and val.endswith(']'):val = val[1:-1]elif ',' not in val:# val is a single valuereturn DictAction._parse_int_float_bool(val)values = []while len(val) > 0:comma_idx = find_next_comma(val)element = DictAction._parse_iterable(val[:comma_idx])values.append(element)val = val[comma_idx + 1:]if is_tuple:return tuple(values)return valuesdef __call__(self,parser: ArgumentParser,namespace: Namespace,values: Union[str, Sequence[Any], None],option_string: str = None):"""Parse Variables in string and add them into argparser.Args:parser (ArgumentParser): Argument parser.namespace (Namespace): Argument namespace.values (Union[str, Sequence[Any], None]): Argument string.option_string (list[str], optional): Option string.Defaults to None."""# Copied behavior from `argparse._ExtendAction`.options = copy.copy(getattr(namespace, self.dest, None) or {})if values is not None:for kv in values:key, val = kv.split('=', maxsplit=1)options[key] = self._parse_iterable(val)setattr(namespace, self.dest, options)def parse_cfg(yaml_file, update_dict={}):"""load configurations from a yaml file & update from command-line argmentsInput:yaml_file: str, path to a yaml configuration fileupdate_dict: dict, to modify/update options in those yaml configurationsOutput:cfg: EasyDict"""with open(args.cfg, "r") as f:cfg = EasyDict(yaml.safe_load(f))if update_dict:assert isinstance(update_dict, dict)for k, v in update_dict.items():k_list = k.split('.')assert len(k_list) > 0if len(k_list) == 1: # 单级,e.g. lr=0.1cfg[k_list[0]] = velse: # 多级,e.g. optimizer.group1.lr=0.2ptr = cfgfor i, _k in enumerate(k_list):if i == len(k_list) - 1: # last layerptr[_k] = velif _k not in ptr:ptr[_k] = {}ptr = ptr[_k]return cfgdef easydict2dict(ed):"""convert EasyDict to dict for clean yaml"""d = {}for k, v in ed.items():if isinstance(v, EasyDict):d[k] = easydict2dict(v)else:d[k] = vreturn dif "__main__" == __name__:# test command:# python config.py --cfg-options int=5 dict2.lr=8 dict2.newdict.newitem=flyimport pprintparser = ArgumentParser()parser.add_argument("--cfg", type=str, default="config.yaml", help="指定 yaml")parser.add_argument('--cfg-options',nargs='+',action=DictAction,help='override some settings in the used config, the key-value pair ''in xxx=yyy format will be merged into config file. If the value to ''be overwritten is a list, it should be like key="[a,b]" or key=a,b ''It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" ''Note that the quotation marks are necessary and that no white space ''is allowed.')args = parser.parse_args()# 命令行临时加、改参数pprint.pprint(args.cfg_options) # dict# 读 yaml,并按命令行输入加、改参数cfg = parse_cfg(args.cfg, args.cfg_options)pprint.pprint(cfg)# 备份 yaml(写 yaml)with open("backup-config.yaml", 'w') as f:yaml.dump(easydict2dict(cfg), f)
输入的 config.yaml:
- 语法参考 [3]
# An example yaml configuration file, used in utils/config.py as an example input.
# Ref: https://pyyaml.org/wiki/PyYAMLDocumentationlog_path: ./log
none: [~, null, None]
bool: [true, false, on, off, True, False]
int: 42 # <- 改它
float: 3.14159
list: [LITE, RES_ACID, SUS_DEXT]
list2:- -1- 0- 1
str:a20.2# d: tom
dict: {hp: 13, sp: 5}
dict2: # <- 加它lr: 0.01 # <- 改它decay_rate: 0.1name: jerry
测试:
# --cfg-options 支持多级指定(用「.」分隔)
python config.py --cfg config.yaml --cfg-options int=5 dict2.lr=8 dict2.newdict.newitem=fly
输出:
{'dict2.lr': 8, 'dict2.newdict.newitem': 'fly', 'int': 5}
{'bool': [True, False, True, False, True, False],'dict': {'hp': 13, 'sp': 5},'dict2': {'decay_rate': 0.1,'lr': 8, # <- 改了'name': 'jerry','newdict': {'newitem': 'fly'}}, # <- 加了'float': 3.14159,'int': 5, # <- 改了'list': ['LITE', 'RES_ACID', 'SUS_DEXT'],'list2': [-1, 0, 1],'log_path': './log','none': [None, None, 'None'],'str': 'a 2 0.2'}
References
- open-mmlab/mmdetection/tools/train.py
- open-mmlab/mmengine/mmengine/config/config.py
- PyYAML Documentation
相关文章:
python用yaml装参数并支持命令行修改
效果: 将实验用的参数写入 yaml 文件,而不是全部用 argparse 传,否则命令会很长;同时支持在命令行临时加、改一些参数,避免事必要在 yaml 中改参数,比较灵活(如 grid-search 时遍历不同的 loss…...

第59讲订单数据下拉实现
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;/*** 订单查询 type值 0 全部订单 1待付款 2 待收货 3 退款/退货* param type* return*/RequestMapping("/list")public R list(Integer type,Integer page,Integer pageSize){System.out.pri…...

[当人工智能遇上安全] 11.威胁情报实体识别 (2)基于BiGRU-CRF的中文实体识别万字详解
您或许知道,作者后续分享网络安全的文章会越来越少。但如果您想学习人工智能和安全结合的应用,您就有福利了,作者将重新打造一个《当人工智能遇上安全》系列博客,详细介绍人工智能与安全相关的论文、实践,并分享各种案…...

16:定时器和计数器
定时器和计数器 1、定时器和计数器的介绍2、定时器是如何工作3、寄存器4、51单片机定时器简介(数据手册)5、定时器中的寄存器(数据手册)5.1、TCON(定时器控制寄存器)5.2、TMOD(工作模式寄存器&a…...
c#通过ExpressionTree 表达式树实现对象关系映射
//反射expression实现对象自动映射 void Main() {Person p1new(){Id1,Name"abc"};var persondto p1.MapTo<Person, PersonDto>();Console.WriteLine($"id:{persondto.Id}-name:{persondto.Name}"); }public static class AutoMapperExs { public s…...

《动手学深度学习(PyTorch版)》笔记7.2
注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过&…...

【MySQL进阶之路】BufferPool 生产环境优化经验
欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送! 在我后台回复 「资料」 可领取编程高频电子书! 在我后台回复「面试」可领取硬核面试笔记! 文章导读地址…...

Vim工具使用全攻略:从入门到精通
引言 在软件开发的世界里,Vim不仅仅是一个文本编辑器,它是一个让你的编程效率倍增的神器。然而,对于新手来说,Vim的学习曲线似乎有些陡峭。本文将手把手教你如何从Vim的新手逐渐变为高手,深入理解Vim的操作模式&#…...
Chapter 8 - 7. Congestion Management in TCP Storage Networks
TCP Flow Monitoring versus I/O Flow Monitoring TCP flow monitoring shouldn’t be confused with I/O flow monitoring because of the following reasons: TCP 流量监控不应与 I/O 流量监控混淆,原因如下: 1. TCP belongs to the transport layer (layer 4) of the OS…...
带你快速入门js高级-基础
1.作用域 全局 scriptxx.js 局部 函数作用域{} 块作用域 const let 2.闭包 函数外有权访问函数内的变量, 闭包可以延长变量生命周期 function 函数名 () {return function () {// 这里的变量不会立刻释放} }3.垃圾回收 不在使用(引用的变量), 防止占用内存,需要…...

数据结构与算法-链表(力扣附链接)
之前我们对C语言进行了一定的学习,有了一些基础之后,我们就可以学习一些比较基础的数据结构算法题了。这部分的知识对于我们编程的深入学习非常有用,对于一些基本的算法,我们学习之后,就可以参加一些编程比赛了&#x…...

多线程JUC:等待唤醒机制(生产者消费者模式)
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:多线程&JUC:解决线程安全问题——synchronized同步代码块、Lock锁 📚订阅专栏:多线程&am…...

无人机动力系统高倍率锂聚合物电池介绍,无人机锂电池使用与保养,无人机飞行控制动力源详解
无人机电池使用及保养 电池是无人机飞行的动力来源,也是一个消耗品,对电池充分了解,采取正确的使用方法,妥善进行维护保养将有助于提高飞行的安全性、延长电池的使用寿命。以下将详细对电池的使用和管理进行讲解。 高倍率锂聚合物电池的含义…...

[BeginCTF]真龙之力
安装程序 双击安装 出现了安装失败的标签,开发者不允许测试。 查看Mainfest入口文件 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android" android:versionCo…...

手写分布式存储系统v0.3版本
引言 承接 手写分布式存储系统v0.2版本 ,今天开始新的迭代开发。主要实现 服务发现功能 一、什么是服务发现 由于咱们的服务是分布式的,那从服务管理的角度来看肯定是要有一个机制来知道具体都有哪些实例可以提供服务。举个例子就是,张三家…...
除夕快乐!
打印的简单实现,祝大家新的一年万事顺意! 龙年大吉! #include <stdio.h> #include <windows.h> #include <string.h>int main() {const char* message "除夕快乐!";int i;for (i 0; i < strlen(message);…...

17:定时器编程实战
1、实验目的 (1)使用定时器来完成LED闪烁 (2)原来实现闪烁时中间的延迟是用delay函数实现的,在delay的过程中CPU要一直耗在这里不能去做别的事情。这是之前的缺点 (3)本节用定时器来定一个时间(譬如0.3s),在这个定时器定时时间内…...

Fink CDC数据同步(五)Kafka数据同步Hive
6、Kafka同步到Hive 6.1 建映射表 通过flink sql client 建Kafka topic的映射表 CREATE TABLE kafka_user_topic(id int,name string,birth string,gender string ) WITH (connector kafka,topic flink-cdc-user,properties.bootstrap.servers 192.168.0.4:6668…...

ubuntu原始套接字多线程负载均衡
原始套接字多线程负载均衡是一种在网络编程中常见的技术,特别是在高性能网络应用或网络安全工具中。这种技术允许应用程序在多个线程之间有效地分配和处理网络流量,提高系统的并发性能。以下是关于原始套接字多线程负载均衡技术的一些介绍: …...

leetcode (算法)66.加一(python版)
需求 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。 示例 1: 输入:digi…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...

AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...