少し遅れそうですが、これが役立つことを願っています。 TF-RNNシリーズの重大な問題は、プレーンフィードフォワードまたは畳み込みNNとは異なり、RNNの変数を直接指定することができないため、EMAed varsを取得してネットワークに接続するという簡単な作業はできません。
本当のことを考えてみましょう(これを参照するための練習コードが添付されていますので、EMA_LSTM.pyを参照してください)。
我々はLSTMを含むネットワーク機能がある、と言うものとする。そして、あなたは必要な入力のためのtf.placeholderを宣言
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
:
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)
最後に、私たちはセッションを実行します指定された入力でnetwork()関数を実行します:
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]
ここでは、 e 'net1'のExponentialMovingAverage(EMA)で指定された値を含む 'net4'と呼ばれるvar_listは、上記のセッションで最初に割り当てられた元の 'net1'と、各要素に1を加えて新たに割り当てられます。 NET1でない変数もなる場合、我々は唯一、自分の名前の変数が「ExponentialMovingAverage」を含む(宣言ジョブを実行し、「init_new_vars_op」を宣言することによって)初期化
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)
注
最終的には、我々は宣言' NET4'。 'sess.run(result)'を実行すると、EMA(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]))
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
})
ここには何が起こっていますか?あなたは 'network()'関数でLSTM変数を 'net4'として間接的に宣言します。次に、forループでは、はを指摘しています。実際には 'net4'は 'net1'と 'net1 + 1'のEMAです。 。最後に、net4が( 'network()'を介して)何をするのか('assass(ema.average())のループを介して)どのような値をとるのかを指定して、プロセスを実行します。
「結果」を最初に宣言し、パラメータの値を2番目に指定するのはやや直感的です。しかし、それは、変数、プロセス、それらの関係を最初に設定してから値を割り当て、その後プロセスを実行することが常に論理的であるため、TFが正確に探しているものの性質です。実際の機械学習のコードのために、さらにどこへ行く
最後に、いくつかのこと:ここで
- は、私はちょうど2番目の「NET1 + 1」で「NET1」を割り当てられました。実際には、これは「+1」です。ステップはあなたのオプティマイザが実行された後に実行されます(どこかで宣言した後)。だから、毎回あなたが 'sess.run(optimiser)'、 'sess.run(target_update_op)'とthen'sess.run(target_assign [i] .op) 'のEMAに沿ってあなたの' net4 'を更新する必要があります'net1'。 Conceretly、あなたは以下のような異なる順序でこの仕事を行うことができます。あなたには、いくつかの実際の実装スニペットを見たい場合は
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
})
、私はディープ強化学習の仕事のための1つを作りました。あなたが興味があるなら、私に返信してください。 Chrs。
詳細な回答ありがとうございます。実際、私の修士論文の中でこれを調べていたのはちょっと遅かったです(これはDeep RLでした)。あなたの実装には間違いありません。 –