首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图在非持久性磁带上调用tape.gradient时,它仍然处于活动状态。

试图在非持久性磁带上调用tape.gradient时,它仍然处于活动状态。
EN

Stack Overflow用户
提问于 2018-05-09 02:33:13
回答 2查看 5.9K关注 0票数 4

为什么TensorFlow给我运行时错误(在标题中)?

我使用WinPython3.5.4.2并安装了TensorFlow 1.8.0。我一直在关注开始/急切的教程,直到题为“训练循环”的部分。

代码语言:javascript
复制
---------------------------------------------------------------------------
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.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-09 08:54:32

在示例中,我怀疑您是在with tf.GradientTape()上下文中调用with tf.GradientTape(),而不是在外部调用。从以下方面转变:

代码语言:javascript
复制
with tf.GradientTape() as tape:
  loss_value = loss(model, inputs, targets)
  return tape.gradient(loss_value, model.variables)

代码语言:javascript
复制
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()调用保存在上下文管理器中。例如:

代码语言:javascript
复制
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的反馈

希望这能帮上忙!

票数 11
EN

Stack Overflow用户

发布于 2020-07-01 18:05:04

我认为这是由于一个常见的误解,即python中的"with“子句会导致其中声明的对象在块末尾超出作用域。事实并非如此。它只会导致在该对象上执行__enter____exit__,这可能使其失效,也可能不会使其失效。在这种情况下,梯度磁带上的"with“子句简单地构造对象,给它一个变量名"g",并开始跟踪渐变。梯度磁带上的__exit__()停止跟踪,但不会使对象本身失效/清除。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50244706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档