我试图通过优化随机“图像”来可视化 CNN 过滤器,以便它在该过滤器上产生高平均激活,这在某种程度上类似于神经风格转移算法。
为此,我使用 TensorFlow==2.2.0-rc。但是在优化过程中,出现错误提示'tensorflow.python.framework.ops.EagerTensor' object has no attribute '_in_graph_mode'
。我尝试调试它,当我不使用它时,它以某种方式起作用opt.apply_gradients()
,而是手动应用它的梯度,就像img = img - lr * grads
但我想使用“亚当”优化器而不是简单的 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]))
Run Code Online (Sandbox Code Playgroud)
该错误的原因是 tf.keras 优化器将梯度应用于变量对象(tf.Variable 类型),而您尝试将梯度应用于张量(tf.Tensor 类型)。张量对象在 TensorFlow 中是不可变的,因此优化器无法对其应用梯度。
您应该将该变量初始化img
为 tf.Variable。您的代码应该是这样的:
# 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]))
Run Code Online (Sandbox Code Playgroud)
另外,建议在磁带上下文之外计算梯度。这是因为保留它会导致磁带跟踪梯度计算本身,从而导致更高的内存使用量。仅当您想计算高阶梯度时才需要这样做。既然你不需要那些,我就把它们放在外面了。
请注意,我已将该行更改y = model(img)[:, :, :, filter]
为y = model(img.value())[:, :, :, filter]
. 这是因为 tf.keras 模型需要张量作为输入,而不是变量(错误或功能?)。
归档时间: |
|
查看次数: |
24576 次 |
最近记录: |