Spec-Zone.ru › TensorFlow 2.9

tf.GradientTape

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

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

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

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

tf.autodiff.GradientTape

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

См. Руководство по миграции для получения дополнительных сведений.

tf.compat.v1.GradientTape

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

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

Обучаемые переменные (созданные с помощью 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)

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

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 Если target — объект None.
ValueError Если target — переменная или если вызывается unconnected gradients с неизвестным значением.

jacobian

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

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

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

Примечание: Если вы не установите persistent=True GradientTape может быть использован только для вычисления одного набора градиентов (или якобианов).
Примечание: По умолчанию реализация якобиана использует параллельное вычисление (pfor), которое создаёт tf.function под капотом для каждого вызова якобиана. Для лучшей производительности и чтобы избежать повторной компиляции и переписывания векторизации при каждом вызове, поместите код 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 Список или вложенная структура тензоров или переменных. Производные будут вычисляться по элементам в sources.
unconnected_gradients Значение, которое может содержать 'none' или 'zero' и изменяет значение, которое будет возвращено, если цель и источники не соединены. Возможные значения и эффекты подробно описаны в 'UnconnectedGradients', по умолчанию используется 'none'.
parallel_iterations Ручка для управления количеством итераций, выполняемых параллельно. Эту ручку можно использовать для управления общим объемом используемой памяти.
experimental_use_pfor Если True, вычисляет якобиан векторизованно. В противном случае использует последовательный цикл while_loop. Векторизация может иногда завершиться ошибкой или привести к чрезмерному использованию памяти. Этот параметр можно использовать для отключения векторизации в таких случаях.
Возвращаемое значение
Список или вложенная структура тензоров (или None), по одному для каждого элемента в sources. Структура возвращаемого значения совпадает со структурой sources. Обратите внимание, что если любой градиент является разреженным (IndexedSlices), функция якобиана в настоящее время делает его плотным и возвращает тензор вместо него. Это может измениться в будущем.
Исключения
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/versions/r2.9/api_docs/python/tf/GradientTape

Spec-Zone.ru

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