使用tf.while_loop进行每个时间步骤的梯度计算。

10

如何在每个时间步中针对网络的所有权重计算x_out的梯度,给定一个TensorFlow中的tf.while_loop

network_input = tf.placeholder(tf.float32, [None])
steps = tf.constant(0.0)

weight_0 = tf.Variable(1.0)
layer_1 = network_input * weight_0

def condition(steps, x):
    return steps <= 5

def loop(steps, x_in):
    weight_1 = tf.Variable(1.0)
    x_out = x_in * weight_1
    steps += 1
    return [steps, x_out]

_, x_final = tf.while_loop(
    condition,
    loop,
    [steps, layer_1]
)

一些注释

  1. 在我的网络中,条件是动态的。不同的运行将对while循环进行不同次数的迭代。
  2. 调用 tf.gradients(x, tf.trainable_variables()) 将会崩溃并出现 AttributeError: 'WhileContext' object has no attribute 'pred'。似乎唯一能够在循环内使用 tf.gradients 的可能性是仅根据当前的 x_in 值 / 时间步长计算相对于 weight_1 的梯度,而不是在时间上反向传播。
  3. 在每个时间步骤中,网络将输出一个关于动作的概率分布。然后需要梯度来实现策略梯度。

你确定你对 x_out 感兴趣而不是 x_final 吗? - ben
1
是的,这个网络是一个自我注册模型,就像图像字幕化一样。该网络在每个时间步骤输出动作的概率分布,直到它决定“完成”。我需要每个输出(动作)的梯度,而不仅仅是最后一个。 - Genius
你是否试图在每个tf.while_loop迭代中创建一个新变量?这在TensorFlow中是不可能的。根据你当前的代码,你只创建了两个变量,一个用于layer_1,另一个用于每个循环迭代。 - jdehesa
不,我不想在每次迭代中创建新变量。我只想通过时间反向传播:对于每个时间步骤,计算x_out相对于weight_0weight_1的梯度。 - Genius
那么为什么你要在循环内声明 weight_1 = tf.Variable(1.0) 呢?你的意图是实际上想使用 tf.get_variable 吗? - ldavid
我认为这不应该有影响,因为“while_loop调用'cond'和'body'正好一次”(引自TensorFlow API)。 - Genius
1个回答

6
根据这里这里,在TensorFlow中无法在tf.while_loop内部调用tf.gradients。当我试图在TensorFlow图中完全创建共轭梯度下降时,我很艰难地发现了这一点。
但是,如果我正确地理解了您的模型,您可以创建自己版本的RNNCell并将其包装在tf.dynamic_rnn中,但实际的单元格实现会更加复杂,因为您需要在运行时动态评估条件。
首先,您可以查看TensorFlow的dynamic_rnn代码这里
或者,动态图形从未是TensorFlow的强项,因此请考虑使用其他框架,如PyTorch,或者尝试使用eager_execution来查看是否有所帮助。

1
你是否找到了在TF中完全避免急切执行的共轭梯度的解决方法? - niko
1
我有,是的。它不是简单的事情。查看[这个代码库](https://github.com/tensorforce/tensorforce)。他们有一个相当强大的实现。 - squadrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接