Реализация пользовательских потерь Keras: ValueError: у операции есть `None` для градиента
Я пытаюсь реализовать эту функцию потерь: MCFD_loss_function из этого документа (P6): функции потерь
Итак, я создал новую функцию, например:
def mcfd_loss(y_true, y_pred):
return K.sum( # ∑
K.cast(
K.greater( # only values greater than 0 (+ float32 cast)
K.dot(K.sign(y_pred), # π
K.sign(y_true))
, 1)
, 'float32')
)
Но когда я начинаю тренироваться, возникает эта ошибка:
ValueError: операция имеет
None
для градиента. Пожалуйста, убедитесь, что все ваши операции имеют определенный градиент (то есть являются дифференцируемыми). Обычные операции без градиента: K.argmax, K.round, K.eval.
Я не знаю, какой момент я упустил. Ошибка, кажется, возникает, потому что я использую большую функцию. Я не знаю, что означает эта ошибка и как исправить мою проблему.
Благодарю.
0 ответов
Вы хотите, чтобы функция потерь проверила, sign(f_(t,1))*sign(Y_(t+1))
больше 0. Так как sign
не дифференцируется в 0, я бы предложил использовать softsign
вместо.
Поскольку функция greate than также не дифференцируема, можно использовать следующее приближение (см. Здесь): maxϵ(x,y):= 0.5(x + y + absϵ(x − y))
, где absϵ(x):=sqrt(x^2 + ϵ)
а также ϵ > 0
, Для простоты я буду называть это приближение в приведенном ниже примере кода как greater_approx
, (Обратите внимание, что вам просто нужно вставить вычисления выше)
Глядя на определение функции потерь, вы должны разделить сумму на количество прогнозов (K.get_variable_shape(y_pred)[0]
) (а также добавить минус). P
соответствует количеству прогнозов в соответствии с функциями потерь в статье Прогнозирование временных рядов.
В целом ваша функция потерь должна выглядеть так:
def mcfd_loss(y_true, y_pred):
return - (1/K.get_variable_shape(y_pred)[0]) * K.sum( # ∑
K.cast(
greater_approx( # only values greater than 0 (+ float32 cast)
K.dot(K.softsign(y_pred), # π
K.softsign(y_true))
, 0)
, 'float32')
)
Последнее замечание: для использования пользовательской функции потерь в Keras проверьте этот SO вопрос