def test_key_should_be_in_features(self): def input_fn(): return {'x': [[3.], [5.]], 'id': [[101], [102]]}, [[1.], [2.]] estimator = linear.LinearRegressor([fc.numeric_column('x')]) estimator.train(input_fn=input_fn, steps=1) estimator = extenders.forward_features(estimator, 'y') with self.assertRaisesRegexp(ValueError, 'keys should be exist in features'): next(estimator.predict(input_fn=input_fn))
def test_forwarded_feature_should_be_a_sparse_tensor(self): input_fn = self.make_dummy_input_fn() estimator = linear.LinearRegressor([fc.numeric_column('x')]) estimator.train(input_fn=input_fn, steps=1) estimator = extenders.forward_features(estimator, sparse_default_values={ 'id': 0, 'sparse_id': 0 }) with self.assertRaisesRegexp( ValueError, 'Feature .* is expected to be a `SparseTensor`.'): next(estimator.predict(input_fn=input_fn))
def test_forward_list(self): def input_fn(): return {'x': [[3.], [5.]], 'id': [[101], [102]]}, [[1.], [2.]] estimator = linear.LinearRegressor([fc.numeric_column('x')]) estimator.train(input_fn=input_fn, steps=1) self.assertNotIn('id', next(estimator.predict(input_fn=input_fn))) estimator = extenders.forward_features(estimator, ['x', 'id']) predictions = next(estimator.predict(input_fn=input_fn)) self.assertIn('id', predictions) self.assertIn('x', predictions) self.assertEqual(101, predictions['id']) self.assertEqual(3., predictions['x'])
def test_forward_in_exported_sparse(self): features_columns = [ fc.indicator_column( fc.categorical_column_with_vocabulary_list('x', range(10))) ] classifier = linear.LinearClassifier(feature_columns=features_columns) def train_input_fn(): dataset = dataset_ops.Dataset.from_tensors({ 'x': sparse_tensor.SparseTensor(values=[1, 2, 3], indices=[[0, 0], [1, 0], [1, 1]], dense_shape=[2, 2]), 'labels': [[0], [1]] }) def _split(x): labels = x.pop('labels') return x, labels dataset = dataset.map(_split) return dataset classifier.train(train_input_fn, max_steps=1) classifier = extenders.forward_features(classifier, keys=['x'], sparse_default_values={'x': 0}) def serving_input_fn(): features_ph = array_ops.placeholder(dtype=dtypes.int32, name='x', shape=[None]) features = {'x': layers.dense_to_sparse(features_ph)} return estimator_lib.export.ServingInputReceiver( features, {'x': features_ph}) export_dir, tmpdir = self._export_estimator(classifier, serving_input_fn) prediction_fn = from_saved_model(export_dir, signature_def_key='predict') features = (0, 2) prediction = prediction_fn({'x': features}) self.assertIn('x', prediction) self.assertEqual(features, tuple(prediction['x'])) gfile.DeleteRecursively(tmpdir)
def test_forwarded_feature_should_not_be_a_sparse_tensor(self): def input_fn(): return { 'x': [[3.], [5.]], 'id': sparse_tensor.SparseTensor(values=['1', '2'], indices=[[0, 0], [1, 0]], dense_shape=[2, 1]) }, [[1.], [2.]] estimator = linear.LinearRegressor([fc.numeric_column('x')]) estimator.train(input_fn=input_fn, steps=1) estimator = extenders.forward_features(estimator) with self.assertRaisesRegexp(ValueError, 'Feature .* should be a Tensor.*'): next(estimator.predict(input_fn=input_fn))
def test_should_not_conflict_with_existing_predictions(self): def input_fn(): return {'x': [[3.], [5.]], 'id': [[101], [102]]} def model_fn(features, mode): del features global_step = training.get_global_step() return estimator_lib.EstimatorSpec( mode, loss=constant_op.constant([5.]), predictions={'x': constant_op.constant([5.])}, train_op=global_step.assign_add(1)) estimator = estimator_lib.Estimator(model_fn=model_fn) estimator.train(input_fn=input_fn, steps=1) estimator = extenders.forward_features(estimator) with self.assertRaisesRegexp(ValueError, 'Cannot forward feature key'): next(estimator.predict(input_fn=input_fn))
def test_forward_keys(self): input_fn = self.make_dummy_input_fn() estimator = linear.LinearRegressor([fc.numeric_column('x')]) estimator.train(input_fn=input_fn, steps=1) forwarded_keys = ['id', 'sparse_id'] for key in forwarded_keys: self.assertNotIn(key, next(estimator.predict(input_fn=input_fn))) estimator = extenders.forward_features( estimator, forwarded_keys, sparse_default_values={'sparse_id': 1}) expected_results = [101, 2, 102, 5] predictions = estimator.predict(input_fn=input_fn) for _ in range(2): prediction = next(predictions) for key in forwarded_keys: self.assertIn(key, prediction) self.assertEqual(expected_results.pop(0), sum(prediction[key]))
def test_forward_in_exported(self): def serving_input_fn(): features_ph = { 'x': array_ops.placeholder(dtypes.float32, [None]), 'id': array_ops.placeholder(dtypes.int32, [None]) } features = { key: array_ops.expand_dims(tensor, -1) for key, tensor in features_ph.items() } return estimator_lib.export.ServingInputReceiver( features, features_ph) def input_fn(): return {'x': [[3.], [5.]], 'id': [[101], [102]]}, [[1.], [2.]] # create estimator feature_columns = [fc.numeric_column('x')] estimator = linear.LinearRegressor(feature_columns) estimator.train(input_fn=input_fn, steps=1) estimator = extenders.forward_features(estimator, 'id') # export saved model export_dir, tmpdir = self._export_estimator(estimator, serving_input_fn) # restore model predict_fn = from_saved_model(export_dir, signature_def_key='predict') predictions = predict_fn({'x': [3], 'id': [101]}) # verify that 'id' exists in predictions self.assertIn('id', predictions) self.assertEqual(101, predictions['id']) # Clean up. gfile.DeleteRecursively(tmpdir)
def test_key_should_be_list_of_string(self): estimator = linear.LinearRegressor([fc.numeric_column('x')]) with self.assertRaisesRegexp(TypeError, 'should be a string'): extenders.forward_features(estimator, ['x', estimator])