def test_build_all_signature_defs_with_single_alternatives(self): # Force the test to run in graph mode. # This tests a deprecated v1 API that depends on graph-only functions such # as build_tensor_info. with ops.Graph().as_default(): receiver_tensor = array_ops.placeholder(dtypes.string) receiver_tensors_alternative_1 = array_ops.placeholder( dtypes.int64) receiver_tensors_alternative_2 = array_ops.sparse_placeholder( dtypes.float32) # Note we are passing single Tensors as values of # receiver_tensors_alternatives, where normally that is a dict. # In this case a dict will be created using the default receiver tensor # name "input". receiver_tensors_alternatives = { "other1": receiver_tensors_alternative_1, "other2": receiver_tensors_alternative_2 } output_1 = constant_op.constant([1.]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.RegressionOutput(value=output_1), "head-2": export_output.ClassificationOutput(classes=output_2), "head-3": export_output.PredictOutput( outputs={"some_output_3": output_3}), } signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs, receiver_tensors_alternatives) expected_signature_defs = { "serving_default": signature_def_utils.regression_signature_def( receiver_tensor, output_1), "head-2": signature_def_utils.classification_signature_def( receiver_tensor, output_2, None), "head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensor}, {"some_output_3": output_3}), "other1:head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensors_alternative_1}, {"some_output_3": output_3}), "other2:head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensors_alternative_2}, {"some_output_3": output_3}) # Note that the alternatives 'other:serving_default' and # 'other:head-2' are invalid, because regression and classification # signatures must take a single string input. Here we verify that # these invalid signatures are not included in the export_utils. } self.assertDictEqual(expected_signature_defs, signature_defs)
def test_build_all_signature_defs(self): input_features = constant_op.constant(["10"]) input_example = constant_op.constant(["11"]) input_ops = input_fn_utils.InputFnOps({ "features": input_features }, None, {"default input": input_example}) input_alternatives, _ = ( saved_model_export_utils.get_input_alternatives(input_ops)) output_1 = constant_op.constant(["1"]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) provided_output_alternatives = { "head-1": (constants.ProblemType.LINEAR_REGRESSION, { "some_output_1": output_1 }), "head-2": (constants.ProblemType.CLASSIFICATION, { "some_output_2": output_2 }), "head-3": (constants.ProblemType.UNSPECIFIED, { "some_output_3": output_3 }), } model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions={"some_output": constant_op.constant(["4"])}, output_alternatives=provided_output_alternatives) output_alternatives, _ = (saved_model_export_utils.get_output_alternatives( model_fn_ops, "head-1")) signature_defs = saved_model_export_utils.build_all_signature_defs( input_alternatives, output_alternatives, "head-1") expected_signature_defs = { "serving_default": signature_def_utils.regression_signature_def(input_example, output_1), "default_input_alternative:head-1": signature_def_utils.regression_signature_def(input_example, output_1), "default_input_alternative:head-2": signature_def_utils.classification_signature_def(input_example, output_2, None), "default_input_alternative:head-3": signature_def_utils.predict_signature_def({ "input": input_example }, {"output": output_3}), "features_input_alternative:head-1": signature_def_utils.regression_signature_def(input_features, output_1), "features_input_alternative:head-2": signature_def_utils.classification_signature_def(input_features, output_2, None), "features_input_alternative:head-3": signature_def_utils.predict_signature_def({ "input": input_features }, {"output": output_3}), } self.assertDictEqual(expected_signature_defs, signature_defs)
def test_build_all_signature_defs_with_single_alternatives(self): receiver_tensor = array_ops.placeholder(dtypes.string) receiver_tensors_alternative_1 = array_ops.placeholder(dtypes.int64) receiver_tensors_alternative_2 = array_ops.sparse_placeholder( dtypes.float32) # Note we are passing single Tensors as values of # receiver_tensors_alternatives, where normally that is a dict. # In this case a dict will be created using the default receiver tensor # name "input". receiver_tensors_alternatives = {"other1": receiver_tensors_alternative_1, "other2": receiver_tensors_alternative_2} output_1 = constant_op.constant([1.]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.RegressionOutput(value=output_1), "head-2": export_output.ClassificationOutput(classes=output_2), "head-3": export_output.PredictOutput(outputs={ "some_output_3": output_3 }), } signature_defs = export.build_all_signature_defs( receiver_tensor, export_outputs, receiver_tensors_alternatives) expected_signature_defs = { "serving_default": signature_def_utils.regression_signature_def( receiver_tensor, output_1), "head-2": signature_def_utils.classification_signature_def( receiver_tensor, output_2, None), "head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensor}, {"some_output_3": output_3}), "other1:head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensors_alternative_1}, {"some_output_3": output_3}), "other2:head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensors_alternative_2}, {"some_output_3": output_3}) # Note that the alternatives 'other:serving_default' and 'other:head-2' # are invalid, because regession and classification signatures must take # a single string input. Here we verify that these invalid signatures # are not included in the export. } self.assertDictEqual(expected_signature_defs, signature_defs)
def test_build_all_signature_defs_serving_only(self): receiver_tensor = {"input": array_ops.placeholder(dtypes.string)} output_1 = constant_op.constant([1.]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.PredictOutput(outputs=output_1), "train": export_output.TrainOutput(loss=output_1), } signature_defs = export.build_all_signature_defs( receiver_tensor, export_outputs) expected_signature_defs = { "serving_default": signature_def_utils.predict_signature_def( receiver_tensor, {"output": output_1}) } self.assertDictEqual(expected_signature_defs, signature_defs) signature_defs = export.build_all_signature_defs( receiver_tensor, export_outputs, serving_only=False) expected_signature_defs.update({ "train": signature_def_utils.supervised_train_signature_def( receiver_tensor, loss={"loss": output_1}) }) self.assertDictEqual(expected_signature_defs, signature_defs)
def run(): model = ViolenceResNetV1L101(num_classes=7) weight_path = r'D:\projects\ContentSupervision\code\ResNetV1_101\20191029_060119\model-12000' export_root = './data/saved_models' export_version = '1' input_type = InputType.BASE64_JPEG export_path = os.path.join(export_root, export_version) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) model._build(weight_path=weight_path, sess=sess, input_type=input_type) builder = saved_model_builder.SavedModelBuilder(export_path) builder.add_meta_graph_and_variables( sess, [SERVING], signature_def_map={ DEFAULT_SERVING_SIGNATURE_DEF_KEY: predict_signature_def( inputs={PREDICT_INPUTS: model.input}, outputs={PREDICT_OUTPUTS: model.output} ) } ) builder.save()
def save_inference_model(export_dir, inference_model, session=None, replace=True): if session is None: session = tf.get_default_session() assert session is not None if replace and is_directory(export_dir): get_logger().info('replacing %s', export_dir) delete_recursively(export_dir) prediction_signature = predict_signature_def( inputs={INPUTS_KEY: inference_model.inputs_tensor}, outputs={ k: v for k, v in { OUTPUTS_KEY: inference_model.outputs_tensor, LABELS_KEY: inference_model.labels_tensor, COLORS_KEY: inference_model.colors_tensor }.items() if v is not None }) signature_def_map = { DEFAULT_SERVING_SIGNATURE_DEF_KEY: prediction_signature } legacy_init_op = tf.group(tf.tables_initializer(), name='legacy_init_op') builder = SavedModelBuilder(export_dir) builder.add_meta_graph_and_variables(session, [SERVING], signature_def_map=signature_def_map, legacy_init_op=legacy_init_op) builder.save()
def export(self, last_checkpoint, output_dir): """Builds a prediction graph and xports the model. Args: last_checkpoint: Path to the latest checkpoint file from training. output_dir: Path to the folder to be used to output the model. """ logging.info('Exporting prediction graph to %s', output_dir) with tf.Session(graph=tf.Graph()) as sess: # Build and save prediction meta graph and trained variable values. inputs, outputs = self.build_prediction_graph() signature_def_map = { 'serving_default': signature_def_utils.predict_signature_def(inputs, outputs) } init_op = tf.global_variables_initializer() sess.run(init_op) self.restore_from_checkpoint(sess, self.inception_checkpoint_file, last_checkpoint) init_op_serving = control_flow_ops.group( variables.local_variables_initializer(), data_flow_ops.tables_initializer()) builder = saved_model_builder.SavedModelBuilder(output_dir) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map=signature_def_map, legacy_init_op=init_op_serving) builder.save(False)
def testPredictionSignatureDef(self): input1 = constant_op.constant("a", name="input-1") input2 = constant_op.constant("b", name="input-2") output1 = constant_op.constant("c", name="output-1") output2 = constant_op.constant("d", name="output-2") meta_graph_def = meta_graph_pb2.MetaGraphDef() self._add_to_signature_def_map(meta_graph_def, { "my_prediction": signature_def_utils.predict_signature_def({ "input-1": input1, "input-2": input2 }, {"output-1": output1, "output-2": output2}) }) # Look up the prediction signature def with the key used while saving. signature_def = signature_def_contrib_utils.get_signature_def_by_key( meta_graph_def, "my_prediction") self.assertEqual(signature_constants.PREDICT_METHOD_NAME, signature_def.method_name) # Check inputs in signature def. self.assertEqual(2, len(signature_def.inputs)) self._check_tensor_info(signature_def.inputs, "input-1", "input-1:0") self._check_tensor_info(signature_def.inputs, "input-2", "input-2:0") # Check outputs in signature def. self.assertEqual(2, len(signature_def.outputs)) self._check_tensor_info(signature_def.outputs, "output-1", "output-1:0") self._check_tensor_info(signature_def.outputs, "output-2", "output-2:0")
def convert_h5_to_pb( path_to_h5, export_path, ): # Set the learning phase to Test since the model is already trained. K.set_learning_phase(0) # Load the Keras model keras_model = load_model(path_to_h5) # Build the Protocol Buffer SavedModel at 'export_path' builder = saved_model_builder.SavedModelBuilder(export_path) # Create prediction signature to be used by TensorFlow Serving Predict API signature = predict_signature_def(inputs={"images": keras_model.input}, outputs={"scores": keras_model.output}) with K.get_session() as sess: # Save the meta graph and the variables builder.add_meta_graph_and_variables( sess=sess, tags=[tag_constants.SERVING], signature_def_map={"predict": signature}) builder.save()
def test_build_all_signature_defs_serving_only(self): receiver_tensor = {"input": array_ops.placeholder(dtypes.string)} output_1 = constant_op.constant([1.]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.PredictOutput(outputs=output_1), "train": export_output.TrainOutput(loss=output_1), } signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs) expected_signature_defs = { "serving_default": signature_def_utils.predict_signature_def( receiver_tensor, {"output": output_1}) } self.assertDictEqual(expected_signature_defs, signature_defs) signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs, serving_only=False) expected_signature_defs.update({ "train": signature_def_utils.supervised_train_signature_def( receiver_tensor, loss={"loss": output_1}) }) self.assertDictEqual(expected_signature_defs, signature_defs)
def save_to_pb(keras_model, export_path): """ Save keras model to protobuf for Tensorflow Serving. Source: https://medium.com/@johnsondsouza23/export-keras-model-to-protobuf-for-tensorflow-serving-101ad6c65142 Parameters ---------- keras_model: Keras model instance export_path: str """ # Set the learning phase to Test since the model is already trained. K.set_learning_phase(0) # Build the Protocol Buffer SavedModel at 'export_path' builder = saved_model_builder.SavedModelBuilder(export_path) # Create prediction signature to be used by TensorFlow Serving Predict API signature = predict_signature_def(inputs={"images": keras_model.input}, outputs={"scores": keras_model.output}) with K.get_session() as sess: # Save the meta graph and the variables builder.add_meta_graph_and_variables( sess=sess, tags=[tag_constants.SERVING], signature_def_map={"predict": signature}) builder.save()
def test_build_all_signature_defs_without_receiver_alternatives(self): receiver_tensor = array_ops.placeholder(dtypes.string) output_1 = constant_op.constant([1.]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.RegressionOutput(value=output_1), "head-2": export_output.ClassificationOutput(classes=output_2), "head-3": export_output.PredictOutput(outputs={ "some_output_3": output_3 }), } signature_defs = export.build_all_signature_defs( receiver_tensor, export_outputs) expected_signature_defs = { "serving_default": signature_def_utils.regression_signature_def(receiver_tensor, output_1), "head-2": signature_def_utils.classification_signature_def(receiver_tensor, output_2, None), "head-3": signature_def_utils.predict_signature_def({ "input": receiver_tensor }, {"some_output_3": output_3}) } self.assertDictEqual(expected_signature_defs, signature_defs)
def testPredictionSignatureDef(self): input1 = constant_op.constant("a", name="input-1") input2 = constant_op.constant("b", name="input-2") output1 = constant_op.constant("c", name="output-1") output2 = constant_op.constant("d", name="output-2") signature_def = signature_def_utils.predict_signature_def({ "input-1": input1, "input-2": input2 }, {"output-1": output1, "output-2": output2}) self.assertEqual(signature_constants.PREDICT_METHOD_NAME, signature_def.method_name) # Check inputs in signature def. self.assertEqual(2, len(signature_def.inputs)) input1_tensor_info_actual = (signature_def.inputs["input-1"]) self.assertEqual("input-1:0", input1_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, input1_tensor_info_actual.dtype) self.assertEqual(0, len(input1_tensor_info_actual.tensor_shape.dim)) input2_tensor_info_actual = (signature_def.inputs["input-2"]) self.assertEqual("input-2:0", input2_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, input2_tensor_info_actual.dtype) self.assertEqual(0, len(input2_tensor_info_actual.tensor_shape.dim)) # Check outputs in signature def. self.assertEqual(2, len(signature_def.outputs)) output1_tensor_info_actual = (signature_def.outputs["output-1"]) self.assertEqual("output-1:0", output1_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, output1_tensor_info_actual.dtype) self.assertEqual(0, len(output1_tensor_info_actual.tensor_shape.dim)) output2_tensor_info_actual = (signature_def.outputs["output-2"]) self.assertEqual("output-2:0", output2_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, output2_tensor_info_actual.dtype) self.assertEqual(0, len(output2_tensor_info_actual.tensor_shape.dim))
def export(train_dir, model_dir): with tf.Session(graph=tf.Graph()) as sess: inputs, outputs = model.build_prediction_graph() signature_def_map = { 'serving_default': signature_def_utils.predict_signature_def(inputs, outputs), } # Restore the moving average version of the learned variables for eval. variable_averages = tf.train.ExponentialMovingAverage( model.MOVING_AVERAGE_DECAY) variables_to_restore = variable_averages.variables_to_restore() saver = tf.train.Saver(variables_to_restore) ckpt = tf.train.get_checkpoint_state(train_dir) if ckpt and ckpt.model_checkpoint_path: # Restores from checkpoint saver.restore(sess, ckpt.model_checkpoint_path) else: print('No checkpoint file found') return builder = saved_model_builder.SavedModelBuilder(model_dir) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map=signature_def_map) builder.save(False)
def test_build_all_signature_defs_without_receiver_alternatives(self): # Force the test to run in graph mode. # This tests a deprecated v1 API that depends on graph-only functions such # as build_tensor_info. with ops.Graph().as_default(): receiver_tensor = array_ops.placeholder(dtypes.string) output_1 = constant_op.constant([1.]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.RegressionOutput(value=output_1), "head-2": export_output.ClassificationOutput(classes=output_2), "head-3": export_output.PredictOutput( outputs={"some_output_3": output_3}), } signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs) expected_signature_defs = { "serving_default": signature_def_utils.regression_signature_def( receiver_tensor, output_1), "head-2": signature_def_utils.classification_signature_def( receiver_tensor, output_2, None), "head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensor}, {"some_output_3": output_3}) } self.assertDictEqual(expected_signature_defs, signature_defs)
def save_pb(session, export_dir, inputs, outputs, legacy_init_op=None, saver=None): ''' 重写 pb 保存模型接口,可以添加saver,剔除额外参数 :param session: :param export_dir: :param inputs: :param outputs: :param legacy_init_op: :param saver: :return: ''' signature_def_map = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def_utils.predict_signature_def(inputs, outputs) } b = builder.SavedModelBuilder(export_dir) b.add_meta_graph_and_variables( session, tags=[tag_constants.SERVING], signature_def_map=signature_def_map, assets_collection=ops.get_collection(ops.GraphKeys.ASSET_FILEPATHS), main_op=legacy_init_op, clear_devices=True, saver=saver ) b.save()
def test_build_all_signature_defs_serving_only(self): # Force the test to run in graph mode. # This tests a deprecated v1 API that depends on graph-only functions such # as build_tensor_info. with ops.Graph().as_default(): receiver_tensor = {"input": array_ops.placeholder(dtypes.string)} output_1 = constant_op.constant([1.]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.PredictOutput(outputs=output_1), "train": export_output.TrainOutput(loss=output_1), } signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs) expected_signature_defs = { "serving_default": signature_def_utils.predict_signature_def( receiver_tensor, {"output": output_1}) } self.assertDictEqual(expected_signature_defs, signature_defs) signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs, serving_only=False) expected_signature_defs.update({ "train": signature_def_utils.supervised_train_signature_def( receiver_tensor, loss={"loss": output_1}) }) self.assertDictEqual(expected_signature_defs, signature_defs)
def export(self, last_checkpoint, output_dir): """Builds a prediction graph and xports the model. Args: last_checkpoint: Path to the latest checkpoint file from training. output_dir: Path to the folder to be used to output the model. """ logging.info('Exporting prediction graph to %s', output_dir) with tf.Session(graph=tf.Graph()) as sess: # Build and save prediction meta graph and trained variable values. inputs, outputs = self.build_prediction_graph() signature_def_map = { 'serving_default': signature_def_utils.predict_signature_def(inputs, outputs) } init_op = tf.global_variables_initializer() sess.run(init_op) self.restore_from_checkpoint(sess, self.inception_checkpoint_file, last_checkpoint) init_op_serving = control_flow_ops.group( variables.local_variables_initializer(), tf.tables_initializer()) builder = saved_model_builder.SavedModelBuilder(output_dir) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map=signature_def_map, legacy_init_op=init_op_serving) builder.save(False)
def _tf_simple_save_for_training(self, itr=None): if proc_id() == 0: assert hasattr( self, "tf_saver_elements" ), "First have to setup saving with self.setup_tf_saver" fpath = "simple_save" + ("%d" % itr if itr is not None else "") fpath = osp.join(self.output_dir, fpath) if osp.exists(fpath): # simple_save refuses to be useful if fpath already exists, # so just delete fpath if it's there. shutil.rmtree(fpath) train_signature_def_map = { "train": signature_def_utils.predict_signature_def( self.tf_saver_elements["train_inputs"], self.tf_saver_elements["train_outputs"], ), } serve_signature_def_map = { "serving_default": signature_def_utils.predict_signature_def( self.tf_saver_elements["infer_inputs"], self.tf_saver_elements["infer_outputs"], ), } b = builder.SavedModelBuilder(fpath) b.add_meta_graph_and_variables( self.tf_saver_elements["session"], tags=[tag_constants.TRAINING], signature_def_map=train_signature_def_map, assets_collection=ops.get_collection( ops.GraphKeys.ASSET_FILEPATHS), main_op=None, clear_devices=True, ) b.add_meta_graph( tags=[tag_constants.SERVING], signature_def_map=serve_signature_def_map, assets_collection=ops.get_collection( ops.GraphKeys.ASSET_FILEPATHS), main_op=None, clear_devices=True, ) b.save() joblib.dump(self.tf_saver_info, osp.join(fpath, "model_info.pkl"))
def test_build_all_signature_defs_with_dict_alternatives(self): with context.graph_mode(): receiver_tensor = array_ops.placeholder(dtypes.string) receiver_tensors_alternative_1 = { "foo": array_ops.placeholder(dtypes.int64), "bar": array_ops.sparse_placeholder(dtypes.float32)} receiver_tensors_alternatives = {"other": receiver_tensors_alternative_1} output_1 = constant_op.constant([1.]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.RegressionOutput(value=output_1), "head-2": export_output.ClassificationOutput(classes=output_2), "head-3": export_output.PredictOutput(outputs={ "some_output_3": output_3 }), } signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs, receiver_tensors_alternatives) expected_signature_defs = { "serving_default": signature_def_utils.regression_signature_def( receiver_tensor, output_1), "head-2": signature_def_utils.classification_signature_def( receiver_tensor, output_2, None), "head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensor}, {"some_output_3": output_3}), "other:head-3": signature_def_utils.predict_signature_def( receiver_tensors_alternative_1, {"some_output_3": output_3}) # Note that the alternatives 'other:serving_default' and # 'other:head-2' are invalid, because regession and classification # signatures must take a single string input. Here we verify that # these invalid signatures are not included in the export_utils. } self.assertDictEqual(expected_signature_defs, signature_defs)
def test_build_all_signature_defs_with_dict_alternatives(self): receiver_tensor = array_ops.placeholder(dtypes.string) receiver_tensors_alternative_1 = { "foo": array_ops.placeholder(dtypes.int64), "bar": array_ops.sparse_placeholder(dtypes.float32)} receiver_tensors_alternatives = {"other": receiver_tensors_alternative_1} output_1 = constant_op.constant([1.]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) export_outputs = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: export_output.RegressionOutput(value=output_1), "head-2": export_output.ClassificationOutput(classes=output_2), "head-3": export_output.PredictOutput(outputs={ "some_output_3": output_3 }), } signature_defs = export_utils.build_all_signature_defs( receiver_tensor, export_outputs, receiver_tensors_alternatives) expected_signature_defs = { "serving_default": signature_def_utils.regression_signature_def( receiver_tensor, output_1), "head-2": signature_def_utils.classification_signature_def( receiver_tensor, output_2, None), "head-3": signature_def_utils.predict_signature_def( {"input": receiver_tensor}, {"some_output_3": output_3}), "other:head-3": signature_def_utils.predict_signature_def( receiver_tensors_alternative_1, {"some_output_3": output_3}) # Note that the alternatives 'other:serving_default' and # 'other:head-2' are invalid, because regession and classification # signatures must take a single string input. Here we verify that # these invalid signatures are not included in the export_utils. } self.assertDictEqual(expected_signature_defs, signature_defs)
def simple_save(session, export_dir, inputs, outputs, legacy_init_op=None): """Convenience function to build a SavedModel suitable for serving. In many common cases, saving models for serving will be as simple as: simple_save(session, export_dir, inputs={"x": x, "y": y}, outputs={"z": z}) Although in many cases it's not necessary to understand all of the many ways to configure a SavedModel, this method has a few practical implications: - It will be treated as a graph for inference / serving (i.e. uses the tag `tag_constants.SERVING`) - The SavedModel will load in TensorFlow Serving and supports the [Predict API](https://github.com/tensorflow/serving/blob/master/tensorflow_serving/apis/predict.proto). To use the Classify, Regress, or MultiInference APIs, please use either [tf.Estimator](https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator) or the lower level [SavedModel APIs](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md). - Some TensorFlow ops depend on information on disk or other information called "assets". These are generally handled automatically by adding the assets to the `GraphKeys.ASSET_FILEPATHS` collection. Only assets in that collection are exported; if you need more custom behavior, you'll need to use the [SavedModelBuilder](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/builder.py). More information about SavedModel and signatures can be found here: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md. Args: session: The TensorFlow session from which to save the meta graph and variables. export_dir: The path to which the SavedModel will be stored. inputs: dict mapping string input names to tensors. These are added to the SignatureDef as the inputs. outputs: dict mapping string output names to tensors. These are added to the SignatureDef as the outputs. legacy_init_op: Legacy support for op or group of ops to execute after the restore op upon a load. """ signature_def_map = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def_utils.predict_signature_def(inputs, outputs) } b = builder.SavedModelBuilder(export_dir) b.add_meta_graph_and_variables( session, tags=[tag_constants.SERVING], signature_def_map=signature_def_map, assets_collection=ops.get_collection(ops.GraphKeys.ASSET_FILEPATHS), main_op=legacy_init_op, clear_devices=True) b.save()
def simple_save(session, export_dir, inputs, outputs, legacy_init_op=None): """Convenience function to build a SavedModel suitable for serving. In many common cases, saving models for serving will be as simple as: simple_save(session, export_dir, inputs={"x": x, "y": y}, outputs={"z": z}) Although in many cases it's not necessary to understand all of the many ways to configure a SavedModel, this method has a few practical implications: - It will be treated as a graph for inference / serving (i.e. uses the tag `saved_model.SERVING`) - The SavedModel will load in TensorFlow Serving and supports the [Predict API](https://github.com/tensorflow/serving/blob/master/tensorflow_serving/apis/predict.proto). To use the Classify, Regress, or MultiInference APIs, please use either [tf.Estimator](https://www.tensorflow.org/api_docs/python/tf/estimator/Estimator) or the lower level [SavedModel APIs](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md). - Some TensorFlow ops depend on information on disk or other information called "assets". These are generally handled automatically by adding the assets to the `GraphKeys.ASSET_FILEPATHS` collection. Only assets in that collection are exported; if you need more custom behavior, you'll need to use the [SavedModelBuilder](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/builder.py). More information about SavedModel and signatures can be found here: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/saved_model/README.md. Args: session: The TensorFlow session from which to save the meta graph and variables. export_dir: The path to which the SavedModel will be stored. inputs: dict mapping string input names to tensors. These are added to the SignatureDef as the inputs. outputs: dict mapping string output names to tensors. These are added to the SignatureDef as the outputs. legacy_init_op: Legacy support for op or group of ops to execute after the restore op upon a load. """ signature_def_map = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def_utils.predict_signature_def(inputs, outputs) } b = builder.SavedModelBuilder(export_dir) b.add_meta_graph_and_variables( session, tags=[tag_constants.SERVING], signature_def_map=signature_def_map, assets_collection=ops.get_collection(ops.GraphKeys.ASSET_FILEPATHS), main_op=legacy_init_op, clear_devices=True) b.save()
def save_model(): print("Saving trained model") tf.gfile.MakeDirs(FLAGS.rundir + "/model") exported_model_path = FLAGS.rundir + "/model/export" tf.train.Saver().save(sess, exported_model_path) from tensorflow.python.saved_model import utils from tensorflow.python.saved_model import signature_constants from tensorflow.python.saved_model import signature_def_utils graph = tf.get_default_graph() inputs_map = {'inputs': x} outputs_map = {'outputs': y} prediction_signature = signature_def_utils.predict_signature_def( inputs=inputs_map, outputs=outputs_map) from tensorflow.python.saved_model import builder as saved_model_builder from tensorflow.python.saved_model import tag_constants # TODO: Fix this logic. Goal is to end up with the saved_model in a place where TF Serving can find it. # (With or without Guild.) if FLAGS.rundir != './runs': saved_model_path = '/root/model/versions/%s' % _version else: saved_model_path = '%s/model/versions/%s' % (FLAGS.rundir, _version) print(saved_model_path) builder = saved_model_builder.SavedModelBuilder(saved_model_path) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map={ 'predict': prediction_signature, signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: prediction_signature }, clear_devices=True, ) builder.save(as_text=False) print("") served_model_path = '%s/%s' % (FLAGS.servingdir, _version) print( "Training complete. tf.train.Saver exported to '%s'.\nSavedModelBuilder saved to '%s'.\nTensorFlow Serving at '%s'" % (exported_model_path, saved_model_path, served_model_path)) print("")
def build_standardized_signature_def(input_tensors, output_tensors, problem_type): """Build a SignatureDef using problem type and input and output Tensors. Note that this delegates the actual creation of the signatures to methods in //third_party/tensorflow/python/saved_model/signature_def_utils.py, which may assign names to the input and output tensors (depending on the problem type) that are standardized in the context of SavedModel. Args: input_tensors: a dict of string key to `Tensor` output_tensors: a dict of string key to `Tensor` problem_type: an instance of constants.ProblemType, specifying classification, regression, etc. Returns: A SignatureDef using SavedModel standard keys where possible. Raises: ValueError: if input_tensors or output_tensors is None or empty. """ if not input_tensors: raise ValueError('input_tensors must be provided.') if not output_tensors: raise ValueError('output_tensors must be provided.') # Per-method signature_def functions will standardize the keys if possible if _is_classification_problem(problem_type, input_tensors, output_tensors): (_, examples), = input_tensors.items() classes = _get_classification_classes(output_tensors) scores = _get_classification_scores(output_tensors) if classes is None and scores is None: items = list(output_tensors.items()) if items[0][1].dtype == dtypes.string: (_, classes), = items else: (_, scores), = items return signature_def_utils.classification_signature_def( examples, classes, scores) elif _is_regression_problem(problem_type, input_tensors, output_tensors): (_, examples), = input_tensors.items() (_, predictions), = output_tensors.items() return signature_def_utils.regression_signature_def( examples, predictions) else: return signature_def_utils.predict_signature_def( input_tensors, output_tensors)
def simple_save(session, export_dir, inputs, outputs, legacy_init_op=None): remove_path(export_dir) signature_def_map = { signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature_def_utils.predict_signature_def(inputs, outputs) } b = builder.SavedModelBuilder(export_dir) b.add_meta_graph_and_variables( session, tags=[tag_constants.SERVING], signature_def_map=signature_def_map, assets_collection=ops.get_collection(ops.GraphKeys.ASSET_FILEPATHS), legacy_init_op=legacy_init_op, clear_devices=True) b.save() export_generic_config(export_dir=export_dir)
def build_standardized_signature_def(input_tensors, output_tensors, problem_type): """Build a SignatureDef using problem type and input and output Tensors. Note that this delegates the actual creation of the signatures to methods in //third_party/tensorflow/python/saved_model/signature_def_utils.py, which may assign names to the input and output tensors (depending on the problem type) that are standardized in the context of SavedModel. Args: input_tensors: a dict of string key to `Tensor` output_tensors: a dict of string key to `Tensor` problem_type: an instance of constants.ProblemType, specifying classification, regression, etc. Returns: A SignatureDef using SavedModel standard keys where possible. Raises: ValueError: if input_tensors or output_tensors is None or empty. """ if not input_tensors: raise ValueError('input_tensors must be provided.') if not output_tensors: raise ValueError('output_tensors must be provided.') # Per-method signature_def functions will standardize the keys if possible if _is_classification_problem(problem_type, input_tensors, output_tensors): (_, examples), = input_tensors.items() classes = _get_classification_classes(output_tensors) scores = _get_classification_scores(output_tensors) if classes is None and scores is None: items = list(output_tensors.items()) if items[0][1].dtype == dtypes.string: (_, classes), = items else: (_, scores), = items return signature_def_utils.classification_signature_def( examples, classes, scores) elif _is_regression_problem(problem_type, input_tensors, output_tensors): (_, examples), = input_tensors.items() (_, predictions), = output_tensors.items() return signature_def_utils.regression_signature_def(examples, predictions) else: return signature_def_utils.predict_signature_def(input_tensors, output_tensors)
def export(self): import os inputs = {'b64_image': self.input_image} export_path = os.path.join(tf.compat.as_bytes("models"), tf.compat.as_bytes(str("1"))) builder = saved_model_builder.SavedModelBuilder(export_path) builder.add_meta_graph_and_variables( self.sess, [SERVING], signature_def_map={ DEFAULT_SERVING_SIGNATURE_DEF_KEY: predict_signature_def(inputs=inputs, outputs=self.output_ops) }) builder.save()
def save_model_with_single_input(self, export_dir): builder = saved_model_builder.SavedModelBuilder(export_dir) with self.test_session(graph=tf.Graph()) as sess: input1 = tf.placeholder(dtype=tf.int32, shape=[5], name='myinput') initializer = tf.constant_initializer([1, 2, 3, 4, 5]) with tf.variable_scope('Model', reuse=None, initializer=initializer): v1 = tf.get_variable('v1', [5], dtype=tf.int32) output1 = tf.add(v1, input1, name='myadd') inputs = {'single_input': input1} outputs = {'single_output': output1} signature_def_map = { 'my_signature_single_input': signature_def_utils.predict_signature_def(inputs, outputs) } sess.run(tf.global_variables_initializer()) builder.add_meta_graph_and_variables( sess, [tag_constants.SERVING], signature_def_map=signature_def_map) builder.save(False)
def save_model(self, model_name): path = '/opt/ml/model/{}'.format(model_name) if '14' in tf.__version__: # 若tensorflow版本为1.14,使用 export_saved_model 方法导出 Saved Model K.experimental.export_saved_model(self.model, path) elif '13' in tf.__version__: # 若tensorflow版本为1.13,使用 export 方法导出 Saved Model K.experimental.export(self.model, path) else: # 当tensorflow版本低于1.12及以下,Keras还没有相关方法支持,需要自行构建 signature 生成 Saved Model bd = builder.SavedModelBuilder(path) signature = predict_signature_def( inputs={"input": self.model.input}, outputs={"score": self.model.output}) with bk.get_session() as sess: bd.add_meta_graph_and_variables( sess=sess, tags=[tag_constants.SERVING], signature_def_map={"serving_default": signature}) bd.save() return
def export_h5_to_pb(path_to_h5, export_path): # Set the learning phase to Test since the model is already trained. K.set_learning_phase(0) # Load the Keras model keras_model = load_model(path_to_h5) # Build the Protocol Buffer SavedModel at 'export_path' builder = saved_model_builder.SavedModelBuilder(export_path) # Create prediction signature to be used by TensorFlow Serving Predict API signature = predict_signature_def( inputs={"input_1": keras_model.input}, outputs={"dense_1": keras_model.output}) with K.get_session() as sess: # Save the meta graph and the variables # https://www.tensorflow.org/tfx/serving/serving_basic builder.add_meta_graph_and_variables( sess=sess, tags=[tag_constants.SERVING], signature_def_map={ signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: signature }) builder.save()
def main(_): with tf.name_scope('name_scope_x'): input = tf.placeholder(dtype= tf.int32,shape= [None, 4], name='input') b = tf.constant([1,1,1,1], dtype=tf.int32, shape=[4, 1]) output = tf.matmul(input,b, name='output') with tf.Session() as sess: sess.run(tf.global_variables_initializer()) #save model export_dir = 'D:/data/1' try: shutil.rmtree(export_dir) except OSError: pass builder = tf.saved_model.builder.SavedModelBuilder(export_dir) signature_def_map = { 'mypredict': signature_def_utils.predict_signature_def(inputs= {"input": input}, outputs= {"output": output}) } builder.add_meta_graph_and_variables(sess, tags = [tag_constants.SERVING], signature_def_map = signature_def_map, assets_collection = ops.get_collection(ops.GraphKeys.ASSET_FILEPATHS), legacy_init_op = None, clear_devices = True) builder.save() #restore, only if this part works, then you should start the implementation #for grpc client, else there is no way to understand the exception tf.reset_default_graph() with tf.Session(graph=tf.Graph()) as sess: tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], export_dir) graph = tf.get_default_graph() input_tensor = graph.get_tensor_by_name("name_scope_x/input:0") output_tensor = graph.get_tensor_by_name("name_scope_x/output:0") tmp = sess.run(output_tensor, feed_dict={input_tensor: [[1,2,3,4]] }) #this should yield [10] print(tmp) print('done')
def save_model(): print("Saving trained model") tf.gfile.MakeDirs(FLAGS.rundir + "/model") exported_model_path = FLAGS.rundir + "/model/export" tf.train.Saver().save(sess, exported_model_path) from tensorflow.python.saved_model import utils from tensorflow.python.saved_model import signature_constants from tensorflow.python.saved_model import signature_def_utils graph = tf.get_default_graph() inputs_map = {'inputs': x} outputs_map = {'outputs': y} prediction_signature = signature_def_utils.predict_signature_def(inputs=inputs_map, outputs=outputs_map) from tensorflow.python.saved_model import builder as saved_model_builder from tensorflow.python.saved_model import tag_constants saved_model_path = '%s/%s' % (FLAGS.servingdir, _version) print(saved_model_path) builder = saved_model_builder.SavedModelBuilder(saved_model_path) builder.add_meta_graph_and_variables(sess, [tag_constants.SERVING], signature_def_map={'predict':prediction_signature, signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:prediction_signature}, clear_devices=True, ) builder.save(as_text=False) print("") # served_model_path = '%s/%s' % (FLAGS.servingdir, _version) print("Training complete. tf.train.Saver exported to '%s'.\nSavedModelBuilder saved to '%s'." % (exported_model_path, saved_model_path)) print("")
def export(self, path): # assumes self.graph contains *all* necessary variables # assert there are variables to save assert self.graph.get_collection(tf.GraphKeys.GLOBAL_VARIABLES) # save current graph -- assumed to be for training & testing saved_model_builder = builder.SavedModelBuilder(path) saved_model_builder.add_meta_graph_and_variables( session=self.session, tags=[self.TRAINING, self.TESTING], ) # build inference ops inn new graph self.graph = Graph() with self.graph.as_default(): inputs = self.inputs() outputs = self.forward(inputs) # build prediction signature def for tf serving if isinstance(inputs, tf.Tensor): inputs = (inputs, ) if isinstance(outputs, tf.Tensor): outputs = (outputs, ) sigdef = predict_signature_def( inputs={op.name for op in inputs}, outputs={op.name for op in outputs}, ) # add inference meta graph saved_model_builder.add_meta_graph(tags=[self.SERVING], signature_def_map={ 'predict': sigdef, }) saved_model_builder.save()
def testPredictionSignatureDef(self): input1 = constant_op.constant("a", name="input-1") input2 = constant_op.constant("b", name="input-2") output1 = constant_op.constant("c", name="output-1") output2 = constant_op.constant("d", name="output-2") signature_def = signature_def_utils.predict_signature_def( { "input-1": input1, "input-2": input2 }, { "output-1": output1, "output-2": output2 }) self.assertEqual(signature_constants.PREDICT_METHOD_NAME, signature_def.method_name) # Check inputs in signature def. self.assertEqual(2, len(signature_def.inputs)) input1_tensor_info_actual = (signature_def.inputs["input-1"]) self.assertEqual("input-1:0", input1_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, input1_tensor_info_actual.dtype) self.assertEqual(0, len(input1_tensor_info_actual.tensor_shape.dim)) input2_tensor_info_actual = (signature_def.inputs["input-2"]) self.assertEqual("input-2:0", input2_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, input2_tensor_info_actual.dtype) self.assertEqual(0, len(input2_tensor_info_actual.tensor_shape.dim)) # Check outputs in signature def. self.assertEqual(2, len(signature_def.outputs)) output1_tensor_info_actual = (signature_def.outputs["output-1"]) self.assertEqual("output-1:0", output1_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, output1_tensor_info_actual.dtype) self.assertEqual(0, len(output1_tensor_info_actual.tensor_shape.dim)) output2_tensor_info_actual = (signature_def.outputs["output-2"]) self.assertEqual("output-2:0", output2_tensor_info_actual.name) self.assertEqual(types_pb2.DT_STRING, output2_tensor_info_actual.dtype) self.assertEqual(0, len(output2_tensor_info_actual.tensor_shape.dim))
def testPredictionSignatureDef(self): input1 = constant_op.constant("a", name="input-1") input2 = constant_op.constant("b", name="input-2") output1 = constant_op.constant("c", name="output-1") output2 = constant_op.constant("d", name="output-2") meta_graph_def = meta_graph_pb2.MetaGraphDef() self._add_to_signature_def_map( meta_graph_def, { "my_prediction": signature_def_utils.predict_signature_def( { "input-1": input1, "input-2": input2 }, { "output-1": output1, "output-2": output2 }) }) # Look up the prediction signature def with the key used while saving. signature_def = signature_def_contrib_utils.get_signature_def_by_key( meta_graph_def, "my_prediction") self.assertEqual(signature_constants.PREDICT_METHOD_NAME, signature_def.method_name) # Check inputs in signature def. self.assertEqual(2, len(signature_def.inputs)) self._check_tensor_info(signature_def.inputs, "input-1", "input-1:0") self._check_tensor_info(signature_def.inputs, "input-2", "input-2:0") # Check outputs in signature def. self.assertEqual(2, len(signature_def.outputs)) self._check_tensor_info(signature_def.outputs, "output-1", "output-1:0") self._check_tensor_info(signature_def.outputs, "output-2", "output-2:0")
def export_tf_model(input_path, export_path): K.set_learning_phase(0) keras_model = load_model(input_path) builder = saved_model_builder.SavedModelBuilder(export_path) print(keras_model.input) print(keras_model.output) signature = predict_signature_def(inputs={"inputs": keras_model.input}, outputs={ "yolo_1": keras_model.output[0], "yolo_2": keras_model.output[1], "yolo_3": keras_model.output[2] }) with K.get_session() as sess: builder.add_meta_graph_and_variables( sess=sess, tags=[tag_constants.SERVING], signature_def_map={"serving_default": signature}) builder.save()
def export_fn(estimator, export_dir_base, checkpoint_path=None, eval_result=None): with ops.Graph().as_default() as g: contrib_variables.create_global_step(g) input_ops = serving_from_csv_input(train_config, args, keep_target) model_fn_ops = estimator._call_model_fn(input_ops.features, None, model_fn_lib.ModeKeys.INFER) output_fetch_tensors = make_output_tensors( train_config=train_config, args=args, input_ops=input_ops, model_fn_ops=model_fn_ops, keep_target=keep_target) signature_def_map = { 'serving_default': signature_def_utils.predict_signature_def(input_ops.default_inputs, output_fetch_tensors) } if not checkpoint_path: # Locate the latest checkpoint checkpoint_path = saver.latest_checkpoint(estimator._model_dir) if not checkpoint_path: raise NotFittedError("Couldn't find trained model at %s." % estimator._model_dir) export_dir = saved_model_export_utils.get_timestamped_export_dir( export_dir_base) if (model_fn_ops.scaffold is not None and model_fn_ops.scaffold.saver is not None): saver_for_restore = model_fn_ops.scaffold.saver else: saver_for_restore = saver.Saver(sharded=True) with tf_session.Session('') as session: saver_for_restore.restore(session, checkpoint_path) init_op = control_flow_ops.group( variables.local_variables_initializer(), resources.initialize_resources(resources.shared_resources()), tf.tables_initializer()) # Perform the export builder = saved_model_builder.SavedModelBuilder(export_dir) builder.add_meta_graph_and_variables( session, [tag_constants.SERVING], signature_def_map=signature_def_map, assets_collection=ops.get_collection( ops.GraphKeys.ASSET_FILEPATHS), legacy_init_op=init_op) builder.save(False) # Add the extra assets if assets_extra: assets_extra_path = os.path.join(compat.as_bytes(export_dir), compat.as_bytes('assets.extra')) for dest_relative, source in assets_extra.items(): dest_absolute = os.path.join(compat.as_bytes(assets_extra_path), compat.as_bytes(dest_relative)) dest_path = os.path.dirname(dest_absolute) gfile.MakeDirs(dest_path) gfile.Copy(source, dest_absolute) # only keep the last 3 models saved_model_export_utils.garbage_collect_exports( python_portable_string(export_dir_base), exports_to_keep=3) # save the last model to the model folder. # export_dir_base = A/B/intermediate_models/ if keep_target: final_dir = os.path.join(args.job_dir, 'evaluation_model') else: final_dir = os.path.join(args.job_dir, 'model') if file_io.is_directory(final_dir): file_io.delete_recursively(final_dir) file_io.recursive_create_dir(final_dir) _recursive_copy(export_dir, final_dir) return export_dir
def as_signature_def(self, receiver_tensors): return signature_def_utils.predict_signature_def(receiver_tensors, self.outputs)