为什么TensorFlow给我运行时错误(在标题中)?
我使用WinPython3.5.4.2并安装了TensorFlow 1.8.0。我一直在关注开始/急切的教程,直到题为“训练循环”的部分。
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-9-e08164fd8374> in <module>()
14 for x, y in train_dataset:
15 # Optimize the model
---> 16 grads = grad(model, x, y)
17 optimizer.apply_gradients(zip(grads, model.variables),
18 global_step=tf.train.get_or_create_global_step())
<ipython-input-7-08164b502799> in grad(model, inputs, targets)
6 with tf.GradientTape() as tape:
7 loss_value = loss(model, inputs, targets)
----> 8 return tape.gradient(loss_value, model.variables)
C:\[deleted]\WinPython3.5.4.2\python-3.5.4.amd64\lib\site-packages\tensorflow\python\eager\backprop.py in gradient(self, target, sources, output_gradients)
765 flat_grad = imperative_grad.imperative_grad(
766 _default_vspace, self._tape, [target], flat_sources,
--> 767 output_gradients=output_gradients)
768
769 if not self._persistent:
C:\[deleted]\WinPython3.5.4.2\python-3.5.4.amd64\lib\site-packages\tensorflow\python\eager\imperative_grad.py in imperative_grad(vspace, tape, target, sources, output_gradients)
61 """
62 return pywrap_tensorflow.TFE_Py_TapeGradient(
---> 63 tape._tape, vspace, target, sources, output_gradients) # pylint: disable=protected-access
RuntimeError: Trying to call tape.gradient on a non-persistent tape while it is still active.发布于 2018-05-09 08:54:32
在示例中,我怀疑您是在with tf.GradientTape()上下文中调用with tf.GradientTape(),而不是在外部调用。从以下方面转变:
with tf.GradientTape() as tape:
loss_value = loss(model, inputs, targets)
return tape.gradient(loss_value, model.variables)至
with tf.GradientTape() as tape:
loss_value = loss(model, inputs, targets)
# Notice the change in indentation of the line below
return tape.gradient(loss_value, model.variables)应该会导致错误消失。
在TensorFlow上下文中执行的GradientTape操作被“记录”,以便以后可以区分记录的计算。此记录需要内存(因为中间操作实现的张量必须保持存活)。在tape.gradient()上下文管理器中调用GradientTape意味着梯度计算也应该被记录下来,并且在梯度计算期间创建的张量需要保持存活。通常情况下,这不是用户想要的-- tape.gradient()调用只是在上下文管理器中意外地出现,导致内存占用超出了必要的范围。因此出现了错误。不过,可以说,错误消息字符串的措辞并不特别好(我相信在TensorFlow 1.8之后的版本中会得到改进)。
引用文档的话
默认情况下,
GradientTape所持有的资源在调用GradientTape.gradient()方法后立即释放。若要在同一计算过程中计算多个梯度,请创建一个persistent梯度磁带。这允许在垃圾收集磁带对象时释放资源时多次调用gradient()方法。
因此,如果您确实希望记录梯度计算(例如,计算二阶导数),那么您可以创建一个持久磁带,并将.gradient()调用保存在上下文管理器中。例如:
x = tfe.Variable(3.0)
with tf.GradientTape(persistent=True) as g:
y = x * x
dy = g.gradient(y, x)
d2y = g.gradient(dy, x)
print(dy)
print(d2y)在TensorFlow中,急切执行是一个相对较新的特性,对它的反馈是非常受欢迎的。如果您认为错误消息可能更好(可能是!)和/或缺省值应该更改(例如,默认情况下是持久化的,特别关注内存开销的用户可以显式地选择一个非持久磁带)-不要犹豫,提供关于GitHub的反馈。
希望这能帮上忙!
发布于 2020-07-01 18:05:04
我认为这是由于一个常见的误解,即python中的"with“子句会导致其中声明的对象在块末尾超出作用域。事实并非如此。它只会导致在该对象上执行__enter__和__exit__,这可能使其失效,也可能不会使其失效。在这种情况下,梯度磁带上的"with“子句简单地构造对象,给它一个变量名"g",并开始跟踪渐变。梯度磁带上的__exit__()停止跟踪,但不会使对象本身失效/清除。
https://stackoverflow.com/questions/50244706
复制相似问题