2017-12-20 3 views
1

Ich bin jetzt auf Aufgabe 3 der Udacity Deep Learning-Klasse. Ich habe das meiste davon fertiggestellt und es funktioniert, aber ich habe festgestellt, dass das Problem 3, bei dem es darum geht, 'Dropout' mit Tensorflow zu verwenden, meine Leistung eher verschlechtert als verbessert.Udacity Deep Learning, Aufgabe 3, Teil 3: Tensorflow Dropout-Funktion

Also ich denke, ich mache etwas falsch. Ich werde meinen vollständigen Code hier eingeben. Wenn mir jemand erklären kann, wie man Dropout richtig einsetzt, würde ich es begrüßen. (Oder bestätige, dass ich es richtig verwende und es in diesem Fall einfach nicht hilft). Es sinkt die Genauigkeit von über 94% (ohne Dropout) auf 91,5%. Wenn Sie keine L2-Regularisierung verwenden, ist die Verschlechterung noch größer.

def create_nn(dataset, weights_hidden, biases_hidden, weights_out, biases_out): 
    # Original layer 
    logits = tf.add(tf.matmul(tf_train_dataset, weights_hidden), biases_hidden) 
    # Drop Out layer 1 
    logits = tf.nn.dropout(logits, 0.5) 
    # Hidden Relu layer 
    logits = tf.nn.relu(logits) 
    # Drop Out layer 2 
    logits = tf.nn.dropout(logits, 0.5) 
    # Output: Connect hidden layer to a node for each class 
    logits = tf.add(tf.matmul(logits, weights_out), biases_out) 
    return logits 


# Create model 
batch_size = 128 
hidden_layer_size = 1024 
beta = 1e-3 

graph = tf.Graph() 
with graph.as_default(): 
    # Input data. For the training data, we use a placeholder that will be fed 
    # at run time with a training minibatch. 
    tf_train_dataset = tf.placeholder(tf.float32, 
            shape=(batch_size, image_size * image_size)) 
    tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels)) 
    tf_valid_dataset = tf.constant(valid_dataset) 
    tf_test_dataset = tf.constant(test_dataset) 

    # Variables. 
    weights_hidden = tf.Variable(
     #tf.truncated_normal([image_size * image_size, num_labels])) 
     tf.truncated_normal([image_size * image_size, hidden_layer_size])) 
    #biases = tf.Variable(tf.zeros([num_labels])) 
    biases_hidden = tf.Variable(tf.zeros([hidden_layer_size])) 

    weights_out = tf.Variable(tf.truncated_normal([hidden_layer_size, num_labels])) 
    biases_out = tf.Variable(tf.zeros([num_labels])) 


    # Training computation. 
    #logits = tf.matmul(tf_train_dataset, weights_out) + biases_out 
    logits = create_nn(tf_train_dataset, weights_hidden, biases_hidden, weights_out, biases_out) 

    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=tf_train_labels, logits=logits)) 
    loss += beta * (tf.nn.l2_loss(weights_hidden) + tf.nn.l2_loss(weights_out)) 

    # Optimizer. 
    optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss) 

    # Predictions for the training, validation, and test data. 
    train_prediction = tf.nn.softmax(logits) 
    #valid_prediction = tf.nn.softmax(tf.matmul(tf_valid_dataset, weights_out) + biases_out) 
    #test_prediction = tf.nn.softmax(tf.matmul(tf_test_dataset, weights_out) + biases_out) 
    valid_prediction = tf.nn.softmax(tf.matmul(tf.nn.relu(tf.matmul(tf_valid_dataset, weights_hidden) + biases_hidden), weights_out) + biases_out) 
    test_prediction = tf.nn.softmax(tf.matmul(tf.nn.relu(tf.matmul(tf_test_dataset, weights_hidden) + biases_hidden), weights_out) + biases_out) 


num_steps = 10000 

with tf.Session(graph=graph) as session: 
    tf.global_variables_initializer().run() 
    print("Initialized") 
    for step in range(num_steps): 
    # Pick an offset within the training data, which has been randomized. 
    # Note: we could use better randomization across epochs. 
    offset = (step * batch_size) % (train_labels.shape[0] - batch_size) 
    #offset = (step * batch_size) % (3*128 - batch_size) 
    #print(offset) 
    # Generate a minibatch. 
    batch_data = train_dataset[offset:(offset + batch_size), :] 
    batch_labels = train_labels[offset:(offset + batch_size), :] 
    # Prepare a dictionary telling the session where to feed the minibatch. 
    # The key of the dictionary is the placeholder node of the graph to be fed, 
    # and the value is the numpy array to feed to it. 
    feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels} 
    _, l, predictions = session.run([optimizer, loss, train_prediction], feed_dict=feed_dict) 

    if (step % 500 == 0): 
     print("Minibatch loss at step %d: %f" % (step, l)) 
     print("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels)) 
     print("Validation accuracy: %.1f%%" % accuracy(valid_prediction.eval(), valid_labels)) 

    print("Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels)) 

Antwort

0

2 Dinge, die ich denke, kann das Problem verursachen.

Zunächst würde ich nicht empfehlen, Dropout in der ersten Schicht (das zu 50%, verwenden Sie niedriger, im Bereich 10-25%, wenn Sie müssen)) als wenn Sie einen solchen hohen Dropout verwenden noch höhere Funktionen sind nicht gelernt und in tiefere Schichten verbreitet. Probieren Sie auch eine Reihe von Dropouts von 10% bis 50% aus und sehen Sie, wie sich die Genauigkeit ändert. Es gibt keine Möglichkeit, vorher zu wissen, welcher Wert funktioniert.

Zweitens verwenden Sie normalerweise nicht Dropout bei der Inferenz. Um diesen Durchlauf im keep_prob -Parameter des Dropouts als Platzhalter zu fixieren, setzen Sie ihn beim Abschließen auf 1.

Auch wenn die Genauigkeitswerte, die Sie angeben, Trainingsgenauigkeit sind, gibt es möglicherweise nicht einmal ein großes Problem an erster Stelle, da Dropout in der Regel die Trainingsgenauigkeit um kleine Beträge verringert, da Sie nicht überarbeiten, ist die Test-/Validierungsgenauigkeit das muss genau überwacht werden

+0

wurde unter Verwendung I Testing Genauigkeit berichten. –

+0

"Zweitens verwenden Sie in der Regel keinen Dropout bei der Inferenz. Um diesen Pass im keep_prob-Parameter des Dropouts als Platzhalter zu fixieren, setzen Sie ihn bei der Inferenz auf 1." Ich verstehe nicht, was du hier meinst. Könnten Sie das klären? –

+0

Ich denke, das könnte der Teil sein, den ich nicht richtig mache. Ich lese weiter darüber, aber es ist mir nicht klar, was es bedeutet. Ich habe in den Test- und Validierungsbewertungen, soweit ich das beurteilen kann, überhaupt keinen Abbruch. –

2

Sie müssten das Dropout während der Inferenz abschalten. Es mag zunächst nicht offensichtlich sein, aber die Tatsache, dass der Ausfall in der NN-Architektur fest codiert ist, bedeutet, dass er die Testdaten während der Inferenz beeinflussen wird. Sie können dies vermeiden, indem Sie einen Platzhalter keep_prob erstellen, anstatt den Wert 0.5 direkt anzugeben. Zum Beispiel:

keep_prob = tf.placeholder(tf.float32) 
logits = tf.nn.dropout(logits, keep_prob) 

Zum Einschalten Aussetzer während des Trainings, stellen Sie die keep_prob Wert bis 0,5:

feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels, keep_prob: 0.5} 

Während Inferenz/-bewertung, sollten Sie in der Lage sein, so etwas zu tun keep_prob-1,0 einstellen in eval:

accuracy.eval(feed_dict={x: test_prediction, y_: test_labels, keep_prob: 1.0} 

EDIT:

Da das Problem nicht darin besteht, dass der Aussetzer bei der Inferenz verwendet wird, wäre der nächste Täter, dass der Aussetzer für diese Netzwerkgröße zu hoch ist. Sie können möglicherweise versuchen, den Aussetzer auf 20% zu reduzieren (d. H. Keep_prob = 0.8) oder die Größe des Netzwerks zu erhöhen, um dem Modell eine Gelegenheit zum Erlernen der Repräsentationen zu geben.

Ich habe es tatsächlich mit Ihrem Code versucht, und ich bin ~ 93,5% mit 20% Dropout mit dieser Netzwerkgröße. Ich habe unten einige zusätzliche Ressourcen hinzugefügt, einschließlich des ursprünglichen Dropout-Papiers, um die Intuition dahinter zu verdeutlichen, und erweitere weitere Tipps bei der Verwendung von Dropouts, z. B. die Lernrate zu erhöhen.

Referenzen:

+0

Ich denke, der Grund, warum ich verwirrt bin, ist, weil ich eine valid_prediction und test_prediction habe, die NICHT aus der hartcodierten NN-Architektur stammen: –

+0

valid_prediction = tf.nn.softmax (tf.matmul (tf.nn.relu (tf.matmul (tf_valid_dataset, weights_hidden) + biases_hidden), weights_out) + biases_out) –

+0

test_prediction = tf.nn.softmax (tf.matmul (tf.nn.relu (tf.matmul (tf_test_dataset, weights_hidden) + biases_hidden), weights_out) + biases_out) –