ChatGPT解决这个技术问题 Extra ChatGPT

How to export Keras .h5 to tensorflow .pb?

I have fine-tuned inception model with a new dataset and saved it as ".h5" model in Keras. now my goal is to run my model on android Tensorflow which accepts ".pb" extension only. question is that is there any library in Keras or tensorflow to do this conversion? I have seen this post so far : https://blog.keras.io/keras-as-a-simplified-interface-to-tensorflow-tutorial.html but can't figure out yet.


j
jdehesa

Keras does not include by itself any means to export a TensorFlow graph as a protocol buffers file, but you can do it using regular TensorFlow utilities. Here is a blog post explaining how to do it using the utility script freeze_graph.py included in TensorFlow, which is the "typical" way it is done.

However, I personally find a nuisance having to make a checkpoint and then run an external script to obtain a model, and instead prefer to do it from my own Python code, so I use a function like this:

def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
    """
    Freezes the state of a session into a pruned computation graph.

    Creates a new computation graph where variable nodes are replaced by
    constants taking their current value in the session. The new graph will be
    pruned so subgraphs that are not necessary to compute the requested
    outputs are removed.
    @param session The TensorFlow session to be frozen.
    @param keep_var_names A list of variable names that should not be frozen,
                          or None to freeze all the variables in the graph.
    @param output_names Names of the relevant graph outputs.
    @param clear_devices Remove the device directives from the graph for better portability.
    @return The frozen graph definition.
    """
    graph = session.graph
    with graph.as_default():
        freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
        output_names = output_names or []
        output_names += [v.op.name for v in tf.global_variables()]
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ""
        frozen_graph = tf.graph_util.convert_variables_to_constants(
            session, input_graph_def, output_names, freeze_var_names)
        return frozen_graph

Which is inspired in the implementation of freeze_graph.py. The parameters are similar to the script too. session is the TensorFlow session object. keep_var_names is only needed if you want to keep some variable not frozen (e.g. for stateful models), so generally not. output_names is a list with the names of the operations that produce the outputs that you want. clear_devices just removes any device directives to make the graph more portable. So, for a typical Keras model with one output, you would do something like:

from keras import backend as K

# Create, compile and train model...

frozen_graph = freeze_session(K.get_session(),
                              output_names=[out.op.name for out in model.outputs])

Then you can write the graph to a file as usual with tf.train.write_graph:

tf.train.write_graph(frozen_graph, "some_directory", "my_model.pb", as_text=False)

That seems to work with me. However, the output .pb file does not have the same input node names. Is that right? The input node name was input_1 but after freezing, I do not know the new name. Can you tell me what the new name would be?
I am getting an error in model.output.op.name. Can you please tell how to resolve this?
In similar posts I have seen "keras.backend.set_learning_phase(0)" used before. Is this also necessary here?
@gebbissimo Well, this "prunes" the graph so only the operations and variables that you need to compute the given outputs are actually exported (so training-related variables should not get exported unless you actually request training operations). But yes, the post you linked is another valid solution, and in fact is pretty much equivalent, since both are based on convert_variables_to_constants (which "freezes" the variables and prunes the graph).
Why I built a simple model but save it into a pb file with a very large file size?
J
Jeff Tang

The freeze_session method works fine. But compared to saving to a checkpoint file then using the freeze_graph tool that comes with TensorFlow seems simpler to me, as it's easier to maintain. All you need to do is the following two steps:

First, add after your Keras code model.fit(...) and train your model:

from keras import backend as K
import tensorflow as tf
print(model.output.op.name)
saver = tf.train.Saver()
saver.save(K.get_session(), '/tmp/keras_model.ckpt')

Then cd to your TensorFlow root directory, run:

python tensorflow/python/tools/freeze_graph.py \
--input_meta_graph=/tmp/keras_model.ckpt.meta \
--input_checkpoint=/tmp/keras_model.ckpt \
--output_graph=/tmp/keras_frozen.pb \
--output_node_names="<output_node_name_printed_in_step_1>" \
--input_binary=true

I had to set K.set_learning_phase(0) before saving the checkpoint. Otherwise I faced the error Keras error “You must feed a value for placeholder tensor 'keras_learning_phase' with dtype bool” while running it on android. I set 0 because I only need the model for inference.
K.set_learning_phase must be called before loading the model.
A
Amir Saniyan

Update for Tensorflow 2

Saving everything into a single archive in the TensorFlow SavedModel format (contains saved_model.pb file):

model = ...  # Get model (Sequential, Functional Model, or Model subclass)
model.save('path/to/location')

or in the older Keras H5 format:

model = ...  # Get model (Sequential, Functional Model, or Model subclass)
model.save('model.h5')

The recommended format is SavedModel.

Loading the model back:

from tensorflow import keras
model = keras.models.load_model('path/to/location')
model = keras.models.load_model('model.h5')

A SavedModel contains a complete TensorFlow program, including trained parameters (i.e, tf.Variables) and computation. It does not require the original model building code to run, which makes it useful for sharing or deploying with TFLite, TensorFlow.js, TensorFlow Serving, or TensorFlow Hub.

Save and load Keras models: https://www.tensorflow.org/guide/keras/save_and_serialize

Using the SavedModel format: https://www.tensorflow.org/guide/saved_model

Example for Tensorflow 2

The following simple example (XOR example) shows how to export Keras models (in both h5 format and pb format), and using the model in Python and C++:

train.py:

import numpy as np
import tensorflow as tf

print(tf.__version__)  # 2.4.1

x_train = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], 'float32')
y_train = np.array([[0], [1], [1], [0]], 'float32')

inputs = tf.keras.Input(shape=(2,), name='input')
x = tf.keras.layers.Dense(64, activation='relu')(inputs)
x = tf.keras.layers.Dense(64, activation='relu')(x)
x = tf.keras.layers.Dense(64, activation='relu')(x)
x = tf.keras.layers.Dense(64, activation="relu")(x)
outputs = tf.keras.layers.Dense(1, activation='sigmoid', name='output')(x)

model = tf.keras.Model(inputs=inputs, outputs=outputs, name='xor')

model.summary()

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

model.fit(x_train, y_train, epochs=100)

model.save('./xor/')  # SavedModel format

model.save('./xor.h5')  # Keras H5 format

After run the above script:

.
├── train.py
├── xor
│   ├── assets
│   ├── saved_model.pb
│   └── variables
│       ├── variables.data-00000-of-00001
│       └── variables.index
└── xor.h5

predict.py:

import numpy as np
import tensorflow as tf

print(tf.__version__)  # 2.4.1

model = tf.keras.models.load_model('./xor/')  # SavedModel format
# model = tf.keras.models.load_model('./xor.h5')  # Keras H5 format

# 0 xor 0 = [[0.11921611]] ~= 0
print('0 xor 0 = ', model.predict(np.array([[0, 0]])))

# 0 xor 1 = [[0.96736085]] ~= 1
print('0 xor 1 = ', model.predict(np.array([[0, 1]])))

# 1 xor 0 = [[0.97254556]] ~= 1
print('1 xor 0 = ', model.predict(np.array([[1, 0]])))

# 1 xor 1 = [[0.0206149]] ~= 0
print('1 xor 1 = ', model.predict(np.array([[1, 1]])))

Convert Model to ONNX:

ONNX is a new standard for exchanging deep learning models. It promises to make deep learning models portable thus preventing vendor lock in.

ONNX is an open format built to represent machine learning models. ONNX defines a common set of operators - the building blocks of machine learning and deep learning models - and a common file format to enable AI developers to use models with a variety of frameworks, tools, runtimes, and compilers.

$ pip install onnxruntime
$ pip install tf2onnx
$ python -m tf2onnx.convert --saved-model ./xor/ --opset 9 --output xor.onnx

# INFO - Successfully converted TensorFlow model ./xor/ to ONNX
# INFO - Model inputs: ['input:0']
# INFO - Model outputs: ['output']
# INFO - ONNX model is saved at xor.onnx

By specifying --opset the user can override the default to generate a graph with the desired opset. For example --opset 13 would create a onnx graph that uses only ops available in opset 13. Because older opsets have in most cases fewer ops, some models might not convert on a older opset.

https://onnx.ai/

https://github.com/onnx/onnx

https://github.com/onnx/tensorflow-onnx

opencv-predict.py:

import numpy as np
import cv2

print(cv2.__version__)  # 4.5.1

model = cv2.dnn.readNetFromONNX('./xor.onnx')

# 0 xor 0 = [[0.11921611]] ~= 0
model.setInput(np.array([[0, 0]]), name='input:0')
print('0 xor 0 = ', model.forward(outputName='output'))

# 0 xor 1 = [[0.96736085]] ~= 1
model.setInput(np.array([[0, 1]]), name='input:0')
print('0 xor 1 = ', model.forward(outputName='output'))

# 1 xor 0 = [[0.97254556]] ~= 1
model.setInput(np.array([[1, 0]]), name='input:0')
print('1 xor 0 = ', model.forward(outputName='output'))

# 1 xor 1 = [[0.02061491]] ~= 0
model.setInput(np.array([[1, 1]]), name='input:0')
print('1 xor 1 = ', model.forward(outputName='output'))

predict.cpp:

#include <cstdlib>
#include <iostream>
#include <opencv2/opencv.hpp>

int main(int argc, char **argv)
{
    std::cout << CV_VERSION << std::endl; // 4.2.0

    cv::dnn::Net net;

    net = cv::dnn::readNetFromONNX("./xor.onnx");

    // 0 xor 0 = [0.11921611] ~= 0
    float x0[] = { 0, 0 };
    net.setInput(cv::Mat(1, 2, CV_32F, x0), "input:0");
    std::cout << "0 xor 0 = " << net.forward("output") << std::endl;

    // 0 xor 1 = [0.96736085] ~= 1
    float x1[] = { 0, 1 };
    net.setInput(cv::Mat(1, 2, CV_32F, x1), "input:0");
    std::cout << "0 xor 1 = " << net.forward("output") << std::endl;

    // 1 xor 0 = [0.97254556] ~= 1
    float x2[] = { 1, 0 };
    net.setInput(cv::Mat(1, 2, CV_32F, x2), "input:0");
    std::cout << "1 xor 0 = " << net.forward("output") << std::endl;

    // 1 xor 1 = [0.020614909] ~= 0
    float x3[] = { 1, 1 };
    net.setInput(cv::Mat(1, 2, CV_32F, x3), "input:0");
    std::cout << "1 xor 1 = " << net.forward("output") << std::endl;

    return EXIT_SUCCESS;
}

Compile and Run:

$ sudo apt install build-essential pkg-config libopencv-dev
$ g++ predict.cpp `pkg-config --cflags --libs opencv4` -o predict
$ ./predict

Original Answer

The following simple example (XOR example) shows how to export Keras models (in both h5 format and pb format), and using the model in Python and C++:

train.py:

import numpy as np
import tensorflow as tf


def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
    """
    Freezes the state of a session into a pruned computation graph.

    Creates a new computation graph where variable nodes are replaced by
    constants taking their current value in the session. The new graph will be
    pruned so subgraphs that are not necessary to compute the requested
    outputs are removed.
    @param session The TensorFlow session to be frozen.
    @param keep_var_names A list of variable names that should not be frozen,
                          or None to freeze all the variables in the graph.
    @param output_names Names of the relevant graph outputs.
    @param clear_devices Remove the device directives from the graph for better portability.
    @return The frozen graph definition.
    """
    graph = session.graph
    with graph.as_default():
        freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
        output_names = output_names or []
        output_names += [v.op.name for v in tf.global_variables()]
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ''
        frozen_graph = tf.graph_util.convert_variables_to_constants(
            session, input_graph_def, output_names, freeze_var_names)
        return frozen_graph


X = np.array([[0,0], [0,1], [1,0], [1,1]], 'float32')
Y = np.array([[0], [1], [1], [0]], 'float32')

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(64, input_dim=2, activation='relu'))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(64, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))

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

model.fit(X, Y, batch_size=1, nb_epoch=100, verbose=0)

# inputs:  ['dense_input']
print('inputs: ', [input.op.name for input in model.inputs])

# outputs:  ['dense_4/Sigmoid']
print('outputs: ', [output.op.name for output in model.outputs])

model.save('./xor.h5')

frozen_graph = freeze_session(tf.keras.backend.get_session(), output_names=[out.op.name for out in model.outputs])
tf.train.write_graph(frozen_graph, './', 'xor.pbtxt', as_text=True)
tf.train.write_graph(frozen_graph, './', 'xor.pb', as_text=False)

predict.py:

import numpy as np
import tensorflow as tf

model = tf.keras.models.load_model('./xor.h5')

# 0 ^ 0 =  [[0.01974997]]
print('0 ^ 0 = ', model.predict(np.array([[0, 0]])))

# 0 ^ 1 =  [[0.99141496]]
print('0 ^ 1 = ', model.predict(np.array([[0, 1]])))

# 1 ^ 0 =  [[0.9897714]]
print('1 ^ 0 = ', model.predict(np.array([[1, 0]])))

# 1 ^ 1 =  [[0.00406971]]
print('1 ^ 1 = ', model.predict(np.array([[1, 1]])))

opencv-predict.py:

import numpy as np
import cv2 as cv


model = cv.dnn.readNetFromTensorflow('./xor.pb')

# 0 ^ 0 =  [[0.01974997]]
model.setInput(np.array([[0, 0]]), name='dense_input')
print('0 ^ 0 = ', model.forward(outputName='dense_4/Sigmoid'))

# 0 ^ 1 =  [[0.99141496]]
model.setInput(np.array([[0, 1]]), name='dense_input')
print('0 ^ 1 = ', model.forward(outputName='dense_4/Sigmoid'))

# 1 ^ 0 =  [[0.9897714]]
model.setInput(np.array([[1, 0]]), name='dense_input')
print('1 ^ 0 = ', model.forward(outputName='dense_4/Sigmoid'))

# 1 ^ 1 =  [[0.00406971]]
model.setInput(np.array([[1, 1]]), name='dense_input')
print('1 ^ 1 = ', model.forward(outputName='dense_4/Sigmoid'))

predict.cpp:

#include <cstdlib>
#include <iostream>
#include <opencv2/opencv.hpp>

int main(int argc, char **argv)
{
    cv::dnn::Net net;

    net = cv::dnn::readNetFromTensorflow("./xor.pb");

    // 0 ^ 0 = [0.018541215]
    float x0[] = { 0, 0 };
    net.setInput(cv::Mat(1, 2, CV_32F, x0), "dense_input");
    std::cout << "0 ^ 0 = " << net.forward("dense_4/Sigmoid") << std::endl;

    // 0 ^ 1 = [0.98295897]
    float x1[] = { 0, 1 };
    net.setInput(cv::Mat(1, 2, CV_32F, x1), "dense_input");
    std::cout << "0 ^ 1 = " << net.forward("dense_4/Sigmoid") << std::endl;

    // 1 ^ 0 = [0.98810625]
    float x2[] = { 1, 0 };
    net.setInput(cv::Mat(1, 2, CV_32F, x2), "dense_input");
    std::cout << "1 ^ 0 = " << net.forward("dense_4/Sigmoid") << std::endl;

    // 1 ^ 1 = [0.010002014]
    float x3[] = { 1, 1 };
    net.setInput(cv::Mat(1, 2, CV_32F, x3), "dense_input");
    std::cout << "1 ^ 1 = " << net.forward("dense_4/Sigmoid") << std::endl;

    return EXIT_SUCCESS;
}

Thank you very much for a complete example. Could I ask you to include an additional sentence? If people use directly keras instead of tf.keras, they also need to use "keras.backend.get_session()" instead of "tf.keras.backend.get_session()" in the function call, otherwise you will get an error concerning uninitialized variables. I didn't realize you were using the prefix "tf.keras" before and that small difference cost me an hour...
This was very helpful to me. An alternative to opencv-predict.py that doesn't use cv2: import tensorflow as tf from tensorflow.python.platform import gfile f = gfile.FastGFile(r'.\xor\xor.pb', 'rb') graph_def = tf.GraphDef() graph_def.ParseFromString(f.read()) f.close() tfSession = tf.InteractiveSession() tfSession.graph.as_default() tf.import_graph_def(graph_def) out = tfSession.graph.get_tensor_by_name('import/dense_4/Sigmoid:0') tfSession.run(out, {'import/dense_input:0': np.array([[0,0]])})
@gebbissimo I get this error AttributeError: module 'tensorflow.keras.backend' has no attribute 'get_session'. Do you have any idea?. I am using it as tf.keras.backend.get_session()
W
WurmD

At this time, all above older answers are outdated. As of Tensorflow 2.1

from tensorflow.keras.models import Model, load_model
model = load_model(MODEL_FULLPATH)
model.save(MODEL_FULLPATH_MINUS_EXTENSION)

will create a folder with a 'saved_model.pb' inside


It worked for me, however when I tried using it in openCV it gave me the following error: FAILED: ReadProtoFromBinaryFile(param_file, param). Failed to parse GraphDef file: ...
No idea. The .pb produced so far has been valid. May be some new incompatibility between the Tensorflow version you're using and the OpenCV version you're using. I'd make a minimal example and create an issue in OpenCV
@GefilteFish The SavedModel exports model into a directory and the saved_model.pb there is not GraphDef. That's why ReadProtoBinary fails to load it. Use LoadSavedModel instead. Check this answer for more details: stackoverflow.com/a/63189994/6596684
H
Hazarapet Tunanyan

There is a very important point when you want to convert to tensorflow. If you use dropout, batch normalization or any other layers like these (which have not trainable but calculating values), you should change the learning phase of keras backend. Here is a discussion about it.

import keras.backend as K
k.set_learning_phase(0) # 0 testing, 1 training mode

T
Tarik GUELZIM

This solution worked for me. Courtesy to https://medium.com/tensorflow/training-and-serving-ml-models-with-tf-keras-fd975cc0fa27

import tensorflow as tf

# The export path contains the name and the version of the model
tf.keras.backend.set_learning_phase(0) # Ignore dropout at inference
model = tf.keras.models.load_model('./model.h5')
export_path = './PlanetModel/1'

# Fetch the Keras session and save the model
# The signature definition is defined by the input and output tensors
# And stored with the default serving key
with tf.keras.backend.get_session() as sess:
    tf.saved_model.simple_save(
        sess,
        export_path,
        inputs={'input_image': model.input},
        outputs={t.name:t for t in model.outputs})

l
lasclocker

Please use tf.saved_model.simple_save, some example codes:

with tf.keras.backend.get_session() as sess:
    tf.saved_model.simple_save(
        sess,
        export_path,
        inputs={'input': keras_model.input},
        outputs={'output': keras_model.output})

===update====

You can use as_a_saved_model, example codes:

saved_model_path = tf.contrib.saved_model.save_keras_model(model, "./saved_models")

Looks like simple_save is deprecated in Tensorflow 2.0.
@scribu, Right, in TF2.0, we can refer to export_to_savedmodel
A
Amir

If you want the model only for inference, you should first freeze the graph and then write it as a .pb file. The code snippet looks like this (code borrowed from here):

import tensorflow as tf
from tensorflow.python.framework import graph_util
from tensorflow.python.framework import graph_io
import keras
from keras import backend as K

sess = K.get_session()

constant_graph = graph_util.convert_variables_to_constants(
        sess,
        sess.graph.as_graph_def(),
        ["name_of_the_output_graph_node"])

graph_io.write_graph(constant_graph, "path/to/output/folder", 
                     "output_model_name", as_text=False)

You can do the above using the keras_to_tensorflow tool: https://github.com/amir-abdi/keras_to_tensorflow

The keras_to_tensorflow tool takes care of the above operations, with some extra features for a more diverse solution. Just call it with the correct input arguments (e.g. input_model and output_model flags).

If you want to retrain the model in tensorflow, use the above tool with the output_meta_ckpt flag to export checkpoints and meta graphs.


A
Aashish Dahiya

using estimator.export_savedmodel we can easily convert h5 model to saved model. check doc here https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator

def prepare_image(image_str_tensor):
    image_contents = tf.read_file(image_str_tensor)
    image = tf.image.decode_jpeg(image_contents, channels=3)
    image = tf.image.resize_images(image, [224, 224])
    image = tf.cast(image, tf.float32)
    return preprocess_input(image)

def serving_input_receiver_fn():
    input_ph = tf.placeholder(tf.string, shape=[None])
    images_tensor = tf.map_fn(
          prepare_image, input_ph, back_prop=False, dtype=tf.float32)
    images_tensor = tf.image.convert_image_dtype(images_tensor, 
                      dtype=tf.float32)

    return tf.estimator.export.ServingInputReceiver({"input": images_tensor}, 
             {'image_url': input_ph})

estimator = tf.keras.estimator.model_to_estimator(
    keras_model_path=h5_model_path
)

estimator.export_savedmodel(saved_model_path, serving_input_receiver_fn=serving_input_receiver_fn)

s
satya prakash patel

Tensorflow tf.saved_model api is best for generating pb model

If you have h5 model then load it through keras load_model

from tensorflow import keras
model = keras.models.load_model("model.h5")

Save tensorflow model through saved_model api, It will save the model in pb format. This model will have required meta data for serving it through Google Ai Platform. So you can upload the directory to Ai Platform for serving your model.

import tensorflow as tf
tf.saved_model.save(model, './directory-to-save-file/')

Note that this will save the model in the SavedModel format which is not the same as a .pb file with a frozen graph.
H
Hassam

tf 2.2.0

import tensorflow.keras instead of just keras, because it will load your model as keras.engine.sequential.Sequential object which cannot be directly convertible into tensorflow .pb format

#import keras
import tensorflow.keras as keras
model = keras.models.load_model(load_path)
model.save(save_path)

getting the below error: ValueError: Attempted to save a function b'__inference_forward_lstm_1_layer_call_fn_14156' which references a symbolic Tensor Tensor("dropout/mul_1:0", shape=(None, 300), dtype=float32) that is not a simple constant. This is not supported.
P
Praveen Kulkarni

With tensorflow 2.x: If you want to save only the graph definition in pbtxt then use the below code.

import tensorflow as tf
keras_model = ...
tf.io.write_graph(
  keras_model.output.graph,
  'model_dir',
  'model.pbtxt',
  as_text=True,
)

D
Dharman

In the case of users trying to convert a Mask-RCNN model/weights into a frozen graph, most answers here won't suffice.

This can be done while saving the model (.h5) weights in the mrcnn/model.py file. Just need to make the following changes (git diff)

+    def freeze_session(self, session, keep_var_names=None, output_names=None, clear_devices=True):
+        """
+        Freezes the state of a session into a pruned computation graph.
+
+        Creates a new computation graph where variable nodes are replaced by
+        constants taking their current value in the session. The new graph will be
+        pruned so subgraphs that are not necessary to compute the requested
+        outputs are removed.
+        @param session The TensorFlow session to be frozen.
+        @param keep_var_names A list of variable names that should not be frozen,
+                              or None to freeze all the variables in the graph.
+        @param output_names Names of the relevant graph outputs.
+        @param clear_devices Remove the device directives from the graph for better portability.
+        @return The frozen graph definition.
+        """
+        graph = session.graph
+        with graph.as_default():
+            freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
+            output_names = output_names or []
+            output_names += [v.op.name for v in tf.global_variables()]
+            input_graph_def = graph.as_graph_def()
+            if clear_devices:
+                for node in input_graph_def.node:
+                    node.device = ""
+            frozen_graph = tf.graph_util.convert_variables_to_constants(
+                session, input_graph_def, output_names, freeze_var_names)
+            return frozen_graph
+
     def train(self, train_dataset, val_dataset, learning_rate, epochs, layers,
               augmentation=None, custom_callbacks=None, no_augmentation_sources=None):
         """Train the model.
@@ -2373,6 +2401,12 @@ class MaskRCNN():
             workers=workers,
             use_multiprocessing=True,
         )
+        #######using session and saving .pb file##
+        frozen_graph = self.freeze_session(K.get_session(),
+                              output_names=[out.op.name for out in self.keras_model.outputs])
+        print('\n\n\t\t******* Writing Frozen Graph in logs directory *******\n\n')
+        tf.train.write_graph(frozen_graph, self.log_dir, "my_model.pb", as_text=False)
+
         self.epoch = max(self.epoch, epochs)

The complete file can be found HERE. With it, I was able to convert ResNet50 and ResNet101 backbones for both coco as well as imagenet weights.


S
Singh

In my case, I was trying to convert darknet weights to a TensorFlow model and I needed the model in .pb format. I tried so many solutions given here as well as on other forums, but I was finally able to fix it by upgrading my Tensorflow v2.2 to Tensorflow v2.3, and I could successfully save the model into a .pb format.

Here are the documentations for reference:

https://www.tensorflow.org/tutorials/keras/save_and_load

https://www.tensorflow.org/guide/saved_model

My imports:

import tensorflow as tf
import tensorflow.keras as keras

Code that saves the model in .pb format:

model.save("/path to directory/")

Code that saves the model in .h5 format:

tf.keras.models.save_model(model = model, filepath, modelname.h5')

Note: I could only get this working when I upgraded the Tensorflow from version 2.2 to 2.3