Является ли tf.GradientTape в TF 2.0 эквивалентным tf.gradients?

#python #tensorflow #tensorflow2.0

#python #тензорный поток #tensorflow2.0

Вопрос:

Я переношу свой цикл обучения на Tensorflow 2.0 API. В режиме быстрого выполнения tf.GradientTape заменяет tf.gradients . Вопрос в том, имеют ли они одинаковую функциональность? В частности:

  • В функции gradient() :

    • Является ли параметр output_gradients эквивалентным grad_ys в старом API?
    • Как насчет параметров colocate_gradients_with_ops . aggregation_method , gate_gradients of tf.gradients ? Они устарели из-за отсутствия использования? Можно ли их заменить с помощью других методов в 2.0 API? Нужны ли они вообще для быстрого выполнения?
  • Является ли функция jacobian() эквивалентной tf.python.ops.parallel_for.gradients ?

Ответ №1:

Пожалуйста, ознакомьтесь с ответом ниже.

  1. Относительно Output Gradients и grad_ys : Да, их можно считать одинаковыми.

Подробное объяснение: Информация о Output Gradients упомянута в Github -> imperative_grad.py как показано ниже.

output_gradients: если не None, то список градиентов, предоставленных для каждого целевого объекта, или None, если мы должны использовать вычисленный нисходящий градиент целевого объекта,

Информация о grad_ys упомянута на сайте TF, как показано ниже:

grad_ys: это список тензоров той же длины, что и ys, который содержит начальные градиенты для каждого y в ys. Когда grad_ys равно None, мы заполняем тензор ‘1’ формы y для каждого y в ys. Пользователь может предоставить свои собственные начальные grad_ys для вычисления производных, используя другой начальный градиент для каждого y (например, если кто-то хочет по-разному взвесить градиент для каждого значения в каждом y).

Из приведенных выше объяснений и приведенного ниже кода, упомянутого на странице 394 книги «Практические занятия по ML с использованием Scikit-Learn amp; Tensorflow», мы можем заключить, что начальное значение Theta может быть случайным значением, и мы можем передать его с помощью параметров, output_gradients или grad_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 -> Графики

  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

  2. Что касается gate_gradients : Не требуется для Eager, поскольку это также связано с контекстом графика.

Подробное объяснение: Как показано в приведенном ниже коде из Github -> gradients_utils.py , если gate_gradients есть True , то некоторые операции добавляются в график с использованием функции, _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 : Да, они одинаковы.