我正在尝试使用泊松无标度偏差作为我的神经网络的损失函数,但是有一个主要的流程:y_true
可以(并且经常会)使用值0
。
对于Poisson案例,未缩放的偏差是这样的:
如果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函数解决此问题,但这是窍门:
如果我有值log(0)
,我不想用0
(用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