2016-09-18 31 views
11

Tôi rất thú vị trong việc xây dựng các mô hình học tăng cường với sự đơn giản của API Keras. Thật không may, tôi không thể trích xuất độ dốc của đầu ra (không phải lỗi) đối với trọng số. Tôi thấy đoạn mã sau đó thực hiện một chức năng tương tự (Saliency maps of neural networks (using Keras))Lấy gradient của khối lượng đầu ra của mô hình bằng cách sử dụng 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]) 

Bất kỳ ý tưởng về làm thế nào để tính toán độ chênh lệch của đầu ra mô hình liên quan đến trọng lượng cho mỗi lớp có sẽ được đánh giá.

+0

Bạn đã có ứng trước chưa? Tôi nhận được lỗi sau bằng cách sử dụng một chức năng tương tự như saliency: https://github.com/fchollet/keras/issues/1777#issuecomment-250040309 – ssierral

+0

Tôi đã không có bất kỳ thành công với Keras. Tuy nhiên, tôi đã có thể làm điều này bằng cách sử dụng tensorflow. –

+0

https://github.com/yanpanlau/DDPG-Keras-Torcs CriticNetwork.py sử dụng phụ trợ tensorflow để tính toán độ dốc khi sử dụng Keras để thực sự xây dựng kiến ​​trúc mạng –

Trả lời

14

Để có được độ dốc của đầu ra mô hình đối với trọng số sử dụng Keras, bạn phải sử dụng mô-đun phụ trợ Keras. Tôi đã tạo ví dụ đơn giản này để minh họa chính xác những việc cần làm:

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

Để tính toán độ dốc, trước tiên chúng ta cần tìm bộ tạo đầu ra. Đối với đầu ra của mô hình (câu hỏi ban đầu của tôi được hỏi), chúng ta chỉ cần gọi model.output. Chúng tôi cũng có thể tìm thấy các độ dốc của các đầu ra cho các lớp khác bằng cách gọi model.layers [index] .output

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

Sau đó chúng ta cần chọn các biến liên quan đến gradient.

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

Bây giờ chúng tôi có thể tính toán độ dốc. Nó dễ dàng như sau:

gradients = k.gradients(outputTensor, listOfVariableTensors) 

Để thực sự chạy gradient cho đầu vào, chúng ta cần sử dụng một chút 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}) 

Và thats it!

+2

Tôi đã chạy mã này (với theano làm phụ trợ) và lỗi sau được nêu lên: "TypeError: chi phí phải là một vô hướng". Tôi tự hỏi, điều này có thể đạt được bằng cách tiếp cận phụ trợ thuyết phục không? –

+0

Matt S, làm thế nào để các gradient được tính toán mà không chỉ định các nhãn trong sess.run? –

+0

Tôi đang dùng đầu vào gradient w.r.t. Nếu bạn muốn giảm độ lệch w.r.t thì bạn cần phải xác định hàm mất, thay thế outputTensor trong k.gradients bằng loss_fn và sau đó chuyển các nhãn tới dict feed. –

Các vấn đề liên quan