簡體   English   中英

numpy.random.seed(0) 有什么作用?

[英]What does numpy.random.seed(0) do?

np.random.seed在下面來自 Scikit-Learn 教程的代碼中做了什么? 我對 NumPy 的隨機狀態生成器的東西不是很熟悉,所以我真的很感激外行人對此的解釋。

np.random.seed(0)
indices = np.random.permutation(len(iris_X))

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 模擬獲得的隨機數,或者,如果這兩個都不可用,它將使用時鍾。

有關使用種子生成偽隨機數的更多信息,請參閱wikipedia

如果每次調用 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]

如前所述, numpy.random.seed(0) 將隨機種子設置為 0,因此您從 random 獲得的偽隨機數將從同一點開始。 在某些情況下,這對調試很有用。 但是,經過一些閱讀后,如果您有線程,這似乎是錯誤的方法,因為它不是線程安全的。

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 的種子)可能會導致一些第一次迭代的分布不均勻,但這取決於算法,並且超出了我目前的擔憂和這個問題的范圍。

我在神經網絡中經常使用它。 眾所周知,當我們開始訓練神經網絡時,我們會隨機初始化權重。 該模型在特定數據集上的這些權重上進行訓練。 在經過多次訓練后,您將獲得一組經過訓練的權重。

現在假設您想再次從頭開始訓練,或者您想將模型傳遞給其他人以重現您的結果,權重將再次初始化為隨機數,該數通常與之前的不同。 在與之前的相同數量的 epoch(保持相同的數據和其他參數)之后獲得的訓練權重會有所不同。 問題是您的模型不再具有可重復性,因為每次您從頭開始訓練模型時,它都會為您提供不同的權重集。 這是因為模型每次都被不同的隨機數初始化。

如果每次從頭開始訓練時,模型都會初始化為相同的隨機初始化權重集怎么辦? 在這種情況下,您的模型可以重現。 這是通過 numpy.random.seed(0) 實現的。 通過向特定數字提及 seed() ,您始終會使用同一組隨機數。

想象一下,您正在向某人展示如何使用一堆“隨機”數字對某些內容進行編碼。 通過使用 numpy 種子,他們可以使用相同的種子數並獲得相同的“隨機”數集。

所以它不是完全隨機的,因為算法會吐出數字,但它看起來像是隨機生成的一堆。

上面的所有答案都顯示了代碼中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]) .

隨機種子指定計算機生成隨機數序列時的起點。

例如,假設您想在 Excel 中生成一個隨機數(注意:Excel 為種子設置了 9999 的限制)。 如果您在此過程中在隨機種子框中輸入一個數字,您將能夠再次使用同一組隨機數。 如果您在框中鍵入“77”,並在下次運行隨機數生成器時鍵入“77”,Excel 將顯示相同的隨機數集。 如果你輸入“99”,你會得到一組完全不同的數字。 但是,如果您恢復到 77 的種子,那么您將獲得與開始時相同的一組隨機數。

例如,“取一個數字 x,加上 900 + x,然后減去 52。” 為了啟動進程,您必須指定一個起始編號 x(種子)。 讓我們以起始數字 77 為例:

加 900 + 77 = 977 減 52 = 925 按照相同的算法,第二個“隨機”數將是:

900 + 925 = 1825 減 52 = 1773 這個簡單的例子遵循一個模式,但計算機數字生成背后的算法要復雜得多

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])但現在輸出與上面不同。

設置特定種子值后生成的所有隨機數在所有平台/系統中都是相同的。

Numpy 文檔中有一個很好的解釋: https ://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.RandomState.html 它指的是Mersenne Twister 偽隨機數生成器 有關該算法的更多詳細信息,請訪問: https : //en.wikipedia.org/wiki/Mersenne_Twister

它是可重復性的種子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM