numpy.random.seed(0)做什么?

np.random.seed做什么?

np.random.seed(0)
595576 次浏览

np.random.seed(0)使随机数可预测

>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])
>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])

随着种子重置(每次),相同数字集将每次出现。

如果随机种子未被重置,则每次调用时都会出现不同的数字:

>>> numpy.random.rand(4)
array([ 0.42,  0.65,  0.44,  0.89])
>>> numpy.random.rand(4)
array([ 0.96,  0.38,  0.79,  0.53])

(伪)随机数的工作原理是从一个数字(种子)开始,乘以一个大数,加上一个偏移量,然后对这个和取模。然后,生成的数字被用作生成下一个“随机”数字的种子。当你(每次)设置种子时,它每次都做同样的事情,给你相同的数字。

如果你想要看似随机的数字,不要设置种子。但是,如果您的代码使用了想要调试的随机数,那么在每次运行之前设置种子会非常有帮助,这样代码每次运行时都会执行相同的操作。

要获得每次运行中最随机的数字,调用numpy.random.seed()将导致numpy将种子设置为从/dev/urandom或其Windows模拟物获得的随机数,或者,如果两者都不可用,它将使用时钟。

有关使用种子生成伪随机数的更多信息,请参见维基百科

如前所述,numpy.random.seed(0)将随机种子设置为0,因此从random获得的伪随机数将从同一点开始。在某些情况下,这有助于调试。然而,经过一些阅读,如果您有线程,这似乎是错误的方法,因为它不是线程安全的。

differences-between-numpy-random-and-random-random-in-python:

对于numpy.random.seed(),主要困难在于它不是 线程安全的——也就是说,如果你有很多不同的线程,那么使用线程安全是不安全的 线程执行,因为如果有两个线程,它不能保证工作 不同的线程同时执行这个函数。如果 您没有使用线程,如果您可以合理地期望您 将来不需要这样重写你的程序, Numpy.random.seed()应该可以用于测试目的。如果有 任何怀疑你将来可能需要线程的理由,都是 从长远来看,更安全的做法是按照建议去做,并在当地 numpy.random.Random类的实例据我所知 random.random.seed()是线程安全的(至少,我没有找到任何线程安全的 相反的证据)。

如何做到这一点的例子:

from numpy.random import RandomState
prng = RandomState()
print prng.permutation(10)
prng = RandomState()
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)

可能给:

[3 0 4 6 8 2 1 9 7 5]

[1 6 9 0 2 7 8 3 5 4]

[8 1 5 0 7 2 9 4 3 6]

[8 1 5 0 7 2 9 4 3 6]

最后,请注意,由于xor的工作方式,在某些情况下初始化为0(而不是所有位都为0的种子)可能会导致一些第一次迭代的不均匀分布,但这取决于算法,超出了我目前的担忧和这个问题的范围。

如果你每次调用numpy的其他随机函数时都设置np.random.seed(a_fixed_number),结果将是相同的:

>>> import numpy as np
>>> np.random.seed(0)
>>> perm = np.random.permutation(10)
>>> print perm
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.rand(4)
[0.5488135  0.71518937 0.60276338 0.54488318]
>>> np.random.seed(0)
>>> print np.random.rand(4)
[0.5488135  0.71518937 0.60276338 0.54488318]

然而,如果你只调用它一次,并使用各种随机函数,结果仍然会不同:

>>> import numpy as np
>>> np.random.seed(0)
>>> perm = np.random.permutation(10)
>>> print perm
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0)
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> print np.random.permutation(10)
[3 5 1 2 9 8 0 6 7 4]
>>> print np.random.permutation(10)
[2 3 8 4 5 1 0 6 9 7]
>>> print np.random.rand(4)
[0.64817187 0.36824154 0.95715516 0.14035078]
>>> print np.random.rand(4)
[0.87008726 0.47360805 0.80091075 0.52047748]

随机种子指定计算机生成随机数序列时的起始点。

例如,假设你想在Excel中生成一个随机数(注意:Excel为种子设置了9999的限制)。如果在此过程中您在“随机种子”框中输入一个数字,您将能够再次使用相同的随机数集。如果您在方框中输入“77”,并在下次运行随机数生成器时输入“77”,Excel将显示同一组随机数。如果你输入“99”,你会得到一组完全不同的数字。但是如果你返回到77的种子,那么你将得到与开始时相同的一组随机数。

例如,“取一个数x,加上900 +x,然后减去52。”为了使进程开始,您必须指定一个起始数字x(种子)。让我们以77为例:

加900 + 77 = 977 减去52 = 925 按照相同的算法,第二个“随机”数字将是:

900 + 925 = 1825 减去52 = 1773 这个简单的例子遵循一个模式,但是计算机数字生成背后的算法要复杂得多

设置特定种子值后产生的所有随机数在所有平台/系统中都是相同的。

我在神经网络中经常用到这个。众所周知,当我们开始训练神经网络时,我们会随机初始化权重。该模型在特定数据集上的这些权重上进行训练。在数代之后,你得到了一组训练好的权重。

现在假设你想再次从头开始训练,或者你想把模型传递给其他人来重现你的结果,权重将再次初始化为一个随机数,其中大多数将与之前的不同。在相同的epoch数(保持相同的数据和其他参数)后得到的训练权值与之前的会有所不同。问题是你的模型不再是可重复的,每次你从头开始训练你的模型,它会提供给你不同的权重集。这是因为模型每次都被不同的随机数初始化。

如果每次你从头开始训练时,模型初始化到相同的随机初始化权重集会怎样?在这种情况下,您的模型可以变得可重复。这是通过numpy.random.seed(0)实现的。通过将seed()提到一个特定的数字,您将始终保留相同的随机数集。

想象一下,您正在向某人展示如何用一堆“随机”数字编写代码。通过使用numpy种子,它们可以使用相同的种子号并获得相同的“随机”数字集。

所以它不是完全随机的,因为算法会吐出数字但它看起来像是随机生成的一堆。

Numpy文档中有一个很好的解释: https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.RandomState.html 它指向梅森扭扭伪随机数发生器。关于算法的更多细节:https://en.wikipedia.org/wiki/Mersenne_Twister

numpy.random.seed(0)
numpy.random.randint(10, size=5)

输出如下: array([5, 0, 3, 3, 7]) 同样,如果我们运行相同的代码,我们将得到相同的结果

现在,如果我们将种子值0改为1或其他:

numpy.random.seed(1)
numpy.random.randint(10, size=5)

这将产生以下输出:array([5 8 9 5 0]),但现在的输出与上面不同。

以上所有答案都在代码中显示了np.random.seed()的实现。我会尽量简单地解释为什么会发生这种情况。计算机是基于预先定义的算法设计的机器。计算机的任何输出都是对输入执行算法的结果。所以当我们要求计算机生成随机数时,当然它们是随机的,但计算机并不是随机产生的!

因此,当我们编写np.random.seed(any_number_here)时,算法将输出参数any_number_here唯一的一组特定数字。这就好像我们传递正确的参数就能得到一组特定的随机数。但这需要我们知道算法是如何工作的,这很乏味。

因此,例如,如果我写np.random.seed(10),我得到的特定数字集将保持不变,即使我在10年后执行同一行,除非算法改变。

我希望给出一个非常简短的答案:

seed使(下一个系列)随机数可预测。你可以认为,每次调用seed之后,它都预先定义了序列号,numpy random保留了它的迭代器,然后每次你得到一个随机数,它就会调用get next。

例如:

np.random.seed(2)
np.random.randn(2) # array([-0.41675785, -0.05626683])
np.random.randn(1) # array([-1.24528809])


np.random.seed(2)
np.random.randn(1) # array([-0.41675785])
np.random.randn(2) # array([-0.05626683, -1.24528809])

你可以注意到,当我设置相同的种子时,无论你每次从numpy请求多少个随机数,它总是给出相同的一系列数字,在本例中是array([-0.41675785, -0.05626683, -1.24528809])

它使得随机数是可预测的。 它们都以相同的组合开始,之后的每一次迭代都是相同的。 例子:< / p >
Output A: 0, 1, 2
Output B: 1, 3, 5
Output C: 2, 4, 6
Reset seed to 0
Output A: 0, 1, 2
Output B: 1, 3, 5
Output C: 2, 4, 6
Reset seed to 0
Output A: 0, 1, 2
Reset seed to 0
Output A: 0, 1, 2
.
.
.

我希望这对你有所帮助!