2.0 API中的tf.GradientTape是否等于tf.gradients?

时间:2019-03-27 14:53:21

标签: python tensorflow tensorflow2.0

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

  • 在功能gradient()中:

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

1 个答案:

答案 0 :(得分:3)

请在下面找到回复。

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

详细说明:Github -> imperative_grad.py中提到了有关Output Gradients的信息,如下所示。

  

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

关于grad_ys的信息在TF Site中提及,如下所示:

  

grad_ys:是与ys长度相同的张量列表,其中包含   y中每个y的初始梯度。当grad_ys为None时,我们填写   y中每个y的y形状的'1'张量。用户可以提供   他们自己的初始grad_ys来使用不同的方法计算导数   每个y的初始梯度(例如,如果要加权   每个y中每个值的梯度都不同。

根据以上说明和以下代码(在本书Hands on ML using Scikit-Learn & Tensorflow的第394页中提到), 我们可以得出结论,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:是的,急切执行不需要它,因为它与图的控制流上下文有关。

详细说明:colocate_gradients_with_ops指向Github -> ops.py中提到的以下代码。控制流上下文与上下文的概念有关,后者与图有关,如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_grads,如Github link

  2. 所示。
  3. 关于gate_gradients:Eager不需要,因为这也与图上下文有关。

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

_colocate_with_for_gradient
  1. 关于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) :是的,它们是相同的。