2016-05-01 2 views
9

J'ai un perceptron multicouche entièrement connecté et formé à Keras. Je lui donne un vecteur de caractéristiques N-dimensionnelles et il prédit une classe parmi M pour le vecteur d'entrée. L'entraînement et la prédiction fonctionnent bien. Maintenant, je veux analyser quelle partie du vecteur de caractéristiques en entrée est réellement responsable d'une classe particulière. Par exemple, disons qu'il existe deux classes A et B, et un vecteur d'entrée f. Le vecteur f appartient à la classe A et le réseau le prédit correctement - la sortie du réseau est A=1 B=0. Parce que j'ai une certaine connaissance du domaine, je sais que l'ensemble f n'est en fait pas responsable de f appartenant à A, seulement une certaine partie à l'intérieur f est responsable de cela. Je veux savoir si le réseau de neurones a capturé cela. Dessiner une correspondance à des images, si une image I a un cat dedans (avec un fond herbeux) et un réseau formé prédit cela correctement, alors le réseau doit savoir que l'image entière n'est pas cat; le réseau connaît en interne l'emplacement du cat dans l'image. De même, dans mon cas, le réseau sait quelle partie de f fait appartenir à la classe A. Je veux savoir quelle partie c'est. Je recherche autour de, et crois que ce que je veux faire s'appelle trouver des cartes de saillance pour mon réseau, pour une entrée donnée. Est-ce exact?
Si je l'ai bien compris, les cartes de saillance sont simplement (change in output)/(change in input), et peuvent être trouvées par une seule opération de rétropropagation où je trouve la dérivée de sortie par rapport à l'entrée.
Je trouve l'extrait de code suivant pour ce faire dans Keras, mais je ne suis pas vraiment sûr si elle est correcte:Cartes de saillance des réseaux de neurones (en utilisant Keras)

inp = model.layers[0].get_input() 
    outp = model.layers[-1].get_output() 
    max_outp = T.max(outp, axis=1) 
    saliency = theano.grad(max_outp.sum(), wrt=inp) 

Dans le code ci-dessus, lors du calcul du gradient, est le rétropropagation qui se passe réellement? La sortie est une fonction non linéaire de l'entrée, donc la seule façon de trouver le dégradé est de faire backprop. Mais dans le code ci-dessus, il n'y a rien à connecter theano et le réseau, comment est-ce que "le réseau" est "conscient" du réseau ici? Pour autant que je sache, lors du calcul des gradients avec Theano, nous définissons d'abord la fonction en termes d'entrée et de sortie. Il faut donc que cette fonction non-linéaire soit connue. Je ne pense pas que cela soit vrai dans l'extrait ci-dessus ..

Mise à jour: Le code ci-dessus ne fonctionne pas parce que j'ai un MLP entièrement connecté. Il donne une erreur en disant "Objet dense n'a pas get_output()". J'ai la fonction Keras suivante, qui calcule la sortie de l'entrée donnée par le réseau. Je veux trouver maintenant gradient de cette fonction par rapport'a l'entrée:

get_output = K.function([self.model.layers[0].input],[self.model.layers[-1].output]) 
+0

Quelle version de Keras utilisez-vous? –

Répondre

7

J'ai trouvé la solution:

get_output = theano.function([model.layers[0].input],model.layers[-1].output,allow_input_downcast=True) 
    fx = theano.function([model.layers[0].input] ,T.jacobian(model.layers[-1].output.flatten(),model.layers[0].input), allow_input_downcast=True) 
    grad = fx([input_feature])