[PYTHON] Korrigieren Sie zufällige Samen mit TensorFlow

Grob gesagt

Hintergrund

Bei der Implementierung von Code für maschinelles Lernen in TensorFlow verwenden wir häufig Pseudozufallszahlen (im Folgenden einfach "Zufallszahlen") für die Gewichtsinitialisierung und so weiter. Daher ändert sich das Ergebnis jedes Mal, wenn der Code erneut ausgeführt wird, und es ist nicht möglich, zwischen der Änderung des Ergebnisses aufgrund von Änderungen der Daten und Parameter und der Änderung des Ergebnisses aufgrund von Zufallszahlen zu unterscheiden. Zufallszahlen werden basierend auf einem Wert generiert, der als "Startwert" bezeichnet wird. Sofern nicht anders angegeben, wird ein etwas variabler Standardwert verwendet (häufig eine Zeit- oder Prozess-ID). TensorFlow bietet auch eine Möglichkeit, den zufälligen Startwert zu korrigieren, aber ich war ein wenig besorgt über sein Verhalten, also habe ich versucht, ihn zu organisieren.

Zusätzlich zu TensorFlow werden wir auch das Fixieren von zufälligen Seeds im Zufallsmodul und im NumPy-Paket diskutieren.

Ausführung

Der Inhalt dieses Artikels basiert auf den folgenden Versionen:

zufälliges Modul

Im Python-Standardmodul "random" können Sie den zufälligen Startwert mit der Funktion "random.seed" festlegen. Der experimentelle Code lautet wie folgt.

seed_random.py


import random
random.seed(0)
print("1:", random.random())
print("2:", random.random())
print("3:", random.random())
random.seed(0)
print("4:", random.random())
print("5:", random.random())
print("6:", random.random())

Das Ergebnis bei dreimaliger Ausführung ist wie folgt. Der gleiche Wert wird jedes Mal ausgegeben, wenn ein Zufallszahlen-Seed gesetzt oder ausgeführt wird.

$ python3 seed_random.py
1: 0.8444218515250481
2: 0.7579544029403025
3: 0.420571580830845
4: 0.8444218515250481
5: 0.7579544029403025
6: 0.420571580830845
$ python3 seed_random.py
1: 0.8444218515250481
2: 0.7579544029403025
3: 0.420571580830845
4: 0.8444218515250481
5: 0.7579544029403025
6: 0.420571580830845
$ python3 seed_random.py
1: 0.8444218515250481
2: 0.7579544029403025
3: 0.420571580830845
4: 0.8444218515250481
5: 0.7579544029403025
6: 0.420571580830845

NumPy-Paket

Im NumPy-Paket können Sie den zufälligen Startwert mit der Funktion numpy.random.seed festlegen. Der experimentelle Code lautet wie folgt.

seed_numpy.py


import numpy as np
np.random.seed(0)
print("1:", np.random.rand(3))
print("2:", np.random.rand(3))
print("3:", np.random.rand(3))
np.random.seed(0)
print("4:", np.random.rand(3))
print("5:", np.random.rand(3))
print("6:", np.random.rand(3))

Das Ergebnis bei dreimaliger Ausführung ist wie folgt. Der gleiche Wert wird jedes Mal ausgegeben, wenn ein Zufallszahlen-Seed gesetzt oder ausgeführt wird.

$ python3 seed_numpy.py
1: [ 0.5488135   0.71518937  0.60276338]
2: [ 0.54488318  0.4236548   0.64589411]
3: [ 0.43758721  0.891773    0.96366276]
4: [ 0.5488135   0.71518937  0.60276338]
5: [ 0.54488318  0.4236548   0.64589411]
6: [ 0.43758721  0.891773    0.96366276]
$ python3 seed_numpy.py
1: [ 0.5488135   0.71518937  0.60276338]
2: [ 0.54488318  0.4236548   0.64589411]
3: [ 0.43758721  0.891773    0.96366276]
4: [ 0.5488135   0.71518937  0.60276338]
5: [ 0.54488318  0.4236548   0.64589411]
6: [ 0.43758721  0.891773    0.96366276]
$ python3 seed_numpy.py
1: [ 0.5488135   0.71518937  0.60276338]
2: [ 0.54488318  0.4236548   0.64589411]
3: [ 0.43758721  0.891773    0.96366276]
4: [ 0.5488135   0.71518937  0.60276338]
5: [ 0.54488318  0.4236548   0.64589411]
6: [ 0.43758721  0.891773    0.96366276]

TensorFlow-Paket

Im TensorFlow-Paket können Sie den zufälligen Startwert mit der Funktion tensorflow.set_random_seed oder dem Argument seed des Zufallsoperators festlegen. In TensorFlow gibt es zwei Arten von zufälligen Startwerten: "Graph Level" und "Operation Level". Sie müssen auch vorsichtig mit der Reihenfolge der Einstellungen sein und die zufälligen Startwerte "nach dem Erstellen des Diagramms" und "vor dem Generieren des Operators" festlegen.

Referenz: Konstanten, Sequenzen und Zufallswerte --tf.set_random_seed (seed)

Ein Beispiel, das wie erwartet funktioniert

Der experimentelle Code lautet wie folgt.

seed_tensorflow1.py


import tensorflow as tf
with tf.Graph().as_default():
    tf.set_random_seed(0)
    rand_op1 = tf.random_normal([3])
    rand_op2 = tf.random_normal([3], seed=1)
    print("session1")
    with tf.Session() as sess1:
        print("op1-1:", sess1.run(rand_op1))
        print("op1-2:", sess1.run(rand_op1))
        print("op2-1:", sess1.run(rand_op2))
        print("op2-2:", sess1.run(rand_op2))
    print("session2")
    with tf.Session() as sess2:
        print("op1-1:", sess2.run(rand_op1))
        print("op1-2:", sess2.run(rand_op1))
        print("op2-1:", sess2.run(rand_op2))
        print("op2-2:", sess2.run(rand_op2))

Das Ergebnis bei dreimaliger Ausführung ist wie folgt.

$ python3 seed_tensorflow1.py
session1
op1-1: [-1.40955448 -0.53668278 -0.56523788]
op1-2: [-1.07107699  0.4139019   2.29180121]
op2-1: [ 0.68034536  0.8777824  -0.64773595]
op2-2: [-1.21607268  0.95542693 -0.16866584]
session2
op1-1: [-1.40955448 -0.53668278 -0.56523788]
op1-2: [-1.07107699  0.4139019   2.29180121]
op2-1: [ 0.68034536  0.8777824  -0.64773595]
op2-2: [-1.21607268  0.95542693 -0.16866584]
$ python3 seed_tensorflow1.py
session1
op1-1: [-1.40955448 -0.53668278 -0.56523788]
op1-2: [-1.07107699  0.4139019   2.29180121]
op2-1: [ 0.68034536  0.8777824  -0.64773595]
op2-2: [-1.21607268  0.95542693 -0.16866584]
session2
op1-1: [-1.40955448 -0.53668278 -0.56523788]
op1-2: [-1.07107699  0.4139019   2.29180121]
op2-1: [ 0.68034536  0.8777824  -0.64773595]
op2-2: [-1.21607268  0.95542693 -0.16866584]
$ python3 seed_tensorflow1.py
session1
op1-1: [-1.40955448 -0.53668278 -0.56523788]
op1-2: [-1.07107699  0.4139019   2.29180121]
op2-1: [ 0.68034536  0.8777824  -0.64773595]
op2-2: [-1.21607268  0.95542693 -0.16866584]
session2
op1-1: [-1.40955448 -0.53668278 -0.56523788]
op1-2: [-1.07107699  0.4139019   2.29180121]
op2-1: [ 0.68034536  0.8777824  -0.64773595]
op2-2: [-1.21607268  0.95542693 -0.16866584]

Funktioniert nicht wie erwartet Beispiel 1: Legen Sie vor dem Erstellen eines Diagramms einen zufälligen Startwert fest

Hier ist ein Beispiel für das Festlegen eines zufälligen Startwerts vor dem Erstellen eines Diagramms. Der experimentelle Code lautet wie folgt.

seed_tensorflow2.py


import tensorflow as tf
tf.set_random_seed(0) #Legen Sie einen zufälligen Startwert fest, bevor Sie ein Diagramm erstellen
with tf.Graph().as_default():
    rand_op1 = tf.random_normal([3])
    rand_op2 = tf.random_normal([3], seed=1)
    with tf.Session() as sess1:
        print("op1-1:", sess1.run(rand_op1))
        print("op1-2:", sess1.run(rand_op1))
        print("op2-1:", sess1.run(rand_op2))
        print("op2-2:", sess1.run(rand_op2))

Das Ergebnis bei dreimaliger Ausführung ist wie folgt. Rand_op2, das den Zufallszahlen-Seed auf Operationsebene setzt, gibt dreimal denselben Wert aus, aber rand_op1 gibt dreimal einen anderen Wert aus.

$ python3 seed_tensorflow2.py
op1-1: [ 0.22292495  0.67142487  0.80927771]
op1-2: [-1.11188841  0.57819426  0.19088539]
op2-1: [-0.81131822  1.48459876  0.06532937]
op2-2: [ 0.55171245 -0.13107552 -0.04481386]
$ python3 seed_tensorflow2.py
op1-1: [-0.96930581  1.48854125  0.52752507]
op1-2: [ 0.91646689  0.85830265 -0.18069462]
op2-1: [-0.81131822  1.48459876  0.06532937]
op2-2: [ 0.55171245 -0.13107552 -0.04481386]
$ python3 seed_tensorflow2.py
op1-1: [ 0.79890805  1.35702407 -0.12329593]
op1-2: [ 1.69212222  0.22590902 -0.73435217]
op2-1: [-0.81131822  1.48459876  0.06532937]
op2-2: [ 0.55171245 -0.13107552 -0.04481386]

Funktioniert nicht wie erwartet Beispiel 2: Legen Sie einen zufälligen Startwert fest, nachdem Sie einen zufälligen Operator generiert haben

Hier ist ein Beispiel für das Setzen eines Zufallszahlen-Startwerts nach dem Generieren eines Zufallszahlenoperators. Der experimentelle Code lautet wie folgt.

seed_tensorflow3.py


import tensorflow as tf
with tf.Graph().as_default():
    rand_op1 = tf.random_normal([3])
    rand_op2 = tf.random_normal([3], seed=1)
    tf.set_random_seed(0) #Legen Sie den Zufallszahlen-Startwert fest, nachdem Sie einen Zufallszahlenoperator generiert haben
    with tf.Session() as sess:
        print("op1-1:", sess.run(rand_op1))
        print("op1-2:", sess.run(rand_op1))
        print("op2-1:", sess.run(rand_op2))
        print("op2-2:", sess.run(rand_op2))

Das Ergebnis bei dreimaliger Ausführung ist wie folgt. Ähnlich wie im obigen Beispiel gibt "rand_op2", das den Zufallszahlen-Startwert auf Operationsebene festlegt, dreimal denselben Wert aus, "rand_op1" gibt jedoch dreimal einen anderen Wert aus.

$ python3 seed_tensorflow3.py
op1-1: [ 0.03802272  1.69988739 -0.59952497]
op1-2: [ 0.62614048  0.07537607 -1.19501412]
op2-1: [-0.81131822  1.48459876  0.06532937]
op2-2: [ 0.55171245 -0.13107552 -0.04481386]
$ python3 seed_tensorflow3.py
op1-1: [ 1.02020776  1.70896292  0.45571503]
op1-2: [-0.46230376 -1.22950804  0.51038951]
op2-1: [-0.81131822  1.48459876  0.06532937]
op2-2: [ 0.55171245 -0.13107552 -0.04481386]
$ python3 seed_tensorflow3.py
op1-1: [ 1.31134415 -1.12688231  0.1805287 ]
op1-2: [-0.57391566  0.94440365 -1.07441545]
op2-1: [-0.81131822  1.48459876  0.06532937]
op2-2: [ 0.55171245 -0.13107552 -0.04481386]

Andere

Es handelt sich um unbestätigte Informationen, aber es scheint, dass dies nicht der gleiche Wert ist, selbst wenn Sie beim Ausführen auf einer GPU einen zufälligen Startwert festlegen.

Referenz: Erwähnen Sie, dass GPU-Reduzierungen in Dokumenten nicht deterministisch sind · Problem Nr. 2732 · Tensorflow / Tensorflow

Vielen Dank

Wir haben sehr nützliche Informationen von Herrn Hirai erhalten, einer anderen Studiengruppe zu TensorFlow. Danke hier.

Recommended Posts

Korrigieren Sie zufällige Samen mit TensorFlow
Zufälliger Samen in TensorFlow und Numpy fixiert Etwas anders
Zufälliger Spaziergang in Python
[TensorFlow 2.x (tf.keras)] Zufälliger Startwert zur Verbesserung der Reproduzierbarkeit behoben
Balanced Random Forest in Python
Clipping und Normalisierung in TensorFlow
Verwenden Sie Random Forest mit Python
Gewichtete zufällige Auswahl in Python
Stellen Sie die Reproduzierbarkeit mit tf.keras in Tensorflow 2.3 sicher
Testen mit Zufallszahlen in Python
Versuchen Sie, die in TensorFlow 0.12 hinzugefügte Visualisierung einzubetten
Problem, bei dem Apscheduler zweimal in Flask ausgeführt wurde - gefixt
Zusammenfassung verschiedener Operationen in Tensorflow
Installieren Sie Tensorflow in einer anaconda + python3.5-Umgebung
So führen Sie TensorFlow 1.0-Code in 2.0 aus
Random Seed Research im maschinellen Lernen
Erstellen Sie eine zufällige Zeichenfolge in Python