Spec-Zone.ru › TensorFlow

tf.GradientTape

Записывает операции для автоматического дифференцирования.

Просмотреть псевдонимы

Основные псевдонимы

tf.autodiff.GradientTape

Псевдонимы для совместимости при миграции

Подробнее см. в руководстве по миграции.

tf.compat.v1.GradientTape

tf.GradientTape(
    persistent=False, watch_accessed_variables=True
)

Используется в блокнотах

Используется в руководстве Используется в учебных материалах
  • Введение в градиенты и автоматическое дифференцирование
  • Расширенные возможности автоматического дифференцирования
  • Повышение производительности с помощью tf.function
  • Основы TensorFlow
  • Эффективное использование TensorFlow 2
  • Глубокая свёрточная генеративно-состязательная сеть
  • DeepDream
  • pix2pix: преобразование изображений с помощью условной GAN
  • Перенос художественного стиля нейронной сетью
  • Настраиваемое обучение: пошаговое руководство

Операции записываются, если они выполняются в рамках этого менеджера контекста и хотя бы один из их входов отслеживается.

Обучаемые переменные (созданные с помощью tf.Variable или tf.compat.v1.get_variable, где trainable=True используется по умолчанию в обоих случаях) отслеживаются автоматически. Тензоры можно отслеживать вручную, вызвав метод watch этого менеджера контекста.

Например, рассмотрим функцию y = x * x. Градиент в точке x = 3.0 можно вычислить следующим образом:

x = tf.constant(3.0)
with tf.GradientTape() as g:
  g.watch(x)
  y = x * x
dy_dx = g.gradient(y, x)
print(dy_dx)
tf.Tensor(6.0, shape=(), dtype=float32)

Экземпляры GradientTape можно вкладывать друг в друга для вычисления производных высших порядков. Например:

x = tf.constant(5.0)
with tf.GradientTape() as g:
  g.watch(x)
  with tf.GradientTape() as gg:
    gg.watch(x)
    y = x * x
  dy_dx = gg.gradient(y, x)  # dy_dx = 2 * x
d2y_dx2 = g.gradient(dy_dx, x)  # d2y_dx2 = 2
print(dy_dx)
tf.Tensor(10.0, shape=(), dtype=float32)
print(d2y_dx2)
tf.Tensor(2.0, shape=(), dtype=float32)

По умолчанию ресурсы, используемые GradientTape, освобождаются сразу после вызова метода GradientTape.gradient(). Чтобы вычислить несколько градиентов для одних и тех же вычислений, создайте постоянную ленту градиентов. Это позволяет многократно вызывать метод gradient(); ресурсы освобождаются при сборке мусора для объекта ленты. Например:

x = tf.constant(3.0)
with tf.GradientTape(persistent=True) as g:
  g.watch(x)
  y = x * x
  z = y * y
dz_dx = g.gradient(z, x)  # (4*x^3 at x = 3)
print(dz_dx)
tf.Tensor(108.0, shape=(), dtype=float32)
dy_dx = g.gradient(y, x)
print(dy_dx)
tf.Tensor(6.0, shape=(), dtype=float32)

По умолчанию GradientTape автоматически отслеживает все обучаемые переменные, к которым обращаются внутри контекста. Если требуется точнее управлять отслеживаемыми переменными, автоматическое отслеживание можно отключить, передав watch_accessed_variables=False конструктору ленты:

x = tf.Variable(2.0)
w = tf.Variable(5.0)
with tf.GradientTape(
    watch_accessed_variables=False, persistent=True) as tape:
  tape.watch(x)
  y = x ** 2  # Gradients will be available for `x`.
  z = w ** 3  # No gradients will be available as `w` isn't being watched.
dy_dx = tape.gradient(y, x)
print(dy_dx)
tf.Tensor(4.0, shape=(), dtype=float32)
# No gradients will be available as `w` isn't being watched.
dz_dw = tape.gradient(z, w)
print(dz_dw)
None

При работе с моделями убедитесь, что переменные созданы до использования watch_accessed_variables=False. В противном случае легко получить ситуацию, когда для первой итерации не будет вычислено ни одного градиента:

a = tf.keras.layers.Dense(32)
b = tf.keras.layers.Dense(32)

with tf.GradientTape(watch_accessed_variables=False) as tape:
  tape.watch(a.variables)  # Since `a.build` has not been called at this point
                           # `a.variables` will return an empty list and the
                           # tape will not be watching anything.
  result = b(a(inputs))
  tape.gradient(result, a.variables)  # The result of this computation will be
                                      # a list of `None`s since a's variables
                                      # are not being watched.

Обратите внимание, что дифференцированию поддаются только тензоры с вещественными или комплексными типами данных.

Аргументы
persistent Логическое значение, определяющее, создаётся ли постоянная лента градиентов. По умолчанию равно False, то есть для этого объекта можно вызвать метод gradient() не более одного раза.
watch_accessed_variables Логическое значение, определяющее, будет ли лента автоматически watch любые (обучаемые) переменные, к которым обращаются, пока лента активна. По умолчанию равно True: градиенты можно запросить для любого результата, вычисленного на ленте на основе чтения обучаемой переменной Variable. Если значение False, пользователям необходимо явно watch любые Variable, для которых нужно запросить градиенты.

Методы

batch_jacobian

Просмотреть исходный код

batch_jacobian(
    target,
    source,
    unconnected_gradients=tf.UnconnectedGradients.NONE,
    parallel_iterations=None,
    experimental_use_pfor=True
)

Вычисляет и объединяет по оси примеров якобианы для отдельных примеров.

Определение якобиана см. в статье в Википедии. Эта функция по сути представляет собой эффективную реализацию следующего:

tf.stack([self.jacobian(y[i], x[i]) for i in range(x.shape[0])]).

В отличие от GradientTape.jacobian, которая вычисляет градиент каждого выходного значения относительно каждого входного значения, эта функция полезна, когда target[i,...] не зависит от source[j,...] для j != i. Это допущение позволяет выполнять вычисления эффективнее, чем с помощью GradientTape.jacobian. Выходные данные и промежуточные активации имеют меньшую размерность и не содержат множества избыточных нулей, которые возникли бы при вычислении якобиана с учётом допущения о независимости.

Примечание: Если не задать persistent=True, GradientTape можно использовать только для вычисления одного набора градиентов (или якобианов).
Примечание: По умолчанию реализация batch_jacobian использует параллельный цикл (pfor), который неявно создаёт tf.function при каждом вызове batch_jacobian. Для повышения производительности и предотвращения повторной компиляции и преобразований векторизации при каждом вызове поместите код GradientTape в @tf.function.

Пример использования:

with tf.GradientTape() as g:
  x = tf.constant([[1., 2.], [3., 4.]], dtype=tf.float32)
  g.watch(x)
  y = x * x
batch_jacobian = g.batch_jacobian(y, x)
# batch_jacobian is [[[2,  0], [0,  4]], [[6,  0], [0,  8]]]
Аргументы
target Тензор ранга 2 или выше с формой [b, y1, ..., y_n]. target[i,...] должен зависеть только от source[i,...].
source Тензор ранга 2 или выше с формой [b, x1, ..., x_m].
unconnected_gradients Значение, которое может быть равно 'none' или 'zero' и определяет возвращаемое значение, если целевой объект и источники не связаны. Возможные значения и их действие описаны в 'UnconnectedGradients'; значение по умолчанию — 'none'.
parallel_iterations Параметр, задающий количество итераций, выполняемых параллельно. С его помощью можно контролировать общий расход памяти.
experimental_use_pfor Если значение равно true, для вычисления якобиана используется pfor. В противном случае используется tf.while_loop.
Возвращает
Тензор t с формой [b, y_1, ..., y_n, x1, ..., x_m], где t[i, ...] — это якобиан target[i, ...] относительно source[i, ...], то есть объединённые по оси примеров якобианы для отдельных примеров.
Вызывает исключения
RuntimeError Если вызван для использованной непостоянной ленты.
RuntimeError Если вызван для непостоянной ленты при включённом eager-выполнении и без включения experimental_use_pfor.
ValueError Если векторизация вычисления якобиана завершается неудачей или первые размерности target и source не совпадают.

gradient

Просмотреть исходный код

gradient(
    target,
    sources,
    output_gradients=None,
    unconnected_gradients=tf.UnconnectedGradients.NONE
)

Вычисляет градиент с помощью операций, записанных в контексте этой ленты.

Примечание: Если не задать persistent=True, GradientTape можно использовать только для вычисления одного набора градиентов (или якобианов).

Помимо тензоров, gradient также поддерживает RaggedTensors. Например:

x = tf.ragged.constant([[1.0, 2.0], [3.0]])
with tf.GradientTape() as g:
  g.watch(x)
  y = x * x
g.gradient(y, x)
<tf.RaggedTensor [[2.0, 4.0], [6.0]]>
Аргументы
target Список или вложенная структура тензоров, переменных или CompositeTensors, для которых требуется вычислить производную.
sources Список или вложенная структура тензоров, переменных или CompositeTensors. Производная от target вычисляется относительно элементов в sources.
output_gradients Список градиентов — по одному для каждого дифференцируемого элемента целевого объекта. По умолчанию None.
unconnected_gradients Значение, которое может быть равно 'none' или 'zero' и определяет возвращаемое значение, если целевой объект и источники не связаны. Возможные значения и их действие описаны в 'UnconnectedGradients'; значение по умолчанию — 'none'.
Возвращает
Список или вложенную структуру тензоров (либо IndexedSlices, None или CompositeTensor), по одному элементу для каждого элемента в sources. Возвращаемая структура совпадает со структурой sources.
Вызывает исключения
RuntimeError Если вызван для использованной непостоянной ленты.
RuntimeError Если вызван внутри контекста ленты.
TypeError Если целевой объект равен None.
ValueError Если целевой объект является переменной или если при вызове unconnected gradients указано неизвестное значение.

jacobian

Просмотреть исходный код

jacobian(
    target,
    sources,
    unconnected_gradients=tf.UnconnectedGradients.NONE,
    parallel_iterations=None,
    experimental_use_pfor=True
)

Вычисляет якобиан с помощью операций, записанных в контексте этой ленты.

Примечание: Если не задать persistent=True, GradientTape можно использовать только для вычисления одного набора градиентов (или якобианов).
Примечание: По умолчанию реализация jacobian использует параллельный цикл (pfor), который неявно создаёт tf.function при каждом вызове jacobian. Для повышения производительности и предотвращения повторной компиляции и преобразований векторизации при каждом вызове поместите код GradientTape в @tf.function.

Определение якобиана см. в статье в Википедии.

Пример использования:

with tf.GradientTape() as g:
  x  = tf.constant([1.0, 2.0])
  g.watch(x)
  y = x * x
jacobian = g.jacobian(y, x)
# jacobian value is [[2., 0.], [0., 4.]]
Аргументы
target Тензор, для которого требуется вычислить производную.
sources Список или вложенная структура тензоров или переменных. Производная от target вычисляется относительно элементов в sources.
unconnected_gradients Значение, которое может быть равно 'none' или 'zero' и определяет возвращаемое значение, если целевой объект и источники не связаны. Возможные значения и их действие описаны в 'UnconnectedGradients'; значение по умолчанию — 'none'.
parallel_iterations Параметр, задающий количество итераций, выполняемых параллельно. С его помощью можно контролировать общий расход памяти.
experimental_use_pfor Если значение равно true, вычисление якобиана векторизуется. В противном случае используется последовательный цикл while_loop. Векторизация иногда завершается неудачей или приводит к чрезмерному расходу памяти. В таких случаях этот параметр позволяет отключить векторизацию.
Возвращает
Список или вложенную структуру тензоров (либо None), по одному элементу для каждого элемента в sources. Возвращаемая структура совпадает со структурой sources. Обратите внимание: если какой-либо градиент является разреженным (IndexedSlices), функция jacobian преобразует его в плотный тензор и возвращает Tensor. В будущем это может измениться.
Вызывает исключения
RuntimeError Если вызван для использованной непостоянной ленты.
RuntimeError Если вызван для непостоянной ленты при включённом eager-выполнении и без включения experimental_use_pfor.
ValueError Если векторизация вычисления якобиана завершается неудачей.

reset

Просмотреть исходный код

reset()

Удаляет всю информацию, хранящуюся в этой ленте.

Эквивалентно выходу из контекста ленты и повторному входу в него с новой лентой. Например, следующие два блока кода эквивалентны:

with tf.GradientTape() as t:
  loss = loss_fn()
with tf.GradientTape() as t:
  loss += other_loss_fn()
t.gradient(loss, ...)  # Only differentiates other_loss_fn, not loss_fn


# The following is equivalent to the above
with tf.GradientTape() as t:
  loss = loss_fn()
  t.reset()
  loss += other_loss_fn()
t.gradient(loss, ...)  # Only differentiates other_loss_fn, not loss_fn

Это полезно, если вы не хотите выходить из менеджера контекста ленты или не можете этого сделать, поскольку требуемая точка сброса находится внутри конструкции потока управления:

with tf.GradientTape() as t:
  loss = ...
  if loss > k:
    t.reset()

stop_recording

Просмотреть исходный код

@tf_contextlib.contextmanager
stop_recording()

Временно прекращает запись операций в этой ленте.

Операции, выполняемые во время активности этого менеджера контекста, не записываются в ленту. Это позволяет уменьшить объём памяти, используемой для трассировки всех вычислений.

Например:

x = tf.constant(4.0)
with tf.GradientTape() as tape:
  with tape.stop_recording():
    y = x ** 2
dy_dx = tape.gradient(y, x)
print(dy_dx)
None
Возвращает
None
Вызывает исключения
RuntimeError если запись на ленту в данный момент не выполняется.

watch

Просмотреть исходный код

watch(
    tensor
)

Обеспечивает трассировку tensor этой лентой.

Аргументы
tensor Тензор/переменная или список тензоров/переменных.
Вызывает исключения
ValueError если встречается объект, не являющийся тензором.

watched_variables

Просмотреть исходный код

watched_variables()

Возвращает переменные, отслеживаемые этой лентой, в порядке их создания.

__enter__

Просмотреть исходный код

__enter__()

Входит в контекст, внутри которого операции записываются в эту ленту.

__exit__

Просмотреть исходный код

__exit__(
    typ, value, traceback
)

Выходит из контекста записи; дальнейшие операции не трассируются.

© 2022 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 4.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/api_docs/python/tf/GradientTape

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API