Scheint ein bisschen spät, aber hoffe, das hilft. Das kritische Problem der TF-RNN-Serie besteht darin, dass wir die Variablen für RNNs im Gegensatz zu einfachen Feedforward- oder Convolutional-NNs nicht direkt bestimmen können, so dass wir keine einfache Arbeit leisten können - EMAed vars und Plug in das Netzwerk.
Lassen Sie uns in die reale Sache gehen (ich habe einen Übungscode angehängt, um nach diesem zu suchen, so beziehen Sie sich bitte EMA_LSTM.py).
Sollen wir sagen, es ist eine Netzwerkfunktion enthält LSTM:
def network(in_x,in_h):
# Input: 'in_x' is the input sequence, 'in_h' is the initial hidden cell(c,m)
# Output: 'hidden_outputs' is the output sequence(c-sequence), 'net' is the list of parameters used in this network function
cell = tf.nn.rnn_cell.BasicLSTMCell(3, state_is_tuple=True)
in_h = tf.nn.rnn_cell.LSTMStateTuple(in_h[0], in_h[1])
hidden_outputs, last_tuple = tf.nn.dynamic_rnn(cell, in_x, dtype=tf.float32, initial_state=in_h)
net = [v for v in tf.trainable_variables() if tf.contrib.framework.get_name_scope() in v.name]
return hidden_outputs, net
Dazu tf.placeholder für die notwendigen Eingaben zu erklären, die da sind:
in_x = tf.placeholder("float", [None,None,6])
in_c = tf.placeholder("float", [None,3])
in_m = tf.placeholder("float", [None,3])
in_h = (in_c, in_m)
Schließlich führen wir eine Sitzung das geht die network() -Funktion mit angegebenen Eingängen weiter:
init_cORm = np.zeros(shape=(1,3))
input = np.ones(shape=(1,1,6))
print '========================new-1(beh)=============================='
with tf.Session() as sess:
with tf.variable_scope('beh', reuse=False) as beh:
result, net1 = network(in_x,in_h)
sess.run(tf.global_variables_initializer())
list = sess.run([result, in_x, in_h, net1], feed_dict={
in_x : input,
in_c : init_cORm,
in_m : init_cORm
})
print 'result:', list[0]
print 'in_x:' , list[1]
print 'in_h:', list[2]
print 'net1:', list[3][0][0][:4]
Jetzt werden wir mak e die var_list namens 'net4', die die ExponentialMovingAverage (EMA) -ed Werte von 'net1' enthält, wie im Folgenden, wobei das ursprüngliche 'net1' zuerst in der obigen Sitzung zugewiesen und neu zugewiesen wird, indem für jedes Element 1 hinzugefügt wird:
ema = tf.train.ExponentialMovingAverage(decay=0.5)
target_update_op = ema.apply(net1)
init_new_vars_op = tf.initialize_variables(var_list=[v for v in tf.global_variables() if 'ExponentialMovingAverage' in v.name]) # 'initialize_variables' will be replaced with 'variables_initializer' in 2017
sess.run(init_new_vars_op)
len_net1 = len(net1)
net1_ema = [[] for i in range(len_net1)]
for i in range(len_net1):
sess.run(net1[i].assign(1. + net1[i]))
sess.run(target_update_op)
Beachten Sie, dass
wir nur initialisiert (damals ‚init_new_vars_op‘ erklärt die Deklaration Job ausgeführt wird) die Variablen ihres Namens enthalten ‚ExponentialMovingAverage‘, wenn nicht die Variablen in net1 auch sein neu initialisiert.
'net1' wird neu mit +1 für alle Elemente der Variablen in 'net1' zugewiesen. Wenn ein Element von 'net1' -0,5 ist und jetzt 0,5 um +1 ist, dann wollen wir 'net4' als 0. wenn die EMA-Abklingrate 0,5 ist.
Schließlich führen wir den EMA-Job mit ' sess.run (target_update_op) NET4 'erste mit dem 'Netzwerk()' Funktion und weisen & die EMA (NET1) Werte in laufen '‘
Schließlich erklären wir' NET4'. Wenn Sie 'sess.run (result)' ausführen, ist es der mit EMA (net1) -ed Variablen.
with tf.variable_scope('tare', reuse=False) as tare:
result, net4 = network(in_x,in_h)
len_net4 = len(net4)
target_assign = [[] for i in range(len_net4)]
for i in range(len_net4):
target_assign[i] = net4[i].assign(ema.average(net1[i]))
sess.run(target_assign[i].op)
list = sess.run([result, in_x, in_h, net4], feed_dict={
in_x : input,
in_c : init_cORm,
in_m : init_cORm
})
Was ist hier passiert? Sie deklarieren indirekt die LSTM-Variablen als 'net4' in der Funktion 'network()'. Dann in der for-Schleife, wir weist darauf hin,, dass "net4" ist eigentlich EMA von "net1" und "net1 + 1." . Schließlich, mit dem net4 angegeben, was zu tun ist (über 'Netzwerk()') und welche Werte es braucht (über 'for-Schleife von. Assign (ema.average()) zu sich selbst'), führen Sie den Prozess.
Es ist etwas kontraintuitiv, dass wir das 'Ergebnis' zuerst deklarieren und den Wert der zweiten Parameter angeben. Dies ist jedoch die Natur von TF, nach der sie genau suchen, da es immer logisch ist, zuerst Variablen, Prozesse und ihre Beziehung festzulegen, dann Werte zuzuweisen und dann die Prozesse auszuführen.
Schließlich paar Dinge weiter zu gehen für die reale Maschine Lern Codes:
- Hier drin, ich habe gerade zweite ‚net1‘ zugeordnet mit ‚net1 + 1‘. Im wirklichen Fall ist das '+1'. Schritt ist, wo Sie 'sess.run()' (nachdem Sie in irgendwo "deklarieren") Ihren Optimierer. Also jedes Mal, nachdem Sie 'sess.run (optimizer)', 'sess.run (target_update_op)' und dann'sess.run (target_assign [i] .op) 'folgen sollten, um Ihr' net4 'entlang der EMA von zu aktualisieren "net1". Conceretly, können Sie diesen Job mit anderen Reihenfolge wie unten tun:
ema = tf.train.ExponentialMovingAverage(decay=0.5)
target_update_op = ema.apply(net1)
with tf.variable_scope('tare', reuse=False) as tare:
result, net4 = network(in_x,in_h)
len_net4 = len(net4)
target_assign = [[] for i in range(len_net4)]
for i in range(len_net4):
target_assign[i] = net4[i].assign(ema.average(net1[i]))
init_new_vars_op = tf.initialize_variables(var_list=[v for v in tf.global_variables() if 'ExponentialMovingAverage' in v.name]) # 'initialize_variables' will be replaced with 'variables_initializer' in 2017
sess.run(init_new_vars_op)
len_net1 = len(net1)
net1_ema = [[] for i in range(len_net1)]
for i in range(len_net1):
sess.run(net1[i].assign(1. + net1[i]))
sess.run(target_update_op)
for i in range(len_net4):
sess.run(target_assign[i].op)
list = sess.run([result, in_x, in_h, net4], feed_dict={
in_x : input,
in_c : init_cORm,
in_m : init_cORm
})
Wenn Sie wollen einige echte Implementierung Schnipsel sehen, habe ich eine für Tief Verstärkung Lernen Arbeit. Antworte mir wenn du interessiert bist. Chrs.
Vielen Dank für die ausführliche Antwort. In der Tat ist es ein bisschen zu spät, als ich dies während meiner Masterarbeit (die auf Deep RL war) untersucht habe. Wäre aber definitiv an Ihrer Implementierung interessiert. –