如何为使用Tensorflow的Keras修正自定义损失函数?

4
我希望编写一个自定义的损失函数,通过加权惩罚对正目标值的低估。它的工作方式类似于均方误差,唯一的区别在于,在这种情况下,平方误差会乘以大于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

然而,当我将其提供给使用tensorflow作为后端的keras中的顺序模型时:

model.compile(loss=wmse,optimizer='rmsprop')

I get the following error:

 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 框架。我尝试用 tensorflow.logical_and 替换 np.logical_and,但是没有成功,错误仍然存在。


1
你正在将NumPy与tensorflow张量混合使用,所有 NumPy 函数都需要用Kerasbackend或直接Tensorflow函数替换。 - nuric
1个回答

8

正如 @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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接