首页 > 解决方案 > Keras 在自定义损失函数中替换 log(0)

问题描述

我正在尝试使用泊松非标度偏差作为我的神经网络的损失函数,但是有一个主要流程:y_true可以(并且会经常)取值0

对于泊松情况,未缩放的偏差像这样工作:

如果y_true = 0,那么loss = 2 * d * y_pred

如果y_true > 0,那么loss = 2 * d *y_pred * (y_true * log(y_true)-y_true * log(y_pred)-y_true+y_pred

请注意,一旦log(0)计算出来,损失就变成了-inf,所以我的目标是防止这种情况发生。

我尝试使用 switch 函数来解决这个问题,但诀窍是:如果我有 value log(0),我不想用0(with K.zeros()) 替换它,因为它会考虑y_true = 1因为log(1) = 0. 因此,我想在这种情况下尝试使用一个大的负值(-10000例如),但我不知道该怎么做,因为K.variable(-10000)给出了错误:

ValueError: Rank of `condition` should be less than or equal to rank of `then_expression` and `else_expression`. ndim(condition)=1, ndim(then_expression)=0

使用K.zeros_like(y_true)代替K.variable(-10000)将适用于 keras,但它在数学上不正确,因此优化无法正常工作。

我想知道如何用 switch 函数中的大负值替换日志。这是我的尝试:

def custom_loss3(data, y_pred):
    y_true = data[:, 0]
    d = data[:, 1]
    # condition
    loss_value = KB.switch(KB.less_equal(y_true, 0),
                           2 * d * y_pred, 2 * d * (y_true * KB.switch(KB.less_equal(y_true, 0),
                           KB.variable(-10000), KB.log(y_true)) - y_true * KB.switch(KB.less_equal(y_pred, 0.), KB.variable(-10000), KB.log(y_pred)) - y_true + y_pred))
    return loss_value

标签: pythonkerasloss-function

解决方案


推荐阅读