由于自定义丢失功能,Keras会抛出DisconnectedInputError

时间:2017-04-05 18:25:57

标签: neural-network theano keras

我正在尝试使用theano后端为Keras中的improved WGAN training实现渐变范数的正则化项。基本上我想根据距离1的距离来惩罚渐变的l2范数。

我正在实施这样的自定义损失:

def get_gradient_norm(model, y_pred):
    weights = model.trainable_weights
    gradients = model.optimizer.get_gradients(K.mean(y_pred), weights)
    acc = None
    for g in gradients:
        s = K.sum(K.square(g))
        if acc == None:
            acc = s
        else:
            acc = s + acc
    return K.sqrt(acc)

def make_w_reg_loss(model):
    lvar = K.variable(lamb, name="Lambda")

    def foo(y_true, y_pred):
        gnorm = get_gradient_norm(model, y_pred)
        return lvar * K.square(gnorm - 1)

return foo

[...]

critic.compile(loss=make_w_reg_loss(critic), optimizer=RMSprop(learn_rate))

一旦训练过程尝试获取自定义丢失函数的渐变,它就会抛出DisconnectedInputError。

为什么?

用一些标准损失代替损失。该错误与我定义的损失函数有关。

查看我的尝试a minimal not-working example的要点

编辑:

所以我想我现在知道如何让它发挥作用。 首先,我在从foo(y_true,y_pred)返回之前直接将这个术语随机添加到我的遗失中:

K.mean(y_pred) - K.mean(y_pred)

显然是一个恒定的零,如果我只使用这个术语作为我的损失,我确实得到零。 但是,如果我将这个“常数零”添加到我的正则化损失中它突然正常工作。我得到了一个非零,因此来自正规化,并且许多train_on_batch的优化确实减少了损失。

这是一个奇怪的问题,theano在抛出异常时有点过于热心吗?我的问题仍然存在:为什么它会抛出原始代码。由于添加一个恒定的零项修复它,对我来说它看起来像个错误?

1 个答案:

答案 0 :(得分:0)

我真的很想在keras中实现这个改进的wgan,我很惊讶你看到了如何解决你的“问题”。您是否验证过您的wgan-gp损失按预期工作的实验? 应该很容易检查,这是一个非常稳定的培训,使您能够使用非常深的鉴别器;) 我想做同样的工作,但是使用tensorflow后端,我会尝试在这里查看你的代码和代码:keras improved wgan

我很高兴听到你的更新,我会在keras / tensorflow中有一个wgan-gp的工作代码后再写一遍! 附:上面的链接正在实现tensorflow代码中的所有过程,强制使用tf训练函数。我非常喜欢你的方法,我们可以使用我们所有常用的keras高级API进行训练来定义keras损失;)

编辑:从您的代码中,您似乎完全使用K后端,因此您的代码也应该可以使用tensorflow后端轻松运行。您是否尝试更改后端以检查问题/错误是否与Theano真正相关?

第二次编辑:你正在计算权重的梯度,但是在wgan-gp论文中,从梯度w.r.t开始计算梯度罚分,生成样本和实际样本之间的平均样本。这会带来截然不同的结果。 在以下链接中,您可以找到一个非常好的改进的wgan loss实现, 也可以在theano上工作: https://github.com/farizrahman4u/keras-contrib/