Как получить результаты от пользовательской функции потерь в Керасе? - PullRequest
0 голосов
/ 27 апреля 2018

Я хочу реализовать пользовательскую функцию потерь в Python, и она должна работать так: псевдокод:

aux = | Real - Prediction | / Prediction
errors = []
if aux <= 0.1:
 errors.append(0)
elif aux > 0.1 & <= 0.15:
 errors.append(5/3)
elif aux > 0.15 & <= 0.2:
 errors.append(5)
else:
 errors.append(2000)
return sum(errors)

Я начал определять метрику следующим образом:

def custom_metric(y_true,y_pred):
    # y_true:
    res = K.abs((y_true-y_pred) / y_pred, axis = 1)
    ....

Но я не знаю, как получить значение res для , если и else . Также я хочу знать, что должна вернуть функция.

Спасибо

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Также я хочу знать, что должна возвращать функция.

Пользовательские метрики могут быть переданы на этапе компиляции.

Функция должна принимать (y_true, y_pred) в качестве аргументов и возвращать одно tensor значение.

Но я не знаю, как получить значение res для if и else.

Вы можете вернуть result из функции result_metric.

def custom_metric(y_true,y_pred):
     result = K.abs((y_true-y_pred) / y_pred, axis = 1)
     return result

Второй шаг - использовать функцию обратного вызова keras, чтобы найти сумму ошибок.

Обратный вызов может быть определен и передан методу fit.

history = CustomLossHistory()
model.fit(callbacks = [history])

Последний шаг - создать класс CustomLossHistory, чтобы узнать список sum ожидаемых ошибок .

CustomLossHistory унаследует некоторые методы по умолчанию от keras.callbacks.Callback.

  • on_epoch_begin : вызывается в начале каждой эпохи.
  • on_epoch_end : вызывается в конце каждой эпохи.
  • on_batch_begin : вызывается в начале каждого пакета.
  • on_batch_end : вызывается в конце каждой партии.
  • on_train_begin : вызывается в начале обучения модели.
  • on_train_end : вызывается в конце обучения модели.

Подробнее читайте в документации Keras

Но для этого примера нам нужны только методы on_train_begin и on_batch_end.

Осуществление

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.errors= []

    def on_batch_end(self, batch, logs={}):
         loss = logs.get('loss')
         self.errors.append(self.loss_mapper(loss))

    def loss_mapper(self, loss):
         if loss <= 0.1:
             return 0
         elif loss > 0.1 & loss <= 0.15:
             return 5/3
         elif loss > 0.15 & loss <= 0.2:
             return 5
         else:
             return 2000

После того, как ваша модель обучена, вы можете получить доступ к ошибкам , используя следующую инструкцию.

errors = history.errors
0 голосов
/ 27 апреля 2018

Я сделаю здесь прыжок и скажу, что это не сработает, потому что это невозможно дифференцировать. Потери должны быть непрерывно дифференцируемыми, чтобы через них можно было распространять градиент.

Если вы хотите сделать эту работу, вам нужно найти способ сделать это без перерыва. Например, вы можете попробовать средневзвешенное значение по вашим 4 дискретным значениям, где веса сильно предпочитают ближайшее значение.

...