本文介绍了'tensorflow.python.framework.ops.EagerTensor' 对象没有属性 '_in_graph_mode'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过优化随机图像"来可视化 CNN 过滤器,以便它在该过滤器上产生高平均激活,这在某种程度上类似于神经风格转移算法.

I am trying to visualize CNN filters by optimizing a random 'image' so that it produces a high mean activation on that filter which is somehow similar to the neural style transfer algorithm.

为此,我使用 TensorFlow==2.2.0-rc.但是在优化过程中,出现了一个错误,说'tensorflow.python.framework.ops.EagerTensor' object has no attribute '_in_graph_mode'.我尝试调试它,当我不使用 opt.apply_gradients() 时它以某种方式工作,而是像 img = img - lr * grads 一样手动应用它的渐变但是我想使用Adam"优化器而不是简单的 SGD.

For that purpose, I am using TensorFlow==2.2.0-rc. But during the optimization process, an error occurs saying 'tensorflow.python.framework.ops.EagerTensor' object has no attribute '_in_graph_mode'. I tried debugging it and it somehow works when I don't use the opt.apply_gradients() and instead, apply its gradient manually like img = img - lr * grads but I want to use the "Adam" optimizer rather than the simple SGD.

这是我的优化部分代码

opt = tf.optimizers.Adam(learning_rate=lr, decay = 1e-6)
for _ in range(epoch):
    with tf.GradientTape() as tape:
        tape.watch(img)
        y = model(img)[:, :, :, filter]
        loss = -tf.math.reduce_mean(y)
        grads = tape.gradient(loss, img)
        opt.apply_gradients(zip([grads], [img]))

推荐答案

该错误的原因是 tf.keras 优化器将渐变应用于变量对象(类型为 tf.Variable),而您尝试将渐变应用于张量(类型为 tf.Tensor).Tensor 对象在 TensorFlow 中不可变,因此优化器无法对其应用梯度.

The reason for the bug is that the tf.keras optimizers apply gradients to variable objects (of type tf.Variable), while you are trying to apply gradients to tensors (of type tf.Tensor). Tensor objects are not mutable in TensorFlow, thus the optimizer cannot apply gradients to it.

您应该将变量 img 初始化为 tf.Variable.您的代码应该是这样的:

You should initialize the variable img as a tf.Variable. This is how your code should be:

# NOTE: The original image is lost here. If this is not desired, then you can
# rename the variable to something like img_var.
img = tf.Variable(img)
opt = tf.optimizers.Adam(learning_rate=lr, decay = 1e-6)

for _ in range(epoch):
    with tf.GradientTape() as tape:
        tape.watch(img)
        y = model(img.value())[:, :, :, filter]
        loss = -tf.math.reduce_mean(y)

    grads = tape.gradient(loss, img)
    opt.apply_gradients(zip([grads], [img]))

此外,建议计算磁带上下文之外的梯度.这是因为保留它会导致磁带跟踪梯度计算本身,从而导致更高的内存使用量.这仅在您想计算高阶梯度时才可取.因为你不需要这些,我把它们放在外面.

Also, it is recommended to calculate the gradients outside the tape's context. This is because keeping it in will lead to the tape tracking the gradient calculation itself, leading to higher memory usage. This is only desirable if you want to calculate higher-order gradients. Since you don't need those, I have kept them outside.

注意我已将 y = model(img)[:, :, :, filter] 行更改为 y = model(img.value())[:, :,:, 过滤器].这是因为 tf.keras 模型需要张量作为输入,而不是变量(错误或特征?).

Note I have changed the line y = model(img)[:, :, :, filter] to y = model(img.value())[:, :, :, filter]. This is because tf.keras models need tensors as input, not variables (bug, or feature?).

这篇关于'tensorflow.python.framework.ops.EagerTensor' 对象没有属性 '_in_graph_mode'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 05:09