如何检索NumPy随机数生成器的当前种子?

问题描述 投票:41回答:3

以下导入NumPy并设置种子。

import numpy as np
np.random.seed(42)

但是,我对设置种子并不感兴趣,而是更多地阅读它。 random.get_state()似乎没有包含种子。 documentation没有显示出明显的答案。

我如何检索numpy.random使用的当前种子,假设我没有手动设置它?

我想使用当前种子来继承进程的下一次迭代。

python numpy random random-seed mersenne-twister
3个回答
57
投票

简短的回答是你根本不能(至少不是一般)。

numpy使用的Mersenne Twister RNG具有219937-1个可能的内部状态,而单个64位整数仅具有264个可能的值。因此,不可能将每个RNG状态映射到唯一的整数种子。

您可以使用np.random.get_statenp.random.set_state直接获取和设置RNG的内部状态。 get_state的输出是一个元组,其第二个元素是32位整数的(624,)数组。该阵列具有足够多的位来表示RNG的每个可能的内部状态(2624 * 32> 219937-1)。

get_state返回的元组可以像种子一样使用,以创建可重现的随机数序列。例如:

import numpy as np

# randomly initialize the RNG from some platform-dependent source of entropy
np.random.seed(None)

# get the initial state of the RNG
st0 = np.random.get_state()

# draw some random numbers
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26  3  1 68 21]

# set the state back to what it was originally
np.random.set_state(st0)

# draw again
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26  3  1 68 21]

10
投票

在我找到有关手头问题的更多细节后,我已经编辑了这个答案。就目前情况而言,我希望它能够很好地澄清来自ali_m的答案,并作为对Dong Justin答案的重要修正。

这些是我的发现:

  1. 使用np.random.seed(X)设置随机种子后,您可以使用np.random.get_state()[1][0]再次找到它。
  2. 但是,它对你没用。

以下代码部分的输出将显示两个语句为何正确的原因。


声明1 - 您可以使用np.random.get_state()[1][0]找到随机种子。

如果使用np.random.seed(123)设置随机种子,则可以使用state = np.random.get_state()将随机状态检索为元组。下面仔细看看state(我在Spyder中使用Variable explorer)。我正在使用屏幕截图,因为使用print(state)会使控制台泛滥,因为元组的第二个元素中的数组大小。

enter image description here

您可以轻松地将123视为第二个元素中包含的数组中的第一个数字。并使用seed = np.random.get_state()[1][0]将给你123。完善?不完全是因为:

声明2 - 然而,它对您没什么用处:

起初它可能看起来不是那样,因为你可以使用np.random.seed(123),用seed = np.random.get_state()[1][0]检索相同的数字,用np.random.seed(444)重置种子,然后(貌似)用123将它设置回np.random.seed(seed)场景。但是之后你已经知道你的随机种子是什么了,所以你不需要这样做。下一个代码部分还将显示您不能使用np.random.get_state()[1][0]获取任何随机状态的第一个数字,并期望重新创建该确切方案。请注意,您很可能必须完全关闭并重新启动内核(或调用np.random.seed(None))才能看到此内容。

以下代码片段使用np.random.randint()生成介于-10和10之间的5个随机整数,并存储有关该过程的一些信息:

片段1

# 1. Imports
import pandas as pd
import numpy as np

# 2. set random seed
#seedSet = None
seedSet = 123
np.random.seed(seedSet)

# 3. describe random state
state = np.random.get_state()
state5 = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]

# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)

# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)

请注意,名为seedState的列与state下的第一个数字相同。我可以把它打印成一个独立的号码,但我想把它们全部保存在同一个地方。另请注意,到目前为止,seedSet = 123np.random.seed(seedSet)已经被注释掉了。因为没有设置随机种子,你的数字将与我的不同。但这不是重要的,而是你的结果的内在一致性:

输出1:

   random seedSet   seedState       state
0       2    None  1558056443  1558056443
1      -1    None  1558056443  1808451632
2       4    None  1558056443   730968006
3      -4    None  1558056443  3568749506
4      -6    None  1558056443  3809593045

在这个特殊情况下,seed = np.random.get_state()[1][0]等于1558056443。按照Dong Justins回答的逻辑(以及我在编辑之前的答案),您可以使用np.random.seed(1558056443)设置随机种子并获得相同的随机状态。下一个片段将显示您不能:

片段2

# 1. Imports
import pandas as pd
import numpy as np

# 2. set random seed
#seedSet = None
seedSet = 1558056443
np.random.seed(seedSet)

# 3. describe random state
#state = np.random.get_state()
state = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]

# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)

# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)

输出2:

   random     seedSet   seedState       state
0       8  1558056443  1558056443  1558056443
1       3  1558056443  1558056443  1391218083
2       7  1558056443  1558056443  2754892524
3      -8  1558056443  1558056443  1971852777
4       4  1558056443  1558056443  2881604748

看到不同? np.random.get_state()[1][0]对于输出1和输出2是相同的,但输出的其余部分不相同(最重要的是随机数不相同)。所以,由于ali_m已经明确说明:

因此,不可能将每个RNG状态映射到唯一的整数种子。


0
投票

检查np.random.get_state()返回的数组的第一个元素,它似乎是我的随机种子。

© www.soinside.com 2019 - 2024. All rights reserved.