Adds an optional dict to hold tensors that are concatenated into the returned

tensor

Notes: for learning tasks built on sparse signals, most of the tensors that go
into the returned tensors are embedding, which are potentially useful for
applications that consume embeddings from other models. This makes it easy for
the caller to retrieve these tensors and make their customized signatures.
PiperOrigin-RevId: 178033410
This commit is contained in:
A. Unique TensorFlower 2017-12-05 17:01:07 -08:00 committed by TensorFlower Gardener
parent af8a550793
commit fb857dcef9
2 changed files with 37 additions and 3 deletions
tensorflow/contrib/layers/python/layers

View File

@ -97,10 +97,13 @@ def _input_from_feature_columns(columns_to_tensors,
trainable,
scope,
output_rank,
default_name):
default_name,
cols_to_outs=None):
"""Implementation of `input_from(_sequence)_feature_columns`."""
columns_to_tensors = columns_to_tensors.copy()
check_feature_columns(feature_columns)
if cols_to_outs is not None and not isinstance(cols_to_outs, dict):
raise ValueError('cols_to_outs must be a dict unless None')
with variable_scope.variable_scope(scope,
default_name=default_name,
values=columns_to_tensors.values()):
@ -144,6 +147,8 @@ def _input_from_feature_columns(columns_to_tensors,
except ValueError as e:
raise ValueError('Error creating input layer for column: {}.\n'
'{}, {}'.format(column.name, e, ee))
if cols_to_outs is not None:
cols_to_outs[column] = output_tensors[-1]
return array_ops.concat(output_tensors, output_rank - 1)
@ -151,7 +156,8 @@ def input_from_feature_columns(columns_to_tensors,
feature_columns,
weight_collections=None,
trainable=True,
scope=None):
scope=None,
cols_to_outs=None):
"""A tf.contrib.layers style input layer builder based on FeatureColumns.
Generally a single example in training data is described with feature columns.
@ -196,6 +202,8 @@ def input_from_feature_columns(columns_to_tensors,
trainable: If `True` also add variables to the graph collection
`GraphKeys.TRAINABLE_VARIABLES` (see tf.Variable).
scope: Optional scope for variable_scope.
cols_to_outs: Optional dict from feature column to output tensor,
which is concatenated into the returned tensor.
Returns:
A Tensor which can be consumed by hidden layers in the neural network.
@ -209,7 +217,8 @@ def input_from_feature_columns(columns_to_tensors,
trainable,
scope,
output_rank=2,
default_name='input_from_feature_columns')
default_name='input_from_feature_columns',
cols_to_outs=cols_to_outs)
@experimental

View File

@ -607,6 +607,31 @@ class CreateInputLayersForDNNsTest(test.TestCase):
# Verify cross compatibility: Core builder output should equal to contrib.
self.assertAllEqual(output.eval().shape, output_core.eval().shape)
def testAllDNNColumnsWithColumnwiseOutputs(self):
sparse_column = feature_column.sparse_column_with_keys(
"ids", ["a", "b", "c", "unseen"])
real_valued_column = feature_column.real_valued_column("income", 2)
one_hot_column = feature_column.one_hot_column(sparse_column)
embedding_column = feature_column.embedding_column(sparse_column, 10)
features = {
"ids":
sparse_tensor.SparseTensor(
values=["c", "b", "a"],
indices=[[0, 0], [1, 0], [2, 0]],
dense_shape=[3, 1]),
"income":
constant_op.constant([[20.3, 10], [110.3, 0.4], [-3.0, 30.4]]),
}
columns = [one_hot_column, embedding_column, real_valued_column]
cols_to_outs = {}
feature_column_ops.input_from_feature_columns(
features, columns, cols_to_outs=cols_to_outs)
with self.test_session():
variables_lib.global_variables_initializer().run()
lookup_ops.tables_initializer().run()
for column in columns:
self.assertTrue(column in cols_to_outs)
def testRealValuedColumn(self):
real_valued = feature_column.real_valued_column("price")
features = {"price": constant_op.constant([[20.], [110], [-3]])}