我正试图将不成比例的泊松偏差作为惯例损失。我已经为此工作了一段时间,并且我已经解决了大多数问题,但是有最后一个我无法摆脱,我想知道你们中的任何人是否知道问题的根源。
当我使用自定义损失拟合模型时,它会完美启动,给我带来预期的偏差,但是在n个历元之后,它会开始将NaN作为输出,并且永远不会返回到实数。我无法说出它需要多少个历元,因为它是相当随机的,并且发生在一个历元的中间。
以下两个提供相同结果的类似自定义损失:
def custom_loss3(data, y_pred):
y_true = data[:, 0]
d = data[:, 1]
lnYTrue = KB.switch(KB.equal(y_true, 0), KB.zeros_like(y_true), KB.log(y_true))
lnYPred = KB.switch(KB.equal(y_pred, 0), KB.zeros_like(y_pred), KB.log(y_pred))
loss_value = 2 * d * (y_true * lnYTrue - y_true * lnYPred[:, 0] - y_true + y_pred[:, 0])
return loss_value
def deviance(data, y_pred):
y_true = data[:, 0]
d = data[:, 1]
lnY = KB.log(y_true)
bool1 = KB.equal(y_true, 0)
zeros = KB.zeros_like(y_true)
lnY = KB.switch(bool1, zeros, lnY)
lnYp = KB.log(y_pred)
bool2 = KB.equal(y_pred, 0)
zeross = KB.zeros_like(y_pred)
lnYp = KB.switch(bool2, zeross, lnYp)
loss = 2 * d * (y_true * lnY - y_true * lnYp[:, 0] - y_true + y_pred[:, 0])
return KB.sum(loss)
注意:y_true的取值范围是0到〜100,但是大多数时候都是0。这就是为什么我尝试在log(0)的情况下使用switch的原因。