TF1 中的渐变到 TF2 中的 GradientTape
Posted
技术标签:
【中文标题】TF1 中的渐变到 TF2 中的 GradientTape【英文标题】:Gradient in TF1 to GradientTape in TF2 【发布时间】:2022-01-11 01:22:27 【问题描述】:我正在实现本书“使用python的深度学习”第05章中的示例。
我知道我可以通过 disable_eager_execution() 禁用 Eager,但这是我的第二选择。
这里是示例代码:
from tensorflow.keras.applications import VGG16
from tensorflow.keras import backend as K
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
def deprocess_image(x):
x -= x.mean()
x /= (x.std()+ 1e-5)
x *= 0.1
x += 0.5
x = np.clip(x, 0, 1)
x *= 255
x = np.clip(x, 0, 255).astype('uint8')
return x
def generate_pattern(layer_name, filter_index, size = 150):
layer_output = model.get_layer(layer_name).output
loss = K.mean(layer_output[:, :, :, filter_index])
grads = K.gradients(loss, model.input)[0] <------- here
grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
iterate = K.function([model.input], [loss, grads])
input_img_data = np.random.random((1, size, size, 3)) * 20 + 128.
step = 1.
for i in range(40):
loss_value, grads_value = iterate([input_img_data])
input_img_data += grads_value * step
img = input_img_data[0]
return deprocess_image(img)
def generate_pattern_grid(layer_name):
size = 64
margin = 5
results = np.zeros((8 * size + 7 * margin, 8 * size + 7 * margin, 3))
for i in range(8):
for j in range(8):
filter_img = generate_pattern(layer_name, i + (j * 8), size = size)
horizontal_start = i * size + i * margin
horizontal_end = horizontal_start + size
vertical_start = j * size + j * margin
vertical_end = vertical_start + size
results[horizontal_start : horizontal_end,
vertical_start : vertical_end, :] = filter_img
plt.figure(figsize = (20, 20))
plt.imshow(results.astype('uint8'))
model = VGG16(weights = "imagenet",
include_top=False)
layer_name = "block3_conv1"
generate_pattern_grid(layer_name)
这会给我
RuntimeError: tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.
我已经阅读了doc 并试试这个:
def generate_pattern(layer_name, filter_index, size = 150):
layer_output = model.get_layer(layer_name).output
loss = K.mean(layer_output[:, :, :, filter_index])
with tf.GradientTape() as tape:
loss = K.mean(layer_output[:, :, :, filter_index])
grads = tape.gradient(loss, model.input)
grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)
iterate = K.function([model.input], [loss, grads])
input_img_data = np.random.random((1, size, size, 3)) * 20 + 128.
step = 1.
for i in range(40):
loss_value, grads_value = iterate([input_img_data])
input_img_data += grads_value * step
img = input_img_data[0]
return deprocess_image(img)
但是得到了
AttributeError: 'KerasTensor' object has no attribute '_id'
有什么解决办法吗?
我想如果有任何方法可以将 kerasTensor 转换为 tfTensor,那么我可能会解决这个问题,但我找不到。
【问题讨论】:
这能回答你的问题吗? tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead @OmG 我已经读过,但我不知道如何在我的情况下实现它。 【参考方案1】:Tf.gradients
在 Tensorflow v2 中已弃用。正如错误消息所说,使用tf.GradientTape
代替 Tf.gradient。欲了解更多信息,请访问tf.GradientTape
对于 TensorFlow v1,禁用急切执行。
看看tf.GradientTape for Keras users。
【讨论】:
以上是关于TF1 中的渐变到 TF2 中的 GradientTape的主要内容,如果未能解决你的问题,请参考以下文章
TensorFlow 和 Keras 入门:过去 (TF1) 现在 (TF2)
Tf 2.0 : RuntimeError: GradientTape.gradient 只能在非持久性磁带上调用一次