web-dev-qa-db-fra.com

Dans TensorFlow 2.0 avec une exécution rapide, comment calculer les gradients d'une sortie réseau par rapport à une couche spécifique?

J'ai un réseau créé avec InceptionNet, et pour un échantillon d'entrée bx, je veux calculer les gradients de la sortie du modèle w.r.t. la couche cachée. J'ai le code suivant:

bx = tf.reshape(x_batch[0, :, :, :], (1, 299, 299, 3))


with tf.GradientTape() as gtape:
    #gtape.watch(x)
    preds = model(bx)
    print(preds.shape, end='  ')

    class_idx = np.argmax(preds[0])
    print(class_idx, end='   ')

    class_output = model.output[:, class_idx]
    print(class_output, end='   ')

    last_conv_layer = model.get_layer('inception_v3').get_layer('mixed10')
    #gtape.watch(last_conv_layer)
    print(last_conv_layer)


grads = gtape.gradient(class_output, last_conv_layer.output)#[0]
print(grads)

Mais cela donnera None. J'ai également essayé gtape.watch(bx), mais cela donne toujours None.

Avant d'essayer GradientTape, j'ai essayé d'utiliser tf.keras.backend.gradient Mais cela a donné une erreur comme suit:

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

Mon modèle est le suivant:

model.summary()

Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
inception_v3 (Model)         (None, 1000)              23851784  
_________________________________________________________________
dense_5 (Dense)              (None, 2)                 2002      
=================================================================
Total params: 23,853,786
Trainable params: 23,819,354
Non-trainable params: 34,432
_________________________________________________________________

Toute solution est appréciée. Il ne doit pas nécessairement s'agir de GradientTape, s'il existe un autre moyen de calculer ces dégradés.

5
Vahid Mirjalili

Si vous avez besoin des gradients des prédictions par rapport aux sorties de toutes les couches, vous pouvez faire:

(S'appuyant sur @nessuno réponse )

import tensorflow as tf

model = tf.keras.models.Sequential(
    [
        tf.keras.layers.Dense(10, input_shape=(3,), name="fc1", activation="relu"),
        tf.keras.layers.Dense(3, input_shape=(3,), name="fc2"),
    ]
)

# build a new model
output_layer = model.outputs
all_layers = [layer.output for layer in model.layers]
grad_model = tf.keras.model(inputs=model.inputs, outputs=all_layers)

inputs = tf.ones((1, 299, 299, 3))
with tf.GradientTape() as tape:
    output_of_all_layers = grad_model(inputs)
    preds = output_layer[-1]  # last layer is output layer
    # take gradients of last layer with respect to all layers in the model
    grads = tape.gradient(preds, output_of_all_layers)
    # note: grads[-1] should be all 1, since it it d(output)/d(output)
print(grads)
0
Ali Salehi