我想在tensorflow中有一个LSTM,其权重是另一个LSTM权重的指数移动平均值。所以基本上我有一些输入占位符和一些初始状态占位符的代码:
def test_lstm(input_ph, init_ph, scope):
cell = tf.nn.rnn_cell.LSTMCell(128, use_peepholes=True)
input_ph = tf.transpose(input_ph, [1, 0, 2])
input_list = tf.unpack(input_ph)
with tf.variable_scope(scope) as vs:
outputs, states = tf.nn.rnn(cell, input_list, initial_state=init_ph)
theta = [v for v in tf.all_variables() if v.name.startswith(vs.name)]
return outputs, theta
lstm_1, theta_1 = test_lstm(input_1, state_init_1, scope="lstm_1")
我现在想做的是沿着这些方面类似的东西(实际上并不起作用,因为指数移动平均线将标记" ema"放在权重的变量名称后面,它们不会出现在变量范围内,因为它们不是用tf.get_variable创建的:
ema = tf.train.ExponentialMovingAverage(decay=1-self.tau, name="ema")
with tf.variable_scope("lstm_2"):
maintain_averages_theta_1 = ema.apply(theta_1)
theta_2_1 = [ema.average(x) for x in theta_1]
lstm_2 , theta_2_2 = test_lstm(input_2, state_init_2, scope="lstm_2"
最终theta_2_1将等于theta_2_2(或因为变量已经存在而抛出异常)。
答案 0 :(得分:2)
似乎有点晚了,但希望这会有所帮助。 TF-RNN系列的关键问题是我们不能直接指定RNN的变量,这与普通的前馈或卷积NN不同,因此我们不能做简单的工作 - 获取EMAed变量并插入网络。
让我们进入真正的交易(我附上了练习代码来查找,所以请参考EMA_LSTM.py)。
我们可以说,有一个包含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
然后声明tf.placeholder以获取必要的输入,即:
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]
现在,我们将把var_list称为'net4',其中包含ExponentialMovingAverage(EMA)-ed值'net1',如下所示,首先在上面的beh会话中分配原始'net1'并在下面为每个元素添加1.:
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)
sess.run([param4.assign(param1.eval()) for param4, param1 in zip(net4,net1)]) # Change0
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)
请注意
我们只初始化(通过声明'init_new_vars_op'然后运行声明作业)包含'ExponentialMovingAverage'的名称变量,否则net1中的变量也将被新初始化。
'net1'新指定为'net1'中变量的每个元素+1。如果'net1'的元素是-0.5并且现在是0.5乘+1,那么我们希望当EMA衰减率为0.5时,'net4'为0.
最后,我们使用'sess.run(target_update_op)'
最终,我们首先使用'network()'函数声明'net4',然后将'EMA(net1)值分配并运行到'net4'。运行'sess.run(result)'时,它将是带有EMA(net1)-ed变量的那个。
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()')和它需要什么值(通过'for循环.assign(ema.average())到自己'),你运行该过程。
我们首先声明'结果'并指定第二个参数的值,这有点违反直觉。然而,这就是TF的本质,它们正是它们所寻找的东西,因为首先设置变量,流程及其关系然后分配值,然后运行流程总是合乎逻辑的。
最后,真正的机器学习代码还有很多事情要做:
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)
sess.run([param4.assign(param1.eval()) for param4, param1 in zip(net4,net1)]) # Change0
最后,请注意,您必须在网络更改后立即sess.run(ema。应用(网络)),然后sess.run(net_ema.assign(ema.average(net)) )。W / O。应用,net_ema不会被赋予平均值
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
})