Keras-retinanet: How to convert to tensorflow?

Created on 26 Mar 2019  路  6Comments  路  Source: fizyr/keras-retinanet

I am trying to convert keras-retinanet model to tensorflow.
And I run into with error:

InvalidArgumentError: You must feed a value for placeholder tensor 'import/input_1' with dtype float and shape [?,?,?,3]
     [[node import/input_1 (defined at <ipython-input-17-c3fde8620d0d>:11)  = Placeholder[dtype=DT_FLOAT, shape=[?,?,?,3], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

My code is:

from keras import backend as K
from keras_retinanet import models
import tensorflow as tf


def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
    from tensorflow.python.framework.graph_util import convert_variables_to_constants
    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()]
        # Graph -> GraphDef ProtoBuf
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ""
        frozen_graph = convert_variables_to_constants(session, input_graph_def,
                                                      output_names, freeze_var_names)
        return frozen_graph

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

tf.train.write_graph(frozen_graph, 'snapshots', 'resnet50_liza_alert_v1_interface.pb', as_text=False)

#Make predictions
import tensorflow as tf
from tensorflow.python.platform import gfile

image = read_image_bgr("./examples/DJI_0422.JPG")
# copy to draw on
draw = image.copy()
draw = cv2.cvtColor(draw, cv2.COLOR_BGR2RGB)

# preprocess image for network
image = preprocess_image(image)
image, scale = resize_image(image)

#predict keras
boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0)) #Work Currect!!!

#predict tensorflow
with tf.Session() as sess:
    # load model from pb file
    with gfile.FastGFile("./snapshots/resnet50_liza_alert_v1_interface.pb", 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        sess.graph.as_default()
        g_in = tf.import_graph_def(graph_def)
    # print all operation names 
    print('\n===== ouptut operation names =====\n')
    #for op in sess.graph.get_operations():
    #  print(op)
    # inference by the model (op name must comes with :0 to specify the index of its output)
    tensor_output = sess.graph.get_tensor_by_name('import/input_1:0')
    tensor_input = sess.graph.get_tensor_by_name('import/filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0')
    predictions = sess.run(tensor_output, {tensor_input: np.expand_dims(image, axis=0)}) #ERROR!!!
    print('\n===== output predicted results =====\n')
    print(predictions)
print(model.inputs)
>>> [<tf.Tensor 'input_1:0' shape=(?, ?, ?, 3) dtype=float32>]

print(model.outputs)
>>> [<tf.Tensor 'filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0' shape=(?, 300, 4) dtype=float32>, <tf.Tensor 'filtered_detections/map/TensorArrayStack_1/TensorArrayGatherV3:0' shape=(?, 300) dtype=float32>, <tf.Tensor 'filtered_detections/map/TensorArrayStack_2/TensorArrayGatherV3:0' shape=(?, 300) dtype=int32>]

print(image.shape)
>>>(800, 1067, 3)

print(np.expand_dims(image, axis=0))
>>>(1, 800, 1067, 3)

Where i am wrong?

Most helpful comment

this is a good colab notebook to freeze retinanet model and convert model for tf serving if anyone want to do it

https://colab.research.google.com/drive/1u79vDN4MZuq6gYIOkPmWsbghjunbDq6m

for inferenece from freeze model run this script

import tensorflow as tf

def load_graph(frozen_graph_filename):
# We load the protobuf file from the disk and parse it to retrieve the
# unserialized graph_def
with tf.gfile.GFile(frozen_graph_filename, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())

# Then, we import the graph_def into a new Graph and returns it 
with tf.Graph().as_default() as graph:
    # The name var will prefix every op/nodes in your graph
    # Since we load everything in a new graph, this is not needed
    tf.import_graph_def(graph_def, name="prefix")
return graph

import argparse
import tensorflow as tf

if __name__ == '__main__':
# Let's allow the user to pass the filename as an argument

# We use our "load_graph" function
graph = load_graph('/content/keras-retinanet/5/freezed_model.pb')

# We can verify that we can access the list of operations in the graph
for op in graph.get_operations():
    print(op.name)
    # prefix/Placeholder/inputs_placeholder
    # ...
    # prefix/Accuracy/predictions

# We access the input and output nodes 
x = graph.get_tensor_by_name('prefix/input_1:0')
y = graph.get_tensor_by_name('prefix/filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0')
y_1 = graph.get_tensor_by_name('prefix/filtered_detections/map/TensorArrayStack_1/TensorArrayGatherV3:0')
y_2 = graph.get_tensor_by_name('prefix/filtered_detections/map/TensorArrayStack_2/TensorArrayGatherV3:0')

# We launch a Session
with tf.Session(graph=graph) as sess:
    # Note: we don't nee to initialize/restore anything
    # There is no Variables in this graph, only hardcoded constants 
    y_out = sess.run([y,y_1, y_2], feed_dict={
        x: np.expand_dims(image, axis=0) # < 45
    })
    # I taught a neural net to recognise when a sum of numbers is bigger than 45
    # it should return False in this case
    print(y_out) # [[ False ]] Yay, it works!

All 6 comments

I ve cinvert it

@gosha20777 How did you convert it?

@gosha20777 How did you convert it?

Oh, just look at theese lines

tensor_output = sess.graph.get_tensor_by_name('import/input_1:0') 
tensor_input = sess.graph.get_tensor_by_name('import/filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0')

Change it to

tensor_input = sess.graph.get_tensor_by_name('import/input_1:0') 
tensor_output = sess.graph.get_tensor_by_name('import/filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0')

I think, you understand)))) I confused the input tensor and output tensor in some places.

Hi @gosha20777 , this might be off topic, but when I use your script (same as SO) to convert to a .pb file, I cannot further use it for conversion to tflite. Some kind of error with tag-sets, this method doesn't save any tag-sets I guess. Exact error RuntimeError: MetaGraphDef associated with tags {'serve'} could not be found in SavedModel. To inspect available tag-sets in the SavedModel, please use the SavedModel CLI:saved_model_cli``
Any help will be appreciated

this is a good colab notebook to freeze retinanet model and convert model for tf serving if anyone want to do it

https://colab.research.google.com/drive/1u79vDN4MZuq6gYIOkPmWsbghjunbDq6m

for inferenece from freeze model run this script

import tensorflow as tf

def load_graph(frozen_graph_filename):
# We load the protobuf file from the disk and parse it to retrieve the
# unserialized graph_def
with tf.gfile.GFile(frozen_graph_filename, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())

# Then, we import the graph_def into a new Graph and returns it 
with tf.Graph().as_default() as graph:
    # The name var will prefix every op/nodes in your graph
    # Since we load everything in a new graph, this is not needed
    tf.import_graph_def(graph_def, name="prefix")
return graph

import argparse
import tensorflow as tf

if __name__ == '__main__':
# Let's allow the user to pass the filename as an argument

# We use our "load_graph" function
graph = load_graph('/content/keras-retinanet/5/freezed_model.pb')

# We can verify that we can access the list of operations in the graph
for op in graph.get_operations():
    print(op.name)
    # prefix/Placeholder/inputs_placeholder
    # ...
    # prefix/Accuracy/predictions

# We access the input and output nodes 
x = graph.get_tensor_by_name('prefix/input_1:0')
y = graph.get_tensor_by_name('prefix/filtered_detections/map/TensorArrayStack/TensorArrayGatherV3:0')
y_1 = graph.get_tensor_by_name('prefix/filtered_detections/map/TensorArrayStack_1/TensorArrayGatherV3:0')
y_2 = graph.get_tensor_by_name('prefix/filtered_detections/map/TensorArrayStack_2/TensorArrayGatherV3:0')

# We launch a Session
with tf.Session(graph=graph) as sess:
    # Note: we don't nee to initialize/restore anything
    # There is no Variables in this graph, only hardcoded constants 
    y_out = sess.run([y,y_1, y_2], feed_dict={
        x: np.expand_dims(image, axis=0) # < 45
    })
    # I taught a neural net to recognise when a sum of numbers is bigger than 45
    # it should return False in this case
    print(y_out) # [[ False ]] Yay, it works!
Was this page helpful?
0 / 5 - 0 ratings