在Keras中,为什么损失函数必须基于神经网络的输出进行计算?

首先,从方法论的角度,我理解为什么损失函数必须依赖于神经网络的输出。这个问题更多地源于我试图更好地理解Keras和TensorFlow时进行的一项实验。请考虑以下内容:

input_1 = Input((5,))hidden_a = Dense(2)(input_1)output = Dense(1)(hidden_a)m3 = Model(input_1, output)def myLoss (y_true, y_pred):    return K.sum(hidden_a)                    # (A)    #return K.sum(hidden_a) + 0*K.sum(y_pred) # (B)m3.compile(optimizer='adam', loss=myLoss)x = np.random.random(size=(10,5))y = np.random.random(size=(10,1))m3.fit(x,y, epochs=25)

这段代码会引发以下错误:

ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.

但是,如果你将A行替换为B行,尽管数值上没有任何变化,代码仍然可以运行。

前一种情况在我看来应该是完全可以接受的。计算图是明确定义的,所有内容在损失方面应该是可微分的。但似乎Keras要求y_pred以某种方式包含在损失函数中,无论它是否有任何影响。

谢谢!


回答:

事实证明,这有点棘手。实际上,Keras并不需要y_pred包含在损失函数中。然而,它需要损失函数中引用所有可训练的变量。

当你调用m3.fit()时,Keras将在你的损失函数和你的层的可训练权重之间进行梯度计算。如果你的损失函数没有引用可训练变量集合中的相同元素,那么一些梯度计算操作将无法进行。

那么如何避免这种情况呢? 你可以引用y_pred,即使它不做任何事情。或者,你可以冻结那些不会受到优化器影响的层(因为你无论如何都不计算它们的损失)

所以在你的情况下,你只需要冻结输出层:

output = Dense(1, trainable = False)(hidden_a)

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注