STT-tensorflow/tensorflow/python/keras/utils/metrics_utils_test.py
Scott Zhu 8ae2236a6a Update keras test to use public TF test API.
PiperOrigin-RevId: 339346336
Change-Id: I96d8c98cd9122c301d2bbf8358f5d0f1e090f670
2020-10-27 16:03:04 -07:00

305 lines
9.2 KiB
Python

# Copyright 2018 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 metrics_utils."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from absl.testing import parameterized
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import test_util
from tensorflow.python.keras import combinations
from tensorflow.python.keras.utils import metrics_utils
from tensorflow.python.ops import script_ops
from tensorflow.python.ops.ragged import ragged_factory_ops
from tensorflow.python.ops.ragged import ragged_tensor
from tensorflow.python.platform import test
@combinations.generate(combinations.combine(mode=['graph', 'eager']))
class RaggedSizeOpTest(test_util.TensorFlowTestCase, parameterized.TestCase):
@parameterized.parameters([
{
'x_list': [1],
'y_list': [2]
},
{
'x_list': [1, 2],
'y_list': [2, 3]
},
{
'x_list': [1, 2, 4],
'y_list': [2, 3, 5]
},
{
'x_list': [[1, 2], [3, 4]],
'y_list': [[2, 3], [5, 6]]
},
])
def test_passing_dense_tensors(self, x_list, y_list):
x = constant_op.constant(x_list)
y = constant_op.constant(y_list)
[x,
y], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values([x, y])
x.shape.assert_is_compatible_with(y.shape)
@parameterized.parameters([
{
'x_list': [1],
},
{
'x_list': [1, 2],
},
{
'x_list': [1, 2, 4],
},
{
'x_list': [[1, 2], [3, 4]],
},
])
def test_passing_one_dense_tensor(self, x_list):
x = constant_op.constant(x_list)
[x], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values([x])
@parameterized.parameters([
{
'x_list': [1],
'y_list': [2]
},
{
'x_list': [1, 2],
'y_list': [2, 3]
},
{
'x_list': [1, 2, 4],
'y_list': [2, 3, 5]
},
{
'x_list': [[1, 2], [3, 4]],
'y_list': [[2, 3], [5, 6]]
},
{
'x_list': [[1, 2], [3, 4], [1]],
'y_list': [[2, 3], [5, 6], [3]]
},
{
'x_list': [[1, 2], [], [1]],
'y_list': [[2, 3], [], [3]]
},
])
def test_passing_both_ragged(self, x_list, y_list):
x = ragged_factory_ops.constant(x_list)
y = ragged_factory_ops.constant(y_list)
[x,
y], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values([x, y])
x.shape.assert_is_compatible_with(y.shape)
@parameterized.parameters([
{
'x_list': [1],
},
{
'x_list': [1, 2],
},
{
'x_list': [1, 2, 4],
},
{
'x_list': [[1, 2], [3, 4]],
},
{
'x_list': [[1, 2], [3, 4], [1]],
},
{
'x_list': [[1, 2], [], [1]],
},
])
def test_passing_one_ragged(self, x_list):
x = ragged_factory_ops.constant(x_list)
[x], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values([x])
@parameterized.parameters([
{
'x_list': [1],
'y_list': [2],
'mask_list': [0]
},
{
'x_list': [1, 2],
'y_list': [2, 3],
'mask_list': [0, 1]
},
{
'x_list': [1, 2, 4],
'y_list': [2, 3, 5],
'mask_list': [1, 1, 1]
},
{
'x_list': [[1, 2], [3, 4]],
'y_list': [[2, 3], [5, 6]],
'mask_list': [[1, 1], [0, 1]]
},
{
'x_list': [[1, 2], [3, 4], [1]],
'y_list': [[2, 3], [5, 6], [3]],
'mask_list': [[1, 1], [0, 0], [1]]
},
{
'x_list': [[1, 2], [], [1]],
'y_list': [[2, 3], [], [3]],
'mask_list': [[1, 1], [], [0]]
},
])
def test_passing_both_ragged_with_mask(self, x_list, y_list, mask_list):
x = ragged_factory_ops.constant(x_list)
y = ragged_factory_ops.constant(y_list)
mask = ragged_factory_ops.constant(mask_list)
[x, y], mask = \
metrics_utils.ragged_assert_compatible_and_get_flat_values([x, y], mask)
x.shape.assert_is_compatible_with(y.shape)
y.shape.assert_is_compatible_with(mask.shape)
@parameterized.parameters([
{
'x_list': [1],
'mask_list': [0]
},
{
'x_list': [1, 2],
'mask_list': [0, 1]
},
{
'x_list': [1, 2, 4],
'mask_list': [1, 1, 1]
},
{
'x_list': [[1, 2], [3, 4]],
'mask_list': [[1, 1], [0, 1]]
},
{
'x_list': [[1, 2], [3, 4], [1]],
'mask_list': [[1, 1], [0, 0], [1]]
},
{
'x_list': [[1, 2], [], [1]],
'mask_list': [[1, 1], [], [0]]
},
])
def test_passing_one_ragged_with_mask(self, x_list, mask_list):
x = ragged_factory_ops.constant(x_list)
mask = ragged_factory_ops.constant(mask_list)
[x], mask = \
metrics_utils.ragged_assert_compatible_and_get_flat_values([x], mask)
x.shape.assert_is_compatible_with(mask.shape)
@parameterized.parameters([
{
'x_list': [[[1, 3]]],
'y_list': [[2, 3]]
},
])
def test_failing_different_ragged_and_dense_ranks(self, x_list, y_list):
x = ragged_factory_ops.constant(x_list)
y = ragged_factory_ops.constant(y_list)
with self.assertRaises(ValueError): # pylint: disable=g-error-prone-assert-raises
[x, y
], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values([x, y])
@parameterized.parameters([
{
'x_list': [[[1, 3]]],
'y_list': [[[2, 3]]],
'mask_list': [[0, 1]]
},
])
def test_failing_different_mask_ranks(self, x_list, y_list, mask_list):
x = ragged_factory_ops.constant(x_list)
y = ragged_factory_ops.constant(y_list)
mask = ragged_factory_ops.constant(mask_list)
with self.assertRaises(ValueError): # pylint: disable=g-error-prone-assert-raises
[x, y
], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values([x, y],
mask)
# we do not support such cases that ragged_ranks are different but overall
# dimension shapes and sizes are identical due to adding too much performance
# overheads to the overall use cases.
def test_failing_different_ragged_ranks(self):
dt = constant_op.constant([[[1, 2]]])
# adding a ragged dimension
x = ragged_tensor.RaggedTensor.from_row_splits(dt, row_splits=[0, 1])
y = ragged_factory_ops.constant([[[[1, 2]]]])
with self.assertRaises(ValueError): # pylint: disable=g-error-prone-assert-raises
[x, y], _ = \
metrics_utils.ragged_assert_compatible_and_get_flat_values([x, y])
@combinations.generate(combinations.combine(mode=['graph', 'eager']))
class FilterTopKTest(test_util.TensorFlowTestCase, parameterized.TestCase):
def test_one_dimensional(self):
x = constant_op.constant([.3, .1, .2, -.5, 42.])
top_1 = self.evaluate(metrics_utils._filter_top_k(x=x, k=1))
top_2 = self.evaluate(metrics_utils._filter_top_k(x=x, k=2))
top_3 = self.evaluate(metrics_utils._filter_top_k(x=x, k=3))
self.assertAllClose(top_1, [
metrics_utils.NEG_INF, metrics_utils.NEG_INF, metrics_utils.NEG_INF,
metrics_utils.NEG_INF, 42.
])
self.assertAllClose(top_2, [
.3, metrics_utils.NEG_INF, metrics_utils.NEG_INF, metrics_utils.NEG_INF,
42.
])
self.assertAllClose(
top_3, [.3, metrics_utils.NEG_INF, .2, metrics_utils.NEG_INF, 42.])
def test_three_dimensional(self):
x = constant_op.constant([[[.3, .1, .2], [-.3, -.2, -.1]],
[[5., .2, 42.], [-.3, -.6, -.99]]])
top_2 = self.evaluate(metrics_utils._filter_top_k(x=x, k=2))
self.assertAllClose(
top_2,
[[[.3, metrics_utils.NEG_INF, .2], [metrics_utils.NEG_INF, -.2, -.1]],
[[5., metrics_utils.NEG_INF, 42.], [-.3, -.6, metrics_utils.NEG_INF]]])
def test_handles_dynamic_shapes(self):
# See b/150281686. # GOOGLE_INTERNAL
def _identity(x):
return x
def _filter_top_k(x):
# This loses the static shape.
x = script_ops.numpy_function(_identity, (x,), dtypes.float32)
return metrics_utils._filter_top_k(x=x, k=2)
x = constant_op.constant([.3, .1, .2, -.5, 42.])
top_2 = self.evaluate(_filter_top_k(x))
self.assertAllClose(top_2, [
.3, metrics_utils.NEG_INF, metrics_utils.NEG_INF, metrics_utils.NEG_INF,
42.
])
if __name__ == '__main__':
test.main()