Как заменить функцию градиента () Keras на GradientTape в TF2.0? - PullRequest
0 голосов
/ 07 октября 2019

Используя «старую» библиотеку Keras, я создавал тепловые карты для своих CNN с помощью функции keras.backend.gradients(), например:

# load model and image, then predict the class this image belongs to
model = load_model(os.path.join(model_folder, "custom_model.h5"))
image = image.load_img(image_path)
img_tensor = image.img_to_array(image)
img_tensor = np.expand_dims(img_tensor, axis=0)
img_tensor = preprocess_input(img_tensor)

preds = model.predict(img_tensor)
model_prediction = model.output[:, np.argmax(preds[0])]

# Calculate pooled grads for heatmap
conv_layer = model.get_layer("block5_conv3")  # last conv. layer
grads = K.gradients(model_prediction, conv_layer.output)[0]
pooled_grads = K.mean(grads, axis=(0, 1, 2))

# Get values of pooled grads and model conv. layer output as Numpy arrays
input_layer = model.get_layer("model_input")
iterate = K.function([input_layer], [pooled_grads, conv_layer.output[0]])
pooled_grads_value, conv_layer_output_value = iterate([img_tensor])

# Continue with heatmap generation ...

Теперь я переключился на TF2.0 и его встроенную реализацию Keras. Все работает нормально, однако, используя этот код, я получаю следующую ошибку при вызове K.gradients():

tf.gradients is not supported when eager execution is enabled. Use tf.GradientTape instead.

Я провел некоторое исследование и попытался понять, как я могу использовать GradientTape, но, к сожалению, яне знаю много ни о TF, ни о TF2.0 - я всегда работал с Keras. Ребята, не могли бы вы подсказать мне, как я могу снова выполнить этот расчет градиента с моей установкой?

1 Ответ

1 голос
/ 09 октября 2019

Вот решение вашей проблемы. Это подразумевает создание модели, которая выводит как conv_output, так и прогнозы, поэтому мы можем правильно применить GradientTape.

Не было вашей модели / данных, поэтому я взял ResNet50 и случайные значения.

import numpy as np
import tensorflow as tf

model = tf.keras.applications.resnet50.ResNet50()
img_tensor = np.random.random((1, 224, 224, 3))

conv_layer = model.get_layer('conv5_block3_1_conv')

heatmap_model = tf.keras.models.Model(
    [model.inputs], [model.get_layer('conv5_block3_1_conv').output, model.output]
)

with tf.GradientTape() as tape:
    conv_output, predictions = heatmap_model(img_tensor)
    loss = predictions[:, np.argmax(predictions[0])]

grads = tape.gradient(loss, conv_output)
...