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

热门
排行
收藏
