我正在尝试调试keras已建立的模型。似乎我的梯度正在爆炸,或者被0除以此类推。当它们通过网络反向传播时,能够检查各种梯度会很方便。如下所示是理想的:
keras
model.evaluate(np.array([[1,2]]), np.array([[1]])) #gives the loss model.evaluate_gradient(np.array([[1,2]]), np.array([[1]]), layer=2) #gives the doutput/dloss at layer 2 for the given input model.evaluate_weight_gradient(np.array([[1,2]]), np.array([[1]]), layer=2) #gives the dweight/dloss at layer 2 for the given input
您需要创建一个符号Keras函数,将输入/输出作为输入并返回渐变。这是一个工作示例:
import numpy as np import keras from keras import backend as K model = keras.Sequential() model.add(keras.layers.Dense(20, input_shape = (10, ))) model.add(keras.layers.Dense(5)) model.compile('adam', 'mse') dummy_in = np.ones((4, 10)) dummy_out = np.ones((4, 5)) dummy_loss = model.train_on_batch(dummy_in, dummy_out) def get_weight_grad(model, inputs, outputs): """ Gets gradient of model for given inputs and outputs for all weights""" grads = model.optimizer.get_gradients(model.total_loss, model.trainable_weights) symb_inputs = (model._feed_inputs + model._feed_targets + model._feed_sample_weights) f = K.function(symb_inputs, grads) x, y, sample_weight = model._standardize_user_data(inputs, outputs) output_grad = f(x + y + sample_weight) return output_grad def get_layer_output_grad(model, inputs, outputs, layer=-1): """ Gets gradient a layer output for given inputs and outputs""" grads = model.optimizer.get_gradients(model.total_loss, model.layers[layer].output) symb_inputs = (model._feed_inputs + model._feed_targets + model._feed_sample_weights) f = K.function(symb_inputs, grads) x, y, sample_weight = model._standardize_user_data(inputs, outputs) output_grad = f(x + y + sample_weight) return output_grad weight_grads = get_weight_grad(model, dummy_in, dummy_out) output_grad = get_layer_output_grad(model, dummy_in, dummy_out)
我编写的第一个函数返回了模型中的所有渐变,但是扩展它并不难,因此它支持图层索引。但是,这可能很危险,因为此索引将忽略模型中没有权重的任何图层,并且最终在模型和渐变中将具有不同的图层索引。 我编写的第二个函数在给定层的输出处返回渐变,那里的索引与模型中的相同,因此可以安全地使用它。
注意 :该版本适用于Keras 2.2.0,而不是低于该版本,因为此发行版包括以下主要重构:keras.engine
keras.engine