首先,我从方法论的角度意识到为什么你的损失函数必须依赖于神经网络的输出。这个问题更多来 self 在尝试更好地理解 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 将在您的损失函数和层的可训练权重之间执行梯度计算。如果您的损失函数未引用您在 trainable_variables 集合中的相同元素,则某些梯度计算操作将无法进行。
那么如何避免呢?好吧,你可以引用 y_pred
,即使什么都不做。或者您可以卡住不受优化器影响的层(因为您无论如何都不计算它们的损失)
所以在你的情况下,你只需要卡住你的输出层:
output = Dense(1, trainable = False)(hidden_a)
关于python - 在 Keras 中,为什么必须根据神经网络的输出来计算损失函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51257037/