Я пытаюсь использовать немасштабируемое отклонение Пуассона в качестве функции потерь для моей нейронной сети, но есть большой поток с этим: 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 для решения этой проблемы, но вот хитрость: если у меня есть значение 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)
будет работать для кератов, но это математически неверно, и из-за этого оптимизация не работает должным образом.
Я хотел бы знать, как заменить журнал большим отрицательным значением вфункция переключения.Вот моя попытка:
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