【问题标题】:Compute gradients for each time step of tf.while_loop计算 tf.while_loop 的每个时间步长的梯度
【发布时间】:2018-09-08 08:23:09
【问题描述】:

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

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 的唯一可能性是计算相对于weight_1 的梯度和x_in 的当前值/时间步长,而无需通过时间反向传播。
  3. 在每个时间步,网络将输出动作的概率分布。然后需要梯度来实现策略梯度。

【问题讨论】:

  • 你确定你对x_out感兴趣而不是x_final吗?
  • 是的,网络是像image captioning这样的自注册模型。网络在每个时间步输出动作的概率分布,直到它决定“完成”。我需要每个输出(动作)的梯度,而不仅仅是最后一个。
  • 您是否尝试在每次tf.while_loop 迭代中创建一个新变量? TensorFlow 无法做到这一点。使用您当前的代码,您只创建了两个变量,一个用于layer_1,另一个用于每次循环迭代。
  • 不,我不想在每次迭代中都创建新变量。我只是想通过时间反向传播:计算每个时间步的x_out 相对于weight_0weight_1 的梯度。
  • 那么你为什么要在循环内声明weight_1 = tf.Variable(1.0)?你真的打算tf.get_variable吗?

标签: python tensorflow while-loop backpropagation


【解决方案1】:

在基于thisthis 的Tensorflow 中,您永远不能在tf.while_loop 中调用tf.gradients,当我尝试将共轭梯度下降完全创建到Tensorflow 中时,我发现了这一点。图表。

但如果我正确理解了您的模型,您可以制作自己的 RNNCell 版本并将其包装在 tf.dynamic_rnn 中,但实际的单元格 实现会有点复杂,因为您需要在运行时动态评估条件。

对于初学者,您可以查看 Tensorflow 的 dynamic_rnn 代码 here

另外,动态图从来都不是Tensorflow 的强项,因此请考虑使用PyTorch 等其他框架,或者您可以尝试eager_execution 看看是否有帮助。

【讨论】:

  • 您是否找到了完全在 TF 中的共轭梯度的解决方法(并避免急切执行)?
  • 我有,是的。这不是微不足道的。查看this repository。他们有一个非常强大的实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
相关资源
最近更新 更多