2

So I defined my keras model and have used a custom_loss function to train the model:

model.compile(optimizer='adam', loss=custom_loss, metrics=[custom_loss])

Then I am training the model:

history = model.fit(X_train, y_train, batch_size=1024, epochs=125, validation_split=0.2, shuffle=True)

Then I save this history object using the following code:

with open('history.pkl', 'wb') as file:  
   pickle.dump(history, file)

Now, when I am trying to read the history object as follows:

with open('history.pkl', 'rb') as file:
    history = pickle.load(file)

I get the following error:

ValueError: Unknown loss function:custom_loss

How can I read the history object? I don't get this error when I am not using custom_loss function. I am using keras 2.2.4 and tensorflow 1.15.5

Edit: Complete error traceback as requested: enter image description here

idpd15
  • 448
  • 2
  • 5
  • 22
  • Can you provide the complete traceback? – Dr. Snoopy Sep 17 '21 at 07:21
  • @Dr.Snoopy Added the complete traceback – idpd15 Sep 17 '21 at 07:46
  • @idpd15 why didn't u use model.save and load_model? https://www.tensorflow.org/tutorials/keras/save_and_load#save_the_entire_model and https://www.tensorflow.org/api_docs/python/tf/keras/models/load_model – Marco Cerliani Sep 17 '21 at 09:14
  • @MarcoCerliani I didn't use and in future can try out alternatives but can anything be done to read this file that I have? – idpd15 Sep 17 '21 at 10:19
  • can you try with `keras.models.load_model('history.pkl', custom_objects={'custom_loss':custom_loss})` . For future use, you can refer [this](https://stackoverflow.com/q/41061457/8243797) – SajanGohil Sep 24 '21 at 09:46

2 Answers2

2

For most use cases, you don't want to serialize the history object. What you are usually interested in is history.history, which is a dict of the logs / metrics / losses / etc.

Try that:

pickle.dump(history.history, file)

The fuller answer is that the history object returned is a tf.keras.callbacks.History, which subclasses tf.keras.callbacks.Callback. Callback itself has a ref to the model, which then has refs to all kinds of stuff including custom objects like your custom loss. Serialization of Keras custom objects is a whole other big topic... tldr the recommended way to serialize Keras models is not to use pickle.

Yaoshiang
  • 1,713
  • 5
  • 15
0

+1 to @Yaoshiang's answer. That's the right answer.

This is just a big note.

Reading that trace, it looks like keras has custom pickle logic that uses the standard keras save/load logic. keras doesn't know about your loss function unless you tell it.

Search for "custom objects" in this guide: https://keras.io/guides/serialization_and_saving/

Try something like:

custom_objects = {"custom_loss": custom_loss}
with keras.utils.custom_object_scope(custom_objects):
  with open('history.pkl', 'rb') as file:
    history = pickle.load(file)
mdaoust
  • 6,242
  • 3
  • 28
  • 29