在今天的编程恐怖故事中…… 在 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)