Neural network 由于自定义丢失函数,Keras抛出DisconnectedInputError

Neural network 由于自定义丢失函数,Keras抛出DisconnectedInputError,neural-network,theano,keras,Neural Network,Theano,Keras,我试图在没有后台的情况下,在Keras中实现梯度范数的正则化项。基本上我想惩罚梯度的l2范数,基于它离1有多远 我正在实施如下自定义损失: 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 gradi

我试图在没有后台的情况下,在Keras中实现梯度范数的正则化项。基本上我想惩罚梯度的l2范数,基于它离1有多远

我正在实施如下自定义损失:

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

为什么?

用一些标准损耗工程替换损耗。这个错误与我定义的损失函数有关

请参阅此要点以了解我的尝试

编辑:

所以我想我现在知道该怎么做了。 首先,我只是在我的损失中随机添加了这个术语,然后直接从foo返回(y_true,y_pred):

很明显是一个常数零,如果我只用这个项作为损失,我得到了一个零。 然而,如果我把这个“常数零”加到正则化损失中,它会突然起作用。我得到了一个非零的损失,这来自于正则化,对批量的多个序列进行优化也减少了损失


所以这是一个奇怪的问题,因为theano在抛出异常时有点过于热心了?我的问题仍然存在:为什么要加入原始代码。由于添加一个常量零项修复了它,所以对我来说它看起来像一个bug?

我真的很想在keras中实现这个改进的wgan,看到您如何解决“问题”我很惊讶。您是否验证了trought实验,您的wgan gp损耗是否按预期工作? 它应该很容易检查,这是一个非常稳定的培训,使您能够使用非常深的鉴别器;) 我想用tensorflow后端完成与您相同的工作,我将尝试查看您的代码和此处的代码:

我会很高兴听到你的更新,我会再次写在这里,只要我有一个在keras/tensorflow工作的wgan gp代码! 另外,上面的链接正在执行tensorflow代码中的所有程序,强制使用tf训练功能。我真的很喜欢你的方法,我们可以简单地定义keras损失,使用我们所有常用的keras高级API进行培训;)

编辑:从您的代码来看,您似乎完全使用K后端,因此您的代码也可以轻松地使用tensorflow后端运行。您是否尝试更改后端以检查问题/错误是否确实与Theano有关

第二次编辑:您正在计算梯度w.r.t权重,但在wgan gp论文中,梯度惩罚是从梯度w.r.t生成的和真实样本之间的平均样本开始计算的。这将带来非常不同的结果。 在下面的链接中,您可以找到一个非常好的改进的wgan loss实现,它也可以在theano上工作:

我发布的代码是一个经过残酷删减的版本,肯定没有正确实现任何东西,它只是为了说明问题。我的真实代码通过在真实和虚假样本之间传递插值数据点来实现采样。到目前为止,我只测试了玩具示例,但它们对我来说很有希望。然而,由于更多的“实际”工作,我无法测试更复杂的数据集。我没有使用tensorflow进行测试,这里没有安装tensorflow,因为最终的丢失函数包含更多的术语异常问题实际上也不是问题。这让我很困惑。我猜您发布的wgan实现可能是由在keras方面有更多经验的人编写的,并且文档记录得更好。当我回到这一点时,我可能会使用它,因为它似乎是在GPU上实现插值部分,我是在CPU上实现的。酷!最后,我在调试中损失了12个小时,试图修改我链接的代码,以便作为一个单独的梯度惩罚损失(而不是集成到鉴别器中)工作,很快我就陷入了“tensorflow没有得到任何损失”类型的错误。我突然想起了你的修正案,对我来说也是修正案。如果没有您的修复,如果我通过model.summary()可视化模型,则没有输入层。通过您的简单修复,输入层突然显示为输入(梯度惩罚损失工作时不会出现任何错误),因此,theano和Keras(就我有限的后端知识而言)的情况似乎是图形编译器没有正确链接所有dumbo许可证变量,以断开连接的图形结束。将y_pred放在损失函数“return”行上,可以在正确构建图形的情况下解决问题。这可能是我一生中最奇怪的错误/问题(和修复!),永远!
K.mean(y_pred) - K.mean(y_pred)