2021/11/11

標準ライブラリrandomの乱数生成 in PyTorchのDataLoader

上記で述べられているように、PyTorch の DataLoader では、

def __getitem__(self, index):
    return np.random.uniform(-1, 1)

のように DataLoader 内で乱数を生成する場合は、同じ seed で生成されてしまうことを避けるために、DataLoader に以下のような引数を設定してあげる必要があります。

worker_init_fn=lambda x: np.random.seed()

これは、生成された worker はもとの seed を引き継いでしまうためです。 では、Python の標準ライブラリのrandomを使う場合はどうなのでしょうか?

結論から述べると、Python 3.7 以上では特に設定しなくても同じ乱数が生成されてしまうということは基本ありません。

Python3.7 の random.pyを見ると、

if hasattr(_os, "fork"):
    _os.register_at_fork(after_in_child=_inst.seed)

という処理が入っており、fork すると自動で seed 値が変更されるため、numpy で起きていたようなことは基本起きません。Python3.6 の random.pyにはこのような処理がないため、Python3.6 では同様の現象が起きます。

以前からnumpy の issueに同様の内容が建てられており、計算機を扱う上では擬似乱数を使っているということはいつも意識しておかないといけないのかもしれません。