Jason
Jason

Reputation: 593

Loading model with custom loss + keras

In Keras, if you need to have a custom loss with additional parameters, we can use it like mentioned on https://datascience.stackexchange.com/questions/25029/custom-loss-function-with-additional-parameter-in-keras

def penalized_loss(noise):
    def loss(y_true, y_pred):
        return K.mean(K.square(y_pred - y_true) - K.square(y_true - noise), axis=-1)
    return loss

The above method works when I am training the model. However, once the model is trained I am having difficulty in loading the model. When I try to use the custom_objects parameter in load_model like below

model = load_model(modelFile, custom_objects={'penalized_loss': penalized_loss} )

it complains ValueError: Unknown loss function:loss

Is there any way to pass in the loss function as one of the custom losses in custom_objects ? From what I can gather, the inner function is not in the namespace during load_model call. Is there any easier way to load the model or use a custom loss with additional parameters

Upvotes: 49

Views: 33525

Answers (5)

SuddenWind
SuddenWind

Reputation: 61

@rickyalbert

def custom_loss(y_true, y_pred):
   nn = np.square(y_true - y_pred)
   return nn

model = load_model(modelFile, custom_objects={'loss': custom_loss})

You should pass the loss function as the object.

Upvotes: 1

madiouni mohssen
madiouni mohssen

Reputation: 51

I had the same problem and after many researches I can assume that this works:

  1. At first, load your model and assign compile=False.
  2. compile your model with your custom loss function.
  3. retrain your model.

example:

def custom_loss(y_true, y_pred):
   nn = np.square(y_true - y_pred)
   return nn

model = load_model("aaaa.h5", compile=False)
model.compile(loss=custom_loss, optimizer='adam', metrics=custom_loss)
model.fit(...)

Upvotes: 5

AZiZA Saber
AZiZA Saber

Reputation: 395

If you are loading your model just for prediction (not training), you can set the compile flag to False in load_model as following:

model = load_model(model_path, compile=False)

This will not search for the loss function as it is only needed for compiling the model.

Upvotes: 24

Amruth Lakkavaram
Amruth Lakkavaram

Reputation: 1517

You can try this:

import keras.losses
keras.losses.penalized_loss = penalized_loss

(after defining 'penalized_loss' function in your current 'py' file).

Upvotes: 3

rickyalbert
rickyalbert

Reputation: 2652

Yes, there is! custom_objects expects the exact function that you used as loss function (the inner one in your case):

model = load_model(modelFile, custom_objects={ 'loss': penalized_loss(noise) })

Unfortunately keras won't store in the model the value of noise, so you need to feed it to the load_model function manually.

Upvotes: 44

Related Questions