Das Problem
ich ein Python-Skript, das TensorFlow verwendet ein mehrschichtiges Perzeptron-Netz (mit Dropout) zu schaffen, um binäre Klassifizierung zu tun. Obwohl ich sorgfältig darauf geachtet habe, sowohl die Python- als auch die TensorFlow-Startwerte festzulegen, erhalte ich nicht wiederholbare Ergebnisse. Wenn ich einmal renne und dann wieder renne, bekomme ich andere Ergebnisse. Ich kann sogar einmal laufen, beende Python, starte Python neu, laufe wieder und erhalte andere Ergebnisse.TensorFlow: Nicht-wiederholbare Ergebnisse
was ich versucht habe
Ich kenne einige Leute Fragen gepostet über das Erhalten nicht wiederholbare Ergebnisse in TensorFlow (zB "How to get stable results...", "set_random_seed not working...", "How to get reproducible result in TensorFlow") und die Antworten in der Regel erweisen sich als eine falsche Verwendung/Verständnis sein von tf.set_random_seed()
. Ich habe sichergestellt, dass die gegebenen Lösungen implementiert werden, aber das hat mein Problem nicht gelöst.
Ein häufiger Fehler ist nicht zu erkennen, dass tf.set_random_seed()
nur ein Seed auf Diagrammebene ist und dass das mehrmalige Ausführen des Skripts den Graphen ändert und die nicht wiederholbaren Ergebnisse erklärt. Ich habe die folgende Anweisung verwendet, um den gesamten Graphen auszudrucken und (über Diff) zu verifizieren, dass der Graph gleich ist, auch wenn die Ergebnisse unterschiedlich sind.
print [n.name for n in tf.get_default_graph().as_graph_def().node]
Ich habe auch verwendet Funktionsaufrufe wie tf.reset_default_graph()
und tf.get_default_graph().finalize()
Änderungen an der grafischen Darstellung zu vermeiden, obwohl dies wahrscheinlich übertrieben ist.
Der (Relevant)-Code
Mein Skript ist ~ 360 Zeilen lang, so sind hier die entsprechenden Zeilen (mit snipped Code angegeben). Alle Elemente, die sich in ALL_CAPS befinden, sind Konstanten, die in meinem Block Parameters
definiert sind.
import numpy as np
import tensorflow as tf
from copy import deepcopy
from tqdm import tqdm # Progress bar
# --------------------------------- Parameters ---------------------------------
(snip)
# --------------------------------- Functions ---------------------------------
(snip)
# ------------------------------ Obtain Train Data -----------------------------
(snip)
# ------------------------------ Obtain Test Data -----------------------------
(snip)
random.seed(12345)
tf.set_random_seed(12345)
(snip)
# ------------------------- Build the TensorFlow Graph -------------------------
tf.reset_default_graph()
with tf.Graph().as_default():
x = tf.placeholder("float", shape=[None, N_INPUT])
y_ = tf.placeholder("float", shape=[None, N_CLASSES])
# Store layers weight & bias
weights = {
'h1': tf.Variable(tf.random_normal([N_INPUT, N_HIDDEN_1])),
'h2': tf.Variable(tf.random_normal([N_HIDDEN_1, N_HIDDEN_2])),
'h3': tf.Variable(tf.random_normal([N_HIDDEN_2, N_HIDDEN_3])),
'out': tf.Variable(tf.random_normal([N_HIDDEN_3, N_CLASSES]))
}
biases = {
'b1': tf.Variable(tf.random_normal([N_HIDDEN_1])),
'b2': tf.Variable(tf.random_normal([N_HIDDEN_2])),
'b3': tf.Variable(tf.random_normal([N_HIDDEN_3])),
'out': tf.Variable(tf.random_normal([N_CLASSES]))
}
# Construct model
pred = multilayer_perceptron(x, weights, biases, USE_DROP_LAYERS, DROP_KEEP_PROB)
mean1 = tf.reduce_mean(weights['h1'])
mean2 = tf.reduce_mean(weights['h2'])
mean3 = tf.reduce_mean(weights['h3'])
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y_))
regularizers = (tf.nn.l2_loss(weights['h1']) + tf.nn.l2_loss(biases['b1']) +
tf.nn.l2_loss(weights['h2']) + tf.nn.l2_loss(biases['b2']) +
tf.nn.l2_loss(weights['h3']) + tf.nn.l2_loss(biases['b3']))
cost += COEFF_REGULAR * regularizers
optimizer = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(cost)
out_labels = tf.nn.softmax(pred)
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
tf.get_default_graph().finalize() # Lock the graph as read-only
#Print the default graph in text form
print [n.name for n in tf.get_default_graph().as_graph_def().node]
# --------------------------------- Training ----------------------------------
print "Start Training"
pbar = tqdm(total = TRAINING_EPOCHS)
for epoch in range(TRAINING_EPOCHS):
avg_cost = 0.0
batch_iter = 0
train_outfile.write(str(epoch))
while batch_iter < BATCH_SIZE:
train_features = []
train_labels = []
batch_segments = random.sample(train_segments, 20)
for segment in batch_segments:
train_features.append(segment[0])
train_labels.append(segment[1])
sess.run(optimizer, feed_dict={x: train_features, y_: train_labels})
line_out = "," + str(batch_iter) + "\n"
train_outfile.write(line_out)
line_out = ",," + str(sess.run(mean1, feed_dict={x: train_features, y_: train_labels}))
line_out += "," + str(sess.run(mean2, feed_dict={x: train_features, y_: train_labels}))
line_out += "," + str(sess.run(mean3, feed_dict={x: train_features, y_: train_labels})) + "\n"
train_outfile.write(line_out)
avg_cost += sess.run(cost, feed_dict={x: train_features, y_: train_labels})/BATCH_SIZE
batch_iter += 1
line_out = ",,,,," + str(avg_cost) + "\n"
train_outfile.write(line_out)
pbar.update(1) # Increment the progress bar by one
train_outfile.close()
print "Completed training"
# ------------------------------ Testing & Output ------------------------------
keep_prob = 1.0 # Do not use dropout when testing
print "now reducing mean"
print(sess.run(mean1, feed_dict={x: test_features, y_: test_labels}))
print "TRUE LABELS"
print(test_labels)
print "PREDICTED LABELS"
pred_labels = sess.run(out_labels, feed_dict={x: test_features})
print(pred_labels)
output_accuracy_results(pred_labels, test_labels)
sess.close()
Was Sie sehen
nicht wiederholbar ist, ich bin am Ende Ergebnisse während jeder Epoche in eine Datei und auch Druckgenauigkeit Zahlen ausgibt. Keine von diesen stimmt von Lauf zu Lauf überein, obwohl ich glaube, dass ich den/die Seed (s) richtig gesetzt habe. Ich habe sowohl random.seed(12345)
als auch tf.set_random_seed(12345)
verwendet. Bitte lassen Sie mich wissen, wenn ich weitere Informationen bereitstellen muss. Und danke im Voraus für jede Hilfe.
-DG
Set-up Details
TensorFlow Version 0.8.0 (nur CPU)
Enthought Canopy Version 1.7.2 (Python 2.7, nicht 3. +)
Mac OS X-Version 10.11.3
Wow. Müssen Sie einen Operationslevel-Startwert für alle Vorgänge festlegen? Alle 'tf.placeholder',' tf.Variable', 'tf.reduce_mean' usw.? – DojoGojira
Nein, nur diejenigen, die Zufälligkeit haben –
@Yaroslav Ich verstehe es nicht: Ich würde annehmen, der Zweck von 'tf.set_random_seed()' ist, alle zufälligen Operationen in der Grafik zu beeinflussen, so dass Sie nicht festlegen müssen manuell einen Seed für jeden zufälligen Operator. Was nützt es sonst? Und aus dem Beispiel in [doc] (https://www.tensorflow.org/versions/r0.11/api_docs/python/constant_op.html#set_random_seed) setzen sie nur den globalen Seed, um reproduzierbare Ergebnisse zu erhalten. – toto2