In TensorFlow gibt es eine Möglichkeit, die Reproduzierbarkeit durch Fixieren des Seeds wie im folgenden Artikel gezeigt aufrechtzuerhalten. In der GPU-Umgebung von TensorFlow 2.3 führte das Fixieren des Seeds allein jedoch nicht jedes Mal zum gleichen Ergebnis. (In Tensorflow 2.1 oder 2.0 denke ich, dass das gleiche Ergebnis nur durch Fixieren des Samens erzielt wurde ...)
Ich habe mehrmals versucht, die Kreuzungsüberprüfung durchzuführen, und habe das gleiche Ergebnis erzielt (ich konnte die Reproduzierbarkeit bestätigen). Daher werde ich es als Memorandum zusammenfassen. Der zur Überprüfung verwendete Quellcode wird auf Github veröffentlicht. Bitte weisen Sie auf Fehler oder Korrekturen hin.
Zunächst werde ich die Schlussfolgerung schreiben, aber wie im folgenden Artikel beschrieben, sollten Sie anscheinend die Einstellung von tf.config.threading und die Umgebungsvariablen TF_DETERMINISTIC_OPS und TF_CUDNN_DETERMINISTIC ändern.
In TensorFlow 2.3 scheint die Reproduzierbarkeit erhalten zu sein, indem eine Funktion erstellt wird, die Zufallszahlen wie unten gezeigt initialisiert und zu Beginn des Programms aufruft.
def setSeed(seed):
os.environ['PYTHONHASHSEED'] = '0'
tf.random.set_seed(seed)
np.random.seed(seed)
random.seed(seed)
os.environ['TF_DETERMINISTIC_OPS'] = '1'
os.environ['TF_CUDNN_DETERMINISTIC'] = '1'
tf.config.threading.set_inter_op_parallelism_threads(1)
tf.config.threading.set_intra_op_parallelism_threads(1)
Laut der offiziellen Dokumentation wird die Leistung auf Kosten der Parallelverarbeitung beeinträchtigt. Ich dachte, es wäre in Ordnung, nur die Schlussfolgerung zu schreiben, aber ich fragte mich, ob es wahr ist, also führte ich eine Kreuzvalidierung durch und bestätigte tatsächlich, ob die Reproduzierbarkeit erhalten blieb.
Ich werde nur die Hauptpunkte des in Github platzierten Codes zusammenfassen.
--__ main.py__: Führen Sie eine Kreuzvalidierung (n = 10) für das Trainingsbild von MNIST durch, um den Verlust und die Genauigkeit des Lernens 10 Mal zu erhalten.
Die Netzwerkkonfiguration ist wie folgt. Die MNIST-Bildgröße 28 wird in Breite und Höhe eingegeben.
```python
def loadModel(width, height):
layer_input = Input(shape=(width, height))
layers_hidden = Reshape(target_shape=(width, height, 1))(layer_input)
layers_hidden = Conv2D(filters=8, kernel_size=(3, 3), strides=1, activation="relu")(layers_hidden)
layers_hidden = MaxPooling2D(pool_size=(2,2), strides=(2,2))(layers_hidden)
layers_hidden = Conv2D(filters=8, kernel_size=(3, 3), strides=1, activation="relu")(layers_hidden)
layers_hidden = MaxPooling2D(pool_size=(2,2), strides=(2,2))(layers_hidden)
layers_hidden = Flatten()(layers_hidden)
layers_hidden = Dense(128, activation="relu")(layers_hidden)
layers_hidden = Dropout(0.2)(layers_hidden)
layer_output = Dense(10, activation="softmax")(layers_hidden)
return Model(inputs=layer_input, outputs=layer_output)
```
Als ich mit einem kurzen Netzwerk mit nur einer vollständig verbundenen Schicht (128 Dimensionen) als verborgener Schicht experimentierte, gab es keinen großen Unterschied in der Verarbeitungszeit, also fügte ich eine Faltungsschicht hinzu.
KFold von Scikit-learn wird zur gegenseitigen Überprüfung verwendet ――Ich wollte nur sehen, ob es reproduzierbar ist, deshalb habe ich nur Trainingsbilder für Training und Bewertung verwendet.
--__ eval.py__: Gibt die durchschnittliche Verteilungs- und Verarbeitungszeit aus der gespeicherten Textdatei aus. ――Da die Kreuzverifizierung zehnmal durchgeführt wird und die Varianz jeder Kreuzverifizierung 0 beträgt, wird beurteilt, dass genau das gleiche Ergebnis = Reproduzierbarkeit bestätigt werden kann. --main.py generiert Textdateien, also laden Sie sie.
Da der Text als erste Speicherzeit gespeichert wird, das Ergebnis der ersten 10 Kreuzungsüberprüfung, die zweite Speicherzeit, die zweite ... (siehe Ergebnisse), die Zeit und das Ergebnis nach dem Lesen jeder Zeile Wird in eine separate Liste aufgenommen, um die Verteilungs- und Verarbeitungszeit anzuzeigen.
def getResults(path_result, n_splits, num_train):
with open(path_result, "r") as f:
lines = f.readlines()
results = []
dates = []
for line in lines:
l = line.splitlines()[0].split()
if len(l) != 1:
results.append(l)
else:
dates.append(datetime.strptime(l[0], "%Y%m%d-%H%M%S"))
results = np.array(results).astype(np.float64)
results = np.reshape(results, newshape=(num_train, n_splits, 3))
var = np.mean(np.var(results[:,:,1:], axis=0))
diff_time_total = np.sum([dates[i + 1] - dates[i] for i in range(0, num_train-1)])
print(f"{path_result}: {var:.4}, {diff_time_total}")
return
getResults(path_result=os.path.join("results", "with_tf_option.txt"), n_splits=10, num_train=10)
(Für die Dispersion wurden sowohl Verlust als auch Genauigkeit gemittelt (np.mean), aber es war besser, sie zu trennen.) --__ Hinweis) Es ist nicht die genaue Zeit der Lernzeit, da es die Gesamtzeit ist, um das Ergebnis in .txt und das nächste Ergebnis in .txt __ zu speichern
--___ run_all.sh (für Ubuntu) oder run_all.ps1 (für Win) ___: Dies ist ein Skript, das main.py 10 Mal wiederholt und schließlich eval.py ausführt.
--__ docker-compose.yml, env / Dockerfile__: Dies ist eine Datei für Docker. (Für Linux)
Dieses Mal habe ich es mit TensorFlow 2.3 + Python 3.7.7 unter Windows 10 ausgeführt. Der Durchschnitt der Varianzen jeder Kreuzungsverifizierung (Varianz) und die Gesamtzeit bis zum Speichern des nächsten Ergebnisses (Time_diff_total) sind wie folgt.
Variance, Time_diff_total
results\with_tf_option.txt: 0.0, 0:17:11 #1037 Sekunden
results\without_tf_option.txt: 6.694e-07, 0:13:45 #825 Sekunden
Mit dieser Option ist die Verteilung 0, sodass Sie davon ausgehen können, dass das Ergebnis der zehnmaligen Ausführung von 10 Kreuzungsüberprüfungen genau das gleiche war. Wenn Sie jedoch versuchen, die Reproduzierbarkeit sicherzustellen, dauert es ungefähr 104 Sekunden, um das nächste Ergebnis zu erreichen, und wenn Sie die Reproduzierbarkeit verwerfen, dauert es ungefähr 82 Sekunden, um den nächsten Vorgang abzuschließen. Da es außer dem Training keinen zeitaufwändigen Prozess gibt, scheint die Leistung zu sinken, wenn die Reproduzierbarkeit gemäß dem offiziellen Dokument gewährleistet ist.
Übrigens waren der Verlust und die Genauigkeit des ersten und zweiten Mal mit und ohne Option wie folgt. (Es ist nicht erforderlich, es zweimal zu veröffentlichen, da die Varianz 0 ist, aber ich werde das Rohergebnis nur für den Fall veröffentlichen.)
#Mit Optionen(Häufigkeit, Verlust, Genauigkeit)
20201002-230020
0 0.041036274284124374 0.987500011920929
1 0.0490814633667469 0.9860000014305115
2 0.05664192885160446 0.9831666946411133
3 0.05320063605904579 0.9833333492279053
4 0.04623125120997429 0.9850000143051147
5 0.047372110188007355 0.984333336353302
6 0.05214701220393181 0.9850000143051147
7 0.03892550244927406 0.9858333468437195
8 0.047721363604068756 0.9851666688919067
9 0.05081837624311447 0.984499990940094
20201002-230216
0 0.041036274284124374 0.987500011920929
1 0.0490814633667469 0.9860000014305115
2 0.05664192885160446 0.9831666946411133
3 0.05320063605904579 0.9833333492279053
4 0.04623125120997429 0.9850000143051147
5 0.047372110188007355 0.984333336353302
6 0.05214701220393181 0.9850000143051147
7 0.03892550244927406 0.9858333468437195
8 0.047721363604068756 0.9851666688919067
9 0.05081837624311447 0.984499990940094
#Keine Optionen
20201002-231902
0 0.039828840643167496 0.9888333082199097
1 0.049601536244153976 0.9866666793823242
2 0.05240510031580925 0.9850000143051147
3 0.05293559655547142 0.9850000143051147
4 0.04633906111121178 0.9850000143051147
5 0.04794950410723686 0.9850000143051147
6 0.053883280605077744 0.9838333129882812
7 0.03880513831973076 0.987333357334137
8 0.04899284988641739 0.9850000143051147
9 0.0499492883682251 0.9851666688919067
20201002-232034
0 0.04064466059207916 0.987666666507721
1 0.04839828982949257 0.9851666688919067
2 0.055755823850631714 0.984499990940094
3 0.05341317877173424 0.9829999804496765
4 0.046509750187397 0.9856666922569275
5 0.04652954265475273 0.9853333234786987
6 0.05223047733306885 0.984666645526886
7 0.039393164217472076 0.9869999885559082
8 0.048276182264089584 0.9854999780654907
9 0.04923468455672264 0.9848333597183228
Aufgrund der Arbeit an der höheren Version von TensoFlow hatte ich Probleme, weil ich die Reproduzierbarkeit nicht bestätigen konnte. Daher bin ich froh, dass ich sie nur durch Hinzufügen der Umgebungsvariablen und Optionseinstellungen lösen konnte. Ich habe mit einem einfachen neuronalen Netzwerk für dieses Modell experimentiert, aber ich denke, dass ein Netzwerk mit mehr Schichten in der tatsächlichen Umgebung verwendet wird. Daher frage ich mich, wie stark sich die diesmal geänderte Einstellung auf die Leistung auswirkt. (Wenn Sie bereits eine haben, lassen Sie es mich bitte wissen)
2020/10/03 Erklärung zum veröffentlichten und geschriebenen Code hinzugefügt
Recommended Posts