I am trying to convert mobilenet V1 .pb file to quantized tflite file. I used the below command to do the quantization:
tflite_convert \
--output_file=/home/wc/users/Mostafiz/TPU/models/mobilnet/test2_4thSep/mobilenetv1_test5.tflite \
--graph_def_file=/home/wc/users/Mostafiz/TPU/models/mobilnet/mobileNet_frozen_graph.pb \
--output_format=TFLITE \
--inference_type=QUANTIZED_UINT8 \
--inference_input_type=QUANTIZED_UINT8 \
--input_shape=1,224,224,3 \
--input_array=input \
--output_array=MobilenetV1/Predictions/Reshape_1 \
--inference_output_type=QUANTIZED_UINT8 \
--default_ranges_min=0 \
--default_ranges_max=6 \
--std_dev_values=127 \
--mean_value=128
The .tflile file is created without any error. But when I am trying to use the .tflile for inference the output classes are messed up. None of the test images are giving correct result.
Not sure where I am doing wrong, can someone please help me?
For inference I am using 'label_image.py' provided by tensorflow. here is the code:
"""label_image for tflite"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import numpy as np
from PIL import Image
from tensorflow.lite.python import interpreter as interpreter_wrapper
def load_labels(filename):
my_labels = []
input_file = open(filename, 'r')
for l in input_file:
my_labels.append(l.strip())
return my_labels
if __name__ == "__main__":
floating_model = False
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--image", default="/tmp/grace_hopper.bmp", \
help="image to be classified")
parser.add_argument("-m", "--model_file", \
default="/tmp/mobilenet_v1_1.0_224_quant.tflite", \
help=".tflite model to be executed")
parser.add_argument("-l", "--label_file", default="/tmp/labels.txt", \
help="name of file containing labels")
parser.add_argument("--input_mean", default=127.5, help="input_mean")
parser.add_argument("--input_std", default=127.5, \
help="input standard deviation")
args = parser.parse_args()
interpreter = interpreter_wrapper.Interpreter(model_path=args.model_file)
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# check the type of the input tensor
if input_details[0]['dtype'] == np.float32:
floating_model = True
# NxHxWxC, H:1, W:2
height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]
img = Image.open(args.image)
img = img.resize((width, height))
# add N dim
input_data = np.expand_dims(img, axis=0)
if floating_model:
input_data = (np.float32(input_data) - args.input_mean) / args.input_std
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
results = np.squeeze(output_data)
top_k = results.argsort()[-5:][::-1]
labels = load_labels(args.label_file)
for i in top_k:
if floating_model:
print('{0:08.6f}'.format(float(results[i]))+":", labels[i])
else:
print('{0:08.6f}'.format(float(results[i]/255.0))+":", labels[i])
Thank you.
The dummy quantization may not work properly as we need to guess the default_max and defual_min values for activation functions.
As Sudarsh mentioned in the comment, we should do a post training full integer quantization to convert .pb to INT8 tflite file.
you can follow this link to start with - here
Hope that helped.
Regards.
Related
I am new to the machine learning concept, I am following a video from Udacity and I run into some problems.
I am trying to create a Transfer Learning model. When I try to 'fit' it it returns an error:
InvalidArgumentError: Graph execution error:
I don't know what I am doing wrong... I am following step by step (only changed some "outdated" code)
here is my code, if someone can help me solve this and explain a bit it'd be very helpful
!pip install -q -U "tensorflow-gpu==2.2.0"
!pip install -q -U tensorflow_hub
!pip install -q -U tensorflow_datasets
import time
import numpy as np
import matplotlib.pylab as plt
import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_datasets as tfds
tfds.disable_progress_bar()
from tensorflow.keras import layers
#Here was supposed to be a split function to split the data 80% (train), 20% (validation), I don't know what I did but in the line below I did "split=['train[:80%]', 'train[20%:]']" is it ok? or should I change something there?
splits, info = tfds.load('cats_vs_dogs', with_info=True, as_supervised=True, split=['train[:80%]', 'train[20%:]'])
(train_examples, validation_examples) = splits
def format_image(image, label):
images = tf.image.resize(image, (IMAGE_RES, IMAGE_RES))//255.0
return image, label
num_examples = info.splits['train'].num_examples
BATCH_SIZE = 32
IMAGE_RES = 224
train_batches = train_examples.cache().shuffle(num_examples//4).map(format_image).batch(BATCH_SIZE).prefetch(1)
validation_batches = validation_examples.cache().map(format_image).batch(BATCH_SIZE).prefetch(1)
URL = "https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4"
feature_extractor = hub.KerasLayer(URL, input_shape=(IMAGE_RES,IMAGE_RES,3))
feature_extractor.trainable = False
model = tf.keras.Sequential([
feature_extractor,
layers.Dense(2, activation='softmax')
])
model.summary()
model.compile(
optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
EPOCHS = 2
history = model.fit(train_batches,
epochs=EPOCHS,
validation_data=validation_batches) #From here I get the problem
I'm using the google research github repository to run deeplab v3+ on my dataset to segment parts of a car. The crop size I've used is 513,513 (default) and the code adds a boundary to images smaller than that size (correct me if I'm wrong).
example!
The model seems to be performing poorly on the added boundary. Is there something I'm supposed to correct or will the model do fine with more training ?
Update: Here's the tensorboard graphs for training. Why is the regularization loss shooting like that? The output seems to be improving, can someone help me making inferences from these graphs?
Is there something I'm supposed to correct or will the model do fine with more training ?
its Ok, don't mind the boundary
To inference you can use this code
import cv2
import tensorflow as tf
import numpy as np
from PIL import Image
from skimage.transform import resize
class DeepLabModel():
"""Class to load deeplab model and run inference."""
INPUT_TENSOR_NAME = 'ImageTensor:0'
OUTPUT_TENSOR_NAME = 'SemanticPredictions:0'
INPUT_SIZE = 513
def __init__(self, path):
"""Creates and loads pretrained deeplab model."""
self.graph = tf.Graph()
graph_def = None
# Extract frozen graph from tar archive.
with tf.gfile.GFile(path, 'rb')as file_handle:
graph_def = tf.GraphDef.FromString(file_handle.read())
if graph_def is None:
raise RuntimeError('Cannot find inference graph')
with self.graph.as_default():
tf.import_graph_def(graph_def, name='')
self.sess = tf.Session(graph=self.graph)
def run(self, image):
"""Runs inference on a single image.
Args:
image: A PIL.Image object, raw input image.
Returns:
seg_map: np.array. values of pixels are classes
"""
width, height = image.size
resize_ratio = 1.0 * self.INPUT_SIZE / max(width, height)
target_size = (int(resize_ratio * width), int(resize_ratio * height))
resized_image = image.convert('RGB').resize(target_size, Image.ANTIALIAS)
batch_seg_map = self.sess.run(
self.OUTPUT_TENSOR_NAME,
feed_dict={self.INPUT_TENSOR_NAME: [np.asarray(resized_image)]})
seg_map = batch_seg_map[0]
seg_map = resize(seg_map.astype(np.uint8), (height, width), preserve_range=True, order=0, anti_aliasing=False)
return seg_map
the code is based on this file https://github.com/tensorflow/models/blob/master/research/deeplab/deeplab_demo.ipynb
model = DeepLabModel(your_model_pb_path)
img = Image.open(img_path)
seg_map = model.run(img)
to get your_model_pb_path you need to export your model to .pb file
you can do it using export_model.py file in Deeplab repo
https://github.com/tensorflow/models/blob/master/research/deeplab/export_model.py
if you were training xception_65 version
python3 <path to your deeplab folder>/export_model.py \
--logtostderr \
--checkpoint_path=<your ckpt> \
--export_path="./my_model.pb" \
--model_variant="xception_65" \
--atrous_rates=6 \
--atrous_rates=12 \
--atrous_rates=18 \
--output_stride=16 \
--decoder_output_stride=4 \
--num_classes=<NUMBER OF YOUR CLASSES> \
--crop_size=513 \
--crop_size=513 \
--inference_scales=1.0
<your ckpt> is a path to your trained model checkpoint you can find checkpoints in the folder that you passed as argument --train_logdir when training
you need to include only model name and number of iterations in path, or in other words you will have in your training folder, for example, files
model-1500.meta, model-1500.index and model-1000.data-00000-of-00001 you need to discard everything that goes after ., so the ckpt path will be model-1000
please make sure that atrous_rates are the same as you used to train the model
if you were training mobilenet_v2 version
python3 <path to your deeplab folder>/export_model.py \
--logtostderr \
--checkpoint_path=<your ckpt> \
--export_path="./my_model.pb" \
--model_variant="mobilenet_v2" \
--num_classes=<NUMBER OF YOUR CLASSES> \
--crop_size=513 \
--crop_size=513 \
--inference_scales=1.0
more you can find here
https://github.com/tensorflow/models/blob/master/research/deeplab/local_test_mobilenetv2.sh
https://github.com/tensorflow/models/blob/master/research/deeplab/local_test.sh
You can visualize results using this code
img_arr = np.array(img)
# as may colors as you have classes
colors = [(255, 0, 0), (0, 255, 0), ...]
for c in range(0, N_CLASSES):
img_arr[seg_map == c] = 0.5 * img_arr[seg_map == c] + 0.5 * np.array(colors[c])
cv2.imshow(img_arr)
cv2.waitKey(0)
Several ways of retraining MobileNet for use with Tensorflow.js have failed for me. Is there any way to use a retrained model with Tensorflow.js?
Both using the modern, hub-based tutorial, as well as using retrain.py seem to fail.
Convert output of retrain.py to tensorflow.js
Error converting keras model to tfjs: duplicate weight name Variable
as well as some other open questions
Retrain an Image Classifier in tensorflow js
Loading of mobilenet v2 works, but pretrained mobilenet v2 fails
Can't convert TensorFlow saved model to tfjs_layers_model webmodel
The top two other questions show the code that failed in both instances, both are unsolved.
The aim is to load the mobilenet, retrain using custom data, and use it in Tensorflow.js. Following both tutorials seem to fail. Could this be done inside node.js? Is there another way? Where did I make mistakes (or is the software unable to use retrained models)? How can this work?
EDITs: latest github issue and one more question
I encountered the same problem and it seems that we use the wrong method.
There are loadGraphModel for TF converted models and loadLayersModel for Keras ones
my comment about the issue
The retrain.py python script does not generate a saved model, it actually generates a frozen graph model. That is why you cannot convert it using the tfjs 1.x converter. You need to use tfjs 0.8.5 pip to convert.
Also, the output node name is different from the mobilenet model graph, it is 'final_result' for retrained graph.
To convert it you need to use the tensorflowjs 0.8.5 pip:
use virtualenv to create an empty env.
pip install tensorflowjs==0.8.5
run the converter
tensorflowjs_converter \
--input_format=tf_frozen_model \
--output_node_names='final_result' \
--output_json=true /tmp/output_graph.pb \ /tmp/web_model
This should give you something like the following:
ls /tmp/web_model/
group1-shard10of21 group1-shard14of21 group1-shard18of21 group1-shard21of21 group1-shard5of21 group1-shard9of21
group1-shard11of21 group1-shard15of21 group1-shard19of21 group1-shard2of21 group1-shard6of21 model.json
group1-shard12of21 group1-shard16of21 group1-shard1of21 group1-shard3of21 group1-shard7of21
group1-shard13of21 group1-shard17of21 group1-shard20of21 group1-shard4of21 group1-shard8of21
To use the latest TFjs:
python retrain.py --tfhub_module https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/2 \
--image_dir /tmp/flower_photos --saved_model_dir /tmp/saved_retrained_model
tensorflowjs_converter --input_format=tf_saved_model \
--output_format=tfjs_graph_model \
--saved_model_tags=serve \
/tmp/saved_retrained_model/ /tmp/converted_model/
creates a model.json file. Command described in https://github.com/tensorflow/tfjs-converter#step-1-converting-a-savedmodel-keras-h5-tfkeras-savedmodel-or-tensorflow-hub-module-to-a-web-friendly-format.
Yet, loading the model with tf.loadLayersModel("file:///tmp/web_model/model.json") failed with
'className' and 'config' must set.
Maybe somebody can modify retain.py to support mobileV2 use my way.
The original retrain.py link. This link is Google's GitHub code, not my link.
I changed retrain.py, the below is my git diff:
diff --git a/scripts/retrain.py b/scripts/retrain.py
index 5fa9b0f..02a4f9a 100644
--- a/scripts/retrain.py
+++ b/scripts/retrain.py
## -1,3 +1,5 ##
+# -*- coding: utf-8 -*-
+
# Copyright 2015 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
## -112,6 +114,13 ## from tensorflow.python.framework import graph_util
from tensorflow.python.framework import tensor_shape
from tensorflow.python.platform import gfile
from tensorflow.python.util import compat
+from tensorflow import saved_model as sm
+from tensorflow.python.saved_model import builder as saved_model_builder
+from tensorflow.python.saved_model import signature_constants
+from tensorflow.python.saved_model import signature_def_utils
+from tensorflow.python.saved_model import tag_constants
+from tensorflow.python.saved_model import utils as saved_model_utils
+
FLAGS = None
## -319,6 +328,7 ## def maybe_download_and_extract(data_url):
Args:
data_url: Web location of the tar file containing the pretrained model.
"""
+ print(FLAGS.model_dir)
dest_directory = FLAGS.model_dir
if not os.path.exists(dest_directory):
os.makedirs(dest_directory)
## -827,6 +837,7 ## def save_graph_to_file(sess, graph, graph_file_name):
sess, graph.as_graph_def(), [FLAGS.final_tensor_name])
with gfile.FastGFile(graph_file_name, 'wb') as f:
f.write(output_graph_def.SerializeToString())
+
return
## -971,6 +982,7 ## def main(_):
# Prepare necessary directories that can be used during training
prepare_file_system()
+ sigs = {}
# Gather information about the model architecture we'll be using.
model_info = create_model_info(FLAGS.architecture)
## -1002,6 +1014,9 ## def main(_):
FLAGS.random_brightness)
with tf.Session(graph=graph) as sess:
+ serialized_tf_example = tf.placeholder(tf.string, name='tf_example')
+ feature_configs = {'x': tf.FixedLenFeature(shape=[784], dtype=tf.float32),}
+ tf_example = tf.parse_example(serialized_tf_example, feature_configs)
# Set up the image decoding sub-graph.
jpeg_data_tensor, decoded_image_tensor = add_jpeg_decoding(
model_info['input_width'], model_info['input_height'],
## -1133,6 +1148,73 ## def main(_):
(test_filename,
list(image_lists.keys())[predictions[i]]))
+ """
+ # analyze SignatureDef protobuf
+ SignatureDef_d = graph.signature_def
+ SignatureDef = SignatureDef_d[sm.signature_constants.CLASSIFY_INPUTS]
+
+ # three TensorInfo protobuf
+ X_TensorInfo = SignatureDef.inputs['input_1']
+ scale_TensorInfo = SignatureDef.inputs['input_2']
+ y_TensorInfo = SignatureDef.outputs['output']
+
+ # Tensor details
+ # .get_tensor_from_tensor_info() to get default graph
+ X = sm.utils.get_tensor_from_tensor_info(X_TensorInfo, sess.graph)
+ scale = sm.utils.get_tensor_from_tensor_info(scale_TensorInfo, sess.graph)
+ y = sm.utils.get_tensor_from_tensor_info(y_TensorInfo, sess.graph)
+ """
+
+ """
+ output_graph_def = graph_util.convert_variables_to_constants(
+ sess, graph.as_graph_def(), [FLAGS.final_tensor_name])
+
+ X_TensorInfo = sm.utils.build_tensor_info(bottleneck_input)
+ scale_TensorInfo = sm.utils.build_tensor_info(ground_truth_input)
+ y_TensorInfo = sm.utils.build_tensor_info(output_graph_def)
+
+ # build SignatureDef protobuf
+ SignatureDef = sm.signature_def_utils.build_signature_def(
+ inputs={'input_1': X_TensorInfo, 'input_2': scale_TensorInfo},
+ outputs={'output': y_TensorInfo},
+ method_name='what'
+ )
+ """
+
+ #graph = tf.get_default_graph()
+ tensors_per_node = [node.values() for node in graph.get_operations()]
+ tensor_names = [tensor.name for tensors in tensors_per_node for tensor in tensors]
+ print(tensor_names)
+
+ export_dir = './tf_files/savemode'
+ builder = saved_model_builder.SavedModelBuilder(export_dir)
+
+ # name="" is important to ensure we don't get spurious prefixing
+ graph_def = tf.GraphDef()
+ tf.import_graph_def(graph_def, name="")
+ g = tf.get_default_graph()
+ inp1 = g.get_tensor_by_name("input:0")
+ inp2 = g.get_tensor_by_name("input_1/BottleneckInputPlaceholder:0")
+ inp3 = g.get_tensor_by_name("input_1/GroundTruthInput:0")
+ out = g.get_tensor_by_name("accuracy_1:0")
+
+ sigs[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY] = \
+ tf.saved_model.signature_def_utils.predict_signature_def(
+ {'input_1': inp1, 'input_2': inp3}, {"output": out})
+
+ builder.add_meta_graph_and_variables(sess,
+ tags=[tag_constants.SERVING],
+ signature_def_map=sigs)
+
+ """
+ builder.add_meta_graph_and_variables(
+ sess=sess,
+ tags=[tag_constants.SERVING],
+ signature_def_map={sm.signature_constants.CLASSIFY_INPUTS: SignatureDef})
+ """
+
+ builder.save()
+
# Write out the trained graph and labels with the weights stored as
# constants.
save_graph_to_file(sess, graph, FLAGS.output_graph)
Using my diff, I can generate Tensorflow Served model.
And then I use the command to convert TensorFlow served model to Tfjs model.
tensorflowjs_converter \
--input_format=tf_saved_model \
--output_format=tfjs_graph_model \
./tf_files/savemode \
./tf_files/js_model
Still unsupported Ops for lasted Tensorflow JS version.
I just make a video here to explain why we cannot convert Tensorflow frozen model to Tensorflow JS model, tells how to find the input Tensor and Output Tensor. The running steps and result, finally, give unsupported Ops ScalarSummary and the reason.
Now that I cannot change the Mobilenet Model to Tensorflow JS model, so my workaround is using Python tensorflow and flask library on Server side, user upload the image to server and then return the result.
I trained the face recognition model with the quantization-aware training method of tensorflow version 1.12.0. The network uses inception-resnet_v1(The source of the code is tensorflow/models/research/slim/nets/). After the training is completed, I get ckpt, then I create a new freeze.py file to generate eval.pb, and then successfully generate the tflite model with toco. But when I finally tested the tflite model with image, I got the following error:
File "src/test_tflite.py", line 21, in <module>
Interpreter.allocate_tensors()
File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/lite/python/interpreter.py", line 71, in allocate_tensors
Return self._interpreter.AllocateTensors()
File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/lite/python/interpreter_wrapper/tensorflow_wrap_interpreter_wrapper.py", line 106, in AllocateTensors
Return _tensorflow_wrap_interpreter_wrapper.InterpreterWrapper_AllocateTensors(self)
RuntimeError: tensorflow/contrib/lite/kernels/pooling.cc:103 input->params.scale != output->params.scale (102483008 != 102482528)Node number 116 (MAX_POOL_2D) failed to prepare.
I tried to replace the network, inception-v3, inception-resnet-v2, but all got a similar error.
My training code is based on the facenet framework and I made small changes based on the original training. After defining total_loss_op, add the following two lines of code:
train_graph = tf.get_default_graph()
tf.contrib.quantize.create_training_graph(input_graph=train_graph, quant_delay=20000)
In the freeze.py file, when the inference graph is defined, I add the following code:
g = tf.get_default_graph()
tf.contrib.quantize.create_eval_graph(input_graph=g)
Then load the ckpt that was trained before, and finally save it as a pb file. The code is as follows:
saver = tf.train.Saver(tf.global_variables())
sess = tf.Session()
with sess.as_default():
saver.restore(sess, ckpt_model_path)
frozen_graph_def = graph_util.convert_variables_to_constants(
sess, sess.graph_def, ['embeddings'])
tf.train.write_graph(
frozen_graph_def,
os.path.dirname(save_pb_path),
os.path.basename(save_pb_path),
as_text=False)
Then I used the tensorflow1.12.0 toco tool to convert the pb file and successfully generated tflite. The specific commands are as follows:
./bazel-bin/tensorflow/contrib/lite/toco/toco \
--input_file=inception_resnet_v1_fake_quantized_eval.pb \
--output_file=tflite_model.tflite \
--input_format=TENSORFLOW_GRAPHDEF \
--output_format=TFLITE \
--inference_type=QUANTIZED_UINT8 \
--input_shape="1,160,160,3" \
--input_array=input \
--output_array=embeddings \
--std_value=127.5 \
--mean_value=127.5 \
--default_ranges_min=-1.0 \
--default_ranges_max=1.0
Finally, I used the generated tflite model to test the image and I got the following error.
RuntimeError: tensorflow/contrib/lite/kernels/pooling.cc:103 input->params.scale != output->params.scale (102483008 != 102482528)Node number 116 (MAX_POOL_2D) failed to prepare.
My test code is as follows:
import numpy as np
import tensorflow as tf
import scipy
#Load TFLite model and allocate tensors.
interpreter = tf.contrib.lite.Interpreter(model_path="tensorflow-1.12.0/tflite_model.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
image = scipy.misc.imread("src/1511.jpg")
image_ = np.array([image.astype('uint8')])
print(image_.shape)
print(type(image_))
print(input_details)
print(output_details)
interpreter.set_tensor(input_details[0]['index'], image_)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)
While converting the model, the function HardcodeMinMaxForConcatenation in hardcode_min_max.cc tweaks the minmax of input arrays and output array of concatenation layer to be the same.
Then the function HardcodeMinMaxForAverageOrMaxPool in the same file, would find the output array of max pooling layer get minmax information and skip changing it to the same as the input arrays'.
It turns out the minmax of input array and output array of pooling layer not the same.
I believe it is a bug.
I have looked on several posts on stackoverflow and have been at it for a few days now, but alas, I'm not able to properly serve an object detection model through tensorflow serving.
I have visited to the following links:
How to properly serve an object detection model from Tensorflow Object Detection API?
and
https://github.com/tensorflow/tensorflow/issues/11863
Here's what I have done.
I have downloaded the ssd_mobilenet_v1_coco_11_06_2017.tar.gz, which contains the following files:
frozen_inference_graph.pb
graph.pbtxt
model.ckpt.data-00000-of-00001
model.ckpt.index
model.ckpt.meta
Using the following script, I was able successfully convert the frozen_inference_graph.pb to a SavedModel (under directory ssd_mobilenet_v1_coco_11_06_2017/saved)
import tensorflow as tf
from tensorflow.python.saved_model import signature_constants
from tensorflow.python.saved_model import tag_constants
import ipdb
# Specify version 1
export_dir = './saved/1'
graph_pb = 'frozen_inference_graph.pb'
builder = tf.saved_model.builder.SavedModelBuilder(export_dir)
with tf.gfile.GFile(graph_pb, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
sigs = {}
with tf.Session(graph=tf.Graph()) as sess:
# name="" is important to ensure we don't get spurious prefixing
tf.import_graph_def(graph_def, name="")
g = tf.get_default_graph()
ipdb.set_trace()
inp = g.get_tensor_by_name("image_tensor:0")
outputs = {}
outputs["detection_boxes"] = g.get_tensor_by_name('detection_boxes:0')
outputs["detection_scores"] = g.get_tensor_by_name('detection_scores:0')
outputs["detection_classes"] = g.get_tensor_by_name('detection_classes:0')
outputs["num_detections"] = g.get_tensor_by_name('num_detections:0')
output_tensor = tf.concat([tf.expand_dims(t, 0) for t in outputs], 0)
# or use tf.gather??
# out = g.get_tensor_by_name("generator/Tanh:0")
sigs[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY] = \
tf.saved_model.signature_def_utils.predict_signature_def(
{"in": inp}, {"out": output_tensor} )
sigs["predict_images"] = \
tf.saved_model.signature_def_utils.predict_signature_def(
{"in": inp}, {"out": output_tensor} )
builder.add_meta_graph_and_variables(sess,
[tag_constants.SERVING],
signature_def_map=sigs)
builder.save()
I get the following error:
bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server
--port=9000 --model_base_path=/serving/ssd_mobilenet_v1_coco_11_06_2017/saved
2017-09-17 22:33:21.325087: W tensorflow_serving/sources/storage_path/file_system_storage_path_source.cc:268] No versions of servable default found under base path /serving/ssd_mobilenet_v1_coco_11_06_2017/saved/1
I understand I will need a client to connect to the server to do the prediction. However, I'm not even able to serve the model properly.
You need to change the export signature somewhat from what the original post did. This script does the necessary changes for you:
$OBJECT_DETECTION_CONFIG=object_detection/samples/configs/ssd_mobilenet_v1_pets.config
$ python object_detection/export_inference_graph.py \ --input_type encoded_image_string_tensor \ --pipeline_config_path ${OBJECT_DETECTION_CONFIG} \ --trained_checkpoint_prefix ${YOUR_LOCAL_CHK_DIR}/model.ckpt-${CHECKPOINT_NUMBER} \ --output_directory ${YOUR_LOCAL_EXPORT_DIR}
For more details on what the program is doing, see:
https://cloud.google.com/blog/big-data/2017/09/performing-prediction-with-tensorflow-object-detection-models-on-google-cloud-machine-learning-engine