2016-09-18 1 views
11

Мне интересно создавать модели обучения подкрепления с простотой API Keras. К сожалению, я не могу извлечь градиент вывода (а не ошибку) относительно весов. Я нашел следующий код, который выполняет аналогичную функцию (Saliency maps of neural networks (using Keras))Получение градиента выходных данных модели w.r.t с использованием 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]) 

Любые идеи о том, как вычислить градиент выходных данных модели относительно весов для каждого слоя будут оценены.

+0

У вас был какой-то прогресс? Я получаю следующую ошибку, используя аналогичную функцию выделения: https://github.com/fchollet/keras/issues/1777#issuecomment-250040309 – ssierral

+0

У меня не было никакого успеха с Keras. Тем не менее, я смог сделать это с помощью тензорного потока. –

+0

https://github.com/yanpanlau/DDPG-Keras-Torcs CriticNetwork.py использует бэкэнден для вычисления градиентов при использовании Keras для фактического построения сетевой архитектуры –

ответ

14

Чтобы получить градиенты вывода модели относительно весов с помощью Keras, вам необходимо использовать модуль Keras backend. Я создал этот простой пример, чтобы проиллюстрировать, что делать:

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

Для расчета градиентов сначала нужно найти тензор выходной. Для вывода модели (что задал мой начальный вопрос) мы просто вызываем model.output. Мы также можем найти градиенты выходов для других слоев с помощью вызова model.layers [индекс] .output

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

Затем нам нужно выбрать переменные, которые по отношению к градиенту.

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

Теперь мы можем рассчитать градиенты. Это так же просто, как:

gradients = k.gradients(outputTensor, listOfVariableTensors) 

Чтобы реально работать градиенты, данные вход, мы должны использовать немного 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}) 

И вот оно!

+2

Я запустил этот код (с помощью anano как backend) и возникает следующая ошибка: «TypeError: стоимость должна быть скаляром». Интересно, может ли это быть достигнуто с помощью бэкендно-агностического подхода? –

+0

Matt S, как градиенты вычисляются без указания меток в sess.run? –

+0

Я принимаю градиентный вход w.r.t. Если вы хотите получить градиентную потерю w.r.t, вам необходимо определить функцию потерь, замените outputTensor на k.gradients на loss_fn, а затем передайте метки в dict dict. –

Смежные вопросы