tf.GradientTape
| Просмотреть исходный код на GitHub |
Запись операций для автоматического дифференцирования.
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) # Will compute to 6.0
GradientTapes могут быть вложены для вычисления производных высших порядков. Например,
x = tf.constant(3.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) # Will compute to 6.0
d2y_dx2 = g.gradient(dy_dx, x) # Will compute to 2.0
По умолчанию ресурсы, используемые GradientTape, освобождаются сразу после вызова метода GradientTape.gradient(). Чтобы вычислить несколько градиентов над одной и той же вычислительной задачей, создайте персистентный GradientTape. Это позволяет выполнить несколько вызовов метода 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) # 108.0 (4*x^3 at x = 3) dy_dx = g.gradient(y, x) # 6.0 del g # Drop the reference to the tape
По умолчанию GradientTape автоматически отслеживает все обучаемые переменные, используемые внутри контекста. Если вы хотите более тонкий контроль над отслеживанием переменных, вы можете отключить автоматическое отслеживание, передав watch_accessed_variables=False конструктору ленты:
with tf.GradientTape(watch_accessed_variables=False) as tape:
tape.watch(variable_a)
y = variable_a ** 2 # Gradients will be available for `variable_a`.
z = variable_b ** 3 # No gradients will be available since `variable_b` is
# not being watched.
Обратите внимание, что при использовании моделей вы должны убедиться, что ваши переменные существуют при использовании 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. Выходные данные, а также промежуточные активации, имеют меньшую размерность и избегают множества избыточных нулей, что привело бы к вычислению матрицы Якоби при условии независимости.
Пример использования:
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 | Если вызов производится в неперсистентной ленте при включенном исполнении eager и без включения experimental_use_pfor. |
ValueError | Если векторизация вычисления Якоби не удалась или если первое измерение target и source не совпадают. |
gradient
gradient(
target, sources, output_gradients=None,
unconnected_gradients=tf.UnconnectedGradients.NONE
)
Вычисляет градиент, используя операции, записанные в контексте этой ленты.
| Аргументы | |
|---|---|
target | список или вложенная структура тензоров или переменных, по которым нужно вычислить производную. |
sources | список или вложенная структура тензоров или переменных. target будут дифференцированы по элементам в sources. |
output_gradients | список градиентов, по одному для каждого элемента цели. По умолчанию None. |
unconnected_gradients | значение, которое может быть 'none' или 'zero' и изменяет значение, которое будет возвращено, если цель и источники не связаны. Возможные значения и эффекты подробно описаны в 'UnconnectedGradients', а по умолчанию оно равно 'none'. |
| Возвращаемое значение | |
|---|---|
список или вложенная структура тензоров (или IndexedSlices, или None), по одному для каждого элемента в sources. Структура возвращаемого значения такая же, как у sources. |
| Исключения | |
|---|---|
RuntimeError | если вызов производится внутри контекста ленты или если вызов производится более одного раза в неперсистентной ленте. |
ValueError | если цель является переменной или если вызов unconnected gradients производится с неизвестным значением. |
jacobian
jacobian(
target, sources, unconnected_gradients=tf.UnconnectedGradients.NONE,
parallel_iterations=None, experimental_use_pfor=True
)
Вычисляет матрицу Якоби, используя операции, записанные в контексте этой ленты.
См. статью Википедии для определения матрицы Якоби.
Пример использования:
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, векторизует вычисление Якоби. В противном случае использует последовательный tf.while_loop. Векторизация иногда может не удаться или привести к чрезмерному использованию памяти. Этот параметр можно использовать для отключения векторизации в таких случаях. |
| Возвращаемое значение | |
|---|---|
Список или вложенная структура тензоров (или None), по одному для каждого элемента в sources. Структура возвращаемого значения такая же, как у sources. Обратите внимание, что если какой-либо градиент является разреженным (IndexedSlices), функция jacobian в настоящее время делает его плотным и возвращает тензор вместо него. Это может измениться в будущем. |
| Исключения | |
|---|---|
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()
Временно останавливает запись операций в этой ленте.
Операции, выполняемые во время активности этого контекстного менеджера, не будут записываться в ленту. Это полезно для уменьшения памяти, используемой для отслеживания всех вычислений.
Например:
with tf.GradientTape(persistent=True) as t:
loss = compute_loss(model)
with t.stop_recording():
# The gradient computation below is not traced, saving memory.
grads = t.gradient(loss, model.variables)
Возвращает:
None
| Исключения | |
|---|---|
RuntimeError | если лента в настоящее время не записывает. |
watch
watch(
tensor
)
Обеспечивает, что tensor отслеживается этой лентой.
| Аргументы | |
|---|---|
tensor | тензор или список тензоров. |
| Исключения | |
|---|---|
ValueError | если обнаруживается что-то, что не является тензором. |
watched_variables
watched_variables()
Возвращает отслеживаемые этой лентой переменные в порядке их создания.
__enter__
__enter__()
Входит в контекст, внутри которого операции записываются в эту ленту.
__exit__
__exit__(
typ, value, traceback
)
Выходит из контекста записи, дальнейшие операции не отслеживаются.
© 2020 The TensorFlow Authors. All rights reserved.
Licensed under the Creative Commons Attribution License 3.0.
Code samples licensed under the Apache 2.0 License.
https://www.tensorflow.org/versions/r1.15/api_docs/python/tf/GradientTape