特遣部队.在编写自定义训练循环时,GradientTape给出None梯度 &g



我想写一个自定义的训练循环。这里是我想做的一个示例代码。我有两个训练参数其中一个参数更新另一个参数。请看下面的代码:

x1 = tf.Variable(1.0, dtype=float)
x2 = tf.Variable(1.0, dtype=float)
with tf.GradientTape() as tape:
n = x2 + 4
x1.assign(n)
x = x1 + 1
y = x**2
val = tape.gradient(y, [x1, x2])
for v in val:
print(v)

,输出为

tf.Tensor(12.0, shape=(), dtype=float32)
None

看起来好像GradientTape没有监视第一个(x2)参数。这两个参数都是tf.Variable类型,因此GradientTape应该监视这两个参数。我也试过tape.watch(x2),这也不工作。我错过什么了吗?

查看None渐变的文档。要获得x1的梯度,您必须使用tape.watch(x):

跟踪x
x1 = tf.Variable(1.0, dtype=float)
x2 = tf.Variable(1.0, dtype=float)
with tf.GradientTape() as tape:
n = x2 + 4
x1.assign(n)
x = x1 + 1
tape.watch(x)
y = x**2
dv0, dv1 = tape.gradient(y, [x1, x2])
print(dv0)
print(dv1)

然而,对于x2,输出y根本没有连接到x2,因为x1.assign(n)似乎没有被跟踪,这就是梯度为None的原因。这与docs:

一致。

状态停止梯度。当从有状态对象中读取数据时,磁带只能观察当前状态,而不能观察导致当前状态的历史。

特遣部队。张量是不可变的。张量一旦被创建,你就不能改变它。它有值,但没有状态。到目前为止讨论的所有操作都是也是无状态的:tf的输出。Matmul只依赖于它的输入。

特遣部队。变量具有内部状态——它的值。当你使用这个变量时,状态被读取。计算关于的梯度是很正常的一个变量,但是变量的状态阻止梯度计算再往前看

例如,如果您这样做:

x1 = tf.Variable(1.0, dtype=float)
x2 = tf.Variable(1.0, dtype=float)
with tf.GradientTape() as tape:
n = x2 + 4
x1 = n
x = x1 + 1
tape.watch(x)
y = x**2 
dv0, dv1 = tape.gradient(y, [x1, x2])

应该可以。

相关内容

  • 没有找到相关文章

最新更新