如何获得keras的渐变?

Sco*_*ott 13 python keras

我正在尝试调试keras我已经构建的模型.似乎我的渐变是爆炸性的,或者有0或者其他类似的除法.当它们通过网络反向传播时能够检查各种梯度将是方便的.像下面这样的东西是理想的:

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
Run Code Online (Sandbox Code Playgroud)

mpa*_*nte 16

您需要创建一个符号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)
Run Code Online (Sandbox Code Playgroud)

我写的第一个函数返回模型中的所有渐变,但扩展它并不困难,因此它支持图层索引.但是,它可能很危险,因为此索引中将忽略模型中没有权重的任何图层,并且最终会在模型和渐变中使用不同的图层索引.
我写的第二个函数返回给定图层输出的渐变,在那里,索引与模型中的索引相同,因此使用它是安全的.

注意:这适用于Keras 2.2.0,不适用于此版本,因为此版本包含了一个重要的重构keras.engine

  • 正如@DanielMöller所说,如果我提供给定的输入,此方法会起作用,但是通常您会希望在训练过程中以某种方式记录和记录渐变(或渐变的某些功能,例如其范数)。我该怎么做? (2认同)