2016-06-29 7 views
3

Ich möchte eine Stoppbedingung basierend auf dem Wert der Steigung der Verlustfunktion implementieren w.r.t. die Gewichte. Zum Beispiel, sagen wir mal ich so etwas wie dieses:Stoppbedingung auf Gradientenwert Tensorflow

optimizer = tf.train.AdamOptimizer() 
grads_and_vars = optimizer.compute_gradients(a_loss_function) 
train_op = optimizer.apply_gradients(grads_and_vars) 

dann würde Ich mag die Grafik mit so etwas laufen:

for step in range(TotSteps): 
    output = sess.run([input], feed_dict=some_dict) 
    if(grad_taken_in_some_way < some_treshold): 
     print("Training finished.") 
     break 

Ich bin nicht sicher, was ich sess passieren sollte. run() um als Ausgabe auch den Farbverlauf (neben allen anderen Sachen, die ich brauche) zu bekommen. Ich bin mir nicht einmal sicher, ob dies der richtige Ansatz ist oder ob ich es anders machen sollte. Ich habe einige Versuche gemacht, aber ich habe jedes Mal versagt. Hoffe, jemand hat ein paar Hinweise. Vielen Dank im Voraus!

EDIT: Englisch Korrektur

EDIT2: Antwort von Iballes ist genau das, was ich tun wollte. Trotzdem bin ich mir nicht sicher, wie ich die Gradienten normieren und summieren soll. Da ich verschiedene Layer in meinem CNN und verschiedene Gewichte mit unterschiedlicher Form habe, bekomme ich einen Fehler bei der Operation add_n(), wenn ich einfach das mache, was Sie vorgeschlagen haben (da ich versuche, Matrizen mit verschiedenen Formen zusammenzufügen). Also sollte ich wohl sowas machen:

grad_norms = [tf.nn.l2_normalize(g[0], 0) for g in grads_and_vars]  
grad_norm = [tf.reduce_sum(grads) for grads in grad_norms] 
final_grad = tf.reduce_sum(grad_norm) 

Kann mir jemand das bestätigen?

Antwort

2

Ihre Zeile output = sess.run([input], feed_dict=some_dict) lässt Sie denken, dass Sie ein kleines Missverständnis des Befehls sess.run haben. Was Sie [input] nennen, soll eine Liste von Tensoren sein, die durch den Befehl sess.run geholt werden sollen. Daher ist es eher eine Ausgabe als eine Eingabe. Nehmen wir zur Lösung Ihrer Frage an, dass Sie stattdessen etwas wie output = sess.run(loss, feed_dict=some_dict) machen (um den Trainingsverlust zu überwachen).

Auch, ich nehme an, dass Sie Ihr Stoppkriterium unter Verwendung der Norm des Gradienten (der Gradient selbst ist eine multidimensionale Menge) formulieren möchten. Daher möchten Sie bei jedem Ausführen des Diagramms die Norm des Gradienten abrufen. Zu diesem Zweck müssen Sie zwei Dinge tun. 1) Fügen Sie dem Berechnungsgraphen die Gradientennorm hinzu. 2) Holen Sie es in jedem Anruf zu sess.run in Ihrer Trainingsschleife.

Ad 1) Sie haben die Gradienten des Graphen über

optimizer = tf.train.AdamOptimizer() 
grads_and_vars = optimizer.compute_gradients(a_loss_function) 

und haben jetzt die Tensoren Halten der Gradienten in grads_and_vars (eine für jede trainierte Variable in der Grafik) hinzugefügt. Lassen Sie uns die Norm für jeden Gradienten nehmen und dann zusammenfassen:

grad_norms = [tf.nn.l2_loss(g) for g, v in grads_and_vars] 
grad_norm = tf.add_n(grad_norms) 

Dort haben Sie Ihre Gradientennorm.

Anzeige 2) Rufen Sie innerhalb Ihrer Schleife die Farbverlaufnorm neben dem Verlust ab, indem Sie dazu den Befehl sess.run eingeben.

for step in range(TotSteps): 
    l, gn = sess.run([loss, grad_norm], feed_dict=some_dict) 
    if(gn < some_treshold): 
     print("Training finished.") 
     break 
+0

Irgendwelche Gedanken zu dieser Antwort @AndreaPavone? – lballes

+0

Genau das wollte ich machen. Trotzdem bin ich mir nicht sicher, wie ich die Gradienten normieren und summieren soll. Da ich verschiedene Layer in meinem CNN und verschiedene Gewichte mit unterschiedlicher Form habe, bekomme ich einen Fehler bei der Operation add_n(), wenn ich einfach das mache, was Sie vorgeschlagen haben (da ich versuche, Matrizen mit verschiedenen Formen zusammenzufügen). Weitere Details in den bearbeiteten Fragen.Vielen Dank! –

+0

Oh, ich wurde mit Tensorfließfunktionsnamen verwirrt. Was ich machen wollte, ist "grad_norms = [tf.nn.l2_loss (g) für g, v in grad_and_vars]". Meine ursprüngliche Antwort verwendete eine Funktion '' tf.nn.l2_norm'', die nicht existiert und ich ** nicht ** ''tf.nn.l2_normalize'' bedeutet. Die Funktion "tf.nn.l2_loss" nimmt die quadrierte L2-Norm eines Vektors und erzeugt somit unabhängig von den Dimensionen dieses Tensors einen Skalar. Diese Skalare können dann addiert werden, um die L2-Norm des Gesamtgradienten zu berechnen. (Korrigiert es in der Antwort.) – lballes