トレンドトピック
#
Bonk Eco continues to show strength amid $USELESS rally
#
Pump.fun to raise $1B token sale, traders speculating on airdrop
#
Boop.Fun leading the way with a new launchpad on Solana.
本日のホラー番組のエピソードでは...
random.seed() defのPythonドキュメントでは、
「aがintなら、直接使われる。」[1]
しかし、3や-3でシードすると、実際にはまったく同じRNGオブジェクトが出て、同じストリームが生成されます。(今日学びました)nanochatでは、トレインやテストのスプリットで異なるRNGシーケンスを得る(自分が思った)巧妙な方法としてサインを使っていました。だからこそ、train=testという厄介なバグが起きています。
cpython/Modules/_randommodule.c [2]でCPythonのコードを見つけました。321行目のコメントに以下が見られます:
「このアルゴリズムは番号が符号なしであることに依存しています。つまり:もしargがPyLongであれば、その絶対値を使う。」と続き、
n = PyNumber_Absolute(arg);
これは明示的にシードのabs()を呼び出して正にし、符号ビットを破棄します。
しかし、このコメントも実は間違っているか誤解を招くものです。その裏で、PythonはMersenne Twister MT19937アルゴリズムと呼び、一般的には19937ビット(ゼロでない)状態を持ちます。Pythonはあなたのint(または他のオブジェクト)を受け取り、その情報をこれらのビットに「分散」します。原則として、符号ビットは状態ビットを補強するために使われることもあり得ます。アルゴリズムには「番号が符号なしであることに依存している」という点はありません。サインビットを組み込まないという決定がなされました(個人的にはそれが間違いだったと思います)。一つの自明な例としては、n -> 2*abs(n) + int(n < 0)を写すことがあります。
最後に、これがPythonのランダム契約につながりますが、これもドキュメントで完全には明記されていません。言及されている契約は以下の通りです:
同じシード=>同じ配列。
しかし、異なる種子が異なる配列を生み出す保証はありません。したがって、原則としてPythonは、例えばseed(5)とseed(6)が異なるRNGストリームであると約束することはありません。(ただし、これは多くの応用で暗黙のうちに前提とされていることが多いです。)実際、seed(5)とseed(-5)は同一のストリームであることがわかります。また、機械学習でトレーニングやテストの行動を分けるために使うべきではないでしょう。最近出会った中でも特に面白いプログラミングホラーのフットガンの一つです。次回のエピソードでお会いしましょう。
[1]
[2]

トップ
ランキング
お気に入り
