在今天的程式設計恐怖故事中... 在 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]