web-dev-qa-db-fra.com

K.gradients (loss, input_img) [0] renvoie "Aucun". (Visualisation Keras CNN avec backend tensorflow)

J'ai des modèles CNN formés à l'aide de Keras avec le backend Tensorflow. Et je veux visualiser mes filtres CNN avec ce tutoriel: https://blog.keras.io/how-convolutional-neural-networks-see-the-world.html

from keras import backend as K
from keras.models import load_model
import numpy as np

model = load_model('my_cnn_model.h5')
input_img = np.load('my_picture.npy')

# get the symbolic outputs of each "key" layer (we gave them unique names).
layer_dict = dict([(layer.name, layer) for layer in model.layers])

layer_name = 'block5_conv3'
filter_index = 0  # can be any integer from 0 to 511, as there are 512 filters in that layer

# build a loss function that maximizes the activation
# of the nth filter of the layer considered
layer_output = layer_dict[layer_name].output
loss = K.mean(layer_output[:, :, :, filter_index])

# compute the gradient of the input picture wrt this loss
grads = K.gradients(loss, input_img)[0]

# normalization trick: we normalize the gradient
grads /= (K.sqrt(K.mean(K.square(grads))) + 1e-5)

# this function returns the loss and grads given the input picture
iterate = K.function([input_img], [loss, grads])

Cependant, lorsque le code s'exécute sur cette ligne:
grads = K.gradients(loss, input_img)[0]
J'ai trouvé qu'il ne renvoie rien d'autre que l'objet None, donc le programme ne progresse pas après cela.

Je cherche une solution. Certaines personnes disent que input_img Devrait être le type Tenseur de tensorflow: https://github.com/keras-team/keras/issues/5455

Mais quand j'ai essayé de convertir l'img en Tensor, le problème existe toujours.
J'ai essayé la solution dans le lien ci-dessus, mais échoue toujours.

Il y a aussi quelqu'un qui dit que ce problème existe parce que votre modèle CNN n'est pas différenciable. https://github.com/keras-team/keras/issues/8478

Mais mon modèle utilise uniquement la fonction d'activation de ReLU et Sigmoid (au niveau de la couche de sortie). Ce problème est-il vraiment causé par un problème non différenciable?

Quelqu'un peut-il m'aider? Merci beaucoup!

10
Jexus

Si vous avez une instance de modèle, pour prendre le gradient de la perte par rapport à l'entrée, vous devez faire:

grads = K.gradients(loss, model.input)[0]

model.input contient le tenseur symbolique qui représente l'entrée du modèle. L'utilisation d'un tableau numpy simple n'a aucun sens car TensorFlow n'a alors aucune idée de la façon dont cela se connecte au graphe de calcul et renvoie None comme gradient.

Ensuite, vous devez également réécrire la fonction iterate comme suit:

iterate = K.function([model.input], [loss, grads])
11
Matias Valdenegro

Ci-dessous, c'est mon exemple. J'espère aider quelqu'un.

gradient = keras.backend.gradients(model.output, model.input)[2]

iterate = keras.backend.function(model.input, [gradient])

grad = iterate([patches, depthes, poses])

[patchs, profondeurs, poses] est mon modèle.

2
Fangjing Song