keras icon indicating copy to clipboard operation
keras copied to clipboard

Can't load model with tf-nightly if the model was saved with tf 2.15

Open reuvenperetz opened this issue 1 year ago • 9 comments

Hello,

I have a model that I saved using tf 2.15 version. When trying to load it using tf-nightly I'm getting the following error:

ImportError: cannot import name 'is_tensor_or_tensor_list' from 'keras.src.utils.tf_utils' (/usr/local/lib/python3.10/dist-packages/keras/src/utils/tf_utils.py)

Standalone code to reproduce the issue

Save model with TF2.15:


import keras
_in = keras.layers.Input(shape=(8, 8, 3))
_out = keras.layers.Conv2D(3, 3)(_in)
model = keras.Model(inputs=_in, outputs=_out)

modelpath = f'model.keras'
model.save(modelpath)

Load model with tf-nightly:

import keras
modelpath = f'model.keras'
loaded_model = keras.models.load_model(modelpath)

Relevant log output

----> 5 loaded_model = keras.models.load_model(modelpath)

/usr/local/lib/python3.10/dist-packages/keras/src/saving/saving_api.py in load_model(filepath, custom_objects, compile, safe_mode)
    174 
    175     if is_keras_zip:
--> 176         return saving_lib.load_model(
    177             filepath,
    178             custom_objects=custom_objects,

/usr/local/lib/python3.10/dist-packages/keras/src/saving/saving_lib.py in load_model(filepath, custom_objects, compile, safe_mode)
    151         # Construct the model from the configuration file in the archive.
    152         with ObjectSharingScope():
--> 153             model = deserialize_keras_object(
    154                 config_dict, custom_objects, safe_mode=safe_mode
    155             )

/usr/local/lib/python3.10/dist-packages/keras/src/saving/serialization_lib.py in deserialize_keras_object(config, custom_objects, safe_mode, **kwargs)
    681             return obj
    682 
--> 683     cls = _retrieve_class_or_fn(
    684         class_name,
    685         registered_name,

/usr/local/lib/python3.10/dist-packages/keras/src/saving/serialization_lib.py in _retrieve_class_or_fn(name, registered_name, module, obj_type, full_config, custom_objects)
    783         # and `class_name`. Import the module, find the class.
    784         try:
--> 785             mod = importlib.import_module(module)
    786         except ModuleNotFoundError:
    787             raise TypeError(

/usr/lib/python3.10/importlib/__init__.py in import_module(name, package)
    124                 break
    125             level += 1
--> 126     return _bootstrap._gcd_import(name[level:], package, level)
    127 
    128 

/usr/lib/python3.10/importlib/_bootstrap.py in _gcd_import(name, package, level)

/usr/lib/python3.10/importlib/_bootstrap.py in _find_and_load(name, import_)

/usr/lib/python3.10/importlib/_bootstrap.py in _find_and_load_unlocked(name, import_)

/usr/lib/python3.10/importlib/_bootstrap.py in _load_unlocked(spec)

/usr/lib/python3.10/importlib/_bootstrap_external.py in exec_module(self, module)

/usr/lib/python3.10/importlib/_bootstrap.py in _call_with_frames_removed(f, *args, **kwds)

/usr/local/lib/python3.10/dist-packages/keras/src/engine/functional.py in <module>
     24 
     25 from keras.src import backend
---> 26 from keras.src.dtensor import layout_map as layout_map_lib
     27 from keras.src.engine import base_layer
     28 from keras.src.engine import base_layer_utils

/usr/local/lib/python3.10/dist-packages/keras/src/dtensor/layout_map.py in <module>
     25 from keras.src.dtensor import lazy_variable
     26 from keras.src.dtensor import utils
---> 27 from keras.src.engine import base_layer
     28 
     29 # isort: off

/usr/local/lib/python3.10/dist-packages/keras/src/engine/base_layer.py in <module>
     52 # A module that only depends on `keras.layers` import these from here.
     53 from keras.src.utils.generic_utils import to_snake_case  # noqa: F401
---> 54 from keras.src.utils.tf_utils import is_tensor_or_tensor_list  # noqa: F401
     55 
     56 # isort: off

ImportError: cannot import name 'is_tensor_or_tensor_list' from 'keras.src.utils.tf_utils' (/usr/local/lib/python3.10/dist-packages/keras/src/utils/tf_utils.py)

reuvenperetz avatar Jan 23 '24 18:01 reuvenperetz

Thanks for reporting the issue.

Tf-Nightly uses Keras 3 where as TensorFlow 2.15 uses Keras 2. You can either migrate your code completely to Keras 3 with Tensorflow as backend and load the saved model via TFSMLayer as mentioned here https://keras.io/guides/migrating_to_keras_3/#loading-a-tf-savedmodel

sachinprasadhs avatar Jan 23 '24 22:01 sachinprasadhs

Thanks for the quick reply!

However, when trying to use TFSMLayer I get this error: OSError: SavedModel file does not exist at: ./model.keras/{saved_model.pbtxt|saved_model.pb}

I guess this is aimed for a model that was saved as a directory. I'm saving it as a .keras model.

reuvenperetz avatar Jan 24 '24 08:01 reuvenperetz

Hi again, I tried to load my saved model, but this time, I installed only Keras 3.0.4 (instead of tf-nightly).

So I saved the model using Keras 2.15 And trying to load with Keras 3.0.4

This time I also get an error but a different one:

[/usr/local/lib/python3.10/dist-packages/keras/src/saving/serialization_lib.py](https://localhost:8080/#) in _retrieve_class_or_fn(name, registered_name, module, obj_type, full_config, custom_objects)
    785             mod = importlib.import_module(module)
    786         except ModuleNotFoundError:
--> 787             raise TypeError(
    788                 f"Could not deserialize {obj_type} '{name}' because "
    789                 f"its parent module {module} cannot be imported. "

TypeError: Could not deserialize class 'Functional' because its parent module keras.src.engine.functional cannot be imported. Full object config: {'module': 'keras.src.engine.functional', 'class_name': 'Functional', 'config': {'name': 'model', 'trainable': True, 'layers': [{'module': 'keras.layers', 'class_name': 'InputLayer', 'config': {'batch_input_shape': [None, 8, 8, 3], 'dtype': 'float32', 'sparse': False, 'ragged': False, 'name': 'input_1'}, 'registered_name': None, 'name': 'input_1', 'inbound_nodes': []}, {'module': 'keras.layers', 'class_name': 'Conv2D', 'config': {'name': 'conv2d', 'trainable': True, 'dtype': 'float32', 'filters': 3, 'kernel_size': [3, 3], 'strides': [1, 1], 'padding': 'valid', 'data_format': 'channels_last', 'dilation_rate': [1, 1], 'groups': 1, 'activation': 'linear', 'use_bias': True, 'kernel_initializer': {'module': 'keras.initializers', 'class_name': 'GlorotUniform', 'config': {'seed': None}, 'registered_name': None}, 'bias_initializer': {'module': 'keras.initializers', 'class_name': 'Zeros', 'config': {}, 'registered_name': None}, 'kernel_regularizer': None, 'bias_regularizer': None, 'activity_regularizer': None, 'kernel_constraint': None, 'bias_constraint': None}, 'registered_name': None, 'build_config': {'input_shape': [None, 8, 8, 3]}, 'name': 'conv2d', 'inbound_nodes': [[['input_1', 0, 0, {}]]]}], 'input_layers': [['input_1', 0, 0]], 'output_layers': [['conv2d', 0, 0]]}, 'registered_name': 'Functional', 'build_config': {'input...

reuvenperetz avatar Jan 24 '24 09:01 reuvenperetz

Could you please provide sample reproducible code to debug the issue.

sachinprasadhs avatar Jan 24 '24 18:01 sachinprasadhs

Sure.

Standalone code to reproduce the issue

Save model with keras 2.15.0:


import keras
_in = keras.layers.Input(shape=(8, 8, 3))
_out = keras.layers.Conv2D(3, 3)(_in)
model = keras.Model(inputs=_in, outputs=_out)

modelpath = f'model.keras'
model.save(modelpath)

Load model with keras 3.0.4:

import keras
modelpath = f'model.keras'
loaded_model = keras.models.load_model(modelpath)

reuvenperetz avatar Jan 24 '24 18:01 reuvenperetz

Thanks for providing the details.

I was able to reproduce the issue here

Similar issue was fixed before here, https://github.com/keras-team/keras/issues/18830

sachinprasadhs avatar Jan 24 '24 22:01 sachinprasadhs

Triage notes: I think the cross version saving/loading might not work between Keras 2 and 3. Maybe we should make this more explicit in the documentation/FAQ,etc.

qlzh727 avatar Jan 25 '24 17:01 qlzh727

Hi, do you have any news about this issue? I would like to load a TensorFlow 2.15 model with Keras 3

estebvac avatar Jul 31 '24 16:07 estebvac

Keras Migration page needs a section referencing this error message: "TypeError: Could not deserialize class 'Functional' because its parent module keras.src.engine.functional cannot be imported." Ultimately the issue was the Model API appears to not migrate well from Keras 2 to 3.

Solution was rebuilding the model layer by layer in Keras 3 and then loading weights file from Keras 2 model. Now able to run the model and obtain predictions.

elpa avatar Aug 12 '24 21:08 elpa