2016-07-19 12 views
6

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

Antwort

5

Sie benötigen Betriebsebene Saatgut zusätzlich zu setzen Samen grafisch darzustellen-Ebene, dh

tf.reset_default_graph() 
a = tf.constant([1, 1, 1, 1, 1], dtype=tf.float32) 
graph_level_seed = 1 
operation_level_seed = 1 
tf.set_random_seed(graph_level_seed) 
b = tf.nn.dropout(a, 0.5, seed=operation_level_seed) 
+0

Wow. Müssen Sie einen Operationslevel-Startwert für alle Vorgänge festlegen? Alle 'tf.placeholder',' tf.Variable', 'tf.reduce_mean' usw.? – DojoGojira

+2

Nein, nur diejenigen, die Zufälligkeit haben –

+1

@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

5

Siehe diesen Tensorflow github issue. Einige Operationen auf der GPU sind nicht vollständig deterministisch (Geschwindigkeit vs Genauigkeit).

ich auch beobachtet, dass für das Saatgut eine Wirkung zu haben, tf.set_random_seed(...)vor die Session erstellt wird aufgerufen werden muss.Außerdem sollten Sie den Python-Interpreter bei jedem Ausführen des Codes entweder vollständig neu starten oder am Anfang tf.reset_default_graph() aufrufen.

0

Um die Antwort zu Yaroslav hinzuzufügen, sollten Sie auch numpy Seed zusätzlich zu den Seeds für die Operation und die Diagrammebene festlegen, da einige Backend-Operationen von numpy abhängen. Das machte den Trick für mich np.random.seed() mit Tensorflow V 1.1.0