Подтвердить что ты не робот

Как я могу получить текущее семя генератора случайных чисел NumPy?

Следующий импортирует NumPy и устанавливает семя.

import numpy as np
np.random.seed(42)

Однако, я не заинтересован в настройке семени, но больше в его чтении. random.get_state(), похоже, не содержит семени. документация не показывает очевидного ответа.

Как получить текущее семя, используемое numpy.random, если я не установил его вручную?

Я хочу использовать текущее семя для переноса для следующей итерации процесса.

4b9b3361

Ответ 1

Короткий ответ заключается в том, что вы просто не можете (по крайней мере, не вообще).

Mersenne Twister RNG, используемый numpy, имеет 2 19937 -1 возможных внутренних состояний, тогда как один 64-битный целое число имеет только 2 64 возможные значения. Поэтому невозможно сопоставить каждое состояние RNG с уникальным целым семенем.

Вы можете получить и установить внутреннее состояние RNG напрямую, используя np.random.get_state и np.random.set_state. Вывод get_state представляет собой набор, второй элемент которого представляет собой массив (624,) из 32-битных целых чисел. Этот массив имеет более чем достаточно бит для представления каждого возможного внутреннего состояния RNG (2 624 * 32 > 2 19937 -1).

Кортеж, возвращаемый get_state, может использоваться как семя, чтобы создать воспроизводимые последовательности случайных чисел. Например:

import numpy as np

# randomly initialize the RNG from some platform-dependent source of entropy
np.random.seed(None)

# get the initial state of the RNG
st0 = np.random.get_state()

# draw some random numbers
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26  3  1 68 21]

# set the state back to what it was originally
np.random.set_state(st0)

# draw again
print(np.random.randint(0, 100, 10))
# [ 8 76 76 33 77 26  3  1 68 21]

Ответ 2

Этот ответ был отредактирован после того, как я узнал некоторые подробности о рассматриваемой проблеме. Сейчас я надеюсь, что это послужит разъяснением к ответу от ali_m и важным исправлением к ответу Донга Джастина.

Вот мои выводы:

  1. После установки случайного начального числа с помощью np.random.seed(X) вы можете найти его снова с помощью np.random.get_state()[1][0].
  2. Это, однако, будет бесполезно для вас.

Вывод следующих разделов кода покажет вам, почему оба утверждения верны.


Утверждение 1 - вы можете найти случайное начальное число, используя np.random.get_state()[1][0].

Если вы установите случайное начальное число с помощью np.random.seed(123), вы можете получить случайное состояние в виде кортежа с помощью state = np.random.get_state(). Ниже приведен более подробный обзор state (я использую Проводник переменных в Spyder). Я использую скриншот, так как использование print(state) приведет к заполнению консоли из-за размера массива во втором элементе кортежа.

enter image description here

Вы можете легко увидеть 123 как первое число в массиве, содержащемся во втором элементе. А использование seed = np.random.get_state()[1][0] даст вам 123. Отлично? Не совсем, потому что:

Утверждение 2 - Однако оно будет бесполезно для вас:

np.random.seed(123) может показаться, что это не так, поскольку вы можете использовать np.random.seed(123), получить то же число с помощью seed = np.random.get_state()[1][0], сбросить начальное значение с помощью np.random.seed(444), а затем (по-видимому) установите его обратно в сценарий 123 с помощью np.random.seed(seed). Но тогда вы уже знаете, что ваше случайное семя было раньше, так что вам не нужно будет делать это таким образом. В следующем разделе кода также будет показано, что вы не можете взять первое число любого случайного состояния с помощью np.random.get_state()[1][0] и ожидать воссоздания этого точного сценария. Обратите внимание, что вам, скорее всего, придется полностью завершить работу ядра (или вызвать np.random.seed(None)), чтобы увидеть это.

Следующий фрагмент np.random.randint() использует np.random.randint() для генерации 5 случайных целых чисел между -10 и 10, а также для хранения некоторой информации о процессе:

Фрагмент 1

# 1. Imports
import pandas as pd
import numpy as np

# 2. set random seed
#seedSet = None
seedSet = 123
np.random.seed(seedSet)

# 3. describe random state
state = np.random.get_state()
state5 = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]

# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)

# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)

Обратите внимание, что столбец с именем seedState совпадает с первым номером в state. Я мог бы напечатать это как отдельный номер, но я хотел сохранить все это в том же месте. Также обратите внимание, что seedSet = 123 и np.random.seed(seedSet) до сих пор были закомментированы. А поскольку случайное начальное число не задано, ваши номера будут отличаться от моих. Но это не то, что здесь важно, а скорее внутренняя согласованность ваших результатов:

Выход 1:

   random seedSet   seedState       state
0       2    None  1558056443  1558056443
1      -1    None  1558056443  1808451632
2       4    None  1558056443   730968006
3      -4    None  1558056443  3568749506
4      -6    None  1558056443  3809593045

В данном конкретном случае seed = np.random.get_state()[1][0] равно 1558056443. И следуя логике ответа Донга Джастина (а также моего собственного ответа до этого редактирования), вы можете установить случайное начальное значение с помощью np.random.seed(1558056443) и получить то же случайное состояние. Следующий фрагмент покажет, что вы не можете:

Фрагмент 2

# 1. Imports
import pandas as pd
import numpy as np

# 2. set random seed
#seedSet = None
seedSet = 1558056443
np.random.seed(seedSet)

# 3. describe random state
#state = np.random.get_state()
state = np.random.get_state()[1][:5]
seedState = np.random.get_state()[1][0]

# 4. generate random numbers
random = np.random.randint(-10, 10, size = 5)

# 5. organize and present findings
df = pd.DataFrame.from_dict({'seedSet':seedSet, 'seedState':seedState, 'state':state, 'random':random})
print(df)

Выход 2:

   random     seedSet   seedState       state
0       8  1558056443  1558056443  1558056443
1       3  1558056443  1558056443  1391218083
2       7  1558056443  1558056443  2754892524
3      -8  1558056443  1558056443  1971852777
4       4  1558056443  1558056443  2881604748

Увидеть разницу? np.random.get_state()[1][0] идентичен для выхода 1 и выхода 2, но остальные выходные данные не являются (самое главное, случайные числа не совпадают). Итак, как уже сказал ali_m:

Поэтому невозможно сопоставить каждое состояние ГСЧ с уникальным целочисленным начальным числом.

Ответ 3

Проверьте первый элемент массива, возвращенный np.random.get_state(), он кажется мне случайным семенем.