Error loading saved hybrid quantum (pennylane + tensorflow keras) model: Unknown layer: 'KerasLayer'

69 views Asked by At

I'm creating a hybrid model consisting of classical convolutional layers and a quantum output using Tensorflow. I can save the model in either .h5 or .keras format, but when I load them with code model = keras.models.load_model('MODEL_PATH') they give

ValueError: Unknown layer: 'KerasLayer'. Please ensure you are using a "keras.utils.custom_object_scope" and that this object is included in the scope. See https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object for details.

The full error log is here:

    ValueError                                Traceback (most recent call last)
/Users/raheyo/Research/SpookyEngine/model.ipynb Cell 30 line 1
----> 1 loadedHybrid = keras.models.load_model('./models/hybrid3232.keras')

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/saving/saving_api.py:230, in load_model(filepath, custom_objects, compile, safe_mode, **kwargs)
    225     if kwargs:
    226         raise ValueError(
    227             "The following argument(s) are not supported "
    228             f"with the native Keras format: {list(kwargs.keys())}"
    229         )
--> 230     return saving_lib.load_model(
    231         filepath,
    232         custom_objects=custom_objects,
    233         compile=compile,
    234         safe_mode=safe_mode,
    235     )
    237 # Legacy case.
    238 return legacy_sm_saving_lib.load_model(
    239     filepath, custom_objects=custom_objects, compile=compile, **kwargs
    240 )

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/saving/saving_lib.py:275, in load_model(filepath, custom_objects, compile, safe_mode)
    272             asset_store.close()
    274 except Exception as e:
--> 275     raise e
    276 else:
    277     return model

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/saving/saving_lib.py:240, in load_model(filepath, custom_objects, compile, safe_mode)
    238 # Construct the model from the configuration file in the archive.
    239 with ObjectSharingScope():
--> 240     model = deserialize_keras_object(
    241         config_dict, custom_objects, safe_mode=safe_mode
    242     )
    244 all_filenames = zf.namelist()
    245 if _VARS_FNAME + ".h5" in all_filenames:

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/saving/serialization_lib.py:704, in deserialize_keras_object(config, custom_objects, safe_mode, **kwargs)
    702 safe_mode_scope = SafeModeScope(safe_mode)
    703 with custom_obj_scope, safe_mode_scope:
--> 704     instance = cls.from_config(inner_config)
    705     build_config = config.get("build_config", None)
    706     if build_config:

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/engine/sequential.py:473, in Sequential.from_config(cls, config, custom_objects)
    471 for layer_config in layer_configs:
    472     use_legacy_format = "module" not in layer_config
--> 473     layer = layer_module.deserialize(
    474         layer_config,
    475         custom_objects=custom_objects,
    476         use_legacy_format=use_legacy_format,
    477     )
    478     model.add(layer)
    480 if (
    481     not model.inputs
    482     and build_input_shape
    483     and isinstance(build_input_shape, (tuple, list))
    484 ):

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/layers/serialization.py:269, in deserialize(config, custom_objects, use_legacy_format)
    265     raise ValueError(
    266         f"Cannot deserialize empty config. Received: config={config}"
    267     )
    268 if use_legacy_format:
--> 269     return legacy_serialization.deserialize_keras_object(
    270         config,
    271         module_objects=LOCAL.ALL_OBJECTS,
    272         custom_objects=custom_objects,
    273         printable_module_name="layer",
    274     )
    276 return serialization_lib.deserialize_keras_object(
    277     config,
    278     module_objects=LOCAL.ALL_OBJECTS,
    279     custom_objects=custom_objects,
    280     printable_module_name="layer",
    281 )

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/saving/legacy/serialization.py:480, in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
    477 if isinstance(identifier, dict):
    478     # In this case we are dealing with a Keras config dictionary.
    479     config = identifier
--> 480     (cls, cls_config) = class_and_config_for_serialized_keras_object(
    481         config, module_objects, custom_objects, printable_module_name
    482     )
    484     # If this object has already been loaded (i.e. it's shared between
    485     # multiple objects), return the already-loaded object.
    486     shared_object_id = config.get(SHARED_OBJECT_KEY)

File /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/keras/src/saving/legacy/serialization.py:365, in class_and_config_for_serialized_keras_object(config, module_objects, custom_objects, printable_module_name)
    361 cls = object_registration.get_registered_object(
    362     class_name, custom_objects, module_objects
    363 )
    364 if cls is None:
--> 365     raise ValueError(
    366         f"Unknown {printable_module_name}: '{class_name}'. "
    367         "Please ensure you are using a `keras.utils.custom_object_scope` "
    368         "and that this object is included in the scope. See "
    369         "https://www.tensorflow.org/guide/keras/save_and_serialize"
    370         "#registering_the_custom_object for details."
    371     )
    373 cls_config = config["config"]
    374 # Check if `cls_config` is a list. If it is a list, return the class and the
    375 # associated class configs for recursively deserialization. This case will
    376 # happen on the old version of sequential model (e.g. `keras_version` ==
    377 # "2.0.6"), which is serialized in a different structure, for example
    378 # "{'class_name': 'Sequential',
    379 #   'config': [{'class_name': 'Embedding', 'config': ...}, {}, ...]}".

Is it that tensorflow doesn't fully support quantum integration yet? Or I did something wrong? Thanks!

1

There are 1 answers

0
Ryan Wang On BEST ANSWER

I posted an alternative solution over here: https://quantumcomputing.stackexchange.com/q/34920/25997

But essentially, I had no way to work around the traditional model.save(MODEL_PATH) method, but I used model.save_weights(WEIGHTS_PATH) instead to save the model and load it back up later. See this official Tensorflow Doc for more details.