Move tf.keras.layers.featureDenseFeature back to Keras package.
PiperOrigin-RevId: 312201284 Change-Id: I8e51198c62a8e79ef493a173d7f4f8ab65f300eb
This commit is contained in:
parent
efd77d2e45
commit
d98a0e6017
|
@ -55,8 +55,6 @@ py_library(
|
||||||
py_library(
|
py_library(
|
||||||
name = "feature_column_v2",
|
name = "feature_column_v2",
|
||||||
srcs = [
|
srcs = [
|
||||||
"dense_features.py",
|
|
||||||
"dense_features_v2.py",
|
|
||||||
"feature_column_v2.py",
|
"feature_column_v2.py",
|
||||||
"sequence_feature_column.py",
|
"sequence_feature_column.py",
|
||||||
"serialization.py",
|
"serialization.py",
|
||||||
|
@ -126,15 +124,6 @@ tf_py_test(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
tf_py_test(
|
|
||||||
name = "dense_features_test",
|
|
||||||
srcs = ["dense_features_test.py"],
|
|
||||||
tags = ["no_pip"],
|
|
||||||
deps = [
|
|
||||||
":feature_column_test_main_lib",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
py_library(
|
py_library(
|
||||||
name = "feature_column_test_main_lib",
|
name = "feature_column_test_main_lib",
|
||||||
srcs = ["feature_column_test.py"],
|
srcs = ["feature_column_test.py"],
|
||||||
|
@ -177,15 +166,6 @@ tf_py_test(
|
||||||
deps = [":feature_column_v2_test_main_lib"],
|
deps = [":feature_column_v2_test_main_lib"],
|
||||||
)
|
)
|
||||||
|
|
||||||
tf_py_test(
|
|
||||||
name = "dense_features_v2_test",
|
|
||||||
srcs = ["dense_features_v2_test.py"],
|
|
||||||
tags = ["no_pip"],
|
|
||||||
deps = [
|
|
||||||
":feature_column_v2_test_main_lib",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
py_library(
|
py_library(
|
||||||
name = "feature_column_v2_test_main_lib",
|
name = "feature_column_v2_test_main_lib",
|
||||||
srcs = ["feature_column_v2_test.py"],
|
srcs = ["feature_column_v2_test.py"],
|
||||||
|
|
|
@ -19,13 +19,13 @@ from __future__ import division
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
# pylint: disable=unused-import,line-too-long,wildcard-import,g-bad-import-order
|
# pylint: disable=unused-import,line-too-long,wildcard-import,g-bad-import-order
|
||||||
# We import dense_features_v2 first so that the V1 DenseFeatures is the default
|
|
||||||
# if users directly import feature_column_lib.
|
|
||||||
from tensorflow.python.feature_column.dense_features_v2 import *
|
|
||||||
from tensorflow.python.feature_column.dense_features import *
|
|
||||||
from tensorflow.python.feature_column.feature_column import *
|
from tensorflow.python.feature_column.feature_column import *
|
||||||
from tensorflow.python.feature_column.feature_column_v2 import *
|
from tensorflow.python.feature_column.feature_column_v2 import *
|
||||||
from tensorflow.python.feature_column.sequence_feature_column import *
|
from tensorflow.python.feature_column.sequence_feature_column import *
|
||||||
from tensorflow.python.feature_column.serialization import *
|
from tensorflow.python.feature_column.serialization import *
|
||||||
|
# We import dense_features_v2 first so that the V1 DenseFeatures is the default
|
||||||
|
# if users directly import feature_column_lib.
|
||||||
|
from tensorflow.python.keras.feature_column.dense_features_v2 import *
|
||||||
|
from tensorflow.python.keras.feature_column.dense_features import *
|
||||||
from tensorflow.python.keras.feature_column.sequence_feature_column import *
|
from tensorflow.python.keras.feature_column.sequence_feature_column import *
|
||||||
# pylint: enable=unused-import,line-too-long
|
# pylint: enable=unused-import,line-too-long
|
||||||
|
|
|
@ -31,7 +31,6 @@ from tensorflow.core.protobuf import rewriter_config_pb2
|
||||||
from tensorflow.python.client import session
|
from tensorflow.python.client import session
|
||||||
from tensorflow.python.eager import backprop
|
from tensorflow.python.eager import backprop
|
||||||
from tensorflow.python.eager import context
|
from tensorflow.python.eager import context
|
||||||
from tensorflow.python.feature_column import dense_features as df
|
|
||||||
from tensorflow.python.feature_column import feature_column as fc_old
|
from tensorflow.python.feature_column import feature_column as fc_old
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.feature_column import serialization
|
from tensorflow.python.feature_column import serialization
|
||||||
|
@ -5582,23 +5581,6 @@ class IndicatorColumnTest(test.TestCase):
|
||||||
self.evaluate(weight_var.assign([[1.], [2.], [3.], [4.]]))
|
self.evaluate(weight_var.assign([[1.], [2.], [3.], [4.]]))
|
||||||
self.assertAllClose([[2. + 3.]], self.evaluate(predictions))
|
self.assertAllClose([[2. + 3.]], self.evaluate(predictions))
|
||||||
|
|
||||||
@test_util.run_deprecated_v1
|
|
||||||
def test_dense_features(self):
|
|
||||||
animal = fc.indicator_column(
|
|
||||||
fc.categorical_column_with_identity('animal', num_buckets=4))
|
|
||||||
with ops.Graph().as_default():
|
|
||||||
features = {
|
|
||||||
'animal':
|
|
||||||
sparse_tensor.SparseTensor(
|
|
||||||
indices=[[0, 0], [0, 1]], values=[1, 2], dense_shape=[1, 2])
|
|
||||||
}
|
|
||||||
net = df.DenseFeatures([animal])(features)
|
|
||||||
|
|
||||||
self.evaluate(variables_lib.global_variables_initializer())
|
|
||||||
self.evaluate(lookup_ops.tables_initializer())
|
|
||||||
|
|
||||||
self.assertAllClose([[0., 1., 1., 0.]], self.evaluate(net))
|
|
||||||
|
|
||||||
@test_util.run_deprecated_v1
|
@test_util.run_deprecated_v1
|
||||||
def test_input_layer(self):
|
def test_input_layer(self):
|
||||||
animal = fc.indicator_column(
|
animal = fc.indicator_column(
|
||||||
|
@ -6271,191 +6253,6 @@ class EmbeddingColumnTest(test.TestCase, parameterized.TestCase):
|
||||||
self.assertAllClose(((94.,), (29.,), (0.,), (42.,)),
|
self.assertAllClose(((94.,), (29.,), (0.,), (42.,)),
|
||||||
self.evaluate(predictions))
|
self.evaluate(predictions))
|
||||||
|
|
||||||
@parameterized.named_parameters(
|
|
||||||
{
|
|
||||||
'testcase_name': 'use_safe_embedding_lookup',
|
|
||||||
'use_safe_embedding_lookup': True,
|
|
||||||
'partition_variables': False,
|
|
||||||
}, {
|
|
||||||
'testcase_name': 'dont_use_safe_embedding_lookup',
|
|
||||||
'use_safe_embedding_lookup': False,
|
|
||||||
'partition_variables': False,
|
|
||||||
}, {
|
|
||||||
'testcase_name': 'use_safe_embedding_lookup_partitioned',
|
|
||||||
'use_safe_embedding_lookup': True,
|
|
||||||
'partition_variables': True,
|
|
||||||
}, {
|
|
||||||
'testcase_name': 'dont_use_safe_embedding_lookup_partitioned',
|
|
||||||
'use_safe_embedding_lookup': False,
|
|
||||||
'partition_variables': True,
|
|
||||||
})
|
|
||||||
@test_util.run_deprecated_v1
|
|
||||||
def test_dense_features(self, use_safe_embedding_lookup, partition_variables):
|
|
||||||
# Inputs.
|
|
||||||
vocabulary_size = 4
|
|
||||||
sparse_input = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [2]
|
|
||||||
# example 1, ids [0, 1]
|
|
||||||
# example 2, ids []
|
|
||||||
# example 3, ids [1]
|
|
||||||
indices=((0, 0), (1, 0), (1, 4), (3, 0)),
|
|
||||||
values=(2, 0, 1, 1),
|
|
||||||
dense_shape=(4, 5))
|
|
||||||
|
|
||||||
# Embedding variable.
|
|
||||||
embedding_dimension = 2
|
|
||||||
embedding_values = (
|
|
||||||
(1., 2.), # id 0
|
|
||||||
(3., 5.), # id 1
|
|
||||||
(7., 11.), # id 2
|
|
||||||
(9., 13.) # id 3
|
|
||||||
)
|
|
||||||
|
|
||||||
def _initializer(shape, dtype, partition_info=None):
|
|
||||||
if partition_variables:
|
|
||||||
self.assertEqual([vocabulary_size, embedding_dimension],
|
|
||||||
partition_info.full_shape)
|
|
||||||
self.assertAllEqual((2, embedding_dimension), shape)
|
|
||||||
else:
|
|
||||||
self.assertAllEqual((vocabulary_size, embedding_dimension), shape)
|
|
||||||
self.assertIsNone(partition_info)
|
|
||||||
|
|
||||||
self.assertEqual(dtypes.float32, dtype)
|
|
||||||
return embedding_values
|
|
||||||
|
|
||||||
# Expected lookup result, using combiner='mean'.
|
|
||||||
expected_lookups = (
|
|
||||||
# example 0, ids [2], embedding = [7, 11]
|
|
||||||
(7., 11.),
|
|
||||||
# example 1, ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
|
||||||
(2., 3.5),
|
|
||||||
# example 2, ids [], embedding = [0, 0]
|
|
||||||
(0., 0.),
|
|
||||||
# example 3, ids [1], embedding = [3, 5]
|
|
||||||
(3., 5.),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Build columns.
|
|
||||||
categorical_column = fc.categorical_column_with_identity(
|
|
||||||
key='aaa', num_buckets=vocabulary_size)
|
|
||||||
partitioner = None
|
|
||||||
if partition_variables:
|
|
||||||
partitioner = partitioned_variables.fixed_size_partitioner(2, axis=0)
|
|
||||||
with variable_scope.variable_scope('vars', partitioner=partitioner):
|
|
||||||
embedding_column = fc.embedding_column(
|
|
||||||
categorical_column,
|
|
||||||
dimension=embedding_dimension,
|
|
||||||
initializer=_initializer,
|
|
||||||
use_safe_embedding_lookup=use_safe_embedding_lookup)
|
|
||||||
|
|
||||||
# Provide sparse input and get dense result.
|
|
||||||
l = df.DenseFeatures((embedding_column,))
|
|
||||||
dense_features = l({'aaa': sparse_input})
|
|
||||||
|
|
||||||
# Assert expected embedding variable and lookups.
|
|
||||||
global_vars = ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES)
|
|
||||||
if partition_variables:
|
|
||||||
self.assertCountEqual(
|
|
||||||
('vars/dense_features/aaa_embedding/embedding_weights/part_0:0',
|
|
||||||
'vars/dense_features/aaa_embedding/embedding_weights/part_1:0'),
|
|
||||||
tuple([v.name for v in global_vars]))
|
|
||||||
else:
|
|
||||||
self.assertCountEqual(
|
|
||||||
('vars/dense_features/aaa_embedding/embedding_weights:0',),
|
|
||||||
tuple([v.name for v in global_vars]))
|
|
||||||
for v in global_vars:
|
|
||||||
self.assertIsInstance(v, variables_lib.Variable)
|
|
||||||
trainable_vars = ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES)
|
|
||||||
if partition_variables:
|
|
||||||
self.assertCountEqual(
|
|
||||||
('vars/dense_features/aaa_embedding/embedding_weights/part_0:0',
|
|
||||||
'vars/dense_features/aaa_embedding/embedding_weights/part_1:0'),
|
|
||||||
tuple([v.name for v in trainable_vars]))
|
|
||||||
else:
|
|
||||||
self.assertCountEqual(
|
|
||||||
('vars/dense_features/aaa_embedding/embedding_weights:0',),
|
|
||||||
tuple([v.name for v in trainable_vars]))
|
|
||||||
|
|
||||||
self.evaluate(variables_lib.global_variables_initializer())
|
|
||||||
self.evaluate(lookup_ops.tables_initializer())
|
|
||||||
|
|
||||||
self.assertAllEqual(embedding_values, self.evaluate(trainable_vars[0]))
|
|
||||||
self.assertAllEqual(expected_lookups, self.evaluate(dense_features))
|
|
||||||
|
|
||||||
if use_safe_embedding_lookup:
|
|
||||||
self.assertIn('SparseFillEmptyRows',
|
|
||||||
[x.type for x in ops.get_default_graph().get_operations()])
|
|
||||||
else:
|
|
||||||
self.assertNotIn(
|
|
||||||
'SparseFillEmptyRows',
|
|
||||||
[x.type for x in ops.get_default_graph().get_operations()])
|
|
||||||
|
|
||||||
@test_util.run_deprecated_v1
|
|
||||||
def test_dense_features_not_trainable(self):
|
|
||||||
# Inputs.
|
|
||||||
vocabulary_size = 3
|
|
||||||
sparse_input = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [2]
|
|
||||||
# example 1, ids [0, 1]
|
|
||||||
# example 2, ids []
|
|
||||||
# example 3, ids [1]
|
|
||||||
indices=((0, 0), (1, 0), (1, 4), (3, 0)),
|
|
||||||
values=(2, 0, 1, 1),
|
|
||||||
dense_shape=(4, 5))
|
|
||||||
|
|
||||||
# Embedding variable.
|
|
||||||
embedding_dimension = 2
|
|
||||||
embedding_values = (
|
|
||||||
(1., 2.), # id 0
|
|
||||||
(3., 5.), # id 1
|
|
||||||
(7., 11.) # id 2
|
|
||||||
)
|
|
||||||
|
|
||||||
def _initializer(shape, dtype, partition_info=None):
|
|
||||||
self.assertAllEqual((vocabulary_size, embedding_dimension), shape)
|
|
||||||
self.assertEqual(dtypes.float32, dtype)
|
|
||||||
self.assertIsNone(partition_info)
|
|
||||||
return embedding_values
|
|
||||||
|
|
||||||
# Expected lookup result, using combiner='mean'.
|
|
||||||
expected_lookups = (
|
|
||||||
# example 0, ids [2], embedding = [7, 11]
|
|
||||||
(7., 11.),
|
|
||||||
# example 1, ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
|
||||||
(2., 3.5),
|
|
||||||
# example 2, ids [], embedding = [0, 0]
|
|
||||||
(0., 0.),
|
|
||||||
# example 3, ids [1], embedding = [3, 5]
|
|
||||||
(3., 5.),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Build columns.
|
|
||||||
categorical_column = fc.categorical_column_with_identity(
|
|
||||||
key='aaa', num_buckets=vocabulary_size)
|
|
||||||
embedding_column = fc.embedding_column(
|
|
||||||
categorical_column,
|
|
||||||
dimension=embedding_dimension,
|
|
||||||
initializer=_initializer,
|
|
||||||
trainable=False)
|
|
||||||
|
|
||||||
# Provide sparse input and get dense result.
|
|
||||||
dense_features = df.DenseFeatures((embedding_column,))({
|
|
||||||
'aaa': sparse_input
|
|
||||||
})
|
|
||||||
|
|
||||||
# Assert expected embedding variable and lookups.
|
|
||||||
global_vars = ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES)
|
|
||||||
self.assertCountEqual(('dense_features/aaa_embedding/embedding_weights:0',),
|
|
||||||
tuple([v.name for v in global_vars]))
|
|
||||||
self.assertCountEqual([],
|
|
||||||
ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES))
|
|
||||||
|
|
||||||
self.evaluate(variables_lib.global_variables_initializer())
|
|
||||||
self.evaluate(lookup_ops.tables_initializer())
|
|
||||||
|
|
||||||
self.assertAllEqual(embedding_values, self.evaluate(global_vars[0]))
|
|
||||||
self.assertAllEqual(expected_lookups, self.evaluate(dense_features))
|
|
||||||
|
|
||||||
@test_util.run_deprecated_v1
|
@test_util.run_deprecated_v1
|
||||||
def test_input_layer(self):
|
def test_input_layer(self):
|
||||||
# Inputs.
|
# Inputs.
|
||||||
|
@ -7389,129 +7186,6 @@ class SharedEmbeddingColumnTest(test.TestCase, parameterized.TestCase):
|
||||||
# = [3*1 + 5*2, 3*0 +5*0] = [13, 0]
|
# = [3*1 + 5*2, 3*0 +5*0] = [13, 0]
|
||||||
self.assertAllClose([[94. + 13.], [29.]], self.evaluate(predictions))
|
self.assertAllClose([[94. + 13.], [29.]], self.evaluate(predictions))
|
||||||
|
|
||||||
def _test_dense_features(self, trainable=True):
|
|
||||||
# Inputs.
|
|
||||||
vocabulary_size = 3
|
|
||||||
sparse_input_a = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [2]
|
|
||||||
# example 1, ids [0, 1]
|
|
||||||
indices=((0, 0), (1, 0), (1, 4)),
|
|
||||||
values=(2, 0, 1),
|
|
||||||
dense_shape=(2, 5))
|
|
||||||
sparse_input_b = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [0]
|
|
||||||
# example 1, ids []
|
|
||||||
indices=((0, 0),),
|
|
||||||
values=(0,),
|
|
||||||
dense_shape=(2, 5))
|
|
||||||
sparse_input_c = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [2]
|
|
||||||
# example 1, ids [0, 1]
|
|
||||||
indices=((0, 1), (1, 1), (1, 3)),
|
|
||||||
values=(2, 0, 1),
|
|
||||||
dense_shape=(2, 5))
|
|
||||||
sparse_input_d = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [2]
|
|
||||||
# example 1, ids []
|
|
||||||
indices=((0, 1),),
|
|
||||||
values=(2,),
|
|
||||||
dense_shape=(2, 5))
|
|
||||||
|
|
||||||
# Embedding variable.
|
|
||||||
embedding_dimension = 2
|
|
||||||
embedding_values = (
|
|
||||||
(1., 2.), # id 0
|
|
||||||
(3., 5.), # id 1
|
|
||||||
(7., 11.) # id 2
|
|
||||||
)
|
|
||||||
|
|
||||||
def _initializer(shape, dtype, partition_info=None):
|
|
||||||
self.assertAllEqual((vocabulary_size, embedding_dimension), shape)
|
|
||||||
self.assertEqual(dtypes.float32, dtype)
|
|
||||||
self.assertIsNone(partition_info)
|
|
||||||
return embedding_values
|
|
||||||
|
|
||||||
# Expected lookup result, using combiner='mean'.
|
|
||||||
expected_lookups = (
|
|
||||||
# example 0:
|
|
||||||
# A ids [2], embedding = [7, 11]
|
|
||||||
# B ids [0], embedding = [1, 2]
|
|
||||||
# C ids [2], embedding = [7, 11]
|
|
||||||
# D ids [2], embedding = [7, 11]
|
|
||||||
(7., 11., 1., 2., 7., 11., 7., 11.),
|
|
||||||
# example 1:
|
|
||||||
# A ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
|
||||||
# B ids [], embedding = [0, 0]
|
|
||||||
# C ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
|
||||||
# D ids [], embedding = [0, 0]
|
|
||||||
(2., 3.5, 0., 0., 2., 3.5, 0., 0.),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Build columns.
|
|
||||||
categorical_column_a = fc.categorical_column_with_identity(
|
|
||||||
key='aaa', num_buckets=vocabulary_size)
|
|
||||||
categorical_column_b = fc.categorical_column_with_identity(
|
|
||||||
key='bbb', num_buckets=vocabulary_size)
|
|
||||||
categorical_column_c = fc.categorical_column_with_identity(
|
|
||||||
key='ccc', num_buckets=vocabulary_size)
|
|
||||||
categorical_column_d = fc.categorical_column_with_identity(
|
|
||||||
key='ddd', num_buckets=vocabulary_size)
|
|
||||||
|
|
||||||
embedding_column_a, embedding_column_b = fc.shared_embedding_columns_v2(
|
|
||||||
[categorical_column_a, categorical_column_b],
|
|
||||||
dimension=embedding_dimension,
|
|
||||||
initializer=_initializer,
|
|
||||||
trainable=trainable)
|
|
||||||
embedding_column_c, embedding_column_d = fc.shared_embedding_columns_v2(
|
|
||||||
[categorical_column_c, categorical_column_d],
|
|
||||||
dimension=embedding_dimension,
|
|
||||||
initializer=_initializer,
|
|
||||||
trainable=trainable)
|
|
||||||
|
|
||||||
features = {
|
|
||||||
'aaa': sparse_input_a,
|
|
||||||
'bbb': sparse_input_b,
|
|
||||||
'ccc': sparse_input_c,
|
|
||||||
'ddd': sparse_input_d
|
|
||||||
}
|
|
||||||
|
|
||||||
# Provide sparse input and get dense result.
|
|
||||||
dense_features = df.DenseFeatures(
|
|
||||||
feature_columns=(embedding_column_b, embedding_column_a,
|
|
||||||
embedding_column_c, embedding_column_d))(
|
|
||||||
features)
|
|
||||||
|
|
||||||
# Assert expected embedding variable and lookups.
|
|
||||||
global_vars = ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES)
|
|
||||||
self.assertCountEqual(
|
|
||||||
['aaa_bbb_shared_embedding:0', 'ccc_ddd_shared_embedding:0'],
|
|
||||||
tuple([v.name for v in global_vars]))
|
|
||||||
for v in global_vars:
|
|
||||||
self.assertIsInstance(v, variables_lib.Variable)
|
|
||||||
trainable_vars = ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES)
|
|
||||||
if trainable:
|
|
||||||
self.assertCountEqual(
|
|
||||||
['aaa_bbb_shared_embedding:0', 'ccc_ddd_shared_embedding:0'],
|
|
||||||
tuple([v.name for v in trainable_vars]))
|
|
||||||
else:
|
|
||||||
self.assertCountEqual([], tuple([v.name for v in trainable_vars]))
|
|
||||||
shared_embedding_vars = global_vars
|
|
||||||
|
|
||||||
self.evaluate(variables_lib.global_variables_initializer())
|
|
||||||
self.evaluate(lookup_ops.tables_initializer())
|
|
||||||
|
|
||||||
self.assertAllEqual(embedding_values,
|
|
||||||
self.evaluate(shared_embedding_vars[0]))
|
|
||||||
self.assertAllEqual(expected_lookups, self.evaluate(dense_features))
|
|
||||||
|
|
||||||
@test_util.run_deprecated_v1
|
|
||||||
def test_dense_features(self):
|
|
||||||
self._test_dense_features()
|
|
||||||
|
|
||||||
@test_util.run_deprecated_v1
|
|
||||||
def test_dense_features_no_trainable(self):
|
|
||||||
self._test_dense_features(trainable=False)
|
|
||||||
|
|
||||||
@test_util.run_deprecated_v1
|
@test_util.run_deprecated_v1
|
||||||
def test_serialization(self):
|
def test_serialization(self):
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,12 @@ import numpy as np
|
||||||
from tensorflow.python import keras
|
from tensorflow.python import keras
|
||||||
from tensorflow.python import tf2
|
from tensorflow.python import tf2
|
||||||
from tensorflow.python.data.ops import dataset_ops
|
from tensorflow.python.data.ops import dataset_ops
|
||||||
from tensorflow.python.feature_column import dense_features_v2
|
|
||||||
from tensorflow.python.feature_column import feature_column_lib as fc
|
from tensorflow.python.feature_column import feature_column_lib as fc
|
||||||
from tensorflow.python.feature_column import feature_column_v2
|
from tensorflow.python.feature_column import feature_column_v2
|
||||||
from tensorflow.python.keras import keras_parameterized
|
from tensorflow.python.keras import keras_parameterized
|
||||||
from tensorflow.python.keras import metrics as metrics_module
|
from tensorflow.python.keras import metrics as metrics_module
|
||||||
from tensorflow.python.keras import testing_utils
|
from tensorflow.python.keras import testing_utils
|
||||||
|
from tensorflow.python.keras.feature_column import dense_features_v2
|
||||||
from tensorflow.python.keras.optimizer_v2 import gradient_descent
|
from tensorflow.python.keras.optimizer_v2 import gradient_descent
|
||||||
from tensorflow.python.keras.premade import linear
|
from tensorflow.python.keras.premade import linear
|
||||||
from tensorflow.python.keras.premade import wide_deep
|
from tensorflow.python.keras.premade import wide_deep
|
||||||
|
|
|
@ -24,7 +24,6 @@ from absl.testing import parameterized
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from tensorflow.python.client import session
|
from tensorflow.python.client import session
|
||||||
from tensorflow.python.feature_column import dense_features
|
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.feature_column import sequence_feature_column as sfc
|
from tensorflow.python.feature_column import sequence_feature_column as sfc
|
||||||
from tensorflow.python.feature_column import serialization
|
from tensorflow.python.feature_column import serialization
|
||||||
|
@ -111,54 +110,6 @@ class ConcatenateContextInputTest(test.TestCase, parameterized.TestCase):
|
||||||
sfc.concatenate_context_input(context_input, seq_input)
|
sfc.concatenate_context_input(context_input, seq_input)
|
||||||
|
|
||||||
|
|
||||||
@test_util.run_all_in_graph_and_eager_modes
|
|
||||||
class DenseFeaturesTest(test.TestCase):
|
|
||||||
"""Tests DenseFeatures with sequence feature columns."""
|
|
||||||
|
|
||||||
def test_embedding_column(self):
|
|
||||||
"""Tests that error is raised for sequence embedding column."""
|
|
||||||
vocabulary_size = 3
|
|
||||||
sparse_input = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [2]
|
|
||||||
# example 1, ids [0, 1]
|
|
||||||
indices=((0, 0), (1, 0), (1, 1)),
|
|
||||||
values=(2, 0, 1),
|
|
||||||
dense_shape=(2, 2))
|
|
||||||
|
|
||||||
categorical_column_a = sfc.sequence_categorical_column_with_identity(
|
|
||||||
key='aaa', num_buckets=vocabulary_size)
|
|
||||||
embedding_column_a = fc.embedding_column(
|
|
||||||
categorical_column_a, dimension=2)
|
|
||||||
|
|
||||||
input_layer = dense_features.DenseFeatures([embedding_column_a])
|
|
||||||
with self.assertRaisesRegexp(
|
|
||||||
ValueError,
|
|
||||||
r'In embedding_column: aaa_embedding\. categorical_column must not be '
|
|
||||||
r'of type SequenceCategoricalColumn\.'):
|
|
||||||
_ = input_layer({'aaa': sparse_input})
|
|
||||||
|
|
||||||
def test_indicator_column(self):
|
|
||||||
"""Tests that error is raised for sequence indicator column."""
|
|
||||||
vocabulary_size = 3
|
|
||||||
sparse_input = sparse_tensor.SparseTensorValue(
|
|
||||||
# example 0, ids [2]
|
|
||||||
# example 1, ids [0, 1]
|
|
||||||
indices=((0, 0), (1, 0), (1, 1)),
|
|
||||||
values=(2, 0, 1),
|
|
||||||
dense_shape=(2, 2))
|
|
||||||
|
|
||||||
categorical_column_a = sfc.sequence_categorical_column_with_identity(
|
|
||||||
key='aaa', num_buckets=vocabulary_size)
|
|
||||||
indicator_column_a = fc.indicator_column(categorical_column_a)
|
|
||||||
|
|
||||||
input_layer = dense_features.DenseFeatures([indicator_column_a])
|
|
||||||
with self.assertRaisesRegexp(
|
|
||||||
ValueError,
|
|
||||||
r'In indicator_column: aaa_indicator\. categorical_column must not be '
|
|
||||||
r'of type SequenceCategoricalColumn\.'):
|
|
||||||
_ = input_layer({'aaa': sparse_input})
|
|
||||||
|
|
||||||
|
|
||||||
def _assert_sparse_tensor_value(test_case, expected, actual):
|
def _assert_sparse_tensor_value(test_case, expected, actual):
|
||||||
_assert_sparse_tensor_indices_shape(test_case, expected, actual)
|
_assert_sparse_tensor_indices_shape(test_case, expected, actual)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ from __future__ import print_function
|
||||||
|
|
||||||
from absl.testing import parameterized
|
from absl.testing import parameterized
|
||||||
|
|
||||||
from tensorflow.python.feature_column import dense_features
|
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.feature_column import serialization
|
from tensorflow.python.feature_column import serialization
|
||||||
from tensorflow.python.framework import test_util
|
from tensorflow.python.framework import test_util
|
||||||
|
@ -114,71 +113,6 @@ class FeatureColumnSerializationTest(test.TestCase):
|
||||||
self.assertIs(new_price.normalizer_fn, _custom_fn)
|
self.assertIs(new_price.normalizer_fn, _custom_fn)
|
||||||
|
|
||||||
|
|
||||||
@test_util.run_all_in_graph_and_eager_modes
|
|
||||||
class DenseFeaturesSerializationTest(test.TestCase, parameterized.TestCase):
|
|
||||||
|
|
||||||
@parameterized.named_parameters(
|
|
||||||
('default', None, None),
|
|
||||||
('trainable', True, 'trainable'),
|
|
||||||
('not_trainable', False, 'frozen'))
|
|
||||||
def test_get_config(self, trainable, name):
|
|
||||||
cols = [fc.numeric_column('a'),
|
|
||||||
fc.embedding_column(fc.categorical_column_with_identity(
|
|
||||||
key='b', num_buckets=3), dimension=2)]
|
|
||||||
orig_layer = dense_features.DenseFeatures(
|
|
||||||
cols, trainable=trainable, name=name)
|
|
||||||
config = orig_layer.get_config()
|
|
||||||
|
|
||||||
self.assertEqual(config['name'], orig_layer.name)
|
|
||||||
self.assertEqual(config['trainable'], trainable)
|
|
||||||
self.assertLen(config['feature_columns'], 2)
|
|
||||||
self.assertEqual(
|
|
||||||
config['feature_columns'][0]['class_name'], 'NumericColumn')
|
|
||||||
self.assertEqual(config['feature_columns'][0]['config']['shape'], (1,))
|
|
||||||
self.assertEqual(
|
|
||||||
config['feature_columns'][1]['class_name'], 'EmbeddingColumn')
|
|
||||||
|
|
||||||
@parameterized.named_parameters(
|
|
||||||
('default', None, None),
|
|
||||||
('trainable', True, 'trainable'),
|
|
||||||
('not_trainable', False, 'frozen'))
|
|
||||||
def test_from_config(self, trainable, name):
|
|
||||||
cols = [fc.numeric_column('a'),
|
|
||||||
fc.embedding_column(fc.categorical_column_with_vocabulary_list(
|
|
||||||
'b', vocabulary_list=['1', '2', '3']), dimension=2),
|
|
||||||
fc.indicator_column(fc.categorical_column_with_hash_bucket(
|
|
||||||
key='c', hash_bucket_size=3))]
|
|
||||||
orig_layer = dense_features.DenseFeatures(
|
|
||||||
cols, trainable=trainable, name=name)
|
|
||||||
config = orig_layer.get_config()
|
|
||||||
|
|
||||||
new_layer = dense_features.DenseFeatures.from_config(config)
|
|
||||||
|
|
||||||
self.assertEqual(new_layer.name, orig_layer.name)
|
|
||||||
self.assertEqual(new_layer.trainable, trainable)
|
|
||||||
self.assertLen(new_layer._feature_columns, 3)
|
|
||||||
self.assertEqual(new_layer._feature_columns[0].name, 'a')
|
|
||||||
self.assertEqual(new_layer._feature_columns[1].initializer.mean, 0.0)
|
|
||||||
self.assertEqual(new_layer._feature_columns[1].categorical_column.name, 'b')
|
|
||||||
self.assertIsInstance(new_layer._feature_columns[2], fc.IndicatorColumn)
|
|
||||||
|
|
||||||
def test_crossed_column(self):
|
|
||||||
a = fc.categorical_column_with_vocabulary_list(
|
|
||||||
'a', vocabulary_list=['1', '2', '3'])
|
|
||||||
b = fc.categorical_column_with_vocabulary_list(
|
|
||||||
'b', vocabulary_list=['1', '2', '3'])
|
|
||||||
ab = fc.crossed_column([a, b], hash_bucket_size=2)
|
|
||||||
cols = [fc.indicator_column(ab)]
|
|
||||||
|
|
||||||
orig_layer = dense_features.DenseFeatures(cols)
|
|
||||||
config = orig_layer.get_config()
|
|
||||||
|
|
||||||
new_layer = dense_features.DenseFeatures.from_config(config)
|
|
||||||
|
|
||||||
self.assertLen(new_layer._feature_columns, 1)
|
|
||||||
self.assertEqual(new_layer._feature_columns[0].name, 'a_X_b_indicator')
|
|
||||||
|
|
||||||
|
|
||||||
@test_util.run_all_in_graph_and_eager_modes
|
@test_util.run_all_in_graph_and_eager_modes
|
||||||
class LinearModelLayerSerializationTest(test.TestCase, parameterized.TestCase):
|
class LinearModelLayerSerializationTest(test.TestCase, parameterized.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,88 @@ exports_files(["LICENSE"])
|
||||||
|
|
||||||
py_library(
|
py_library(
|
||||||
name = "feature_column",
|
name = "feature_column",
|
||||||
|
srcs = ["__init__.py"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":dense_features",
|
||||||
|
":dense_features_v2",
|
||||||
":sequence_feature_column",
|
":sequence_feature_column",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
py_library(
|
||||||
|
name = "dense_features",
|
||||||
|
srcs = [
|
||||||
|
"dense_features.py",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//tensorflow/python:framework_ops",
|
||||||
|
"//tensorflow/python:tf_export",
|
||||||
|
"//tensorflow/python:util",
|
||||||
|
"//tensorflow/python/feature_column:feature_column_v2",
|
||||||
|
"//tensorflow/python/keras:backend",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
py_library(
|
||||||
|
name = "dense_features_v2",
|
||||||
|
srcs = [
|
||||||
|
"dense_features_v2.py",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
":dense_features",
|
||||||
|
"//tensorflow/python:framework_ops",
|
||||||
|
"//tensorflow/python:tf_export",
|
||||||
|
"//tensorflow/python/feature_column:feature_column_v2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
tf_py_test(
|
||||||
|
name = "dense_features_test",
|
||||||
|
srcs = ["dense_features_test.py"],
|
||||||
|
tags = ["no_pip"],
|
||||||
|
deps = [
|
||||||
|
":dense_features",
|
||||||
|
"//tensorflow/python:array_ops",
|
||||||
|
"//tensorflow/python:client_testlib",
|
||||||
|
"//tensorflow/python:constant_op",
|
||||||
|
"//tensorflow/python:dtypes",
|
||||||
|
"//tensorflow/python:errors",
|
||||||
|
"//tensorflow/python:framework_ops",
|
||||||
|
"//tensorflow/python:framework_test_lib",
|
||||||
|
"//tensorflow/python:lookup_ops",
|
||||||
|
"//tensorflow/python:partitioned_variables",
|
||||||
|
"//tensorflow/python:session",
|
||||||
|
"//tensorflow/python:sparse_tensor",
|
||||||
|
"//tensorflow/python:variables",
|
||||||
|
"//tensorflow/python/eager:backprop",
|
||||||
|
"//tensorflow/python/eager:context",
|
||||||
|
"//tensorflow/python/feature_column:feature_column_v2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
tf_py_test(
|
||||||
|
name = "dense_features_v2_test",
|
||||||
|
srcs = ["dense_features_v2_test.py"],
|
||||||
|
tags = ["no_pip"],
|
||||||
|
deps = [
|
||||||
|
":dense_features_v2",
|
||||||
|
"//tensorflow/python:array_ops",
|
||||||
|
"//tensorflow/python:client_testlib",
|
||||||
|
"//tensorflow/python:constant_op",
|
||||||
|
"//tensorflow/python:dtypes",
|
||||||
|
"//tensorflow/python:errors",
|
||||||
|
"//tensorflow/python:framework_ops",
|
||||||
|
"//tensorflow/python:framework_test_lib",
|
||||||
|
"//tensorflow/python:lookup_ops",
|
||||||
|
"//tensorflow/python:session",
|
||||||
|
"//tensorflow/python:sparse_tensor",
|
||||||
|
"//tensorflow/python:variables",
|
||||||
|
"//tensorflow/python/eager:backprop",
|
||||||
|
"//tensorflow/python/eager:context",
|
||||||
|
"//tensorflow/python/feature_column:feature_column_v2",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
py_library(
|
py_library(
|
||||||
name = "sequence_feature_column",
|
name = "sequence_feature_column",
|
||||||
srcs = ["sequence_feature_column.py"],
|
srcs = ["sequence_feature_column.py"],
|
||||||
|
@ -59,6 +136,7 @@ py_test(
|
||||||
srcs_version = "PY2AND3",
|
srcs_version = "PY2AND3",
|
||||||
tags = ["no_pip"],
|
tags = ["no_pip"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":dense_features",
|
||||||
":sequence_feature_column",
|
":sequence_feature_column",
|
||||||
"//tensorflow/python:client_testlib",
|
"//tensorflow/python:client_testlib",
|
||||||
"//tensorflow/python:framework_test_lib",
|
"//tensorflow/python:framework_test_lib",
|
||||||
|
|
|
@ -23,7 +23,6 @@ import json
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.framework import ops
|
from tensorflow.python.framework import ops
|
||||||
from tensorflow.python.keras import backend
|
from tensorflow.python.keras import backend
|
||||||
from tensorflow.python.keras.layers import serialization as layer_serialization
|
|
||||||
from tensorflow.python.util import serialization
|
from tensorflow.python.util import serialization
|
||||||
from tensorflow.python.util.tf_export import keras_export
|
from tensorflow.python.util.tf_export import keras_export
|
||||||
|
|
||||||
|
@ -173,7 +172,3 @@ class DenseFeatures(fc._BaseFeaturesLayer): # pylint: disable=protected-access
|
||||||
cols_to_output_tensors[column] = processed_tensors
|
cols_to_output_tensors[column] = processed_tensors
|
||||||
output_tensors.append(processed_tensors)
|
output_tensors.append(processed_tensors)
|
||||||
return self._verify_and_concat_tensors(output_tensors)
|
return self._verify_and_concat_tensors(output_tensors)
|
||||||
|
|
||||||
|
|
||||||
layer_serialization.inject_feature_column_v1_objects(
|
|
||||||
'DenseFeatures', DenseFeatures)
|
|
|
@ -18,22 +18,25 @@ from __future__ import absolute_import
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from absl.testing import parameterized
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from tensorflow.python.client import session
|
from tensorflow.python.client import session
|
||||||
from tensorflow.python.eager import backprop
|
from tensorflow.python.eager import backprop
|
||||||
from tensorflow.python.eager import context
|
from tensorflow.python.eager import context
|
||||||
from tensorflow.python.feature_column import dense_features as df
|
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
|
from tensorflow.python.feature_column import sequence_feature_column as sfc
|
||||||
from tensorflow.python.framework import constant_op
|
from tensorflow.python.framework import constant_op
|
||||||
from tensorflow.python.framework import dtypes
|
from tensorflow.python.framework import dtypes
|
||||||
from tensorflow.python.framework import errors
|
from tensorflow.python.framework import errors
|
||||||
from tensorflow.python.framework import ops
|
from tensorflow.python.framework import ops
|
||||||
from tensorflow.python.framework import sparse_tensor
|
from tensorflow.python.framework import sparse_tensor
|
||||||
from tensorflow.python.framework import test_util
|
from tensorflow.python.framework import test_util
|
||||||
|
from tensorflow.python.keras.feature_column import dense_features as df
|
||||||
from tensorflow.python.ops import array_ops
|
from tensorflow.python.ops import array_ops
|
||||||
from tensorflow.python.ops import lookup_ops
|
from tensorflow.python.ops import lookup_ops
|
||||||
from tensorflow.python.ops import partitioned_variables
|
from tensorflow.python.ops import partitioned_variables
|
||||||
|
from tensorflow.python.ops import variable_scope
|
||||||
from tensorflow.python.ops import variables as variables_lib
|
from tensorflow.python.ops import variables as variables_lib
|
||||||
from tensorflow.python.platform import test
|
from tensorflow.python.platform import test
|
||||||
|
|
||||||
|
@ -676,5 +679,452 @@ class DenseFeaturesTest(test.TestCase):
|
||||||
sess.run(net, feed_dict={features['price']: np.array(1)})
|
sess.run(net, feed_dict={features['price']: np.array(1)})
|
||||||
|
|
||||||
|
|
||||||
|
class IndicatorColumnTest(test.TestCase):
|
||||||
|
|
||||||
|
@test_util.run_deprecated_v1
|
||||||
|
def test_dense_features(self):
|
||||||
|
animal = fc.indicator_column(
|
||||||
|
fc.categorical_column_with_identity('animal', num_buckets=4))
|
||||||
|
with ops.Graph().as_default():
|
||||||
|
features = {
|
||||||
|
'animal':
|
||||||
|
sparse_tensor.SparseTensor(
|
||||||
|
indices=[[0, 0], [0, 1]], values=[1, 2], dense_shape=[1, 2])
|
||||||
|
}
|
||||||
|
net = df.DenseFeatures([animal])(features)
|
||||||
|
|
||||||
|
self.evaluate(variables_lib.global_variables_initializer())
|
||||||
|
self.evaluate(lookup_ops.tables_initializer())
|
||||||
|
|
||||||
|
self.assertAllClose([[0., 1., 1., 0.]], self.evaluate(net))
|
||||||
|
|
||||||
|
|
||||||
|
class EmbeddingColumnTest(test.TestCase, parameterized.TestCase):
|
||||||
|
|
||||||
|
@parameterized.named_parameters(
|
||||||
|
{
|
||||||
|
'testcase_name': 'use_safe_embedding_lookup',
|
||||||
|
'use_safe_embedding_lookup': True,
|
||||||
|
'partition_variables': False,
|
||||||
|
}, {
|
||||||
|
'testcase_name': 'dont_use_safe_embedding_lookup',
|
||||||
|
'use_safe_embedding_lookup': False,
|
||||||
|
'partition_variables': False,
|
||||||
|
}, {
|
||||||
|
'testcase_name': 'use_safe_embedding_lookup_partitioned',
|
||||||
|
'use_safe_embedding_lookup': True,
|
||||||
|
'partition_variables': True,
|
||||||
|
}, {
|
||||||
|
'testcase_name': 'dont_use_safe_embedding_lookup_partitioned',
|
||||||
|
'use_safe_embedding_lookup': False,
|
||||||
|
'partition_variables': True,
|
||||||
|
})
|
||||||
|
@test_util.run_deprecated_v1
|
||||||
|
def test_dense_features(self, use_safe_embedding_lookup, partition_variables):
|
||||||
|
# Inputs.
|
||||||
|
vocabulary_size = 4
|
||||||
|
sparse_input = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [2]
|
||||||
|
# example 1, ids [0, 1]
|
||||||
|
# example 2, ids []
|
||||||
|
# example 3, ids [1]
|
||||||
|
indices=((0, 0), (1, 0), (1, 4), (3, 0)),
|
||||||
|
values=(2, 0, 1, 1),
|
||||||
|
dense_shape=(4, 5))
|
||||||
|
|
||||||
|
# Embedding variable.
|
||||||
|
embedding_dimension = 2
|
||||||
|
embedding_values = (
|
||||||
|
(1., 2.), # id 0
|
||||||
|
(3., 5.), # id 1
|
||||||
|
(7., 11.), # id 2
|
||||||
|
(9., 13.) # id 3
|
||||||
|
)
|
||||||
|
|
||||||
|
def _initializer(shape, dtype, partition_info=None):
|
||||||
|
if partition_variables:
|
||||||
|
self.assertEqual([vocabulary_size, embedding_dimension],
|
||||||
|
partition_info.full_shape)
|
||||||
|
self.assertAllEqual((2, embedding_dimension), shape)
|
||||||
|
else:
|
||||||
|
self.assertAllEqual((vocabulary_size, embedding_dimension), shape)
|
||||||
|
self.assertIsNone(partition_info)
|
||||||
|
|
||||||
|
self.assertEqual(dtypes.float32, dtype)
|
||||||
|
return embedding_values
|
||||||
|
|
||||||
|
# Expected lookup result, using combiner='mean'.
|
||||||
|
expected_lookups = (
|
||||||
|
# example 0, ids [2], embedding = [7, 11]
|
||||||
|
(7., 11.),
|
||||||
|
# example 1, ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
||||||
|
(2., 3.5),
|
||||||
|
# example 2, ids [], embedding = [0, 0]
|
||||||
|
(0., 0.),
|
||||||
|
# example 3, ids [1], embedding = [3, 5]
|
||||||
|
(3., 5.),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build columns.
|
||||||
|
categorical_column = fc.categorical_column_with_identity(
|
||||||
|
key='aaa', num_buckets=vocabulary_size)
|
||||||
|
partitioner = None
|
||||||
|
if partition_variables:
|
||||||
|
partitioner = partitioned_variables.fixed_size_partitioner(2, axis=0)
|
||||||
|
with variable_scope.variable_scope('vars', partitioner=partitioner):
|
||||||
|
embedding_column = fc.embedding_column(
|
||||||
|
categorical_column,
|
||||||
|
dimension=embedding_dimension,
|
||||||
|
initializer=_initializer,
|
||||||
|
use_safe_embedding_lookup=use_safe_embedding_lookup)
|
||||||
|
|
||||||
|
# Provide sparse input and get dense result.
|
||||||
|
l = df.DenseFeatures((embedding_column,))
|
||||||
|
dense_features = l({'aaa': sparse_input})
|
||||||
|
|
||||||
|
# Assert expected embedding variable and lookups.
|
||||||
|
global_vars = ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES)
|
||||||
|
if partition_variables:
|
||||||
|
self.assertCountEqual(
|
||||||
|
('vars/dense_features/aaa_embedding/embedding_weights/part_0:0',
|
||||||
|
'vars/dense_features/aaa_embedding/embedding_weights/part_1:0'),
|
||||||
|
tuple([v.name for v in global_vars]))
|
||||||
|
else:
|
||||||
|
self.assertCountEqual(
|
||||||
|
('vars/dense_features/aaa_embedding/embedding_weights:0',),
|
||||||
|
tuple([v.name for v in global_vars]))
|
||||||
|
for v in global_vars:
|
||||||
|
self.assertIsInstance(v, variables_lib.Variable)
|
||||||
|
trainable_vars = ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES)
|
||||||
|
if partition_variables:
|
||||||
|
self.assertCountEqual(
|
||||||
|
('vars/dense_features/aaa_embedding/embedding_weights/part_0:0',
|
||||||
|
'vars/dense_features/aaa_embedding/embedding_weights/part_1:0'),
|
||||||
|
tuple([v.name for v in trainable_vars]))
|
||||||
|
else:
|
||||||
|
self.assertCountEqual(
|
||||||
|
('vars/dense_features/aaa_embedding/embedding_weights:0',),
|
||||||
|
tuple([v.name for v in trainable_vars]))
|
||||||
|
|
||||||
|
self.evaluate(variables_lib.global_variables_initializer())
|
||||||
|
self.evaluate(lookup_ops.tables_initializer())
|
||||||
|
|
||||||
|
self.assertAllEqual(embedding_values, self.evaluate(trainable_vars[0]))
|
||||||
|
self.assertAllEqual(expected_lookups, self.evaluate(dense_features))
|
||||||
|
|
||||||
|
if use_safe_embedding_lookup:
|
||||||
|
self.assertIn('SparseFillEmptyRows',
|
||||||
|
[x.type for x in ops.get_default_graph().get_operations()])
|
||||||
|
else:
|
||||||
|
self.assertNotIn(
|
||||||
|
'SparseFillEmptyRows',
|
||||||
|
[x.type for x in ops.get_default_graph().get_operations()])
|
||||||
|
|
||||||
|
@test_util.run_deprecated_v1
|
||||||
|
def test_dense_features_not_trainable(self):
|
||||||
|
# Inputs.
|
||||||
|
vocabulary_size = 3
|
||||||
|
sparse_input = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [2]
|
||||||
|
# example 1, ids [0, 1]
|
||||||
|
# example 2, ids []
|
||||||
|
# example 3, ids [1]
|
||||||
|
indices=((0, 0), (1, 0), (1, 4), (3, 0)),
|
||||||
|
values=(2, 0, 1, 1),
|
||||||
|
dense_shape=(4, 5))
|
||||||
|
|
||||||
|
# Embedding variable.
|
||||||
|
embedding_dimension = 2
|
||||||
|
embedding_values = (
|
||||||
|
(1., 2.), # id 0
|
||||||
|
(3., 5.), # id 1
|
||||||
|
(7., 11.) # id 2
|
||||||
|
)
|
||||||
|
|
||||||
|
def _initializer(shape, dtype, partition_info=None):
|
||||||
|
self.assertAllEqual((vocabulary_size, embedding_dimension), shape)
|
||||||
|
self.assertEqual(dtypes.float32, dtype)
|
||||||
|
self.assertIsNone(partition_info)
|
||||||
|
return embedding_values
|
||||||
|
|
||||||
|
# Expected lookup result, using combiner='mean'.
|
||||||
|
expected_lookups = (
|
||||||
|
# example 0, ids [2], embedding = [7, 11]
|
||||||
|
(7., 11.),
|
||||||
|
# example 1, ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
||||||
|
(2., 3.5),
|
||||||
|
# example 2, ids [], embedding = [0, 0]
|
||||||
|
(0., 0.),
|
||||||
|
# example 3, ids [1], embedding = [3, 5]
|
||||||
|
(3., 5.),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build columns.
|
||||||
|
categorical_column = fc.categorical_column_with_identity(
|
||||||
|
key='aaa', num_buckets=vocabulary_size)
|
||||||
|
embedding_column = fc.embedding_column(
|
||||||
|
categorical_column,
|
||||||
|
dimension=embedding_dimension,
|
||||||
|
initializer=_initializer,
|
||||||
|
trainable=False)
|
||||||
|
|
||||||
|
# Provide sparse input and get dense result.
|
||||||
|
dense_features = df.DenseFeatures((embedding_column,))({
|
||||||
|
'aaa': sparse_input
|
||||||
|
})
|
||||||
|
|
||||||
|
# Assert expected embedding variable and lookups.
|
||||||
|
global_vars = ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES)
|
||||||
|
self.assertCountEqual(('dense_features/aaa_embedding/embedding_weights:0',),
|
||||||
|
tuple([v.name for v in global_vars]))
|
||||||
|
self.assertCountEqual([],
|
||||||
|
ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES))
|
||||||
|
|
||||||
|
self.evaluate(variables_lib.global_variables_initializer())
|
||||||
|
self.evaluate(lookup_ops.tables_initializer())
|
||||||
|
|
||||||
|
self.assertAllEqual(embedding_values, self.evaluate(global_vars[0]))
|
||||||
|
self.assertAllEqual(expected_lookups, self.evaluate(dense_features))
|
||||||
|
|
||||||
|
|
||||||
|
class SharedEmbeddingColumnTest(test.TestCase, parameterized.TestCase):
|
||||||
|
|
||||||
|
def _test_dense_features(self, trainable=True):
|
||||||
|
# Inputs.
|
||||||
|
vocabulary_size = 3
|
||||||
|
sparse_input_a = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [2]
|
||||||
|
# example 1, ids [0, 1]
|
||||||
|
indices=((0, 0), (1, 0), (1, 4)),
|
||||||
|
values=(2, 0, 1),
|
||||||
|
dense_shape=(2, 5))
|
||||||
|
sparse_input_b = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [0]
|
||||||
|
# example 1, ids []
|
||||||
|
indices=((0, 0),),
|
||||||
|
values=(0,),
|
||||||
|
dense_shape=(2, 5))
|
||||||
|
sparse_input_c = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [2]
|
||||||
|
# example 1, ids [0, 1]
|
||||||
|
indices=((0, 1), (1, 1), (1, 3)),
|
||||||
|
values=(2, 0, 1),
|
||||||
|
dense_shape=(2, 5))
|
||||||
|
sparse_input_d = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [2]
|
||||||
|
# example 1, ids []
|
||||||
|
indices=((0, 1),),
|
||||||
|
values=(2,),
|
||||||
|
dense_shape=(2, 5))
|
||||||
|
|
||||||
|
# Embedding variable.
|
||||||
|
embedding_dimension = 2
|
||||||
|
embedding_values = (
|
||||||
|
(1., 2.), # id 0
|
||||||
|
(3., 5.), # id 1
|
||||||
|
(7., 11.) # id 2
|
||||||
|
)
|
||||||
|
|
||||||
|
def _initializer(shape, dtype, partition_info=None):
|
||||||
|
self.assertAllEqual((vocabulary_size, embedding_dimension), shape)
|
||||||
|
self.assertEqual(dtypes.float32, dtype)
|
||||||
|
self.assertIsNone(partition_info)
|
||||||
|
return embedding_values
|
||||||
|
|
||||||
|
# Expected lookup result, using combiner='mean'.
|
||||||
|
expected_lookups = (
|
||||||
|
# example 0:
|
||||||
|
# A ids [2], embedding = [7, 11]
|
||||||
|
# B ids [0], embedding = [1, 2]
|
||||||
|
# C ids [2], embedding = [7, 11]
|
||||||
|
# D ids [2], embedding = [7, 11]
|
||||||
|
(7., 11., 1., 2., 7., 11., 7., 11.),
|
||||||
|
# example 1:
|
||||||
|
# A ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
||||||
|
# B ids [], embedding = [0, 0]
|
||||||
|
# C ids [0, 1], embedding = mean([1, 2] + [3, 5]) = [2, 3.5]
|
||||||
|
# D ids [], embedding = [0, 0]
|
||||||
|
(2., 3.5, 0., 0., 2., 3.5, 0., 0.),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build columns.
|
||||||
|
categorical_column_a = fc.categorical_column_with_identity(
|
||||||
|
key='aaa', num_buckets=vocabulary_size)
|
||||||
|
categorical_column_b = fc.categorical_column_with_identity(
|
||||||
|
key='bbb', num_buckets=vocabulary_size)
|
||||||
|
categorical_column_c = fc.categorical_column_with_identity(
|
||||||
|
key='ccc', num_buckets=vocabulary_size)
|
||||||
|
categorical_column_d = fc.categorical_column_with_identity(
|
||||||
|
key='ddd', num_buckets=vocabulary_size)
|
||||||
|
|
||||||
|
embedding_column_a, embedding_column_b = fc.shared_embedding_columns_v2(
|
||||||
|
[categorical_column_a, categorical_column_b],
|
||||||
|
dimension=embedding_dimension,
|
||||||
|
initializer=_initializer,
|
||||||
|
trainable=trainable)
|
||||||
|
embedding_column_c, embedding_column_d = fc.shared_embedding_columns_v2(
|
||||||
|
[categorical_column_c, categorical_column_d],
|
||||||
|
dimension=embedding_dimension,
|
||||||
|
initializer=_initializer,
|
||||||
|
trainable=trainable)
|
||||||
|
|
||||||
|
features = {
|
||||||
|
'aaa': sparse_input_a,
|
||||||
|
'bbb': sparse_input_b,
|
||||||
|
'ccc': sparse_input_c,
|
||||||
|
'ddd': sparse_input_d
|
||||||
|
}
|
||||||
|
|
||||||
|
# Provide sparse input and get dense result.
|
||||||
|
dense_features = df.DenseFeatures(
|
||||||
|
feature_columns=(embedding_column_b, embedding_column_a,
|
||||||
|
embedding_column_c, embedding_column_d))(
|
||||||
|
features)
|
||||||
|
|
||||||
|
# Assert expected embedding variable and lookups.
|
||||||
|
global_vars = ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES)
|
||||||
|
self.assertCountEqual(
|
||||||
|
['aaa_bbb_shared_embedding:0', 'ccc_ddd_shared_embedding:0'],
|
||||||
|
tuple([v.name for v in global_vars]))
|
||||||
|
for v in global_vars:
|
||||||
|
self.assertIsInstance(v, variables_lib.Variable)
|
||||||
|
trainable_vars = ops.get_collection(ops.GraphKeys.TRAINABLE_VARIABLES)
|
||||||
|
if trainable:
|
||||||
|
self.assertCountEqual(
|
||||||
|
['aaa_bbb_shared_embedding:0', 'ccc_ddd_shared_embedding:0'],
|
||||||
|
tuple([v.name for v in trainable_vars]))
|
||||||
|
else:
|
||||||
|
self.assertCountEqual([], tuple([v.name for v in trainable_vars]))
|
||||||
|
shared_embedding_vars = global_vars
|
||||||
|
|
||||||
|
self.evaluate(variables_lib.global_variables_initializer())
|
||||||
|
self.evaluate(lookup_ops.tables_initializer())
|
||||||
|
|
||||||
|
self.assertAllEqual(embedding_values,
|
||||||
|
self.evaluate(shared_embedding_vars[0]))
|
||||||
|
self.assertAllEqual(expected_lookups, self.evaluate(dense_features))
|
||||||
|
|
||||||
|
@test_util.run_deprecated_v1
|
||||||
|
def test_dense_features(self):
|
||||||
|
self._test_dense_features()
|
||||||
|
|
||||||
|
@test_util.run_deprecated_v1
|
||||||
|
def test_dense_features_no_trainable(self):
|
||||||
|
self._test_dense_features(trainable=False)
|
||||||
|
|
||||||
|
|
||||||
|
@test_util.run_all_in_graph_and_eager_modes
|
||||||
|
class DenseFeaturesSerializationTest(test.TestCase, parameterized.TestCase):
|
||||||
|
|
||||||
|
@parameterized.named_parameters(
|
||||||
|
('default', None, None),
|
||||||
|
('trainable', True, 'trainable'),
|
||||||
|
('not_trainable', False, 'frozen'))
|
||||||
|
def test_get_config(self, trainable, name):
|
||||||
|
cols = [fc.numeric_column('a'),
|
||||||
|
fc.embedding_column(fc.categorical_column_with_identity(
|
||||||
|
key='b', num_buckets=3), dimension=2)]
|
||||||
|
orig_layer = df.DenseFeatures(
|
||||||
|
cols, trainable=trainable, name=name)
|
||||||
|
config = orig_layer.get_config()
|
||||||
|
|
||||||
|
self.assertEqual(config['name'], orig_layer.name)
|
||||||
|
self.assertEqual(config['trainable'], trainable)
|
||||||
|
self.assertLen(config['feature_columns'], 2)
|
||||||
|
self.assertEqual(
|
||||||
|
config['feature_columns'][0]['class_name'], 'NumericColumn')
|
||||||
|
self.assertEqual(config['feature_columns'][0]['config']['shape'], (1,))
|
||||||
|
self.assertEqual(
|
||||||
|
config['feature_columns'][1]['class_name'], 'EmbeddingColumn')
|
||||||
|
|
||||||
|
@parameterized.named_parameters(
|
||||||
|
('default', None, None),
|
||||||
|
('trainable', True, 'trainable'),
|
||||||
|
('not_trainable', False, 'frozen'))
|
||||||
|
def test_from_config(self, trainable, name):
|
||||||
|
cols = [fc.numeric_column('a'),
|
||||||
|
fc.embedding_column(fc.categorical_column_with_vocabulary_list(
|
||||||
|
'b', vocabulary_list=['1', '2', '3']), dimension=2),
|
||||||
|
fc.indicator_column(fc.categorical_column_with_hash_bucket(
|
||||||
|
key='c', hash_bucket_size=3))]
|
||||||
|
orig_layer = df.DenseFeatures(
|
||||||
|
cols, trainable=trainable, name=name)
|
||||||
|
config = orig_layer.get_config()
|
||||||
|
|
||||||
|
new_layer = df.DenseFeatures.from_config(config)
|
||||||
|
|
||||||
|
self.assertEqual(new_layer.name, orig_layer.name)
|
||||||
|
self.assertEqual(new_layer.trainable, trainable)
|
||||||
|
self.assertLen(new_layer._feature_columns, 3)
|
||||||
|
self.assertEqual(new_layer._feature_columns[0].name, 'a')
|
||||||
|
self.assertEqual(new_layer._feature_columns[1].initializer.mean, 0.0)
|
||||||
|
self.assertEqual(new_layer._feature_columns[1].categorical_column.name, 'b')
|
||||||
|
self.assertIsInstance(new_layer._feature_columns[2], fc.IndicatorColumn)
|
||||||
|
|
||||||
|
def test_crossed_column(self):
|
||||||
|
a = fc.categorical_column_with_vocabulary_list(
|
||||||
|
'a', vocabulary_list=['1', '2', '3'])
|
||||||
|
b = fc.categorical_column_with_vocabulary_list(
|
||||||
|
'b', vocabulary_list=['1', '2', '3'])
|
||||||
|
ab = fc.crossed_column([a, b], hash_bucket_size=2)
|
||||||
|
cols = [fc.indicator_column(ab)]
|
||||||
|
|
||||||
|
orig_layer = df.DenseFeatures(cols)
|
||||||
|
config = orig_layer.get_config()
|
||||||
|
|
||||||
|
new_layer = df.DenseFeatures.from_config(config)
|
||||||
|
|
||||||
|
self.assertLen(new_layer._feature_columns, 1)
|
||||||
|
self.assertEqual(new_layer._feature_columns[0].name, 'a_X_b_indicator')
|
||||||
|
|
||||||
|
|
||||||
|
@test_util.run_all_in_graph_and_eager_modes
|
||||||
|
class SequenceFeatureColumnsTest(test.TestCase):
|
||||||
|
"""Tests DenseFeatures with sequence feature columns."""
|
||||||
|
|
||||||
|
def test_embedding_column(self):
|
||||||
|
"""Tests that error is raised for sequence embedding column."""
|
||||||
|
vocabulary_size = 3
|
||||||
|
sparse_input = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [2]
|
||||||
|
# example 1, ids [0, 1]
|
||||||
|
indices=((0, 0), (1, 0), (1, 1)),
|
||||||
|
values=(2, 0, 1),
|
||||||
|
dense_shape=(2, 2))
|
||||||
|
|
||||||
|
categorical_column_a = sfc.sequence_categorical_column_with_identity(
|
||||||
|
key='aaa', num_buckets=vocabulary_size)
|
||||||
|
embedding_column_a = fc.embedding_column(
|
||||||
|
categorical_column_a, dimension=2)
|
||||||
|
|
||||||
|
input_layer = df.DenseFeatures([embedding_column_a])
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
ValueError,
|
||||||
|
r'In embedding_column: aaa_embedding\. categorical_column must not be '
|
||||||
|
r'of type SequenceCategoricalColumn\.'):
|
||||||
|
_ = input_layer({'aaa': sparse_input})
|
||||||
|
|
||||||
|
def test_indicator_column(self):
|
||||||
|
"""Tests that error is raised for sequence indicator column."""
|
||||||
|
vocabulary_size = 3
|
||||||
|
sparse_input = sparse_tensor.SparseTensorValue(
|
||||||
|
# example 0, ids [2]
|
||||||
|
# example 1, ids [0, 1]
|
||||||
|
indices=((0, 0), (1, 0), (1, 1)),
|
||||||
|
values=(2, 0, 1),
|
||||||
|
dense_shape=(2, 2))
|
||||||
|
|
||||||
|
categorical_column_a = sfc.sequence_categorical_column_with_identity(
|
||||||
|
key='aaa', num_buckets=vocabulary_size)
|
||||||
|
indicator_column_a = fc.indicator_column(categorical_column_a)
|
||||||
|
|
||||||
|
input_layer = df.DenseFeatures([indicator_column_a])
|
||||||
|
with self.assertRaisesRegexp(
|
||||||
|
ValueError,
|
||||||
|
r'In indicator_column: aaa_indicator\. categorical_column must not be '
|
||||||
|
r'of type SequenceCategoricalColumn\.'):
|
||||||
|
_ = input_layer({'aaa': sparse_input})
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test.main()
|
test.main()
|
|
@ -18,10 +18,9 @@ from __future__ import absolute_import
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from tensorflow.python.feature_column import dense_features
|
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.framework import ops
|
from tensorflow.python.framework import ops
|
||||||
from tensorflow.python.keras.layers import serialization as layer_serialization
|
from tensorflow.python.keras.feature_column import dense_features
|
||||||
from tensorflow.python.util.tf_export import keras_export
|
from tensorflow.python.util.tf_export import keras_export
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +93,3 @@ class DenseFeatures(dense_features.DenseFeatures):
|
||||||
# We would like to call Layer.build and not _DenseFeaturesHelper.build.
|
# We would like to call Layer.build and not _DenseFeaturesHelper.build.
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
super(fc._BaseFeaturesLayer, self).build(None) # pylint: disable=bad-super-call
|
super(fc._BaseFeaturesLayer, self).build(None) # pylint: disable=bad-super-call
|
||||||
|
|
||||||
|
|
||||||
layer_serialization.inject_feature_column_v2_objects(
|
|
||||||
'DenseFeatures', DenseFeatures)
|
|
|
@ -23,7 +23,6 @@ import numpy as np
|
||||||
from tensorflow.python.client import session
|
from tensorflow.python.client import session
|
||||||
from tensorflow.python.eager import backprop
|
from tensorflow.python.eager import backprop
|
||||||
from tensorflow.python.eager import context
|
from tensorflow.python.eager import context
|
||||||
from tensorflow.python.feature_column import dense_features_v2 as df
|
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.framework import constant_op
|
from tensorflow.python.framework import constant_op
|
||||||
from tensorflow.python.framework import dtypes
|
from tensorflow.python.framework import dtypes
|
||||||
|
@ -31,6 +30,7 @@ from tensorflow.python.framework import errors
|
||||||
from tensorflow.python.framework import ops
|
from tensorflow.python.framework import ops
|
||||||
from tensorflow.python.framework import sparse_tensor
|
from tensorflow.python.framework import sparse_tensor
|
||||||
from tensorflow.python.framework import test_util
|
from tensorflow.python.framework import test_util
|
||||||
|
from tensorflow.python.keras.feature_column import dense_features_v2 as df
|
||||||
from tensorflow.python.ops import array_ops
|
from tensorflow.python.ops import array_ops
|
||||||
from tensorflow.python.ops import lookup_ops
|
from tensorflow.python.ops import lookup_ops
|
||||||
from tensorflow.python.ops import variables as variables_lib
|
from tensorflow.python.ops import variables as variables_lib
|
|
@ -24,11 +24,11 @@ from google.protobuf import text_format
|
||||||
from tensorflow.core.example import example_pb2
|
from tensorflow.core.example import example_pb2
|
||||||
from tensorflow.core.example import feature_pb2
|
from tensorflow.core.example import feature_pb2
|
||||||
from tensorflow.python.data.ops import dataset_ops
|
from tensorflow.python.data.ops import dataset_ops
|
||||||
from tensorflow.python.feature_column import dense_features
|
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.feature_column import sequence_feature_column as sfc
|
from tensorflow.python.feature_column import sequence_feature_column as sfc
|
||||||
from tensorflow.python.framework import sparse_tensor
|
from tensorflow.python.framework import sparse_tensor
|
||||||
from tensorflow.python.framework import test_util
|
from tensorflow.python.framework import test_util
|
||||||
|
from tensorflow.python.keras.feature_column import dense_features
|
||||||
from tensorflow.python.keras.feature_column import sequence_feature_column as ksfc
|
from tensorflow.python.keras.feature_column import sequence_feature_column as ksfc
|
||||||
from tensorflow.python.keras.layers import recurrent
|
from tensorflow.python.keras.layers import recurrent
|
||||||
from tensorflow.python.ops import init_ops_v2
|
from tensorflow.python.ops import init_ops_v2
|
||||||
|
|
|
@ -64,23 +64,11 @@ ALL_V2_MODULES = (
|
||||||
recurrent_v2,
|
recurrent_v2,
|
||||||
preprocessing_normalization
|
preprocessing_normalization
|
||||||
)
|
)
|
||||||
FEATURE_COLUMN_V1_OBJECTS = {}
|
|
||||||
FEATURE_COLUMN_V2_OBJECTS = {}
|
|
||||||
# ALL_OBJECTS is meant to be a global mutable. Hence we need to make it
|
# ALL_OBJECTS is meant to be a global mutable. Hence we need to make it
|
||||||
# thread-local to avoid concurrent mutations.
|
# thread-local to avoid concurrent mutations.
|
||||||
LOCAL = threading.local()
|
LOCAL = threading.local()
|
||||||
|
|
||||||
|
|
||||||
def inject_feature_column_v1_objects(name, cls):
|
|
||||||
global FEATURE_COLUMN_V1_OBJECTS
|
|
||||||
FEATURE_COLUMN_V1_OBJECTS[name] = cls
|
|
||||||
|
|
||||||
|
|
||||||
def inject_feature_column_v2_objects(name, cls):
|
|
||||||
global FEATURE_COLUMN_V2_OBJECTS
|
|
||||||
FEATURE_COLUMN_V2_OBJECTS[name] = cls
|
|
||||||
|
|
||||||
|
|
||||||
def populate_deserializable_objects():
|
def populate_deserializable_objects():
|
||||||
"""Populates dict ALL_OBJECTS with every built-in layer.
|
"""Populates dict ALL_OBJECTS with every built-in layer.
|
||||||
"""
|
"""
|
||||||
|
@ -134,9 +122,11 @@ def populate_deserializable_objects():
|
||||||
LOCAL.ALL_OBJECTS['WideDeepModel'] = WideDeepModel
|
LOCAL.ALL_OBJECTS['WideDeepModel'] = WideDeepModel
|
||||||
|
|
||||||
if tf2.enabled():
|
if tf2.enabled():
|
||||||
LOCAL.ALL_OBJECTS.update(FEATURE_COLUMN_V2_OBJECTS)
|
from tensorflow.python.keras.feature_column.dense_features_v2 import DenseFeatures # pylint: disable=g-import-not-at-top
|
||||||
|
LOCAL.ALL_OBJECTS['DenseFeatures'] = DenseFeatures
|
||||||
else:
|
else:
|
||||||
LOCAL.ALL_OBJECTS.update(FEATURE_COLUMN_V1_OBJECTS)
|
from tensorflow.python.keras.feature_column.dense_features import DenseFeatures # pylint: disable=g-import-not-at-top
|
||||||
|
LOCAL.ALL_OBJECTS['DenseFeatures'] = DenseFeatures
|
||||||
|
|
||||||
# Merge layers, function versions.
|
# Merge layers, function versions.
|
||||||
LOCAL.ALL_OBJECTS['add'] = merge.add
|
LOCAL.ALL_OBJECTS['add'] = merge.add
|
||||||
|
|
|
@ -39,7 +39,6 @@ from tensorflow.python.distribute import mirrored_strategy
|
||||||
from tensorflow.python.eager import context
|
from tensorflow.python.eager import context
|
||||||
from tensorflow.python.eager import def_function
|
from tensorflow.python.eager import def_function
|
||||||
from tensorflow.python.feature_column import feature_column_v2 as fc
|
from tensorflow.python.feature_column import feature_column_v2 as fc
|
||||||
from tensorflow.python.feature_column.dense_features import DenseFeatures
|
|
||||||
from tensorflow.python.framework import constant_op
|
from tensorflow.python.framework import constant_op
|
||||||
from tensorflow.python.framework import dtypes
|
from tensorflow.python.framework import dtypes
|
||||||
from tensorflow.python.framework import ops
|
from tensorflow.python.framework import ops
|
||||||
|
@ -48,6 +47,7 @@ from tensorflow.python.keras import combinations
|
||||||
from tensorflow.python.keras import keras_parameterized
|
from tensorflow.python.keras import keras_parameterized
|
||||||
from tensorflow.python.keras import regularizers
|
from tensorflow.python.keras import regularizers
|
||||||
from tensorflow.python.keras import testing_utils
|
from tensorflow.python.keras import testing_utils
|
||||||
|
from tensorflow.python.keras.feature_column.dense_features import DenseFeatures
|
||||||
from tensorflow.python.keras.saving.saved_model import load as keras_load
|
from tensorflow.python.keras.saving.saved_model import load as keras_load
|
||||||
from tensorflow.python.keras.saving.saved_model import save_impl as keras_save
|
from tensorflow.python.keras.saving.saved_model import save_impl as keras_save
|
||||||
from tensorflow.python.keras.utils import generic_utils
|
from tensorflow.python.keras.utils import generic_utils
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
path: "tensorflow.keras.layers.DenseFeatures"
|
path: "tensorflow.keras.layers.DenseFeatures"
|
||||||
tf_class {
|
tf_class {
|
||||||
is_instance: "<class \'tensorflow.python.feature_column.dense_features.DenseFeatures\'>"
|
is_instance: "<class \'tensorflow.python.keras.feature_column.dense_features.DenseFeatures\'>"
|
||||||
is_instance: "<class \'tensorflow.python.feature_column.feature_column_v2._BaseFeaturesLayer\'>"
|
is_instance: "<class \'tensorflow.python.feature_column.feature_column_v2._BaseFeaturesLayer\'>"
|
||||||
is_instance: "<class \'tensorflow.python.keras.engine.base_layer.Layer\'>"
|
is_instance: "<class \'tensorflow.python.keras.engine.base_layer.Layer\'>"
|
||||||
is_instance: "<class \'tensorflow.python.module.module.Module\'>"
|
is_instance: "<class \'tensorflow.python.module.module.Module\'>"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
path: "tensorflow.keras.layers.DenseFeatures"
|
path: "tensorflow.keras.layers.DenseFeatures"
|
||||||
tf_class {
|
tf_class {
|
||||||
is_instance: "<class \'tensorflow.python.feature_column.dense_features_v2.DenseFeatures\'>"
|
is_instance: "<class \'tensorflow.python.keras.feature_column.dense_features_v2.DenseFeatures\'>"
|
||||||
is_instance: "<class \'tensorflow.python.feature_column.dense_features.DenseFeatures\'>"
|
is_instance: "<class \'tensorflow.python.keras.feature_column.dense_features.DenseFeatures\'>"
|
||||||
is_instance: "<class \'tensorflow.python.feature_column.feature_column_v2._BaseFeaturesLayer\'>"
|
is_instance: "<class \'tensorflow.python.feature_column.feature_column_v2._BaseFeaturesLayer\'>"
|
||||||
is_instance: "<class \'tensorflow.python.keras.engine.base_layer.Layer\'>"
|
is_instance: "<class \'tensorflow.python.keras.engine.base_layer.Layer\'>"
|
||||||
is_instance: "<class \'tensorflow.python.module.module.Module\'>"
|
is_instance: "<class \'tensorflow.python.module.module.Module\'>"
|
||||||
|
|
Loading…
Reference in New Issue