10

我正在将我的训练循环迁移到Tensorflow 2.0 API。在急切执行模式下,tf.GradientTape替换tf.gradients. 问题是,它们是否具有相同的功能?具体来说:

  • 在功能gradient()

    • 参数是否output_gradients等同grad_ys于旧 API?
    • 参数呢colocate_gradients_with_opsaggregation_method,gate_gradientstf.gradients? 它们是否由于缺乏使用而被弃用?可以使用 2.0 API 中的其他方法替换它们吗?急切执行中是否需要它们?
  • 功能是否jacobian()等同于tf.python.ops.parallel_for.gradients

4

1 回答 1

6

请在下面找到回复。

  1. 关于Output Gradientsand grad_ys:是的,它们可以被认为是相同的。

详细说明:Github -> 命令式_grad.pyOutput Gradients中提到了关于的信息,如下图所示。

output_gradients:如果不是 None,则为每个 Target 提供梯度列表,如果我们要使用目标计算的下游梯度,则为 None,

TF网站grad_ys中提到了关于的信息,如下所示:

grad_ys:是与 ys 长度相同的张量列表,它保存 ys 中每个 y 的初始梯度。当 grad_ys 为 None 时,我们为 ys 中的每个 y 填充 y 形状的 '1's 张量。用户可以提供他们自己的初始 grad_ys 以使用每个 y 的不同初始梯度来计算导数(例如,如果想要为每个 y 中的每个值不同地加权梯度)。

从上面的解释和下面的代码,在书的第 394 页提到,使用 Scikit-Learn 和 Tensorflow 进行机器学习,我们可以得出结论,初始值Theta可以是随机值,我们可以使用参数传递它,output_gradientsgrad_ys

theta = tf.Variable(tf.random_uniform([n + 1, 1], -1.0, 1.0), name="theta")
gradients = tf.gradients(mse, [theta])[0]
training_op = tf.assign(theta, theta - learning_rate * gradients)
  1. 关于colocate_gradients_with_ops:是的,急切执行不需要它,因为它与图的控制流上下文有关。

详解:指向Github -> ops.pycolocate_gradients_with_ops中提到的以下代码。控制流Context与Context的概念有关,与Graphs有关,在TF Site -> Graphs中有说明

 def _colocate_with_for_gradient(self, op, gradient_uid,
                                  ignore_existing=False):
    with self.colocate_with(op, ignore_existing):
      if gradient_uid is not None and self._control_flow_context is not None:
        self._control_flow_context.EnterGradientColocation(op, gradient_uid)
        try:
          yield
        finally:
          self._control_flow_context.ExitGradientColocation(op, gradient_uid)
      else:
        yield
  1. 关于aggregation_method:这个参数的等价物在2.0已经实现,命名_aggregate_gradsGithub链接

  2. 关于gate_gradients:Eager 不需要,因为这也与 Graph Context 有关。

详细说明:如下 Github -> gradients_utils.py中的代码所示,如​​果gate_gradientsTrue,则使用函数 向图形添加一些操作_colocate_with_for_gradient,这又取决于图形的控制流上下文。

if gate_gradients and len([x for x in in_grads
                                         if x is not None]) > 1:
                with ops.device(None):
                  with ops._colocate_with_for_gradient(  # pylint: disable=protected-access
                      None,
                      gradient_uid,
                      ignore_existing=True):
                    in_grads = control_flow_ops.tuple(in_grads)
  1. 关于jacobian:是的,它们是相同的。
于 2019-08-22T05:40:11.700 回答