如何使用 tensorflow 纠正 keras 的自定义损失函数?
How to correct this custom loss function for keras with tensorflow?
我想编写一个自定义损失函数来惩罚低估具有权重的正目标值。它会像均方误差一样工作,唯一的区别是在所述情况下平方误差会乘以大于 1 的权重。
我是这样写的:
def wmse(ground_truth, predictions):
square_errors = np.square(np.subtract(ground_truth, predictions))
weights = np.ones_like(square_errors)
weights[np.logical_and(predictions < ground_truth, np.sign(ground_truth) > 0)] = 100
weighted_mse = np.mean(np.multiply(square_errors, weights))
return weighted_mse
但是,当我将它提供给 keras
中的顺序模型并使用 tensorflow
作为后端时:
model.compile(loss=wmse,optimizer='rmsprop')
我收到以下错误:
raise TypeError("Using a `tf.Tensor` as a Python `bool` is not allowed.
TypeError: Using a `tf.Tensor` as a Python `bool` is not allowed. Use `if t is not None:` instead of `if t:` to test if a tensor is defined, and use TensorFlow ops such as tf.cond to execute subgraphs conditioned on the value of a tensor.
回溯指向 wmse
中的这一行:
weights[np.logical_and(predictions < ground_truth, np.sign(ground_truth) > 0)] = 100
直到现在我还从未使用过 keras
或 tensorflow
,所以如果有人帮助我将此损失函数适应 keras
/tensorflow
,我将不胜感激框架。我尝试将np.logical_and
替换为tensorflow.logical_and
,但没有用,错误依旧。
正如@nuric 所提到的,您必须仅使用 Keras / Tensorflow 操作和导数来实现损失,因为这些框架将无法通过其他操作(如 numpy 操作)进行反向传播。
仅 Keras 的实现可能如下所示:
from keras import backend as K
def wmse(ground_truth, predictions):
square_errors = (ground_truth - predictions) ** 2
weights = K.ones_like(square_errors)
mask = K.less(predictions, ground_truth) & K.greater(K.sign(ground_truth), 0)
weights = K.switch(mask, weights * 100, weights)
weighted_mse = K.mean(square_errors * weights)
return weighted_mse
gt = K.constant([-2, 2, 1, -1, 3], dtype="int32")
pred = K.constant([-2, 1, 1, -1, 1], dtype="int32")
weights, loss = wmse(gt, pred)
sess = K.get_session()
print(loss.eval(session=sess))
# 100
我想编写一个自定义损失函数来惩罚低估具有权重的正目标值。它会像均方误差一样工作,唯一的区别是在所述情况下平方误差会乘以大于 1 的权重。
我是这样写的:
def wmse(ground_truth, predictions):
square_errors = np.square(np.subtract(ground_truth, predictions))
weights = np.ones_like(square_errors)
weights[np.logical_and(predictions < ground_truth, np.sign(ground_truth) > 0)] = 100
weighted_mse = np.mean(np.multiply(square_errors, weights))
return weighted_mse
但是,当我将它提供给 keras
中的顺序模型并使用 tensorflow
作为后端时:
model.compile(loss=wmse,optimizer='rmsprop')
我收到以下错误:
raise TypeError("Using a `tf.Tensor` as a Python `bool` is not allowed.
TypeError: Using a `tf.Tensor` as a Python `bool` is not allowed. Use `if t is not None:` instead of `if t:` to test if a tensor is defined, and use TensorFlow ops such as tf.cond to execute subgraphs conditioned on the value of a tensor.
回溯指向 wmse
中的这一行:
weights[np.logical_and(predictions < ground_truth, np.sign(ground_truth) > 0)] = 100
直到现在我还从未使用过 keras
或 tensorflow
,所以如果有人帮助我将此损失函数适应 keras
/tensorflow
,我将不胜感激框架。我尝试将np.logical_and
替换为tensorflow.logical_and
,但没有用,错误依旧。
正如@nuric 所提到的,您必须仅使用 Keras / Tensorflow 操作和导数来实现损失,因为这些框架将无法通过其他操作(如 numpy 操作)进行反向传播。
仅 Keras 的实现可能如下所示:
from keras import backend as K
def wmse(ground_truth, predictions):
square_errors = (ground_truth - predictions) ** 2
weights = K.ones_like(square_errors)
mask = K.less(predictions, ground_truth) & K.greater(K.sign(ground_truth), 0)
weights = K.switch(mask, weights * 100, weights)
weighted_mse = K.mean(square_errors * weights)
return weighted_mse
gt = K.constant([-2, 2, 1, -1, 3], dtype="int32")
pred = K.constant([-2, 1, 1, -1, 1], dtype="int32")
weights, loss = wmse(gt, pred)
sess = K.get_session()
print(loss.eval(session=sess))
# 100