熱門話題
#
Bonk 生態迷因幣展現強韌勢頭
#
有消息稱 Pump.fun 計劃 40 億估值發幣,引發市場猜測
#
Solana 新代幣發射平臺 Boop.Fun 風頭正勁
在今天的程式設計恐怖故事中...
在 Python 的 random.seed() 定義文件中,我們被告知
"如果 a 是整數,則直接使用它。" [1]
但如果你用 3 或 -3 作為種子,你實際上會得到完全相同的 rng 物件,產生相同的流。(今天學到了)。在 nanochat 中,我使用符號作為一種(我認為是)巧妙的方法來獲得不同的 rng 序列以進行訓練/測試拆分。因此出現了棘手的錯誤,因為現在 train=test。
我在 cpython/Modules/_randommodule.c [2] 中找到了負責的 CPython 代碼,在第 321 行我們在註釋中看到:
"這個算法依賴於數字是無符號的。所以:如果參數是 PyLong,則使用其絕對值。" 接下來是
n = PyNumber_Absolute(arg);
這明確地對你的種子調用了 abs() 以使其為正,丟棄了符號位。
但這個註釋實際上也是錯誤/誤導的。在底層,Python 調用了 Mersenne Twister MT19937 算法,這在一般情況下有 19937(非零)位狀態。Python 將你的整數(或其他物件)並 "擴展" 這些信息到這些位上。原則上,符號位本可以用來增強狀態位。這個算法並沒有任何關於 "依賴於數字是無符號的" 的內容。做出了不包含符號位的決定(在我看來這是一個錯誤)。一個微不足道的例子可以是將 n -> 2*abs(n) + int(n < 0) 進行映射。
最後,這使我們來到了 Python 的 random 的合約,這在文檔中也沒有完全說明。提到的合約是:
相同的種子 => 相同的序列。
但沒有保證不同的種子會產生不同的序列。因此,原則上,Python 並不保證例如 seed(5) 和 seed(6) 是不同的 rng 流。(雖然這在許多應用中通常被隱含地假設。)事實上,我們看到 seed(5) 和 seed(-5) 是相同的流。你可能不應該使用它們來區分你的機器學習中的訓練/測試行為。這是我最近遇到的更有趣的程式設計恐怖故事之一。我們下集再見。
[1]
[2]

熱門
排行
收藏
