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
GradientTape могут быть вложены для вычисления производных более высокого порядка. Например,
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(). Для вычисления нескольких градиентов над одним и тем же вычислением создайте устойчивую градиентную ленту. Это позволяет вызывать метод 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, векторизует вычисление якобиана. В противном случае использует последовательный цикл while. Векторизация иногда может завершиться ошибкой или привести к чрезмерному использованию памяти. Этот параметр можно использовать для отключения векторизации в таких случаях. |
| Возвращает | |
|---|---|
список или вложенная структура тензоров (или None), по одному для каждого элемента в sources. Возвращаемая структура такая же, как структура sources. Обратите внимание, что если какой-либо градиент является разреженным (IndexedSlices), функция якобиана в настоящее время делает его плотным и возвращает тензор вместо него. Это может измениться в будущем. |
| Возбуждает | |
|---|---|
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/r2.3/api_docs/python/tf/GradientTape