diff --git a/tensorflow/python/saved_model/model_utils/BUILD b/tensorflow/python/saved_model/model_utils/BUILD index 82a33c8e522..775d81a86bc 100644 --- a/tensorflow/python/saved_model/model_utils/BUILD +++ b/tensorflow/python/saved_model/model_utils/BUILD @@ -103,6 +103,7 @@ py_strict_test( "//tensorflow/python:client_testlib", "//tensorflow/python:constant_op", "//tensorflow/python:dtypes", + "//tensorflow/python:framework_ops", "//tensorflow/python:framework_test_lib", "//tensorflow/python/saved_model:signature_constants", "//tensorflow/python/saved_model:signature_def_utils", diff --git a/tensorflow/python/saved_model/model_utils/export_test.py b/tensorflow/python/saved_model/model_utils/export_test.py index 8620a3a6a06..f62f4150bf6 100644 --- a/tensorflow/python/saved_model/model_utils/export_test.py +++ b/tensorflow/python/saved_model/model_utils/export_test.py @@ -24,6 +24,7 @@ import time from tensorflow.python.framework import constant_op from tensorflow.python.framework import dtypes +from tensorflow.python.framework import ops from tensorflow.python.framework import test_util from tensorflow.python.ops import array_ops from tensorflow.python.platform import test @@ -36,136 +37,147 @@ from tensorflow.python.saved_model.model_utils.mode_keys import KerasModeKeys class ExportTest(test_util.TensorFlowTestCase): - @test_util.deprecated_graph_mode_only 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 - }), - } + # 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) + 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}) - } + 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) + self.assertDictEqual(expected_signature_defs, signature_defs) - @test_util.deprecated_graph_mode_only 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 - }), - } + # 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 = { + "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) + 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}) + 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 regression and classification - # signatures must take a single string input. Here we verify that - # these invalid signatures are not included in the export_utils. - } + # 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) + self.assertDictEqual(expected_signature_defs, signature_defs) - @test_util.deprecated_graph_mode_only 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 - }), - } + # 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) + 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}) + 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. - } + # 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) + self.assertDictEqual(expected_signature_defs, signature_defs) def test_build_all_signature_defs_export_outputs_required(self): receiver_tensor = constant_op.constant(["11"]) @@ -210,37 +222,42 @@ class ExportTest(test_util.TensorFlowTestCase): self.assertEqual(tmp_export_dir, os.path.join(b"tmp", b"export", b"temp-1576013284")) - @test_util.deprecated_graph_mode_only 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), - } + # 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) + 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}) - } + expected_signature_defs = { + "serving_default": + signature_def_utils.predict_signature_def(receiver_tensor, + {"output": output_1}) + } - self.assertDictEqual(expected_signature_defs, signature_defs) + self.assertDictEqual(expected_signature_defs, signature_defs) - signature_defs = export_utils.build_all_signature_defs( - receiver_tensor, export_outputs, serving_only=False) + 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}) - }) + 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) + self.assertDictEqual(expected_signature_defs, signature_defs) - @test_util.deprecated_graph_mode_only def test_export_outputs_for_mode(self): predictions = {"predictions": constant_op.constant([1.])} loss = {"loss": constant_op.constant([2.])}