First of all, thanks for taking the time to make this amazing repo.
While using this repo I am stuck in the following situation, I am trying to convert a trained keras model to a compatible format to enable running it using tensorflow serving. I have the following two pieces of code with me which I am trying to use to convert.
from __future__ import print_function
import os
import shutil
from glob import glob
from keras.models import load_model
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from tensorflow.python.keras.estimator import model_to_estimator
import tensorflow as tf
import keras_resnet
from tensorflow.python.keras._impl.keras.models import Model
from keras_retinanet import models
import keras_resnet.models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
def export_for_serving(model_path, model):
'''
Converts model to the TensorFlow estimator and saves it to the disk
:param model: keras model to prepare for serving
'''
export_dir = 'tf_serving_model/'
if os.path.exists(export_dir):
shutil.rmtree(export_dir)
tf_estimator = model_to_estimator(keras_model=model)
tf_estimator.export_savedmodel(
export_dir,
serving_input_receiver_fn,
strip_default_attrs=True)
model_path = os.path.join('.', 'snapshots', 'resnet50_csv_15_model.h5')
model = Model(models.load_model(model_path, backbone_name='resnet50'))
print("loaded model")
export_for_serving(model_path=model_path, model=model)
Running this throws the following error:
Traceback (most recent call last): File "keras_to_tensorflow_serving.py", line 42, in <module>
model = Model(models.load_model(model_path, backbone_name='resnet50'))
TypeError: __init__() missing 1 required positional argument: 'outputs'
from __future__ import print_function
import os
import shutil
from glob import glob
from keras.models import load_model
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from tensorflow.python.keras.estimator import model_to_estimator
import tensorflow as tf
import keras_resnet
from keras_retinanet import models
import keras_resnet.models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
def export_for_serving(model_path, model):
'''
Converts model to the TensorFlow estimator and saves it to the disk
:param model: keras model to prepare for serving
'''
export_dir = 'tf_serving_model/'
if os.path.exists(export_dir):
shutil.rmtree(export_dir)
tf_estimator = model_to_estimator(keras_model_path=model_path)
tf_estimator.export_savedmodel(
export_dir,
serving_input_receiver_fn,
strip_default_attrs=True)
model_path = os.path.join('.', 'snapshots', 'resnet50_csv_15_model.h5')
model = models.load_model(model_path, backbone_name='resnet50')
print("Loaded Model")
export_for_serving(model_path=model_path, model=model)
I am receiving the following error:
Traceback (most recent call last):
File "keras_to_tensorflow_serving.py", line 42, in <module>
export_for_serving(model_path=model_path, model=model)
File "keras_to_tensorflow_serving.py", line 32, in export_for_serving
tf_estimator = model_to_estimator(keras_model_path=model_path, custom_objects=custom_objects)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/estimator.py", line 456, in model_to_estimator
keras_model = models.load_model(keras_model_path)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/engine/saving.py", line 240, in load_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/engine/saving.py", line 317, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 171, in deserialize_keras_object
list(custom_objects.items())))
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/engine/network.py", line 1060, in from_config
process_layer(layer_data)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/engine/network.py", line 1046, in process_layer
layer = deserialize_layer(layer_data, custom_objects=custom_objects)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 173, in deserialize_keras_object
return cls.from_config(config['config'])
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/engine/base_layer.py", line 473, in from_config
return cls(**config)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/layers/normalization.py", line 107, in __init__
**kwargs
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/layers/normalization.py", line 146, in __init__
name=name, trainable=trainable, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/keras/_impl/keras/engine/base_layer.py", line 128, in __init__
raise TypeError('Keyword argument not understood:', kwarg)
TypeError: ('Keyword argument not understood:', u'freeze')
I am using the latest version of the repo using Keras 2.2.0. Also, the model I am trying to convert is trained using the same latest version of the repo.
Can anyone please point out the mistake I am making. Any help would be greatly appreciated.
Thanks in advance.
I had a quick look at the second part, from .h5 file, the missing part are the custom_objects; you should retrieve the custom objects of keras_retinanet and pass them to the function model_to_estimator, as described here https://www.tensorflow.org/api_docs/python/tf/keras/estimator/model_to_estimator.
Hey, I tried using the following piece:
from __future__ import print_function
import os
import shutil
from glob import glob
from keras.models import load_model
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from tensorflow.python.keras.estimator import model_to_estimator
import tensorflow as tf
from keras_retinanet import models
import keras_resnet.models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
from tensorflow.python.keras._impl.keras.models import Model
def export_for_serving(model_path, model):
'''
Converts model to the TensorFlow estimator and saves it to the disk
:param model: keras model to prepare for serving
'''
export_dir = 'tf_serving_model/'
if os.path.exists(export_dir):
shutil.rmtree(export_dir)
tf_estimator = model_to_estimator(keras_model_path=model_path, custom_objects=models.backbone('resnet50').custom_objects)
tf_estimator.export_savedmodel(
export_dir,
serving_input_receiver_fn,
strip_default_attrs=True)
model_path = os.path.join('.', 'snapshots', 'resnet50_csv_15_infer.h5')
model = models.load_model(model_path, backbone_name='resnet50')
print("Loaded Model")
export_for_serving(model_path=model_path, model=model)
The following is the log from this run:
Loaded Model
Traceback (most recent call last):
File "keras_to_tensorflow_serving.py", line 42, in <module>
export_for_serving(model_path=model_path, model=model)
File "keras_to_tensorflow_serving.py", line 32, in export_for_serving
tf_estimator = model_to_estimator(keras_model_path=model_path, custom_objects=models.backbone('resnet50').custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/estimator.py", line 265, in model_to_estimator
keras_model = models.load_model(keras_model_path)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 245, in load_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 323, in model_from_config
return layer_module.deserialize(config, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 163, in deserialize_keras_object
list(custom_objects.items())))
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 967, in from_config
process_layer(layer_data)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 953, in process_layer
layer = deserialize_layer(layer_data, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 165, in deserialize_keras_object
return cls.from_config(config['config'])
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 475, in from_config
return cls(**config)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/normalization.py", line 104,in __init__
**kwargs
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/layers/normalization.py", line 118, in __init__
name=name, trainable=trainable, **kwargs)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 141, in __init__
raise TypeError('Keyword argument not understood:', kwarg)
TypeError: ('Keyword argument not understood:', 'freeze')
I believe there is some issue in loading custom_object correctly. Any ideas how I can make this work.
@vcarpani Will be glad if you can please help me out with this
TypeError: ('Keyword argument not understood:', 'freeze')
That indeed usually means the custom_objects are not used, which means it is trying to load a wrong layer. I've never used tensorflow serving before, but it seems like you can give model_to_estimator either a model path or a model. What happens if you give it a model instead of the path, as you do in your code above?
Did you manage to resolve the issue ?
Hi @hgaiser,
I tried passing model to model_to_estimator() function :
from __future__ import print_function
import os
import shutil
from glob import glob
from keras.models import load_model
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from tensorflow.python.keras.estimator import model_to_estimator
import tensorflow as tf
from tensorflow.python.keras._impl.keras.models import Model
from keras_retinanet import models
import keras_resnet.models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
def export_for_serving(model_path, model):
'''
Converts model to the TensorFlow estimator and saves it to the disk
:param model: keras model to prepare for serving
'''
export_dir = 'tf_serving_model/'
if os.path.exists(export_dir):
shutil.rmtree(export_dir)
tf_estimator = model_to_estimator(keras_model=model, custom_objects=models.backbone('resnet50').custom_objects)
tf_estimator.export_savedmodel(
export_dir,
serving_input_receiver_fn,
strip_default_attrs=True)
model_path = os.path.join('.', 'snapshots', 'resnet50_csv_15_model.h5')
model = models.load_model(model_path, backbone_name='resnet50')
print("Loaded Model")
export_for_serving(model_path=model_path, model=model)
Following is the error from that run :-
Using TensorFlow backend.
/opt/conda/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6
return f(*args, **kwds)
2018-09-25 13:56:57.765407: I tensorflow/core/platform/cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX
Loaded Model
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp62vc_5qg
Traceback (most recent call last):
File "keras_to_tensorflow_serving.py", line 42, in <module>
export_for_serving(model_path=model_path, model=model)
File "keras_to_tensorflow_serving.py", line 32, in export_for_serving
tf_estimator = model_to_estimator(keras_model=model, custom_objects=models.backbone('resnet50').custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/estimator.py", line 280, in model_to_estimator
_save_first_checkpoint(keras_model, est, custom_objects, keras_weights)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/estimator.py", line 209, in _save_first_checkpoint
custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/estimator.py", line 95, in _clone_and_build_model
model = models.clone_model(keras_model, input_tensors=input_tensors)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 1461, in clone_model
return _clone_functional_model(model, input_tensors=input_tensors)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 1265, in _clone_functional_model
'to be a `Model` instance, got ', model)
ValueError: ('Expected `model` argument to be a `Model` instance, got ', <keras.engine.training.Model object at 0x7f618f9a0b00>)
I also tried keras implementation of tensorflow.
On using tf implementation of keras to load model file without custom objects :-
from __future__ import print_function
import os
import shutil
from glob import glob
#from keras.models import load_model
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from tensorflow.python.keras.estimator import model_to_estimator
import tensorflow as tf
from tensorflow.python.keras._impl.keras.models import Model, load_model
from keras_retinanet import models
import keras_resnet.models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
def export_for_serving(model_path, model):
'''
Converts model to the TensorFlow estimator and saves it to the disk
:param model: keras model to prepare for serving
'''
export_dir = 'tf_serving_model/'
if os.path.exists(export_dir):
shutil.rmtree(export_dir)
tf_estimator = model_to_estimator(keras_model=model, custom_objects=models.backbone('resnet50').custom_objects)
tf_estimator.export_savedmodel(
export_dir,
serving_input_receiver_fn,
strip_default_attrs=True)
model_path = os.path.join('.', 'snapshots', 'resnet50_csv_15_model.h5')
model = load_model(model_path, compile=True)
print("Loaded Model")
export_for_serving(model_path=model_path, model=model)
Following is the error :
Using TensorFlow backend.
Traceback (most recent call last):
File "keras_to_tensorflow.py", line 39, in <module>
model = load_model(model_path)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 246, in load_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 324, in model_from_config
return layer_module.deserialize(config, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 164, in deserialize_keras_object
list(custom_objects.items())))
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 975, in from_config
process_layer(layer_data)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 961, in process_layer
layer = deserialize_layer(layer_data, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 166, in deserialize_keras_object
return cls.from_config(config['config'])
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 483, in from_config
return cls(**config)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/normalization.py", line 104,in __init__
**kwargs
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/layers/normalization.py", line 144, in __init__
name=name, trainable=trainable, **kwargs)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 147, in __init__
raise TypeError('Keyword argument not understood:', kwarg)
TypeError: ('Keyword argument not understood:', 'freeze')
On using tf implementation of keras to load model file with custom objects
from __future__ import print_function
import os
import shutil
from glob import glob
#from keras.models import load_model
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from tensorflow.python.keras.estimator import model_to_estimator
import tensorflow as tf
from tensorflow.python.keras._impl.keras.models import Model, load_model
from keras_retinanet import models
import keras_resnet.models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
def export_for_serving(model_path, model):
'''
Converts model to the TensorFlow estimator and saves it to the disk
:param model: keras model to prepare for serving
'''
export_dir = 'tf_serving_model/'
if os.path.exists(export_dir):
shutil.rmtree(export_dir)
tf_estimator = model_to_estimator(keras_model=model, custom_objects=models.backbone('resnet50').custom_objects)
tf_estimator.export_savedmodel(
export_dir,
serving_input_receiver_fn,
strip_default_attrs=True)
model_path = os.path.join('.', 'snapshots', 'resnet50_csv_15_model.h5')
model = load_model(model_path, custom_objects=models.backbone('resnet50').custom_objects, compile=True)
print("Loaded Model")
export_for_serving(model_path=model_path, model=model)
Following is the error :
Using TensorFlow backend.
Traceback (most recent call last):
File "keras_to_tensorflow.py", line 39, in <module>
model = load_model(model_path, custom_objects=models.backbone('resnet50').custom_objects, compile=True)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 246, in load_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/models.py", line 324, in model_from_config
return layer_module.deserialize(config, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 164, in deserialize_keras_object
list(custom_objects.items())))
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 975, in from_config
process_layer(layer_data)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 961, in process_layer
layer = deserialize_layer(layer_data, custom_objects=custom_objects)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/layers/serialization.py", line 63, in deserialize
printable_module_name='layer')
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/utils/generic_utils.py", line 164, in deserialize_keras_object
list(custom_objects.items())))
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 985, in from_config
process_node(layer, node_data)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 943, in process_node
layer(input_tensors[0], **kwargs)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 258, in __call__
output = super(Layer, self).__call__(inputs, **kwargs)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/layers/base.py", line 636, in __call__
self.build(input_shapes)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/layers/convolutional.py", line 151, in build
dtype=self.dtype)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/layers/base.py", line 504, in add_variable
partitioner=partitioner)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variable_scope.py", line 1262, in get_variable
constraint=constraint)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variable_scope.py", line 1097, in get_variable
constraint=constraint)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variable_scope.py", line 435, in get_variable
constraint=constraint)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variable_scope.py", line 404, in _true_getter
use_resource=use_resource, constraint=constraint)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variable_scope.py", line 806, in _get_single_variable
constraint=constraint)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variables.py", line 229, in __init__
constraint=constraint)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variables.py", line 323, in _init_from_args
initial_value(), name="initial_value", dtype=dtype)
File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/variable_scope.py", line 780, in <lambda>
shape.as_list(), dtype=dtype, partition_info=partition_info)
TypeError: __call__() got an unexpected keyword argument 'partition_info'
I am pretty much stuck at this. Do you have any clue what might be going wrong. We need to deploy our created model on production so any help would be greatly appreciated.
@hgaiser @vcarpani Any suggestions would be helpful. Thanks.
I've never seen that error before, nor have I ever tried tensorflow serving.
@hgaiser Any suggestions on the best way to deploy the trained model for production?
I've not yet looked into deploying tensorflow models, but I'd be interested to hear your experiences :)
Hey, I have successed transforming a keras model to tf model and i can load it with the tf C-api. But I acturally met a problem. That is i had to fix the image size to a square, such as 448X448,this issue lead to a drop performence. Beside, I can't finish the postprocessing with C++.
Hey, I have successed transforming a keras model to tf model and i can load it with the tf C-api. But I acturally met a problem. That is i had to fix the image size to a square, such as 448X448,this issue lead to a drop performence. Beside, I can't finish the postprocessing with C++.
Can you share the code how to convert this model to tf model?Thanks.
"""
Copyright (c) 2017, by the Authors: Amir H. Abdi
This software is freely available under the MIT Public License.
Please see the License file in the root for details.
The following code snippet will convert the keras model file,
which is saved using model.save('kerasmodel_weight_file'),
to the freezed .pb tensorflow weight file which holds both the
network architecture and its associated weights.
""";
'''
Input arguments:
num_output: this value has nothing to do with the number of classes, batch_size, etc.,
and it is mostly equal to 1. If the network is a multi-stream network
(forked network with multiple outputs), set the value to the number of outputs.
quantize: if set to True, use the quantize feature of Tensorflow
(https://www.tensorflow.org/performance/quantization) [default: False]
use_theano: Thaeno and Tensorflow implement convolution in different ways.
When using Keras with Theano backend, the order is set to 'channels_first'.
This feature is not fully tested, and doesn't work with quantizization [default: False]
input_fld: directory holding the keras weights file [default: .]
output_fld: destination directory to save the tensorflow files [default: .]
input_model_file: name of the input weight file [default: 'model.h5']
output_model_file: name of the output weight file [default: args.input_model_file + '.pb']
graph_def: if set to True, will write the graph definition as an ascii file [default: False]
output_graphdef_file: if graph_def is set to True, the file name of the
graph definition [default: model.ascii]
output_node_prefix: the prefix to use for output nodes. [default: output_node]
'''
import argparse
parser = argparse.ArgumentParser(description='set input arguments')
parser.add_argument('-input_fld', action="store",
dest='input_fld', type=str, default='.')
parser.add_argument('-output_fld', action="store",
dest='output_fld', type=str, default='')
parser.add_argument('-input_model_file', action="store",
dest='input_model_file', type=str, default='model.h5')
parser.add_argument('-output_model_file', action="store",
dest='output_model_file', type=str, default='')
parser.add_argument('-output_graphdef_file', action="store",
dest='output_graphdef_file', type=str, default='model.ascii')
parser.add_argument('-num_outputs', action="store",
dest='num_outputs', type=int, default=4)
parser.add_argument('-graph_def', action="store",
dest='graph_def', type=bool, default=True)
parser.add_argument('-output_node_prefix', action="store",
dest='output_node_prefix', type=str, default='output_node')
parser.add_argument('-quantize', action="store",
dest='quantize', type=bool, default=False)
parser.add_argument('-theano_backend', action="store",
dest='theano_backend', type=bool, default=False)
parser.add_argument('-f')
args = parser.parse_args()
parser.print_help()
print('input args: ', args)
if args.theano_backend is True and args.quantize is True:
raise ValueError("Quantize feature does not work with theano backend.")
from resnet import custom_objects
from keras.models import load_model
import tensorflow as tf
from pathlib import Path
from keras import backend as K
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "1"
output_fld = args.input_fld if args.output_fld == '' else args.output_fld
if args.output_model_file == '':
args.output_model_file = str(Path(args.input_model_file).name) + '.pb'
Path(output_fld).mkdir(parents=True, exist_ok=True)
weight_file_path = str(Path(args.input_fld) / args.input_model_file)
K.set_learning_phase(0)
if args.theano_backend:
K.set_image_data_format('channels_first')
else:
K.set_image_data_format('channels_last')
try:
net_model = load_model(weight_file_path,custom_objects=custom_objects)
except ValueError as err:
print('''Input file specified ({}) only holds the weights, and not the model defenition.
Save the model using mode.save(filename.h5) which will contain the network architecture
as well as its weights.
If the model is saved using model.save_weights(filename.h5), the model architecture is
expected to be saved separately in a json format and loaded prior to loading the weights.
Check the keras documentation for more details (https://keras.io/getting-started/faq/)'''
.format(weight_file_path))
raise err
num_output = args.num_outputs
pred = [None]num_output
pred_node_names = [None]num_output
for i in range(num_output):
pred_node_names[i] = args.output_node_prefix+str(i)
pred[i] = tf.identity(net_model.outputs[i], name=pred_node_names[i])
print('output nodes names are: ', pred_node_names)
sess = K.get_session()
if args.graph_def:
f = args.output_graphdef_file
tf.train.write_graph(sess.graph.as_graph_def(), output_fld, f, as_text=True)
print('saved the graph definition in ascii format at: ', str(Path(output_fld) / f))
@vivekpd15 maybe you can try the following code.
import tensorflow as tf
import os
import os.path as osp
from keras import backend as K
from sys import argv
import sys
if __name__ == "__main__" and __package__ is None:
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
import keras_retinanet.bin # noqa: F401
__package__ = "keras_retinanet.bin"
from .. import models
input_path = argv[-2]
weight_file = argv[-1]
weight_file_path = osp.join(input_path,weight_file)
output_graph_name = weight_file[:-3] + '.pb'
def get_session():
""" Construct a modified tf session.
"""
config = tf.ConfigProto()
os.environ["CUDA_VISIBLE_DEVICES"] = ""
return tf.Session(config=config)
def h5_to_pb(h5_model,output_dir,model_name,out_prefix = "output_",log_tensorboard = True):
if osp.exists(output_dir) == False:
os.mkdir(output_dir)
out_nodes = []
for i in range(len(h5_model.outputs)):
out_nodes.append(out_prefix + str(i + 1))
tf.identity(h5_model.output[i],out_prefix + str(i + 1))
sess = K.get_session()
from tensorflow.python.framework import graph_util,graph_io
init_graph = sess.graph.as_graph_def()
main_graph = graph_util.convert_variables_to_constants(sess,init_graph,out_nodes)
graph_io.write_graph(main_graph,output_dir,name = model_name,as_text = False)
if log_tensorboard:
from tensorflow.python.tools import import_pb_to_tensorboard
import_pb_to_tensorboard.import_to_tensorboard(osp.join(output_dir,model_name),output_dir)
output_dir = osp.join(os.getcwd(),"trans_model")
K.tensorflow_backend.set_session(get_session())
anchor_parameters = None
h5_model = models.load_model(weight_file_path)
models.check_training_model(h5_model)
h5_model = models.convert_model(h5_model, nms=True, class_specific_filter=False, anchor_params=anchor_parameters)
h5_to_pb(h5_model,output_dir = output_dir,model_name = output_graph_name)
print('model saved')
@Alan000 Thanks for replying. Can you please send the code of yours with proper indentations. I am unable to run this or figure out where exactly to put the indentations. It would be of great help. Thanks.
@Alan000 Thanks for replying. Can you please send the code of yours with proper indentations. I am unable to run this or figure out where exactly to put the indentations. It would be of great help. Thanks.
Sorry for improper indentations. The revised code is as follows.
import tensorflow as tf
import os
import os.path as osp
from keras import backend as K
from sys import argv
import sys
# Allow relative imports when being executed as script.
if __name__ == "__main__" and __package__ is None:
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
import keras_retinanet.bin # noqa: F401
__package__ = "keras_retinanet.bin"
from .. import models
input_path = argv[-2]
weight_file = argv[-1]
weight_file_path = osp.join(input_path,weight_file)
output_graph_name = weight_file[:-3] + '.pb'
def get_session():
""" Construct a modified tf session.
"""
config = tf.ConfigProto()
os.environ["CUDA_VISIBLE_DEVICES"] = ""
return tf.Session(config=config)
# convert hdf5 file to protocolbuffer file
def h5_to_pb(h5_model,output_dir,model_name,out_prefix = "output_",log_tensorboard = True):
if osp.exists(output_dir) == False:
os.mkdir(output_dir)
out_nodes = []
for i in range(len(h5_model.outputs)):
out_nodes.append(out_prefix + str(i + 1))
tf.identity(h5_model.output[i],out_prefix + str(i + 1))
sess = K.get_session()
from tensorflow.python.framework import graph_util,graph_io
init_graph = sess.graph.as_graph_def()
main_graph = graph_util.convert_variables_to_constants(sess,init_graph,out_nodes)
graph_io.write_graph(main_graph,output_dir,name = model_name,as_text = False)
if log_tensorboard:
from tensorflow.python.tools import import_pb_to_tensorboard
import_pb_to_tensorboard.import_to_tensorboard(osp.join(output_dir,model_name),output_dir)
output_dir = osp.join(os.getcwd(),"trans_model")
K.tensorflow_backend.set_session(get_session())
# optionally load config parameters
anchor_parameters = None
h5_model = models.load_model(weight_file_path)
# check if this is indeed a training model
models.check_training_model(h5_model)
# convert the model
h5_model = models.convert_model(h5_model, nms=True, class_specific_filter=False, anchor_params=anchor_parameters)
h5_to_pb(h5_model,output_dir = output_dir,model_name = output_graph_name)
print('model saved')
@Alan000 I converted h5 model to pb model by you code, however锛寃hen i predict a image with the pb model, the predict result is error, can you explain this error?
tensor prefix/filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0 result is:
[[[ 9.5135071e+02 0.0000000e+00 1.0670000e+03 2.1252492e+02]
[ 9.6763727e+02 0.0000000e+00 1.0670000e+03 2.4177216e+02]
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]
...
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]]]
@Alan000 I converted h5 model to pb model by you code, however锛寃hen i predict a image with the pb model, the predict result is error, can you explain this error?
tensor prefix/filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0 result is:
[[[ 9.5135071e+02 0.0000000e+00 1.0670000e+03 2.1252492e+02]
[ 9.6763727e+02 0.0000000e+00 1.0670000e+03 2.4177216e+02]
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]
...
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]
[-1.0000000e+00 -1.0000000e+00 -1.0000000e+00 -1.0000000e+00]]]
The result maybe right锛宨t is just the complete output of model. The predict result contains boxes, scores and labels value, you need filter the result by score threshold and use NMS to choose the final boxes.
@WillLiGitHub Once you load the graph from the .pb file, you just need to specify the input and output tensors and run inference normally. At least that's what I did. Refer this Stack Overflow post to learn more.
If you just want to see how to do inference using the .pb file, check out my notebook here
I converted .h5 to .pb using https://github.com/fizyr/keras-retinanet/issues/676#issuecomment-442711158 and tried to run with tfserving, but I get a following error.
2019-03-08 04:26:00.087954: I tensorflow_serving/model_servers/server.cc:82] Building single TensorFlow model file config: model_name: retinanet model_base_path: /models/retinanet
2019-03-08 04:26:00.088646: I tensorflow_serving/model_servers/server_core.cc:461] Adding/updating models.
2019-03-08 04:26:00.088672: I tensorflow_serving/model_servers/server_core.cc:558] (Re-)adding model: retinanet
2019-03-08 04:26:00.189388: I tensorflow_serving/core/basic_manager.cc:739] Successfully reserved resources to load servable {name: retinanet version: 1}
2019-03-08 04:26:00.189424: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: retinanet version: 1}
2019-03-08 04:26:00.189501: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: retinanet version: 1}
2019-03-08 04:26:00.189576: I external/org_tensorflow/tensorflow/contrib/session_bundle/bundle_shim.cc:363] Attempting to load native SavedModelBundle in bundle-shim from: /models/retinanet/1
2019-03-08 04:26:00.189593: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:31] Reading SavedModel from: /models/retinanet/1
2019-03-08 04:26:00.420547: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:54] Reading meta graph with tags { serve }
2019-03-08 04:26:00.428493: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:259] SavedModel load for tags { serve }; Status: fail. Took 238876 microseconds.
2019-03-08 04:26:00.428544: E tensorflow_serving/util/retrier.cc:37] Loading servable: {name: retinanet version: 1} failed: Not found: Could not find meta graph def matching supplied tags: { serve }. To inspect available tag-sets in the SavedModel, please use the SavedModel CLI: `saved_model_cli`
Anybody knows how to fix this? Sorry but I'm newbie in tfserving.
I haven't found a solution, but I think I've found the root of the problem.
Retinanet implements batch norm with it's own layer that allows freezing, found here: https://github.com/broadinstitute/keras-resnet/blob/master/keras_resnet/layers/_batch_normalization.py
It passes one extra boolean variable freeze that controls the freezing. The file is pretty simple but I can explain it if someone doesn't get it.
So when tensorflow tries to load up the custom objects, it gets confused when it gets batch norm with one extra variable name "freeze," and thus returns the error. My layer's batch norm was all default values, so I tried doing something like so:
bn = keras.layers.BatchNormalization()
c_o = models.backbone("resnet50").custom_objects
c_o["BatchNormalization"] = bn
tf_estimator = model_to_estimator(keras_model_path=model_path, custom_objects=c_o)
but ended up STILL getting the error. Based on the traceback, which I'll put below, I was pretty certain that replacing the custom BatchNormalization would do the trick. I looked at the other layers in custom_objects and they didn't have anything like "freeze," and the final lines of the traceback imply that the problem is in defining the normalization. The fact that it's a keyword argument further reinforces my idea that it's the batch norm layer.
I didn't figure it out but I think we can get this working!!
Here's the full traceback error I got. Happy to provide more info if it'd help.
Traceback (most recent call last):
File "app/models/convert_model.py", line 93, in <module>
export_for_serving("resnet50_kw_24.h5", model)
File "app/models/convert_model.py", line 84, in export_for_serving
tf_estimator = model_to_estimator(keras_model_path=model_path, custom_objects=c_o)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/estimator/__init__.py", line 73, in model_to_estimator
config=config)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow_estimator/python/estimator/keras.py", line 458, in model_to_estimator
keras_model = models.load_model(keras_model_path)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/engine/saving.py", line 234, in load_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/engine/saving.py", line 324, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/layers/serialization.py", line 74, in deserialize
printable_module_name='layer')
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/utils/generic_utils.py", line 192, in deserialize_keras_object
list(custom_objects.items())))
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py", line 1263, in from_config
process_layer(layer_data)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py", line 1249, in process_layer
layer = deserialize_layer(layer_data, custom_objects=custom_objects)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/layers/serialization.py", line 74, in deserialize
printable_module_name='layer')
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/utils/generic_utils.py", line 194, in deserialize_keras_object
return cls.from_config(cls_config)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 402, in from_config
return cls(**config)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/layers/normalization.py", line 155, in __init__
name=name, trainable=trainable, **kwargs)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/training/checkpointable/base.py", line 442, in _method_wrapper
method(self, *args, **kwargs)
File "/home/max/anaconda3/envs/paper2digital/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 122, in __init__
raise TypeError('Keyword argument not understood:', kwarg)
TypeError: ('Keyword argument not understood:', 'freeze')
I use the following to create a TensorFlow model for TensorFlow serving. The code below assumes that you have a RetinaNet model with 8 classes using the resnet101 backbone with weights saved in a file called model.h5. You'll need to edit those for your use case. It will create a folder called retinanet_savedmodel with the TensorFlow files inside of it.
from keras import backend as K
import tensorflow as tf
from tensorflow.python import saved_model
from tensorflow.python.saved_model.signature_def_utils_impl import (
build_signature_def, predict_signature_def
)
from keras_retinanet import models
import shutil
import os
export_path = 'retinanet_savedmodel'
model = models.convert_model(
model=models.backbone(backbone_name='resnet101').retinanet(num_classes=8),
nms=True,
class_specific_filter=True,
anchor_params=None
)
model.load_weights('model.h5')
print('Output layers', [o.name[:-2] for o in model.outputs])
print('Input layer', model.inputs[0].name[:-2])
if os.path.isdir(export_path):
shutil.rmtree(export_path)
builder = saved_model.builder.SavedModelBuilder(export_path)
signature = predict_signature_def(
inputs={'images': model.input},
outputs={
'output1': model.outputs[0],
'output2': model.outputs[1],
'output3': model.outputs[2]
}
)
sess = K.get_session()
builder.add_meta_graph_and_variables(sess=sess,
tags=[saved_model.tag_constants.SERVING],
signature_def_map={'predict': signature})
builder.save()
After executing the above, you can use TensorFlow Serving using the following command (note the 1 which is important).
docker run -t --rm -p 8501:8501 -v "$PWD/retinanet_savedmodel:/models/retinanet/1" -e MODEL_NAME=retinanet tensorflow/serving
I hope this helps someone! :)
Awesome, thanks @faustomorales . I'll go ahead and close this issue then :)
I use the following to create a TensorFlow model for TensorFlow serving. The code below assumes that you have a RetinaNet model with 8 classes using the
resnet101backbone with weights saved in a file calledmodel.h5. You'll need to edit those for your use case. It will create a folder calledretinanet_savedmodelwith the TensorFlow files inside of it.from keras import backend as K import tensorflow as tf from tensorflow.python import saved_model from tensorflow.python.saved_model.signature_def_utils_impl import ( build_signature_def, predict_signature_def ) from keras_retinanet import models import shutil import os export_path = 'retinanet_savedmodel' model = models.convert_model( model=models.backbone(backbone_name='resnet101').retinanet(num_classes=8), nms=True, class_specific_filter=True, anchor_params=None ) model.load_weights('model.h5') print('Output layers', [o.name[:-2] for o in model.outputs]) print('Input layer', model.inputs[0].name[:-2]) if os.path.isdir(export_path): shutil.rmtree(export_path) builder = saved_model.builder.SavedModelBuilder(export_path) signature = predict_signature_def( inputs={'images': model.input}, outputs={ 'output1': model.outputs[0], 'output2': model.outputs[1], 'output3': model.outputs[2] } ) sess = K.get_session() builder.add_meta_graph_and_variables(sess=sess, tags=[saved_model.tag_constants.SERVING], signature_def_map={'predict': signature}) builder.save()After executing the above, you can use TensorFlow Serving using the following command (note the
1which is important).docker run -t --rm -p 8501:8501 -v "$PWD/retinanet_savedmodel:/models/retinanet/1" -e MODEL_NAME=retinanet tensorflow/servingI hope this helps someone! :)
thanks a lot,it works!
@b1xian and @hgaiser I have serving script ready. Can you help me in the inference part. Once you start docker how do you get the inference ?
I use the following to create a TensorFlow model for TensorFlow serving. The code below assumes that you have a RetinaNet model with 8 classes using the
resnet101backbone with weights saved in a file calledmodel.h5. You'll need to edit those for your use case. It will create a folder calledretinanet_savedmodelwith the TensorFlow files inside of it.from keras import backend as K import tensorflow as tf from tensorflow.python import saved_model from tensorflow.python.saved_model.signature_def_utils_impl import ( build_signature_def, predict_signature_def ) from keras_retinanet import models import shutil import os export_path = 'retinanet_savedmodel' model = models.convert_model( model=models.backbone(backbone_name='resnet101').retinanet(num_classes=8), nms=True, class_specific_filter=True, anchor_params=None ) model.load_weights('model.h5') print('Output layers', [o.name[:-2] for o in model.outputs]) print('Input layer', model.inputs[0].name[:-2]) if os.path.isdir(export_path): shutil.rmtree(export_path) builder = saved_model.builder.SavedModelBuilder(export_path) signature = predict_signature_def( inputs={'images': model.input}, outputs={ 'output1': model.outputs[0], 'output2': model.outputs[1], 'output3': model.outputs[2] } ) sess = K.get_session() builder.add_meta_graph_and_variables(sess=sess, tags=[saved_model.tag_constants.SERVING], signature_def_map={'predict': signature}) builder.save()After executing the above, you can use TensorFlow Serving using the following command (note the
1which is important).docker run -t --rm -p 8501:8501 -v "$PWD/retinanet_savedmodel:/models/retinanet/1" -e MODEL_NAME=retinanet tensorflow/servingI hope this helps someone! :)
I have a problem, this is:
ValueError: Dimension 0 in both shapes must be equal, but are 3 and 18. Shapes are [3,3,256,72] and [18,256,3,3]. for 'Assign_299' (op: 'Assign') with input shapes: [3,3,256,72], [18,256,3,3].
can someone help me, please.
Most helpful comment
I use the following to create a TensorFlow model for TensorFlow serving. The code below assumes that you have a RetinaNet model with 8 classes using the
resnet101backbone with weights saved in a file calledmodel.h5. You'll need to edit those for your use case. It will create a folder calledretinanet_savedmodelwith the TensorFlow files inside of it.After executing the above, you can use TensorFlow Serving using the following command (note the
1which is important).I hope this helps someone! :)