Keras / Tensorflow中带有if语句的自定义损失函数

时间:2018-07-12 18:12:56

标签: python tensorflow machine-learning keras

我需要在Keras中创建一个自定义损失函数,并根据条件返回的结果创建两个不同的损失值。我无法让if语句正常运行。

我需要做类似的事情:

def custom_loss(y_true, y_pred):
    sees = tf.Session()
    const = 2
    if (sees.run(tf.keras.backend.less(y_pred, y_true))): #i.e. y_pred - y_true < 0
        return const * mean_squared_error(y_true, y_pred)
    else:
        return mean_squared_error(y_true, y_pred)

尝试运行此命令时,我不断收到张量错误(请参见下文)。任何帮助/建议将不胜感激!

InvalidArgumentError: You must feed a value for placeholder tensor 'dense_63_target' with dtype float and shape [?,?]
 [[Node: dense_63_target = Placeholder[dtype=DT_FLOAT, shape=[?,?], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

1 个答案:

答案 0 :(得分:2)

相反,您应该简单地乘以一个掩码以获得所需的功能

import keras.backend as K
def custom_1loss(y_true, y_pred):
    const = 2
    mask = K.less(y_pred, y_true) #i.e. y_pred - y_true < 0
    return (const - 1) * mask * mean_squared_error(y_true, y_pred) + mean_squared_error(y_true, y_pred)

具有与y_pred低预测相同的期望输出,因此添加了另一个MSE项。您可能必须将蒙版转换为整数张量-我不记得具体的类型-但这将是次要的更改。

也可作为主动提供的方法建议。我认为您可以采用其他方法来获得更好的结果。

import keras.backend as K
def custom_loss2(y_true, y_pred):
    beta = 0.1
    return mean_squared_error(y_true, y_pred) + beta*K.mean(y_true - y_pred)

观察梯度行为的差异:

https://www.desmos.com/calculator/uubwgdhpi6

我向您展示的第二个损失函数将局部最小值的时刻偏移为轻微的高估而不是低估(根据您的期望)。您提供的损失函数仍会局部优化为均值0,但强度梯度不同。这很可能会导致收敛到与MSE相同的结果的速度变慢,而不是想要一个模型,而该模型宁可过预测,也要过预测。我希望这是有道理的。