如何取消发送之前在numpy中播种的随机序列



我正在尝试在多程序函数中生成随机数。我的问题是,我需要播种随机生成的第一部分,而不是第二部分。我希望第一部分的种子在所有过程中都是一样的。

我尝试的是通过选择一个随机Int(np.random.seed(np.random.randint(100000000))(来取消对生成器的设置,但因为我首先对生成器进行了种子设置,所以我为生成的其余部分选择了相同的Int。

我不能使用np.random.seed(None)np.random.seed(random.seed(time.time())),因为我的类使用@jitclass,这使得它们不合适。

所以我对每个过程都有相同的顺序。

0 [0.5488135  0.71518937 0.60276338 0.54488318 0.4236548 ]
0 [0.91989807 0.99511873 0.6750629  0.60976887 0.65852849]
1 [0.5488135  0.71518937 0.60276338 0.54488318 0.4236548 ]
1 [0.91989807 0.99511873 0.6750629  0.60976887 0.65852849]
2 [0.5488135  0.71518937 0.60276338 0.54488318 0.4236548 ]
2 [0.91989807 0.99511873 0.6750629  0.60976887 0.65852849]

这里是MWE

import numpy as np
import multiprocessing
import random

class mp_worker_class():
def __init__(self,):
pass
@classmethod
def start(self, nb=None, seed=None, nbcore=None):
lfp_p=np.empty((nbcore,nb))
pipe_list = []
for h in range(nbcore):
recv_end, send_end = multiprocessing.Pipe( )
p = multiprocessing.Process(target=self.mp_worker , args=(h, nb, seed, send_end ))
p.start()
pipe_list.append(recv_end)
for idx, recv_end in enumerate(pipe_list):
lfp_p[idx,:]=recv_end.recv()

return lfp_p
@classmethod
def mp_worker(self,h, nb=None, seed=None, send_end=None):
np.random.seed(seed)
np.random.seed(0)
print(h,np.random.rand(5))
#trying to undo the seed
np.random.seed(np.random.randint(100000000))
print(h, np.random.rand(5))
send_end.send(np.random.rand(5))
return
if __name__ == '__main__':
print(mp_worker_class().start(nb=10, seed=1, nbcore=3 ))

您只需给每个进程一个不同的第二种子:

...
@classmethod
def start(self, nb=None, seed=None, seeds=None, nbcore=None):
if seeds if not None:
seeds = iter(seeds)          # get an iterator
lfp_p=np.empty((nbcore,nb))
pipe_list = []
for h in range(nbcore):
recv_end, send_end = multiprocessing.Pipe( )
seed2 = None if seeds = None else next(seeds)
p = multiprocessing.Process(target=self.mp_worker ,
args=(h, nb, seed, seed2, send_end ))
p.start()
pipe_list.append(recv_end)
for idx, recv_end in enumerate(pipe_list):
lfp_p[idx,:]=recv_end.recv()

return lfp_p
@classmethod
def mp_worker(self,h, nb=None, seed=None, seed2=None, send_end=None):
np.random.seed(seed)
print(h,np.random.rand(5))
np.random.seed(seed2)
print(h, np.random.rand(5))
send_end.send(np.random.rand(5))
return
if __name__ == '__main__':
print(mp_worker_class().start(nb=10, seed=1, seeds=[2, 3, 4], nbcore=3 ))

通过这种方式,您为seedsstart提供任何可迭代项,每个工作者都将获得自己的种子。

您可以保存随机数生成器的状态,并在稍后恢复:

original_state = np.random.get_state()
np.random.seed(seed)
# ... stuff using your seeded random
np.random.set_state(original_state)

最新更新