def test_get_output_alternatives_empty_provided_with_default(self): prediction_tensor = constant_op.constant(["bogus"]) model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions={"some_output": prediction_tensor}, output_alternatives={}) with self.assertRaises(ValueError) as e: saved_model_export_utils.get_output_alternatives(model_fn_ops, "WRONG") self.assertEqual("Requested default_output_alternative: WRONG, but " "available output_alternatives are: []", str(e.exception))
def test_build_all_signature_defs_legacy_input_fn_not_supported(self): """Tests that legacy input_fn returning (features, labels) raises error. serving_input_fn must return InputFnOps including a default input alternative. """ input_features = constant_op.constant(["10"]) input_ops = ({"features": input_features}, None) 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")) with self.assertRaisesRegexp( ValueError, "A default input_alternative must be provided"): saved_model_export_utils.build_all_signature_defs( input_alternatives, output_alternatives, "head-1")
def test_build_all_signature_defs_legacy_input_fn_not_supported(self): """Tests that legacy input_fn returning (features, labels) raises error. serving_input_fn must return InputFnOps including a default input alternative. """ input_features = constant_op.constant(["10"]) input_ops = ({"features": input_features}, None) 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")) with self.assertRaisesRegexp( ValueError, "A default input_alternative must be provided"): saved_model_export_utils.build_all_signature_defs( input_alternatives, output_alternatives, "head-1")
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(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_get_output_alternatives_multi_no_default(self): provided_output_alternatives = { "head-1": (constants.ProblemType.LINEAR_REGRESSION, "bogus output dict"), "head-2": (constants.ProblemType.CLASSIFICATION, "bogus output dict 2"), "head-3": (constants.ProblemType.UNSPECIFIED, "bogus output dict 3"), } model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions={"some_output": "bogus_tensor"}, output_alternatives=provided_output_alternatives) with self.assertRaises(ValueError) as e: saved_model_export_utils.get_output_alternatives(model_fn_ops) self.assertEqual("Please specify a default_output_alternative. Available " "output_alternatives are: ['head-1', 'head-2', 'head-3']", str(e.exception))
def test_get_output_alternatives_implicit(self): prediction_tensor = tf.constant(["bogus"]) model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions={"some_output": prediction_tensor}, output_alternatives=None) output_alternatives, _ = saved_model_export_utils.get_output_alternatives( model_fn_ops, "some_output") self.assertEqual( {"default_output_alternative": (constants.ProblemType.UNSPECIFIED, {"some_output": prediction_tensor})}, output_alternatives)
def test_get_output_alternatives_explicit(self): provided_output_alternatives = { "head-1": (constants.ProblemType.LINEAR_REGRESSION, "bogus output dict"), "head-2": (constants.ProblemType.CLASSIFICATION, "bogus output dict 2"), "head-3": (constants.ProblemType.UNSPECIFIED, "bogus output dict 3"), } model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions={"some_output": "bogus_tensor"}, output_alternatives=provided_output_alternatives) output_alternatives, _ = saved_model_export_utils.get_output_alternatives( model_fn_ops, "head-1") self.assertEqual(provided_output_alternatives, output_alternatives)
def test_get_output_alternatives_explicit(self): provided_output_alternatives = { "head-1": (constants.ProblemType.LINEAR_REGRESSION, "bogus output dict"), "head-2": (constants.ProblemType.CLASSIFICATION, "bogus output dict 2"), "head-3": (constants.ProblemType.UNSPECIFIED, "bogus output dict 3"), } model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions={"some_output": "bogus_tensor"}, output_alternatives=provided_output_alternatives) output_alternatives, _ = saved_model_export_utils.get_output_alternatives( model_fn_ops, "head-1") self.assertEqual(provided_output_alternatives, output_alternatives)
def __init__(self, estimator, prediction_input_fn, input_alternative_key=None, output_alternative_key=None, graph=None, config=None): """Initialize a `ContribEstimatorPredictor`. Args: estimator: an instance of `tf.contrib.learn.Estimator`. prediction_input_fn: a function that takes no arguments and returns an instance of `InputFnOps`. input_alternative_key: Optional. Specify the input alternative used for prediction. output_alternative_key: Specify the output alternative used for prediction. Not needed for single-headed models but required for multi-headed models. graph: Optional. The Tensorflow `graph` in which prediction should be done. config: `ConfigProto` proto used to configure the session. """ self._graph = graph or ops.Graph() with self._graph.as_default(): input_fn_ops = prediction_input_fn() # pylint: disable=protected-access model_fn_ops = estimator._get_predict_ops(input_fn_ops.features) # pylint: enable=protected-access checkpoint_path = checkpoint_management.latest_checkpoint( estimator.model_dir) self._session = monitored_session.MonitoredSession( session_creator=monitored_session.ChiefSessionCreator( config=config, checkpoint_filename_with_path=checkpoint_path)) input_alternative_key = ( input_alternative_key or saved_model_export_utils.DEFAULT_INPUT_ALTERNATIVE_KEY) input_alternatives, _ = saved_model_export_utils.get_input_alternatives( input_fn_ops) self._feed_tensors = input_alternatives[input_alternative_key] (output_alternatives, output_alternative_key ) = saved_model_export_utils.get_output_alternatives( model_fn_ops, output_alternative_key) _, fetch_tensors = output_alternatives[output_alternative_key] self._fetch_tensors = fetch_tensors
def __init__(self, estimator, prediction_input_fn, input_alternative_key=None, output_alternative_key=None, graph=None, config=None): """Initialize a `ContribEstimatorPredictor`. Args: estimator: an instance of `tf.contrib.learn.Estimator`. prediction_input_fn: a function that takes no arguments and returns an instance of `InputFnOps`. input_alternative_key: Optional. Specify the input alternative used for prediction. output_alternative_key: Specify the output alternative used for prediction. Not needed for single-headed models but required for multi-headed models. graph: Optional. The Tensorflow `graph` in which prediction should be done. config: `ConfigProto` proto used to configure the session. """ self._graph = graph or ops.Graph() with self._graph.as_default(): input_fn_ops = prediction_input_fn() # pylint: disable=protected-access model_fn_ops = estimator._get_predict_ops(input_fn_ops.features) # pylint: enable=protected-access checkpoint_path = checkpoint_management.latest_checkpoint( estimator.model_dir) self._session = monitored_session.MonitoredSession( session_creator=monitored_session.ChiefSessionCreator( config=config, checkpoint_filename_with_path=checkpoint_path)) input_alternative_key = ( input_alternative_key or saved_model_export_utils.DEFAULT_INPUT_ALTERNATIVE_KEY) input_alternatives, _ = saved_model_export_utils.get_input_alternatives( input_fn_ops) self._feed_tensors = input_alternatives[input_alternative_key] (output_alternatives, output_alternative_key) = saved_model_export_utils.get_output_alternatives( model_fn_ops, output_alternative_key) _, fetch_tensors = output_alternatives[output_alternative_key] self._fetch_tensors = fetch_tensors
def test_get_output_alternatives_single_no_default(self): prediction_tensor = constant_op.constant(["bogus"]) provided_output_alternatives = { "head-1": (constants.ProblemType.LINEAR_REGRESSION, {"output": prediction_tensor}), } model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions=prediction_tensor, output_alternatives=provided_output_alternatives) output_alternatives, _ = saved_model_export_utils.get_output_alternatives( model_fn_ops) self.assertEqual({"head-1": (constants.ProblemType.LINEAR_REGRESSION, {"output": prediction_tensor})}, output_alternatives)
def test_get_output_alternatives_single_no_default(self): prediction_tensor = constant_op.constant(["bogus"]) provided_output_alternatives = { "head-1": (constants.ProblemType.LINEAR_REGRESSION, {"output": prediction_tensor}), } model_fn_ops = model_fn.ModelFnOps( model_fn.ModeKeys.INFER, predictions=prediction_tensor, output_alternatives=provided_output_alternatives) output_alternatives, _ = saved_model_export_utils.get_output_alternatives( model_fn_ops) self.assertEqual({"head-1": (constants.ProblemType.LINEAR_REGRESSION, {"output": prediction_tensor})}, output_alternatives)