Search code examples
pythontensorflowmachine-learningkerasloss

How to get results from custom loss function in Keras?


I want to implement a custom loss function in Python and It should work like this pseudocode:

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)

I started to define the metric like this:

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

But I do not know how to get the value of the res for the if and else. Also I want to know what have to return the function.

Thanks


Solution

  • Also I want to know what have to return the function.

    Custom metrics can be passed at the compilation step.

    The function would need to take (y_true, y_pred) as arguments and return a single tensor value.

    But I do not know how to get the value of the res for the if and else.

    You can return the result from result_metric function.

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

    The second step is to use a keras callback function in order to find the sum of the errors.

    The callback can be defined and passed to the fit method.

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

    The last step is to create the the CustomLossHistory class in order to find out the sum of your expecting errors list.

    CustomLossHistory will inherit some default methods from keras.callbacks.Callback.

    • on_epoch_begin: called at the beginning of every epoch.
    • on_epoch_end: called at the end of every epoch.
    • on_batch_begin: called at the beginning of every batch.
    • on_batch_end: called at the end of every batch.
    • on_train_begin: called at the beginning of model training.
    • on_train_end: called at the end of model training.

    You can read more in the Keras Documentation

    But for this example we only need on_train_begin and on_batch_end methods.

    Implementation

    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
    

    After your model is trained you can access your errors using following statement.

    errors = history.errors