引 言 训练模型的配置参数在每次实验中都存在部分参数值需要略微调整的情况,如果只在运行主程序文件内调整参数值增加了实验的繁琐程度,严重降低用户体验。良好的配置系统应该具备以下特点:
- 方便修改实验所需的超参数
- 用户可以快捷管理项目和复现实验结果
- 项目结构清晰
实际项目中常见的配置系统:1) argparse.ArgumentParser 2) 使用yaml文件配置参数 3)使用yacs库结合yaml文件配置系统。argparse库提供了用户友好的命令行接口可以不用打开文件直接从命令行传递需要修改的配置参数,完美地解决了模型运行环境参数配置的难题。在本文中,主要介绍argparse模块实际使用场景中涉及的一些操作。若想全面了解该库可查阅argparse官方文档。
文章目录
一、创建ArgumentParser对象
语法:
import argparse #导入模块
parser = argparse.ArgumentParser(description='what the program does') #创建对象
参数description
描述本程序用途以及怎么使用。
parser = argparse.ArgumentParser(description='what the program does')
parser.print_help() #打印帮助信息
在命令行输入执行命令后,发现描述信息出现在界面中。
python ssss.py #主程序执行命令
二、add_argument()定义参数及parse_args()解析参数
创建对象后,调用add_argument()
函数定义模型需要使用的单个参数名称以及如何解析。
2.1 定义位置参数或者可选参数
- 定义位置参数语法
parser.add_argument(‘name’),直接输入参数名称name
,位置参数在参数解析过程中必须赋值否则会报错。
parser.add_argument('batch_size')
- 定义可选参数语法
parser.add_argument(‘-flag’,‘–flag’)
可以在参数名flag前添加前缀--
或-
,表示同一个可选参数的两种形式。例如示例中的-m
和--model
。
parser.add_argument('-m','--model')
parser.add_argument('--lr')
2.2 parse_args()参数解析
2.2.1 parse_args()参数赋值及解析的常用方法
定义的参数在命令行传递相应数值后,需调用parse_args()
函数解析参数并返回一个Namespace对象
,参数变成对象的属性。参数值匹配优先按照-
匹配(可选参数),剩余参数值依次赋给定义的位置参数。
parser = argparse.ArgumentParser(description='what the program does')
parser.add_argument('batch_size')
parser.add_argument('-m','--model')
parser.add_argument('--lr')
args = parser.parse_args()
print(args) #打印返回的命名空间对象
- 参数赋值方法一:参数赋值可以在命令行窗口中输入命令:
python ***.py [参数值列表]
参数值会自动解析成字符串,若想要参数值为int
或者float
可以在定义参数时设置关键字type
( 在下面小节详解[type属性] #2.3.6type属性
)。
- 参数赋值方法二:直接在主程序内部的
parse_args()
中添加参数值列表,
parser.parse_args([参数值列表])
传递的参数名和参数值必须为字符串,否则程序会报错。
args = parser.parse_args(['5','--model','lenet'])
print(args)
####结果
Namespace(batch_size='5', lr=None, model='lenet')
- 参数赋值方法三:在命令行输入与方法一相同的命令后,调用
parse_args(sys.argv[1:])
函数解析参数。
注:sys.argv列表的第一项是当前文件相对路径【相对于命令行窗口根目录】,从列表第二项开始为命令行传递的参数名和参数值。
import sys
print(sys.argv) #在主程序中打印argv列表
args = parser.parse_args(sys.argv[1:])
print(args)
注意:
在命令行输入携带参数值的命令后,主程序argv列表
显示结果为下面内容。由于参数在主程序中会解析成字符串,如果在命令行传递参数值为字符串,则会在主程序的的argv列表
中出现双层包裹的字符串,如红色方框标注的那样。命名空间对象中的属性值也是一个双层包裹的字符串。
注意:位置参数在命令行接口中必须赋值,不赋值会报错。可选参数若没有配置required=True时可以赋值也可以不赋值。
举例:在命令行中输入语句只给可选参数[model]赋值,位置参数[batcdh_size]没有赋值时程序报错。
2.2.2 parse_args()和parse_known_args()解析参数的区别
项目主程序脚本除了使用parser.parse_args()
函数解析参数值外,也可以调用parser.parse_known_args()
解析参数,下面会介绍两种解析方法的区别。
parser.parse_args()
只解析在parser.add_argument()
中定义的参数名。
在示例代码中,对未定义参数'--blocks'
赋值程序报错。
import argparse
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-m','--model')
parser.add_argument('--lr')
args = parser.parse_args(['--blocks','10'])
usage: ssss.py [-h] [-m MODEL] [--lr LR]
ssss.py: error: unrecognized arguments: --blocks 10
parser.parse_known_args()
提高未定义参数的容错能力。
parser.parse_known_args()
函数的参数值列表中可以存在未定义的参数名,函数的返回值分为两部分,一个是解析参数的namespace,另一个是未知参数列表。
namespace, unknow_args = parser.parse_known_args([params])
示例代码:
import argparse
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-m','--model')
parser.add_argument('--lr')
args,unknown_args = parser.parse_known_args(['--blocks','10','--lr','0.01','--model','lenet'])
print('known_args:',args)
print('unknown_args:',unknown_args)
##结果##
known_args: Namespace(lr='0.01', model='lenet')
unknown_args: ['--blocks', '10']
访问解析后的参数值可以直接通过args.参数名
方式。
print('model name:', args.model)
###
model name: lenet
2.3 定义参数的属性设置
2.3.1 default属性
在命令行或者parser.parse_args()函数中没有给可选参数赋值时,参数使用默认值。赋值时使用新值。
parser.add_argument('batch_size',default=32)
parser.add_argument('-m','--model',default='Resnet')
parser.add_argument('--lr')
args = parser.parse_args(['8'])
print(args)
###
Namespace(batch_size='8', lr=None, model='Resnet')
2.3.2 action属性
- action=‘store_true’或’store_false’,在命令行或者parser.parse_args()函数中没有出现参数名,参数使用默认bool值,出现参数名称时,动作为’store_true’时,参数bool值为True,动作为’store_false’参数时,bool值为False。
# 1.解析参数列表中出现参数名,use_gpu为True
parser.add_argument('--use_gpu',action='store_true',default=False)
args = parser.parse_args(['6'