【问题标题】:How to obtain the gradients in keras?如何获得keras中的渐变?
【发布时间】:2018-12-10 23:07:33
【问题描述】:

我正在尝试调试我构建的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

【问题讨论】:

标签: python keras


【解决方案1】:

您需要创建一个符号 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 的重大重构

【讨论】:

  • 以后如何使用K.function获取实际输入的值?
  • 正如@DanielMöller 已经评论的那样,如果我提供给定的输入,这将有效,但通常您会希望在训练期间以某种方式记录和记录梯度(或它们的某些函数,例如它们的范数) .我该怎么做?
  • 如果输入是一批样本,你能解释一下这两个函数返回什么格式(形状)吗?
  • 我知道这个问题很老了,但是对于具有多个输入和输出的网络,您将如何修改它?我的有两个输入和两个输出,两个损失函数。当我按原样应用此解决方案时,我收到与不兼容尺寸相关的错误。
  • @Mastiff 使用这个:[dummy_in1 dummy_in2] 代替 dummy_in。对多个输出执行相同操作
猜你喜欢
  • 1970-01-01
  • 2017-06-13
  • 2023-03-12
  • 1970-01-01
  • 2013-11-01
  • 2011-01-18
  • 2020-01-05
  • 1970-01-01
  • 2019-08-27
相关资源
最近更新 更多