如何解决使用不同的默认值集解析参数 使用环境变量使用子解析器
我有一组用于训练的参数和一组用于调整的参数。它们共享相同的名称,但默认值不同。我想使用 argparse 来定义要使用的默认值组并解析这些值。
我了解到可以使用 add_subparsers
为每种模式设置子解析器。但是,它们的名称是相同的,这意味着我必须两次设置相同的参数(很长)。
我也尝试包含两个解析器,第一个解析几个args以确定使用哪组默认值,然后使用parser.set_defaults(**defaults)
为第二个解析器设置默认值,如下所示:
train_defaults = dict(
optimizer='AdamW',lr=1e-3,strategy='linear',warmup_steps=5_000,weight_decay=0.3
)
tune_defaults = dict(
optimizer='SGD',lr=1e-2,strategy='cosine',warmup_steps=500,weight_decay=0.0
)
selector = argparse.ArgumentParser(description='Mode Selector')
mode = selector.add_mutually_exclusive_group()
mode.add_argument('-t','--train',action='store_true',help='train model')
mode.add_argument('-u','--tune',help='tune model')
select,unkNown = selector.parse_kNown_args()
defaults = tune_defaults if select.tune else select.train
parser.set_defaults(**defaults)
args,unkNown = parser.parse_kNown_args()
但是两个解析器会在一些参数上发生冲突,例如,-td
指的是 --train_data
中的 parser
,但它也会被 selector
解析,它会引发一个例外:
usage: run.py [-h] [-pt | -pa] [-t] [-u] [-v]
run.py: error: argument -t/--train: ignored explicit argument 'd'
(这是一个 MWE,实际参数可能会有所不同。
解决方法
正如您所发现的,多解析器解决方案可能容易出错。我看到了两种选择:
使用环境变量
像这样:
import os
do_tuning = os.getenv("DO_THE_TUNING_MODE",None) is not None
...
defaults = tune_defaults if do_tuning else select.train
parser = argparse.ArgumentParser()
...
parser.set_defaults(**defaults)
args,unknown = parser.parse_known_args()
使用喜欢
DO_THE_TUNING_MODE=1 run.py <options>
或
export DO_THE_TUNING_MODE=1
run.py <options>
(当然,不要设置为训练模式)
- 优点:
- 调整/选择方法在解析器之外,因此不会发生冲突
- 用户可以在他们的 shell 会话中设置一个“状态”来调整或训练,而不必在运行时连续设置选项
- 缺点:
- 设置环境变量不如调用一次性使用的命令行选项简单
- 很容易忘记您的环境变量设置为什么
使用子解析器
这可能是最好的解决方案。你表示你不想这样做,因为你有很多选择,但这就是函数的用途。
def add_parsing_options(parser):
# All your 40 options go here
parser.add_argument(...)
parser.add_argument(...)
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
tuning_parser = subparser.add_parser("tune")
training_parser = subparser.add_parser("train")
add_parsing_options(tuning_parser)
add_parsing_options(training_parser)
tuning_parser.set_defaults(**tune_defaults)
training_parser.set_defaults(**train_defaults)
args,unknown = parser.parse_known_args()
点赞
run.py train <options>
或
run.py tune <options>
- 优点:
- 使用工具时要明确使用哪种模式
- 缺点:
- 每次使用该工具时都要输入一个额外的参数
我通过一些硬代码部分解决了这个问题,即
由于第一个解析器仅用于设置第二个解析器的默认参数,因此只有几个参数,在我的情况下为 2。
所以我所做的是将 sys.argv
分成两部分:
import sys
select,unknown = selector.parse_known_args(sys.argv[:3])
args,unknown = parser.parse_known_args(sys.argv[3:])
优点:
- 拥有其他方法的大部分优点
- 无需每次都输入额外的参数
缺点:
- 值 3 是一个超参数
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。