为什么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可以随时输入提示音

希望有帮助!

09-11 17:52
查看更多