2016-06-22 9 views
0

Heute füge ich meinem LSTM in Tensorflow einen Lernratenabfall hinzu.Warum verlangsamt tf.assign() die Ausführungszeit?

I

ändern
train_op = tf.train.RMSPropOptimizer(lr_rate).minimize(loss) 

zu

lr = tf.Variable(0.0,trainable=False) 

und jeden Zug Schritt

sess.run(tf.assign(lr, lr_rate*0.9**epoch)) 

Allerdings laufen, erhöht sich diese Änderung der Ausführungszeit von ~ 7 Minuten auf über ~ 20 Minuten .

Meine Frage ist: Warum erhöht diese Änderung die Ausführungszeit?

Eine offensichtliche Problemumgehung besteht darin, die Zuweisung nur alle 1000 Iterationen durchzuführen. Ich möchte jedoch die Gründe dafür verstehen.

  • Macht sess.run() zusätzliche Zeit?
  • Benötigt tf.asign() zusätzliche Zeit?
  • Könnte ich diese tf.assign() auf eine andere, effizientere Weise implementieren?

Antwort

2

Eine Erhöhung der Rechenzeit von 3 scheint ein wenig seltsam, aber hier sind einige Dinge, die Sie ausprobieren können:

  • eine op im Diagramm erstellen Sie Ihre Lernrate zu aktualisieren. In Ihrem Code erstellen Sie bei jedem Schritt eine neue Operation, die dem Diagramm hinzugefügt wird, sodass möglicherweise zusätzliche Zeit benötigt wird. Im Allgemeinen ist es am besten Praxis alle notwendigen Operationen vor dem tf.Session()
update_lr = tf.assign(lr, lr_rate*0.9**epoch) 
  • nur 1 sess.run(), bei jeder Iteration Gebrauch erstellen Training op kombiniert und update_lr
sess.run([train_op, update_lr], ...) 
  • Der effizientere Weg, eine veraltete Lernrate zu implementieren, ist die Verwendung von tf.train.exponential_decay(). Wenn Sie von 0.9 jede Epoche verfallen möchten, können Sie tun:
training_size = 60000 # size of an epoch 
global_step = tf.Variable(0, trainable=False) 
starter_learning_rate = 0.1 
learning_rate = tf.train.exponential_decay(starter_learning_rate, global_step, 
              training_size, 0.9, staircase=True) 
# Passing global_step to minimize() will increment it at each step. 

train_op = tf.train.RMSPropOptimizer(lr_rate).minimize(loss, global_step=global_step) 
+0

Dank Olivier, ich werde die Exponential_Decay() implementieren. Am Ende der Woche werde ich die Verbesserungen melden –

+0

Ja, Ihre Implementierung funktioniert gut! –

4

Das Problem, das Sie haben nichts mit sess.run oder tf.assign zu tun hat. Dies ist ein sehr beliebtes Problem in vielen Modellen und Ihr Modell ist langsam wegen Ihrer aufgeblähten Grafik. Ich werde erklären, was das alles für ein sehr einfaches Beispiel bedeutet, das nichts mit Ihrem Code zu tun hat.Werfen Sie einen Blick auf diese 2-Schnipsel:

Snippet 1

a = tf.Variable(1, name='a') 
b = tf.Variable(2, name='b') 
with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 
    for _ in range(3): 
     print sess.run(tf.add(a, b)), 

Snippet 2

a = tf.Variable(1, name='a') 
b = tf.Variable(2, name='b') 
res = tf.add(a, b) 
with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 
    for _ in range(3): 
     print sess.run(res), 

sie beide die gleichen Werte zurück und schaut, wie sie beide tun das gleiche Zeug. Das Problem ist, dass sie verschiedene Diagramme erstellen und wenn Sie nach der Schleife werden Sie sehen, dass Snippet 1 mehr Knoten als Snippet 2 hat. Erhöhen Sie den Bereich auf ein paar tausend, und der Unterschied wird erheblich sein.

Sie haben das gleiche Problem mit einem aufgeblähten Graphen. Weil Sie in jeder Iteration der Schleife tf.assign(lr, lr_rate*0.9**epoch) 3 Knoten in der Grafik erstellen. Verschieben Sie Ihre Diagrammdefinition getrennt von dem Diagrammlauf und Sie werden die Verbesserung sehen.

Verwandte Themen