在今天的程式設計恐怖故事中… 在 Python 文件中關於 random.seed() 函數的定義中,我們得知… 「如果 a 是整數,則直接使用。」[1] 但如果你用 3 或 -3 作為種子,實際上會得到完全相同的隨機數產生器對象,產生相同的資料流。 (我今天才知道)。在 NanoChat 中,我曾以為自己很巧妙地利用這個符號來為訓練集/測試集分割產生不同的隨機數序列。結果卻出現了棘手的 bug,因為現在訓練集和測試集的隨機數序列都相同了。 我在 cpython/Modules/_randommodule.c [2] 中找到了相關的 CPython 程式碼,在第 321 行的註解中可以看到: “此演算法依賴無符號數。因此:如果參數是 PyLong 類型,則使用其絕對值。” n = PyNumber_Absolute(arg); 它會明確地對你的種子呼叫 abs() 函數,使其變成正數,並丟棄符號位。 但這則評論實際上也是錯誤的/誤導性的。 Python 底層呼叫的是梅森旋轉演算法 MT19937,該演算法通常有 19937 位元(非零)狀態。 Python 會將你的整數(或其他物件)的資訊「分散」到這些位元上。原則上,符號位元可以用來擴展狀態位元。該演算法本身並沒有「依賴無符號數」。最終決定不使用符號位(我認為這是個錯誤)。一個簡單的例子是將 n 對應到 2*abs(n) + int(n 相同的序列。 但並不能保證不同的種子會產生不同的序列。因此,原則上,Python 並不保證例如 seed(5) 和 seed(6) 是不同的隨機數產生器流。 (儘管在許多應用程式中,這通常被隱式地假設為不同的隨機數產生器流。)事實上,我們看到 seed(5) 和 seed(-5) 是相同的流。而且,你最好不要用它們來區分機器學習中的訓練/測試行為。這是我最近遇到的最有趣的程式設計陷阱之一。我們下期再見。 [1] https://t.co/srv1ZBlDsi [2]
感謝 GitHub 用戶 ericsilberstein1 發現這個 bug。 https://t.co/1github.com/karpathy/nanoc…而且只在拼字比賽的綜合任務評估中出現,但還是值得注意。)
![在今天的程式設計恐怖故事中…
在 Python 文件中關於 random.seed() 函數的定義中,我們得知…
「如果 a 是整數,則直接使用。」[1]
但如果你用 3 或 -3 作為種子,實際上會得到完全相同的隨機數產生器對象,產](https://pbs.twimg.com/media/G7sc167aMAAuZi5.png)