golden96371
golden96371

Reputation: 410

Keras failed to load SavedModel: TypeError 'module' object is not callable

I trained an SSD MobileNet v2 network using the TensorFlow Object Detection API with TensorFlow 2 and then converted the trained model into a SavedModel. Now I need to convert the SavedModel to a FrozenGraph in order to make the model compatible with external libraries like OpenCV. I use this example for conversion and I cannot even load the Keras model.

from keras.models import load_model
model = load_model("training/model/saved_model")

Calling load_model() produces an exception:

Exception has occurred: TypeError
'module' object is not callable

Full traceback:
Traceback (most recent call last):
  File "path\to\tensorflow\python\util\dispatch.py", line 201, in wrapper
    return target(*args, **kwargs)
TypeError: 'str' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "path\to\saved_model_to_frozen_graph.py", line 17, in <module>
    model = load_model("saved_model")
  File "path\to\tensorflow\python\keras\saving\save.py", line 187, in load_model
    return saved_model_load.load(filepath, compile, options)
  File "path\to\tensorflow\python\keras\saving\saved_model\load.py", line 121, in load
    path, options=options, loader_cls=KerasObjectLoader)
  File "path\to\tensorflow\python\saved_model\load.py", line 633, in load_internal
    ckpt_options)
  File "path\to\tensorflow\python\keras\saving\saved_model\load.py", line 194, in __init__
    super(KerasObjectLoader, self).__init__(*args, **kwargs)
  File "path\to\tensorflow\python\saved_model\load.py", line 130, in __init__
    self._load_all()
  File "path\to\tensorflow\python\keras\saving\saved_model\load.py", line 221, in _load_all
    self._finalize_objects()
  File "path\to\tensorflow\python\keras\saving\saved_model\load.py", line 530, in _finalize_objects
    self._reconstruct_all_models()
  File "path\to\tensorflow\python\keras\saving\saved_model\load.py", line 548, in _reconstruct_all_models
    self._reconstruct_model(model_id, model, layers)
  File "path\to\tensorflow\python\keras\saving\saved_model\load.py", line 589, in _reconstruct_model
    config, created_layers={layer.name: layer for layer in layers})
  File "path\to\tensorflow\python\keras\engine\functional.py", line 1215, in reconstruct_from_config
    process_node(layer, node_data)
  File "path\to\tensorflow\python\keras\engine\functional.py", line 1163, in process_node
    output_tensors = layer(input_tensors, **kwargs)
  File "path\to\tensorflow\python\keras\engine\base_layer.py", line 926, in __call__
    input_list)
  File "path\to\tensorflow\python\keras\engine\base_layer.py", line 1117, in _functional_construction_call
    outputs = call_fn(cast_inputs, *args, **kwargs)
  File "path\to\tensorflow\python\keras\layers\core.py", line 903, in call
    result = self.function(inputs, **kwargs)
  File "path\to\tensorflow\python\util\dispatch.py", line 205, in wrapper
    result = dispatch(wrapper, args, kwargs)
TypeError: 'module' object is not callable

type(layer) = <class 'tensorflow.python.keras.layers.core.Lambda'>

Anyone knows how to fix that?


Additional information:

Windows 10, Python 3.7, TensorFlow 2.3.1, Keras 2.4.3

# Train the network
python model_main_tf2.py --model_dir="training" --pipeline_config_path="training/pipeline.config"
# Export the network
python exporter_main_v2.py --input_type=image_tensor --pipeline_config_path="training/pipeline.config" --trained_checkpoint_dir="training" --output_directory="training/model"

Folder structure:

training/
-> label_map.pbtxt
-> pipeline.config
-> model
 . -> checkpoint
 . -> saved_model
 .  . -> assets
 .  . -> variables
 .  . -> saved_model.pb
-> checkpoint
-> ckpt.x.data-00000-of-00001
-> ckpt.x.index

Upvotes: 3

Views: 3361

Answers (2)

user15583898
user15583898

Reputation: 1

The reason might be the lambda layer in your model.

There are some issues in Keras that may raise TypeError(str is not callable or module is not callable) while loading a model with lambda layer.

To solve the issue, not save the model with model.save. Instead, save the model weights and recreate the model architecture using the code,then load weights.

Example:

model.save_weights('model_weights.h5')

or

ModelCheckPoint(file,save_weights_only=True)#this will call save_weights

After create the model,then:

model.load_weights('model_weights.h5')

Note: save the model architecture as a JSON file can't solve the error

Upvotes: 0

golden96371
golden96371

Reputation: 410

I have found a way to convert the model without Keras, which is working for me. https://github.com/opencv/opencv/issues/16879

import tensorflow as tf
from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2

loaded = tf.saved_model.load('training/model/saved_model')
infer = loaded.signatures['serving_default']

f = tf.function(infer).get_concrete_function(input_tensor=tf.TensorSpec(shape=[1, None, None, 3], dtype=tf.uint8))
f2 = convert_variables_to_constants_v2(f)
graph_def = f2.graph.as_graph_def()

# Export frozen graph
with tf.io.gfile.GFile('frozen_graph.pb', 'wb') as f:
   f.write(graph_def.SerializeToString())

Upvotes: 3

Related Questions