2016-09-18 2 views
11

Ich bin interessant beim Aufbau von Verstärkung Lernmodelle mit der Einfachheit der Keras API. Leider kann ich den Gradienten der Ausgabe (kein Fehler) in Bezug auf die Gewichte nicht extrahieren. Ich fand den folgenden Code, der eine ähnliche Funktion (Saliency maps of neural networks (using Keras))Get Gradienten der Modellausgabe w.r.t Gewichte mit Keras

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([trainingData]) 

Alle Ideen, wie führt für jede Schicht würde geschätzt werden, um die Steigung der Modellausgabe in Bezug auf die Gewichte zu berechnen.

+0

Hatten Sie einen Vorschuss? Ich bekomme den folgenden Fehler mit einer ähnlichen Ausprägung Funktion: https://github.com/fchollet/keras/issues/1777#issuecomment-250040309 – ssierral

+0

Ich hatte keinen Erfolg mit Keras. Dies ist mir jedoch mit Tensorflow gelungen. –

+0

https://github.com/yanpanlau/DDPG-Keras-Torcs CriticNetwork.py verwendet das Tensorflow-Backend, um Gradienten zu berechnen, während Keras verwendet wird, um tatsächlich die Netzarchitektur zu erstellen –

Antwort

14

Um die Gradienten der Modellausgabe in Bezug auf Gewichte mit Keras zu erhalten, müssen Sie das Keras-Backend-Modul verwenden. Ich habe dieses einfaches Beispiel genau zu zeigen, was zu tun ist:

from keras.models import Sequential 
from keras.layers import Dense, Activation 
from keras import backend as k 


model = Sequential() 
model.add(Dense(12, input_dim=8, init='uniform', activation='relu')) 
model.add(Dense(8, init='uniform', activation='relu')) 
model.add(Dense(1, init='uniform', activation='sigmoid')) 
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) 

Um die Steigungen zu berechnen wir zunächst den Ausgang Tensor finden müssen. Für die Ausgabe des Modells (was meine ursprüngliche Frage war) nennen wir einfach model.output. Wir können auch die Steigungen der Ausgänge für andere Schichten durch den Aufruf model.layers [index] finden .output

outputTensor = model.output #Or model.layers[index].output 

Dann müssen wir die Variablen auswählen, die in Bezug auf den Gradienten sind.

listOfVariableTensors = model.trainable_weights 
    #or variableTensors = model.trainable_weights[0] 

Wir können jetzt die Gradienten berechnen. Es ist so einfach wie die folgenden:

gradients = k.gradients(outputTensor, listOfVariableTensors) 

Um tatsächlich die Gradienten führen einen Eingang gegeben, brauchen wir ein bisschen Tensorflow verwenden.

trainingExample = np.random.random((1,8)) 
sess = tf.InteractiveSession() 
sess.run(tf.initialize_all_variables()) 
evaluated_gradients = sess.run(gradients,feed_dict={model.input:trainingExample}) 

Und das ist es!

+2

Ich habe diesen Code ausgeführt (mit Theano als Backend) und der folgende Fehler wird ausgelöst: "TypeError: Kosten müssen ein Skalar sein.". Ich frage mich, ob dies mit einem Backend-Agnostic-Ansatz erreicht werden kann? –

+0

Matt S, wie werden die Gradienten berechnet, ohne die Beschriftungen in sess.run anzugeben? –

+0

Ich nehme Gradient w.r.t Eingang. Wenn Sie den Gradient w.r.t verlust wollen, dann müssen Sie die Verlustfunktion definieren, outputTensor in k.gradients durch loss_fn ersetzen und dann die Labels an das feed dict übergeben. –

Verwandte Themen