此页面由 Cloud Translation API 翻译。
Switch to English

tf.GradientTape

TensorFlow 1版本 在GitHub上查看源代码

记录操作以自动区分。

用于笔记本

在指南中使用在教程中使用

如果在此上下文管理器中执行了操作,并且“输入”中的至少一个输入被监视,则会记录这些操作。

trainable=True自动监视trainable=True变量(由tf.Variabletf.compat.v1.get_variable创建,其中两种情况下默认为tf.compat.v1.get_variable trainable=True )。通过在此上下文管理器上调用watch方法,可以手动监视张量。

例如,考虑函数y = x * xx = 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.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.
 

请注意,只有具有实型或复杂dtype的张量才是可微的。

persistent 布尔值,用于控制是否创建持久渐变磁带。默认情况下为False,这意味着最多可以在此对象上对gradient()方法进行一次调用。
watch_accessed_variables 布尔值控制磁带在磁带处于活动状态时是否将自动watch任何(可训练的)变量。默认值是True,可以从磁带中计算出的任何结果中请求梯度,这些结果是通过读取可训练的Variable得出的。如果False用户必须显式地watch他们想要从中请求渐变的任何Variable

方法

batch_jacobian

查看资料

按示例计算并堆叠jacobian。

有关雅可比定律的定义,请参见维基百科文章 。此功能实质上是以下各项的有效实现:

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

请注意,与计算每个输入值的每个输出值的梯度的GradientTape.jacobian相比,当target[i,...]独立于j != isource[j,...]时,此函数很有用。与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 一个值,该值可以保持“无”或“零”,并更改目标和源未连接时将返回的值。可能的值和效果在“ UnconnectedGradients”中详细说明,默认为“ none”。
parallel_iterations 一个旋钮,用于控制并行调度的迭代次数。该旋钮可用于控制总内存使用量。
experimental_use_pfor 如果为true,则使用pfor计算雅可比行列式。其他使用tf.while_loop。

退货
形状为[b,y_1,...,y_n,x1,...,x_m]的张量t ,其中t[i, ...]target[i, ...] wrt source[i, ...] ,即按示例堆叠的jacobians。

加薪
RuntimeError 如果在启用了急切执行且未启用experimental_use_pfor的非持久磁带上调用。
ValueError 如果jacobian计算的向量化失败,或者targetsource第一维不匹配。

gradient

查看资料

使用在此磁带上下文中记录的操作计算梯度。

精氨酸
target 要区分的张量或变量的列表或嵌套结构。
sources 张量或变量的列表或嵌套结构。 target将与sources中的要素区别开。
output_gradients 渐变列表,每个目标元素一个。默认为无。
unconnected_gradients 一个值,该值可以保持“无”或“零”,并更改目标和源未连接时将返回的值。可能的值和效果在“ UnconnectedGradients”中详细说明,默认为“ none”。

退货
张量的列表或嵌套结构(或IndexedSlices或None), sources每个元素一个。返回的结构与sources的结构相同。

加薪
RuntimeError 如果在磁带上下文中调用,或者在非永久性磁带上多次调用。
ValueError 如果目标是变量,或者使用未知值调用未连接的渐变。

jacobian

查看资料

使用在此磁带上下文中记录的操作来计算jacobian。

有关雅可比定律的定义,请参见维基百科文章

用法示例:

 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 一个值,该值可以保持“无”或“零”,并更改目标和源未连接时将返回的值。可能的值和效果在“ UnconnectedGradients”中详细说明,默认为“ none”。
parallel_iterations 一个旋钮,用于控制并行调度的迭代次数。该旋钮可用于控制总内存使用量。
experimental_use_pfor 如果为true,则向量化jacobian计算。否则回退到顺序的while_loop。向量化有时会失败或导致过多的内存使用。在这种情况下,可以使用此选项禁用向量化。

退货
张量的列表或嵌套结构(或无), sources每个元素一个。返回的结构与sources的结构相同。请注意,如果任何渐变都是稀疏的(IndexedSlices),则jacobian函数当前使其变得密集,并返回张量。将来可能会改变。

加薪
RuntimeError 如果在启用了急切执行且未启用experimental_use_pfor的非持久磁带上调用。
ValueError 如果jacobian计算的向量化失败。

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

查看资料

暂时停止在该磁带上进行记录操作。

此上下文管理器处于活动状态时执行的操作将不会记录在磁带上。这有助于减少通过跟踪所有计算而使用的内存。

例如:

   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)
 

产量:

没有

加薪
RuntimeError 如果磁带当前未在录制。

watch

查看资料

确保此磁带正在跟踪tensor

精氨酸
tensor 张量或张量列表。

加薪
ValueError 如果遇到非张量的东西。

watched_variables

查看资料

按构造顺序返回此磁带监视的变量。

__enter__

查看资料

输入一个上下文,在该上下文中将操作记录在此磁带上。

__exit__

查看资料

退出记录上下文,不再跟踪任何操作。