【问题标题】:Having problems keeping a simulation deterministic with random.Random(0) in python在 python 中使用 random.Random(0) 保持模拟确定性时遇到问题
【发布时间】:2016-10-19 14:41:33
【问题描述】:

我在 python 中有一个非常大的模拟,有很多模块。我调用了很多随机函数。为了保持相同的随机结果,我有一个变量 keep_seed_random。

这样:

import random

keep_seed_random = True

if keep_seed_random is False:
    fixed_seed = random.Random(0)
else:
    fixed_seed = random

然后我在整个程序中使用fixed_seed,比如

fixed_seed.choice(['male', 'female'])
fixed_seed.randint()
fixed_seed.gammavariate(3, 3)
fixed_seed.random()
fixed_seed.randrange(20, 40)

等等……

它曾经运作良好。 但是现在,程序太大,有其他干扰,结果不再相同,即使我选择 keep_seed_random = False

我的问题是 Python 中是否还有其他我遗漏的随机性来源?

附:我只随机导入一次。

已编辑

我们一直在努力确定程序从完全相同的结果转变为不同结果的确切时刻。似乎是在我们引入大量读取数据库而不连接随机模块的时候。

结果现在在两个相似的结果中交替出现。 也就是说,我运行 main.py 一次得到 GDP 的 8148.78 的结果 我再次运行我得到 7851.49 再次返回 8148.78 再次 7851.49

对于工作版本,在更改之前,第一个结果(当我们创建实例并 pickle 保存它们时)我得到一个结果。然后,从第二个开始,结果都是一样的。所以,我猜它与泡菜阅读/加载有关。

问题依然存在!

第二次编辑

我们部分发现了问题。 问题是当我们创建实例和pickle转储然后pickle加载时。

对于创建和加载,我们仍然无法获得完全相同的结果。 但是,当重复加载时,结果是准确的。

因此,问题出在 PICKLE 转储和加载时可能会发生一些随机化(我猜)。

谢谢,

【问题讨论】:

  • 我会尝试缩小程序范围以找到可以重现问题的最少代码。这个问题很难以现在的方式回答。
  • 我知道。这才是重点。我不知道随机性可能来自哪里......谢谢@mart0903
  • 好话。我看了!但在视频示例中,它适用于一个非常具体的问题。这对我来说可能是不同的......

标签: python random deterministic


【解决方案1】:

如@mart0903 所述,如果没有良好的重现案例,这很难诊断。但是,一般而言,可能会出现多种随机性来源。想到了几件事:

例如,如果您使用multiprocessing 和/或subprocess 包来生成多个并行进程,您可能会遇到竞争情况。也就是说,每次运行程序时,不同的进程在不同的时间完成。也许您正在以某种方式组合结果,这取决于这些线程以特定顺序执行。

也许您只是简单地遍历字典并期望键按特定顺序排列,而事实上,字典没有排序。例如,连续运行几次以下命令(我使用 Python 3.5 以防万一),您会注意到键值对每次都以不同的顺序打印出来:

if __name__=='__main__':
    data = dict()
    data['a'] = 6
    data['b'] = 7
    data['c'] = 42
    for key in data:
        print(key + ' : ' + str(data[key]))

您甚至可能正在查看时间戳或设置一些值,或者可能在某处生成您在计算中使用的 uuid。

可能性还会继续。但同样,如果没有简单的重现案例,很难确定。它可能只需要一些好的断点和大量的代码单步执行。

祝你好运!

【讨论】:

  • 谢谢,但我不使用多处理。正如您在此处建议的那样,我都没有使用关键字典。我猜这个问题来自于导入一个或另一个库。特别是,我使用 osgeo、ogr、pandas、numpy、pickle、subprocess、sys、os、geopandas、shapely、ggplot、glob、itertools、operator
  • 啊,是的。 subprocess 可以让您像 multiprocessing 包一样容易地进入竞争状态,如果您一次运行多个包。那基本上是一样的。如果您有两个进程,并且您的结果取决于它们完成的顺序,那么您肯定会遇到同样的事情。我将在上面更新我的答案以包括subprocess
  • 但是只有在我多次运行模拟时才会调用子进程。在一次运行中,没有从问题中调用main.py,然后没有使用子进程......我认为随机性的来源可能来自另一个库!
  • 它当然可以是另一个库,正如你所建议的那样。如果没有缩小范围的重现病例,就很难诊断。
  • 谢谢!我重新编写了所有代码,包括 setseed、saveseed、检查 numpy.seed,但仍然有问题。我还检查了stackoverflow.com/questions/11526975/… 的所有解决方案,但没有结果。问题是它是一个完整的程序,有 25 个模块和一些必要的阅读数据库。也许我应该在 GitHubt 上分享它,但我还没有提交任何论文......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-14
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 2023-02-13
  • 1970-01-01
相关资源
最近更新 更多