вычислить градиенты для GradCam в TF 2.0 - PullRequest
0 голосов
/ 06 февраля 2020

Я обновил свой тензор потока в Python с 1.14 до 2.0. Теперь у меня есть проблема с градиентными вычислениями, чтобы увидеть визуализацию GradCam для слоя.

Например, с моделью my_cnn_model, которая уже установлена ​​на данных, для задачи классификации с тремя классами. Если я хочу, например, «вычислить gradCam» для заданного слоя с именем «conv2d_3», я бы начал со следующего в 1.14:

layer_conv = my_cnn_model.get_layer( "conv2d_3" )

#I want it with respect to the first class (so 0), because for example it might have been the model prediction for that image, so I check the proba for that class :
final_layer = my_cnn_model.output[:, 0]

#Then I computed the gradients like that :
grads = keras.backend.gradients( final_layer, layer_conv.output )[0]
print(grads)

Последнее выражение (print) скажет (форма Speci c для CNN, который я использовал, но не имеет значения):

Tensor("gradients/max_pooling2d/MaxPool_grad/MaxPoolGrad:0", shape=(?, 76, 76, 64), dtype=float32)

Теперь, когда я использую TF 2.0: часть вычисления Grads, так что:

grads = keras.backend.gradients( final_layer, layer_conv.output )[0]

не работает какой-либо более того, с ошибкой:

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

Я уже искал и находил такие вещи, как

with tf.GradientTape() as tape:
...

Но все равно я получаю ошибки, или я не могу получить тот же вывод Tensor("gradients/max_pooling2d/MaxPool_grad/MaxPoolGrad:0", shape=(?, 76, 76, 64), dtype=float32), так что остальная часть моей функции gradcam не работает.

Как я могу вычислить grads, что, конечно, было бы похоже на мой env 1.14 tf? Я пропускаю что-то тривиальное?

Редактировать: я использовал функциональный API, со своим собственным CNN или с моделью «Transfer Learning», уже здесь, в tf.keras, с измененными / добавленными слоями вверху.

Спасибо за любую помощь.

1 Ответ

1 голос
/ 06 февраля 2020

Если вас не интересует активный режим, например использование старого кода, вы можете просто отключить активное выполнение.

Как уже упоминалось здесь :

import tensorflow as tf
tf.compat.v1.disable_eager_execution()

Если, с другой стороны, вы хотите оставить включенный режим, если другая вещь беспокоит ваш код, вы можно вместо:

#you need a persistent tape if you're calling many gradients instead of just one
with tf.GradientTape(persistent = True) as tape:

    #must "watch" all variables that are not "trainable weights" 
    #if you are using them for gradients
    tape.watch(layer_conv.output)

    #if the input data should be watched (you're getting the gradients related to the inputs)
    input_tensor = tf.constant(input_data)
    tape.watch(input_tensor)

    #must do the entire prediction inside this tape block.
    #it would be better if you could make your model output all tensors of interest
    #not sure if you can do "some_layer.output" in eager mode for this purpose
    model_outputs = model(input_tensor) 

#finally, outside the block you can get the gradients
g1 = tape.gradient(model_outputs, layer_conv.output) 
    #again, maybe you need this layer output to be "actually output" 
    #instead of gotten from the layer like this

g2 = tape.gradient(some_output, input_tensor)

g3...
g4...

#finally delete the persistent tape
del tape
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...