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) 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_dy = tape.gradient(z, w)
print(dz_dy)
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 может быть использован только для вычисления одного набора градиентов (или якобианов).
Пример использования:
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 может быть использован только для вычисления одного набора градиентов (или якобианов).
| Аргументы | |
|---|---|
target | список или вложенная структура тензоров или переменных, которые нужно продифференцировать. |
sources | список или вложенная структура тензоров или переменных. target будут продифференцированы по элементам в sources. |
output_gradients | список градиентов, по одному для каждого элемента целевого значения. По умолчанию None. |
unconnected_gradients | значение, которое может содержать 'none' или 'zero' и изменяет значение, которое будет возвращено, если целевые и исходные значения не связаны. Возможные значения и эффекты подробно описаны в 'UnconnectedGradients', по умолчанию значение 'none'. |
| Возвращаемое значение | |
|---|---|
список или вложенная структура тензоров (или IndexedSlices, или None), по одному для каждого элемента в sources. Возвращаемая структура такая же, как структура sources. |
| Исключения | |
|---|---|
RuntimeError | Если вызвано на использованной, непостоянной ленте. |
RuntimeError | Если вызвано внутри контекста ленты. |
ValueError | Если целевое значение является переменной или если вызываются несвязанные градиенты с неизвестным значением. |
jacobian
jacobian(
target, sources, unconnected_gradients=tf.UnconnectedGradients.NONE,
parallel_iterations=None, experimental_use_pfor=True
)
Вычисляет якобиан с помощью операций, записанных в контексте этой ленты.
Примечание: Если вы не установите persistent=True , GradientTape может быть использован только для вычисления одного набора градиентов (или якобианов).
См. статью википедии для определения якобиана.
Пример использования:
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), функция якобиана в настоящее время делает его плотным и возвращает тензор вместо него. В будущем это может измениться. |
| Исключения | |
|---|---|
RuntimeError | Если вызов производится на используемой, непродолжительной записи. |
RuntimeError | Если вызов производится на непродолжительной записи с включённым жадным выполнением и без включения 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
)
Выходит из контекста записи, дальнейшие операции не отслеживаются.
© 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/r2.4/api_docs/python/tf/GradientTape