使用 tf.function 时采用渐变
Taking gradients when using tf.function
我对在以下示例中观察到的行为感到困惑:
import tensorflow as tf
@tf.function
def f(a):
c = a * 2
b = tf.reduce_sum(c ** 2 + 2 * c)
return b, c
def fplain(a):
c = a * 2
b = tf.reduce_sum(c ** 2 + 2 * c)
return b, c
a = tf.Variable([[0., 1.], [1., 0.]])
with tf.GradientTape() as tape:
b, c = f(a)
print('tf.function gradient: ', tape.gradient([b], [c]))
# outputs: tf.function gradient: [None]
with tf.GradientTape() as tape:
b, c = fplain(a)
print('plain gradient: ', tape.gradient([b], [c]))
# outputs: plain gradient: [<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
# array([[2., 6.],
# [6., 2.]], dtype=float32)>]
较低的行为是我所期望的。
我如何理解@tf.function 案例?
非常感谢您!
(请注意,此问题不同于:,因为此处所有计算都在函数内部。)
渐变带不记录@tf.function
生成的tf.Graph内部的操作,将函数作为一个整体处理。粗略地说,f
应用于 a
,梯度磁带记录了 f
的输出相对于输入 a
的梯度(它是唯一观察的变量,tape.watched_variables()
).
第二种情况,没有生成图,采用Eager模式进行操作。所以一切都按预期工作。
一个好的做法是将计算量最大的函数包装在 @tf.function
(通常是训练循环)中。在你的情况下,它会像这样:
@tf.function
def f(a):
with tf.GradientTape() as tape:
c = a * 2
b = tf.reduce_sum(c ** 2 + 2 * c)
grads = tape.gradient([b], [c])
print('tf.function gradient: ', grads)
return grads
我对在以下示例中观察到的行为感到困惑:
import tensorflow as tf
@tf.function
def f(a):
c = a * 2
b = tf.reduce_sum(c ** 2 + 2 * c)
return b, c
def fplain(a):
c = a * 2
b = tf.reduce_sum(c ** 2 + 2 * c)
return b, c
a = tf.Variable([[0., 1.], [1., 0.]])
with tf.GradientTape() as tape:
b, c = f(a)
print('tf.function gradient: ', tape.gradient([b], [c]))
# outputs: tf.function gradient: [None]
with tf.GradientTape() as tape:
b, c = fplain(a)
print('plain gradient: ', tape.gradient([b], [c]))
# outputs: plain gradient: [<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
# array([[2., 6.],
# [6., 2.]], dtype=float32)>]
较低的行为是我所期望的。 我如何理解@tf.function 案例?
非常感谢您!
(请注意,此问题不同于:
渐变带不记录@tf.function
生成的tf.Graph内部的操作,将函数作为一个整体处理。粗略地说,f
应用于 a
,梯度磁带记录了 f
的输出相对于输入 a
的梯度(它是唯一观察的变量,tape.watched_variables()
).
第二种情况,没有生成图,采用Eager模式进行操作。所以一切都按预期工作。
一个好的做法是将计算量最大的函数包装在 @tf.function
(通常是训练循环)中。在你的情况下,它会像这样:
@tf.function
def f(a):
with tf.GradientTape() as tape:
c = a * 2
b = tf.reduce_sum(c ** 2 + 2 * c)
grads = tape.gradient([b], [c])
print('tf.function gradient: ', grads)
return grads