我将在这个回复前言,这不是一个完整的解决方案,而是一些关于如何改进你的细胞的评论。
首先,在 ACTStep 函数中,您调用rnn.rnn
对于一个时间步(定义为[input]
。如果您正在执行单个时间步,那么简单地使用实际的时间步可能会更有效self.cell
通话功能。您将看到张量流中使用相同的机制细胞包装器 https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/rnn_cell.py#L708
你提到你已经尝试过使用TensorArrays
。您是否正确打包和解包张量数组?这里有一个repo https://github.com/ofirnachum/sequence_gan/blob/master/model.py你会在哪里找到model.py
张量数组已正确打包和解包。
您还问是否有一个功能control_flow_ops
这将需要累积所有张量。我想你正在寻找tf.control_dependencies https://www.tensorflow.org/versions/r0.9/api_docs/python/framework.html#control_dependencies
您可以在 control_dependicies 中列出所有输出张量操作,这将需要张量流来计算该点之前的所有张量。
另外,它看起来像你的counter
变量是可训练的。您确定要这样吗?如果您将计数器加一,则可能不会产生正确的结果。另一方面,您可以故意使其保持可训练性,以便在思考成本函数的最后对其进行区分。
另外我相信 Remainder 函数应该在您的脚本中:
remainder = 1.0 - tf.add_n(acc_probs[:-1])
#note that there is a -1 in the list as you do not want to grab the last probability
这是我编辑的代码版本:
class ACTCell(RNNCell):
"""An RNN cell implementing Graves' Adaptive Computation time algorithm
Notes: https://www.evernote.com/shard/s189/sh/fd165646-b630-48b7-844c-86ad2f07fcda/c9ab960af967ef847097f21d94b0bff7
"""
def __init__(self, num_units, cell, max_computation = 5.0, epsilon = 0.01):
self.one_minus_eps = tf.constant(1.0 - epsilon) #episolon is 0.01 as found in the paper
self._num_units = num_units
self.cell = cell
self.N = tf.constant(max_computation)
@property
def input_size(self):
return self._num_units
@property
def output_size(self):
return self._num_units
@property
def state_size(self):
return self._num_units
def __call__(self, inputs, state, scope=None):
with vs.variable_scope(scope or type(self).__name__):
# define within cell constants/ counters used to control while loop
prob = tf.constant(0.0, shape = [batch_size])
counter = tf.constant(0.0, shape = [batch_size])
# the predicate for stopping the while loop. Tensorflow demands that we have
# all of the variables used in the while loop in the predicate.
pred = lambda prob,counter,state,input,acc_states,acc_output,acc_probs:\
tf.logical_and(tf.less(prob,self.one_minus_eps), tf.less(counter,self.N))
acc_probs, acc_outputs, acc_states = [], [], []
_,iterations,_,_,acc_states,acc_output,acc_probs = \
control_flow_ops.while_loop(
pred,
self.ACTStep, #looks like he purposely makes the while loop here
[prob, counter, state, input, acc_states, acc_outputs, acc_probs])
'''mean-field updates for states and outputs'''
next_state = tf.add_n([x*y for x,y in zip(acc_probs,acc_states)])
output = tf.add_n([x*y for x,y in zip(acc_probs,acc_outputs)])
remainder = 1.0 - tf.add_n(acc_probs[:-1]) #you take the last off to avoid a negative ponder cost #the problem here is we need to take the sum of all the remainders
tf.add_to_collection("ACT_remainder", remainder) #if this doesnt work then you can do self.list based upon timesteps
tf.add_to_collection("ACT_iterations", iterations)
return output, next_state
def ACTStep(self,prob, counter, state, input, acc_states, acc_outputs, acc_probs):
'''run rnn once'''
output, new_state = rnn.rnn(self.cell, [input], state, scope=type(self.cell).__name__)
prob_w = tf.get_variable("prob_w", [self.cell.input_size,1])
prob_b = tf.get_variable("prob_b", [1])
halting_probability = tf.nn.sigmoid(tf.matmul(prob_w,new_state) + prob_b)
acc_states.append(new_state)
acc_outputs.append(output)
acc_probs.append(halting_probability)
return [p + prob, counter + 1.0, new_state, input,acc_states,acc_outputs,acc_probs]
def PonderCostFunction(self, time_penalty = 0.01):
'''
note: ponder is completely different than probability and ponder = roe
the ponder cost function prohibits the rnn from cycling endlessly on each timestep when not much is needed
'''
n_iterations = tf.get_collection_ref("ACT_iterations")
remainder = tf.get_collection_ref("ACT_remainder")
return tf.reduce_sum(n_iterations + remainder) #completely different from probability
这是一篇我自己一直在努力实现的复杂论文。我不介意与您合作在 Tensorflow 中完成它。如果您有兴趣,请在 Skype 上添加我的 LeavesBreathe,我们可以从那里开始。