2016-09-18 20 views
11

Jestem interesujący w budowaniu modeli uczenia się wzmacniania z prostotą API Keras. Niestety, nie jestem w stanie wyodrębnić gradientu wyniku (nie błędu) w odniesieniu do wag. I znaleziono następujące kod pełni podobną funkcję (Saliency maps of neural networks (using Keras))Uzyskiwanie gradientu danych wyjściowych modelu w.r.t przy użyciu 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]) 

pomysłów, jak obliczyć nachylenie wyjściu modelu względem wagi dla każdej warstwy będzie docenione.

+0

Czy masz jakieś zaliczki? Otrzymuję następujący błąd za pomocą podobnej funkcji istotności: https://github.com/fchollet/keras/issues/1777#issuecomment250040309 – ssierral

+0

Nie miałem żadnego sukcesu z Keras. Jednak udało mi się to zrobić za pomocą tensorflow. –

+0

https://github.com/yanpanlau/DDPG-Keras-Torcs CriticNetwork.py używa backendu tensorflow do obliczenia gradientów podczas korzystania z Keras do budowania architektury sieciowej –

Odpowiedz

14

Aby uzyskać gradienty danych wyjściowych modelu w odniesieniu do wag za pomocą Keras, należy użyć modułu backend Keras. Stworzyłem ten prosty przykład, aby zilustrować dokładnie, co należy zrobić:

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']) 

Aby obliczyć gradienty, najpierw musimy znaleźć tensor wyjściowy. Dla wyjścia modelu (jakie było moje pierwsze pytanie) po prostu wywołujemy model.output. Możemy również znaleźć gradienty wyjść do innych warstw przez model.layers zawijających [Index] .output

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

Następnie musimy wybrać zmienne, które są w stosunku do gradientu.

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

Możemy teraz obliczyć gradienty. To jest tak proste, jak następuje:

gradients = k.gradients(outputTensor, listOfVariableTensors) 

Aby rzeczywiście uruchomić gradienty podane wejście, musimy użyć trochę Tensorflow.

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}) 

I to wszystko!

+2

Uruchomiłem ten kod (z theano jako backendem) i zgłaszany jest następujący błąd: "TypeError: cost musi być skalarem.". Zastanawiam się, czy można to osiągnąć za pomocą agnostycznego podejścia? –

+0

Matt S, w jaki sposób gradienty są obliczane bez określania etykiet w sess.run? –

+0

Biorę wejście gradientowe w.r.t. Jeśli chcesz utratę gradientu w.r.t, musisz zdefiniować funkcję utraty, zastąp parametr outputTensor w k.gradients parametrem loss_fn, a następnie przekaż etykiety do pliku danych. –