如何将 fixed_seed 从 main.py 模块转移到其他模块?

Posted

技术标签:

【中文标题】如何将 fixed_seed 从 main.py 模块转移到其他模块?【英文标题】:How can I transfer a fixed_seed from main.py module to other modules? 【发布时间】:2016-10-19 22:05:35 【问题描述】:

我一直在研究一个模型,该模型具有许多使用随机数生成器的过程。第一次,我曾经在每个需要使用随机生成数字的模块中调用import random。我像random.Random.seed(1) 一样使用它,因为它在“参数”模块中生成了“fixed_seed”,所以它足以运行模型两次不同的时间并获得相同的结果。

问题是有很多调用过程我需要调用parameters 模块,它是重新创建fixed_seed。事实上,每个模拟月都会为随机数生成器获得相同的种子。

所以我尝试将这个fixed_seed 创建从参数传输到主模块,但我无法使用sys 或argparse 库来传输fixed_seed

我的例子:

############################################
# in the main model
############################################
import argparse
import random

# creating the fixed seed random generator 
fixed_seed = random.Random(0)

# transfering the fixed_seed to other modules
parser = argparse.ArgumentParser()
parsed_args = parser.parse_args(fixed_seed)

###############################################
# importing the fixed_seed in the other module
###############################################
import argparse

parser = argparse.ArgumentParser()
fixed_seed = parser.parse_args()

【问题讨论】:

【参考方案1】:

您似乎不明白 parser 的参数从何而来,以及当您进行解析时会发生什么。

解析器不是状态机,因此它不保存有关它所解析内容的信息或将其传递给其他解析器。

当你调用脚本时,例如

$ python mycode.py one two three

shell 和解释器将该命令行拆分为字符串并设置 sys.argv 变量

import sys
print(sys.argv)

应该显示:

['mycode', 'one', 'two', 'three]

第一个字符串是prog名称,其余的,sys.argv[1:]被解析。

所以

args = parser.parse_args()

相同
args = parser.parse_args(sys.argv[1:])

在这种情况下

args = parser.parse_args(['one', 'two', 'three'])

考虑到这一点,考虑这一行:

parsed_args = parser.parse_args(fixed_seed)

您将fixed_seed 定义为random.Random(0)。这是一个以0 为种子的随机数生成器(一个对象)。它不是像sys.argv 这样的字符串列表。我确定这会产生错误

我怀疑您正在尝试将fixed_seed 保存在另一个使用argparse 的地方。 argparse 不是这样使用的。

===========================

您可以使用任何hashable 设置随机种子,包括字符串。所以如果你在两个不同的进程中做x = random.Random('onetwo')x.random()会生成相同的随机数。

所以argparse 可以这样使用:

import argparse
import random

parser = argparse.ArgumentParser()
parser.add_argument('seed')
args = parser.parse_args()
x = random.Random(args.seed)
for _ in range(3):
    print x.random()

并且只要你给每个调用提供相同的“种子”字,随机数应该是相同的。

1926:~/mypy$ python stack37892221.py one
0.438175178474
0.0834683812319
0.43595707944
1926:~/mypy$ python stack37892221.py one
0.438175178474
0.0834683812319
0.43595707944
1926:~/mypy$ python stack37892221.py two
0.183364783476
0.195633546206
0.877462699471

如果您需要传递Random 对象而不是传递seed 字符串,则可以通过Pickle 保存它,然后从该文件加载它。

https://pymotw.com/2/random/#saving-state

谈到使用pickle 来保存x.getstate() 以在另一个进程中使用。

【讨论】:

嗨@hpaulj 我的需要正是这个。我需要在主模块中生成“fixed_seed”,并在需要的更多 7 个模块中使用它。那么,我该怎么办? # 在主模型中 import random # 创建固定种子随机生成器 fixed_seed = random.Random(0) # 在其他模块中导入 fixed_seed import sys fixed_seed = sys.argv[1] 查看我的新 saving-state 链接。 谢谢@hpaulj!!!它工作正常,解决了我的问题!我在每个模块中第一次在 main、pickle 和 load 中创建了一个随机状态。之后,在模拟的其他月份,每个模块转储并加载自己的随机种子“状态”!干杯!

以上是关于如何将 fixed_seed 从 main.py 模块转移到其他模块?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 main.py 文件中定义的变量用于另一个文件?

从python中的更高目录导入[重复]

如何仅在评估模式下运行 TF 对象检测 API model_main.py

Python - 从导入的模块注册函数

非阻塞 subprocess.call

从 Jupyter Notebook 中的文件“main.py”传输代码