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 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_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 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_standardized_signature_def_regression(self): with context.graph_mode(): input_tensors = { 'input-1': array_ops.placeholder( dtypes.string, 1, name='input-tensor-1') } value = array_ops.placeholder(dtypes.float32, 1, name='output-tensor-1') export_output = export_output_lib.RegressionOutput(value) actual_signature_def = export_output.as_signature_def(input_tensors) expected_signature_def = meta_graph_pb2.SignatureDef() shape = tensor_shape_pb2.TensorShapeProto( dim=[tensor_shape_pb2.TensorShapeProto.Dim(size=1)]) dtype_float = types_pb2.DataType.Value('DT_FLOAT') dtype_string = types_pb2.DataType.Value('DT_STRING') expected_signature_def.inputs[ signature_constants.REGRESS_INPUTS].CopyFrom( meta_graph_pb2.TensorInfo(name='input-tensor-1:0', dtype=dtype_string, tensor_shape=shape)) expected_signature_def.outputs[ signature_constants.REGRESS_OUTPUTS].CopyFrom( meta_graph_pb2.TensorInfo(name='output-tensor-1:0', dtype=dtype_float, tensor_shape=shape)) expected_signature_def.method_name = ( signature_constants.REGRESS_METHOD_NAME) self.assertEqual(actual_signature_def, expected_signature_def)
def test_regress_value_must_be_float(self): with context.graph_mode(): value = array_ops.placeholder(dtypes.string, 1, name='output-tensor-1') with self.assertRaisesRegexp( ValueError, 'Regression output value must be a float32 Tensor'): export_output_lib.RegressionOutput(value)
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): # 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) } unfed_input = array_ops.placeholder(dtypes.bool) receiver_tensors_alternative_2 = {"unfed": unfed_input} receiver_tensors_alternatives = { "other": receiver_tensors_alternative_1, "with_unfed_input": receiver_tensors_alternative_2 } output_1 = constant_op.constant([1.]) output_2 = constant_op.constant(["2"]) output_3 = constant_op.constant(["3"]) output_4 = unfed_input output_5 = math_ops.logical_not(unfed_input) 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}), "head-4": export_output.PredictOutput(outputs={"some_output_4": output_4}), "head-5": export_output.PredictOutput(outputs={"some_output_5": output_5}), } 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 regression and classification # signatures must take a single string input. Here we verify that # these invalid signatures are not included in the export_utils. # Similarly, we verify that 'head-4' and 'head-5', which depend on an # input that is not being fed as a receiver tensor, are also omitted. # All the three heads are present when that input is fed, however: "with_unfed_input:head-3": signature_def_utils.predict_signature_def( receiver_tensors_alternative_2, {"some_output_3": output_3}), "with_unfed_input:head-4": signature_def_utils.predict_signature_def( receiver_tensors_alternative_2, {"some_output_4": output_4}), "with_unfed_input:head-5": signature_def_utils.predict_signature_def( receiver_tensors_alternative_2, {"some_output_5": output_5}) } self.assertDictEqual(expected_signature_defs, signature_defs)