Если семя не указано явно, numpy.random
будет семенами, используя источник случайности, зависящий от ОС. Обычно он будет использовать /dev/urandom
в системах на базе Unix (или в некоторых эквивалентах Windows), но если это по какой-то причине недоступно, оно будет засеиваться с настенных часов. Так как самосеяние происходит в то время, когда новая подпроцессная вилка позволяет нескольким субпроцессам наследовать одно и то же семя, если они разветвляются в одно и то же время, что приводит к одинаковым случайным вариациям, создаваемым разными подпроцессами.
Часто это соотносится с количеством одновременных потоков, которые вы используете. Например:
import numpy as np
import random
from multiprocessing import Pool
def Foo_np(seed=None):
# np.random.seed(seed)
return np.random.uniform(0, 1, 5)
pool = Pool(processes=8)
print np.array(pool.map(Foo_np, xrange(20)))
# [[ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.64672339 0.99851749 0.8873984 0.42734339 0.67158796]
# [ 0.64672339 0.99851749 0.8873984 0.42734339 0.67158796]
# [ 0.64672339 0.99851749 0.8873984 0.42734339 0.67158796]
# [ 0.64672339 0.99851749 0.8873984 0.42734339 0.67158796]
# [ 0.64672339 0.99851749 0.8873984 0.42734339 0.67158796]
# [ 0.11283279 0.28180632 0.28365286 0.51190168 0.62864241]
# [ 0.11283279 0.28180632 0.28365286 0.51190168 0.62864241]
# [ 0.28917586 0.40997875 0.06308188 0.71512199 0.47386047]
# [ 0.11283279 0.28180632 0.28365286 0.51190168 0.62864241]
# [ 0.64672339 0.99851749 0.8873984 0.42734339 0.67158796]
# [ 0.11283279 0.28180632 0.28365286 0.51190168 0.62864241]
# [ 0.14463001 0.80273208 0.5559258 0.55629762 0.78814652] <-
# [ 0.11283279 0.28180632 0.28365286 0.51190168 0.62864241]]
Вы можете видеть, что группы до 8 потоков одновременно раздвоенные с тем же семени, давая мне одинаковые случайные последовательности (я пометил первую группу со стрелками).
Вызов np.random.seed()
в подпроцессе заставляет локальный экземпляр RNG нить локализовать снова с /dev/urandom
или настенные часы, которые (вероятно) не позволят вам видеть идентичный вывод из нескольких подпроцессов. Лучшая практика явно передать другое семя (или numpy.random.RandomState
экземпляра) для каждого подпроцесса, например:
def Foo_np(seed=None):
local_state = np.random.RandomState(seed)
print local_state.uniform(0, 1, 5)
pool.map(Foo_np, range(20))
Я не совсем уверен, что лежит в основе различия между random
и numpy.random
в этом отношении (возможно, он имеет немного отличается правила выбора источника случайности для самостоятельного семени по сравнению с numpy.random
?). Я бы по-прежнему рекомендовал явно передавать семя или экземпляр random.Random
для каждого подпроцесса, чтобы быть в безопасности. Вы также можете использовать метод .jumpahead()
random.Random
, который предназначен для перетасовки состояний экземпляров Random
в многопоточных программах.
Пожалуйста, объясните, что заставляет вас думать, что вы * должны * – shx2
Потому что, если я надену t, то каждый из разветвленных процессов будет генерировать идентичную последовательность случайных чисел (только в Ex.2) – overcomer
, какая у вас ОС? – shx2