2017-01-18 4 views
1

Übersicht: Ich möchte nur ausgewählte Variablen in einem Netzwerk aktualisieren. Das Netzwerk hat Teile A ->B (in Vorwärtsrichtung) und jeder von ihnen hat separate Verluste La und Lb. Ich möchte die Gewichte a von A trainieren, um Lb zu optimieren. Dabei sollten die Gewichte b von B festgelegt werden. Wie kann ich das machen?Tensorflow Update nur ausgewählte Variablen

Ansatz 1: nur a als Variablen Wählen Sie mit var_list in optimizer.minimize(loss, var_list=[a]) zu minimieren. https://github.com/tensorflow/tensorflow/issues/834. Dies stürzt mit einem Fehler ValueError: No gradients provided for any variable, check your graph for ops that do not support gradients, between variables (...) and loss (...) ab. Das funktioniert in anderen Szenarien auch gut, aber anscheinend mag es nicht, dass Gewichte b nicht in der var_list sind.

Edit 1: Die Zeile, die den Fehler verursacht: a_optim = tf.train.AdamOptimizer(args.lr, beta1=args.beta1).minimize(self.a_loss, var_list=self.a_vars, global_step=self.global_step)

Ansatz 2: Gleiche wie Ansatz 1, aber auch b im var_list. Das Problem ist jetzt, dass das Netzwerk a und b aktualisiert, während es die Gradienten nur über B senden und nur A aktualisieren sollte.

Edit 2: Die Linie, die funktioniert, aber nicht das, was ich will: a_optim = tf.train.AdamOptimizer(args.lr, beta1=args.beta1).minimize(self.a_loss, var_list=self.a_vars+self.b_vars, global_step=self.global_step)

Ansatz 3: Verwendung tf.stop_gradient(tensor)Holding variables constant during optimizer. Aus der Dokumentation folgere ich, dass dies nur dazu führt, dass die Gradienten im Diagramm nicht weiter nach links fließen. Ich möchte die Ignoriervariablen auf der rechten Seite.

Ansatz 4: Set tf.Variable(..., trainable=True), aber das sieht sehr unflexibel, wenn ich mit dem Training zwischen A und B wechseln will

+0

können Sie einen Beispielcode eingeben, der den Fehler von Approach 1 reproduziert? das sollte der Weg sein, es zu tun. Vielleicht gibt es einen Fehler. Welche Version von Tensorflow verwenden Sie? – fabrizioM

+0

Danke, ich habe zwei Änderungen hinzugefügt, um die Version zu zeigen, die funktioniert und die, die nicht funktioniert. Ich benutze die neueste v. 0.12 von TensorFlow. – nightrome

Antwort

0

Es stellt sich heraus, dass die endgültige op in A war nicht differenzierbar (tf_argmax) und damit Offensichtlich konnten Gradienten nicht von B nach A weitergegeben werden.

0

Ich fand heraus, dass für eine bessere Kontrolle, welche Variablen während der Optimierung zu aktualisieren sind, es besser ist: 'compute_gradients' und 'apply_gradients' Ansatz.

Die compute_gradients wird eine Liste von Tupel von Gradienten und Variablen Tensoren zurückgeben. Sie können die zurückkehrenden Gradiententensoren beliebig ändern und auch die Teilmenge der zu aktualisierenden Variablen auswählen.

Dann Sie eine Liste von Tupel von Gradienten und Variablen übergeben, die Sie

Hier sind einige Beispiele zu ‚apply_gradients‘ aktualisieren möchten:

optimizer = tf.train.AdamOptimizer(learning_rate=0.0001) 
grads = optimizer.compute_gradients(your_cost_function) 

# You can update 'g' and exclude some v's 
grad_lists = [(g, v) for g, v in grads] 

train_op = optimizer.apply_gradients(grad_lists) 

Then, run your session. 

sess.run(train_op, feed_dict={...}) 

Auch da Sie 2 Verlustfunktionen haben, Sie sollten 2 Zugoperationen anlegen.

Hoffe diese Hilfe!

Verwandte Themen