为什么TensorFlow给我运行时错误(标题中)?
我正在使用WinPython3.5.4.2并已安装TensorFlow 1.8.0。我一直在遵循https://www.tensorflow.org/get_started/eager上的教程,直到标题为“训练循环”的部分。
---------------------------------------------------------------------------
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.
最佳答案
我怀疑您的示例中您是在tape.gradient()
上下文中而不是外部调用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)
应该会导致错误消失。
在
GradientTape
上下文中执行的TensorFlow操作被“记录”,以便以后可以区分记录的计算。此记录会消耗内存(因为必须保留通过中间操作实现的张量)。在tape.gradient()
上下文管理器中调用GradientTape
意味着应该也记录梯度计算,并且需要保持在梯度计算过程中创建的张量。通常这不是用户想要的-tape.gradient()
调用只是偶然地在上下文管理器内部,从而导致不必要的内存占用。因此,错误。不过,可以说错误消息字符串的措辞不是特别好(我相信在TensorFlow 1.8之后的版本中会有所改善)。从documentation引用
默认情况下,一旦调用
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中的一个相对较新的功能,对此的反馈非常受欢迎。如果您认为错误消息可能更好(可能是!)和/或应更改默认消息(例如,默认情况下为永久性,并且特别关注内存开销的用户可以明确选择非永久性磁带)-请不要通过提供feedback on GitHub可以随时输入提示音
希望有帮助!