blob: 3eed1ab163f3ad5c4f3b711f6034dd3d59e0dc61 [file] [log] [blame]
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Tests for export."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import tempfile
import time
from google.protobuf import text_format
from tensorflow.core.example import example_pb2
from tensorflow.python.estimator.export import export
from tensorflow.python.estimator.export import export_output
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import sparse_tensor
from tensorflow.python.framework import tensor_shape
from tensorflow.python.framework import test_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import parsing_ops
from tensorflow.python.platform import test
from tensorflow.python.saved_model import signature_constants
from tensorflow.python.saved_model import signature_def_utils
class LabeledTensorMock(object):
"""Mock class emulating LabeledTensor."""
def __init__(self):
self.tensor = constant_op.constant([1])
def _convert_labeled_tensor_mock_to_tensor(value, *args, **kwargs):
return ops.internal_convert_to_tensor(value.tensor, *args, **kwargs)
ops.register_tensor_conversion_function(LabeledTensorMock,
_convert_labeled_tensor_mock_to_tensor)
class ServingInputReceiverTest(test_util.TensorFlowTestCase):
def test_serving_input_receiver_constructor(self):
"""Tests that no errors are raised when input is expected."""
features = {
"feature0": constant_op.constant([0]),
u"feature1": constant_op.constant([1]),
"feature2": sparse_tensor.SparseTensor(
indices=[[0, 0]], values=[1], dense_shape=[1, 1]),
}
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
export.ServingInputReceiver(features, receiver_tensors)
def test_serving_input_receiver_features_invalid(self):
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
with self.assertRaisesRegexp(ValueError, "features must be defined"):
export.ServingInputReceiver(
features=None,
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(ValueError, "feature keys must be strings"):
export.ServingInputReceiver(
features={1: constant_op.constant([1])},
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(
ValueError, "feature feature1 must be a Tensor or SparseTensor"):
export.ServingInputReceiver(
features={"feature1": [1]},
receiver_tensors=receiver_tensors)
def test_serving_input_receiver_receiver_tensors_invalid(self):
features = {
"feature0": constant_op.constant([0]),
u"feature1": constant_op.constant([1]),
"feature2": sparse_tensor.SparseTensor(
indices=[[0, 0]], values=[1], dense_shape=[1, 1]),
}
with self.assertRaisesRegexp(
ValueError, "receiver_tensors must be defined"):
export.ServingInputReceiver(
features=features,
receiver_tensors=None)
with self.assertRaisesRegexp(
ValueError, "receiver_tensor keys must be strings"):
export.ServingInputReceiver(
features=features,
receiver_tensors={
1: array_ops.placeholder(dtypes.string, name="example0")})
with self.assertRaisesRegexp(
ValueError, "receiver_tensor example1 must be a Tensor"):
export.ServingInputReceiver(
features=features,
receiver_tensors={"example1": [1]})
def test_single_feature_single_receiver(self):
feature = constant_op.constant(5)
receiver_tensor = array_ops.placeholder(dtypes.string)
input_receiver = export.ServingInputReceiver(
feature, receiver_tensor)
# single feature is automatically named
feature_key, = input_receiver.features.keys()
self.assertEqual("feature", feature_key)
# single receiver is automatically named
receiver_key, = input_receiver.receiver_tensors.keys()
self.assertEqual("input", receiver_key)
def test_multi_feature_single_receiver(self):
features = {"foo": constant_op.constant(5),
"bar": constant_op.constant(6)}
receiver_tensor = array_ops.placeholder(dtypes.string)
_ = export.ServingInputReceiver(features, receiver_tensor)
def test_multi_feature_multi_receiver(self):
features = {"foo": constant_op.constant(5),
"bar": constant_op.constant(6)}
receiver_tensors = {"baz": array_ops.placeholder(dtypes.int64),
"qux": array_ops.placeholder(dtypes.float32)}
_ = export.ServingInputReceiver(features, receiver_tensors)
def test_feature_wrong_type(self):
feature = "not a tensor"
receiver_tensor = array_ops.placeholder(dtypes.string)
with self.assertRaises(ValueError):
_ = export.ServingInputReceiver(feature, receiver_tensor)
def test_feature_labeled_tensor(self):
feature = LabeledTensorMock()
receiver_tensor = array_ops.placeholder(dtypes.string)
_ = export.ServingInputReceiver(feature, receiver_tensor)
def test_receiver_wrong_type(self):
feature = constant_op.constant(5)
receiver_tensor = "not a tensor"
with self.assertRaises(ValueError):
_ = export.ServingInputReceiver(feature, receiver_tensor)
class UnsupervisedInputReceiverTest(test_util.TensorFlowTestCase):
# Since this is basically a wrapper around ServingInputReceiver, we only
# have a simple sanity check to ensure that it works.
def test_unsupervised_input_receiver_constructor(self):
"""Tests that no errors are raised when input is expected."""
features = {
"feature0":
constant_op.constant([0]),
u"feature1":
constant_op.constant([1]),
"feature2":
sparse_tensor.SparseTensor(
indices=[[0, 0]], values=[1], dense_shape=[1, 1]),
}
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
export.UnsupervisedInputReceiver(features, receiver_tensors)
class SupervisedInputReceiverTest(test_util.TensorFlowTestCase):
def test_input_receiver_constructor(self):
"""Tests that no errors are raised when input is expected."""
features = {
"feature0": constant_op.constant([0]),
u"feature1": constant_op.constant([1]),
"feature2": sparse_tensor.SparseTensor(
indices=[[0, 0]], values=[1], dense_shape=[1, 1]),
}
labels = {
"classes": constant_op.constant([0] * 100),
}
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
export.SupervisedInputReceiver(features, labels, receiver_tensors)
def test_input_receiver_raw_values(self):
"""Tests that no errors are raised when input is expected."""
features = {
"feature0": constant_op.constant([0]),
u"feature1": constant_op.constant([1]),
"feature2": sparse_tensor.SparseTensor(
indices=[[0, 0]], values=[1], dense_shape=[1, 1]),
}
labels = {
"classes": constant_op.constant([0] * 100),
}
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
rec = export.SupervisedInputReceiver(
features["feature2"], labels, receiver_tensors)
self.assertIsInstance(rec.features, sparse_tensor.SparseTensor)
rec = export.SupervisedInputReceiver(
features, labels["classes"], receiver_tensors)
self.assertIsInstance(rec.labels, ops.Tensor)
def test_input_receiver_features_invalid(self):
features = constant_op.constant([0] * 100)
labels = constant_op.constant([0])
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
with self.assertRaisesRegexp(ValueError, "features must be defined"):
export.SupervisedInputReceiver(
features=None,
labels=labels,
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(ValueError, "feature keys must be strings"):
export.SupervisedInputReceiver(
features={1: constant_op.constant([1])},
labels=labels,
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(ValueError, "label keys must be strings"):
export.SupervisedInputReceiver(
features=features,
labels={1: constant_op.constant([1])},
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(
ValueError, "feature feature1 must be a Tensor or SparseTensor"):
export.SupervisedInputReceiver(
features={"feature1": [1]},
labels=labels,
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(
ValueError, "feature must be a Tensor or SparseTensor"):
export.SupervisedInputReceiver(
features=[1],
labels=labels,
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(
ValueError, "label must be a Tensor or SparseTensor"):
export.SupervisedInputReceiver(
features=features,
labels=100,
receiver_tensors=receiver_tensors)
def test_input_receiver_receiver_tensors_invalid(self):
features = {
"feature0": constant_op.constant([0]),
u"feature1": constant_op.constant([1]),
"feature2": sparse_tensor.SparseTensor(
indices=[[0, 0]], values=[1], dense_shape=[1, 1]),
}
labels = constant_op.constant([0])
with self.assertRaisesRegexp(
ValueError, "receiver_tensors must be defined"):
export.SupervisedInputReceiver(
features=features,
labels=labels,
receiver_tensors=None)
with self.assertRaisesRegexp(
ValueError, "receiver_tensor keys must be strings"):
export.SupervisedInputReceiver(
features=features,
labels=labels,
receiver_tensors={
1: array_ops.placeholder(dtypes.string, name="example0")})
with self.assertRaisesRegexp(
ValueError, "receiver_tensor example1 must be a Tensor"):
export.SupervisedInputReceiver(
features=features,
labels=labels,
receiver_tensors={"example1": [1]})
def test_single_feature_single_receiver(self):
feature = constant_op.constant(5)
label = constant_op.constant(5)
receiver_tensor = array_ops.placeholder(dtypes.string)
input_receiver = export.SupervisedInputReceiver(
feature, label, receiver_tensor)
# single receiver is automatically named
receiver_key, = input_receiver.receiver_tensors.keys()
self.assertEqual("input", receiver_key)
def test_multi_feature_single_receiver(self):
features = {"foo": constant_op.constant(5),
"bar": constant_op.constant(6)}
labels = {"value": constant_op.constant(5)}
receiver_tensor = array_ops.placeholder(dtypes.string)
_ = export.SupervisedInputReceiver(features, labels, receiver_tensor)
def test_multi_feature_multi_receiver(self):
features = {"foo": constant_op.constant(5),
"bar": constant_op.constant(6)}
labels = {"value": constant_op.constant(5)}
receiver_tensors = {"baz": array_ops.placeholder(dtypes.int64),
"qux": array_ops.placeholder(dtypes.float32)}
_ = export.SupervisedInputReceiver(features, labels, receiver_tensors)
def test_feature_labeled_tensor(self):
feature = LabeledTensorMock()
label = constant_op.constant(5)
receiver_tensor = array_ops.placeholder(dtypes.string)
_ = export.SupervisedInputReceiver(feature, label, receiver_tensor)
class ExportTest(test_util.TensorFlowTestCase):
def test_build_parsing_serving_input_receiver_fn(self):
feature_spec = {"int_feature": parsing_ops.VarLenFeature(dtypes.int64),
"float_feature": parsing_ops.VarLenFeature(dtypes.float32)}
serving_input_receiver_fn = export.build_parsing_serving_input_receiver_fn(
feature_spec)
with ops.Graph().as_default():
serving_input_receiver = serving_input_receiver_fn()
self.assertEqual(set(["int_feature", "float_feature"]),
set(serving_input_receiver.features.keys()))
self.assertEqual(set(["examples"]),
set(serving_input_receiver.receiver_tensors.keys()))
example = example_pb2.Example()
text_format.Parse("features: { "
" feature: { "
" key: 'int_feature' "
" value: { "
" int64_list: { "
" value: [ 21, 2, 5 ] "
" } "
" } "
" } "
" feature: { "
" key: 'float_feature' "
" value: { "
" float_list: { "
" value: [ 525.25 ] "
" } "
" } "
" } "
"} ", example)
with self.test_session() as sess:
sparse_result = sess.run(
serving_input_receiver.features,
feed_dict={
serving_input_receiver.receiver_tensors["examples"].name:
[example.SerializeToString()]})
self.assertAllEqual([[0, 0], [0, 1], [0, 2]],
sparse_result["int_feature"].indices)
self.assertAllEqual([21, 2, 5],
sparse_result["int_feature"].values)
self.assertAllEqual([[0, 0]],
sparse_result["float_feature"].indices)
self.assertAllEqual([525.25],
sparse_result["float_feature"].values)
def test_build_raw_serving_input_receiver_fn_name(self):
"""Test case for issue #12755."""
f = {
"feature":
array_ops.placeholder(
name="feature", shape=[32], dtype=dtypes.float32)
}
serving_input_receiver_fn = export.build_raw_serving_input_receiver_fn(f)
v = serving_input_receiver_fn()
self.assertTrue(isinstance(v, export.ServingInputReceiver))
def test_build_raw_serving_input_receiver_fn_without_shape(self):
"""Test case for issue #21178."""
f = {"feature_1": array_ops.placeholder(dtypes.float32),
"feature_2": array_ops.placeholder(dtypes.int32)}
serving_input_receiver_fn = export.build_raw_serving_input_receiver_fn(f)
v = serving_input_receiver_fn()
self.assertTrue(isinstance(v, export.ServingInputReceiver))
self.assertEqual(
tensor_shape.unknown_shape(),
v.receiver_tensors["feature_1"].shape)
self.assertEqual(
tensor_shape.unknown_shape(),
v.receiver_tensors["feature_2"].shape)
@test_util.run_in_graph_and_eager_modes
def test_build_raw_serving_input_receiver_fn(self):
features = {"feature_1": constant_op.constant(["hello"]),
"feature_2": constant_op.constant([42])}
serving_input_receiver_fn = export.build_raw_serving_input_receiver_fn(
features)
with ops.Graph().as_default():
serving_input_receiver = serving_input_receiver_fn()
self.assertEqual(set(["feature_1", "feature_2"]),
set(serving_input_receiver.features.keys()))
self.assertEqual(set(["feature_1", "feature_2"]),
set(serving_input_receiver.receiver_tensors.keys()))
self.assertEqual(
dtypes.string,
serving_input_receiver.receiver_tensors["feature_1"].dtype)
self.assertEqual(
dtypes.int32,
serving_input_receiver.receiver_tensors["feature_2"].dtype)
@test_util.run_in_graph_and_eager_modes
def test_build_raw_supervised_input_receiver_fn(self):
features = {"feature_1": constant_op.constant(["hello"]),
"feature_2": constant_op.constant([42])}
labels = {"foo": constant_op.constant([5]),
"bar": constant_op.constant([6])}
input_receiver_fn = export.build_raw_supervised_input_receiver_fn(
features, labels)
with ops.Graph().as_default():
input_receiver = input_receiver_fn()
self.assertEqual(set(["feature_1", "feature_2"]),
set(input_receiver.features.keys()))
self.assertEqual(set(["foo", "bar"]),
set(input_receiver.labels.keys()))
self.assertEqual(set(["feature_1", "feature_2", "foo", "bar"]),
set(input_receiver.receiver_tensors.keys()))
self.assertEqual(
dtypes.string, input_receiver.receiver_tensors["feature_1"].dtype)
self.assertEqual(
dtypes.int32, input_receiver.receiver_tensors["feature_2"].dtype)
@test_util.run_in_graph_and_eager_modes
def test_build_raw_supervised_input_receiver_fn_raw_tensors(self):
features = {"feature_1": constant_op.constant(["hello"]),
"feature_2": constant_op.constant([42])}
labels = {"foo": constant_op.constant([5]),
"bar": constant_op.constant([6])}
input_receiver_fn1 = export.build_raw_supervised_input_receiver_fn(
features["feature_1"], labels)
input_receiver_fn2 = export.build_raw_supervised_input_receiver_fn(
features["feature_1"], labels["foo"])
with ops.Graph().as_default():
input_receiver = input_receiver_fn1()
self.assertIsInstance(input_receiver.features, ops.Tensor)
self.assertEqual(set(["foo", "bar"]),
set(input_receiver.labels.keys()))
self.assertEqual(set(["input", "foo", "bar"]),
set(input_receiver.receiver_tensors.keys()))
input_receiver = input_receiver_fn2()
self.assertIsInstance(input_receiver.features, ops.Tensor)
self.assertIsInstance(input_receiver.labels, ops.Tensor)
self.assertEqual(set(["input", "label"]),
set(input_receiver.receiver_tensors.keys()))
@test_util.run_in_graph_and_eager_modes
def test_build_raw_supervised_input_receiver_fn_batch_size(self):
features = {"feature_1": constant_op.constant(["hello"]),
"feature_2": constant_op.constant([42])}
labels = {"foo": constant_op.constant([5]),
"bar": constant_op.constant([6])}
input_receiver_fn = export.build_raw_supervised_input_receiver_fn(
features, labels, default_batch_size=10)
with ops.Graph().as_default():
input_receiver = input_receiver_fn()
self.assertEqual([10], input_receiver.receiver_tensors["feature_1"].shape)
self.assertEqual([10], input_receiver.features["feature_1"].shape)
@test_util.run_in_graph_and_eager_modes
def test_build_raw_supervised_input_receiver_fn_overlapping_keys(self):
features = {"feature_1": constant_op.constant(["hello"]),
"feature_2": constant_op.constant([42])}
labels = {"feature_1": constant_op.constant([5]),
"bar": constant_op.constant([6])}
with self.assertRaises(ValueError):
export.build_raw_supervised_input_receiver_fn(features, labels)
@test_util.run_in_graph_and_eager_modes
def test_build_supervised_input_receiver_fn_from_input_fn(self):
def dummy_input_fn():
return ({"x": constant_op.constant([[1], [1]]),
"y": constant_op.constant(["hello", "goodbye"])},
constant_op.constant([[1], [1]]))
input_receiver_fn = export.build_supervised_input_receiver_fn_from_input_fn(
dummy_input_fn)
with ops.Graph().as_default():
input_receiver = input_receiver_fn()
self.assertEqual(set(["x", "y"]),
set(input_receiver.features.keys()))
self.assertIsInstance(input_receiver.labels, ops.Tensor)
self.assertEqual(set(["x", "y", "label"]),
set(input_receiver.receiver_tensors.keys()))
@test_util.run_in_graph_and_eager_modes
def test_build_supervised_input_receiver_fn_from_input_fn_args(self):
def dummy_input_fn(feature_key="x"):
return ({feature_key: constant_op.constant([[1], [1]]),
"y": constant_op.constant(["hello", "goodbye"])},
{"my_label": constant_op.constant([[1], [1]])})
input_receiver_fn = export.build_supervised_input_receiver_fn_from_input_fn(
dummy_input_fn, feature_key="z")
with ops.Graph().as_default():
input_receiver = input_receiver_fn()
self.assertEqual(set(["z", "y"]),
set(input_receiver.features.keys()))
self.assertEqual(set(["my_label"]),
set(input_receiver.labels.keys()))
self.assertEqual(set(["z", "y", "my_label"]),
set(input_receiver.receiver_tensors.keys()))
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 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.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.
}
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_export_outputs_required(self):
receiver_tensor = constant_op.constant(["11"])
with self.assertRaises(ValueError) as e:
export.build_all_signature_defs(receiver_tensor, None)
self.assertTrue(str(e.exception).startswith(
"export_outputs must be a dict"))
def test_get_timestamped_export_dir(self):
export_dir_base = tempfile.mkdtemp() + "export/"
export_dir_1 = export.get_timestamped_export_dir(
export_dir_base)
time.sleep(2)
export_dir_2 = export.get_timestamped_export_dir(
export_dir_base)
time.sleep(2)
export_dir_3 = export.get_timestamped_export_dir(
export_dir_base)
# Export directories should be named using a timestamp that is seconds
# since epoch. Such a timestamp is 10 digits long.
time_1 = os.path.basename(export_dir_1)
self.assertEqual(10, len(time_1))
time_2 = os.path.basename(export_dir_2)
self.assertEqual(10, len(time_2))
time_3 = os.path.basename(export_dir_3)
self.assertEqual(10, len(time_3))
self.assertTrue(int(time_1) < int(time_2))
self.assertTrue(int(time_2) < int(time_3))
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)
class TensorServingReceiverTest(test_util.TensorFlowTestCase):
def test_tensor_serving_input_receiver_constructor(self):
features = constant_op.constant([0])
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
r = export.TensorServingInputReceiver(features, receiver_tensors)
self.assertTrue(isinstance(r.features, ops.Tensor))
self.assertTrue(isinstance(r.receiver_tensors, dict))
def test_tensor_serving_input_receiver_sparse(self):
features = sparse_tensor.SparseTensor(
indices=[[0, 0]], values=[1], dense_shape=[1, 1])
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
r = export.TensorServingInputReceiver(features, receiver_tensors)
self.assertTrue(isinstance(r.features, sparse_tensor.SparseTensor))
self.assertTrue(isinstance(r.receiver_tensors, dict))
def test_serving_input_receiver_features_invalid(self):
receiver_tensors = {
"example0": array_ops.placeholder(dtypes.string, name="example0"),
u"example1": array_ops.placeholder(dtypes.string, name="example1"),
}
with self.assertRaisesRegexp(ValueError, "features must be defined"):
export.TensorServingInputReceiver(
features=None,
receiver_tensors=receiver_tensors)
with self.assertRaisesRegexp(ValueError, "feature must be a Tensor"):
export.TensorServingInputReceiver(
features={"1": constant_op.constant([1])},
receiver_tensors=receiver_tensors)
def test_serving_input_receiver_receiver_tensors_invalid(self):
features = constant_op.constant([0])
with self.assertRaisesRegexp(
ValueError, "receiver_tensors must be defined"):
export.TensorServingInputReceiver(
features=features,
receiver_tensors=None)
with self.assertRaisesRegexp(
ValueError, "receiver_tensor keys must be strings"):
export.TensorServingInputReceiver(
features=features,
receiver_tensors={
1: array_ops.placeholder(dtypes.string, name="example0")})
with self.assertRaisesRegexp(
ValueError, "receiver_tensor example1 must be a Tensor"):
export.TensorServingInputReceiver(
features=features,
receiver_tensors={"example1": [1]})
if __name__ == "__main__":
test.main()