在今天的编程恐怖故事中…… 在 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 调用的是梅森旋转算法 MT19937,该算法在一般情况下有 19937(非零)位状态。Python 将你的整数(或其他对象)信息 "分散" 到这些位中。原则上,符号位本可以用来增强状态位。这个算法并没有什么 "依赖于数字是无符号的"。做出了不包含符号位的决定(在我看来这是一个错误)。一个简单的例子可以是将 n 映射为 2*abs(n) + int(n < 0)。 最后,这引出了 Python 的 random 合同,这在文档中也没有完全说明。提到的合同是: 相同的种子 => 相同的序列。 但没有保证不同的种子会产生不同的序列。因此原则上,Python 并没有承诺例如 seed(5) 和 seed(6) 是不同的 rng 流。(尽管在许多应用中通常隐含地假设这一点。)实际上,我们看到 seed(5) 和 seed(-5) 是相同的流。你可能不应该使用它们来区分机器学习中的训练/测试行为。这是我最近遇到的更有趣的编程恐怖故事之一。下次再见。 [1] [2]