Unverified Commit 451906e4 authored by pkulzc's avatar pkulzc Committed by GitHub
Browse files

Release MobileDet code and model, and require tf_slim installation for OD API. (#8562)



* Merged commit includes the following changes:
311933687  by Sergio Guadarrama:

    Removes spurios use of tf.compat.v2, which results in spurious tf.compat.v1.compat.v2. Adds basic test to nasnet_utils.
    Replaces all remaining import tensorflow as tf with import tensorflow.compat.v1 as tf

--
311766063  by Sergio Guadarrama:

    Removes explicit tf.compat.v1 in all call sites (we already import tf.compat.v1, so this code was  doing tf.compat.v1.compat.v1). The existing code worked in latest version of tensorflow, 2.2, (and 1.15) but not in 1.14 or in 2.0.0a, this CL fixes it.

--
311624958  by Sergio Guadarrama:

    Updates README that doesn't render properly in github documentation

--
310980959  by Sergio Guadarrama:

    Moves research_models/slim off tf.contrib.slim/layers/framework to tf_slim

--
310263156  by Sergio Guadarrama:

    Adds model breakdown for MobilenetV3

--
308640516  by Sergio Guadarrama:

    Internal change

308244396  by Sergio Guadarrama:

    GroupNormalization support for MobilenetV3.

--
307475800  by Sergio Guadarrama:

    Internal change

--
302077708  by Sergio Guadarrama:

    Remove `disable_tf2` behavior from slim py_library targets

--
301208453  by Sergio Guadarrama:

    Automated refactoring to make code Python 3 compatible.

--
300816672  by Sergio Guadarrama:

    Internal change

299433840  by Sergio Guadarrama:

    Internal change

299221609  by Sergio Guadarrama:

    Explicitly disable Tensorflow v2 behaviors for all TF1.x binaries and tests

--
299179617  by Sergio Guadarrama:

    Internal change

299040784  by Sergio Guadarrama:

    Internal change

299036699  by Sergio Guadarrama:

    Internal change

298736510  by Sergio Guadarrama:

    Internal change

298732599  by Sergio Guadarrama:

    Internal change

298729507  by Sergio Guadarrama:

    Internal change

298253328  by Sergio Guadarrama:

    Internal change

297788346  by Sergio Guadarrama:

    Internal change

297785278  by Sergio Guadarrama:

    Internal change

297783127  by Sergio Guadarrama:

    Internal change

297725870  by Sergio Guadarrama:

    Internal change

297721811  by Sergio Guadarrama:

    Internal change

297711347  by Sergio Guadarrama:

    Internal change

297708059  by Sergio Guadarrama:

    Internal change

297701831  by Sergio Guadarrama:

    Internal change

297700038  by Sergio Guadarrama:

    Internal change

297670468  by Sergio Guadarrama:

    Internal change.

--
297350326  by Sergio Guadarrama:

    Explicitly replace "import tensorflow" with "tensorflow.compat.v1" for TF2.x migration

--
297201668  by Sergio Guadarrama:

    Explicitly replace "import tensorflow" with "tensorflow.compat.v1" for TF2.x migration

--
294483372  by Sergio Guadarrama:

    Internal change

PiperOrigin-RevId: 311933687

* Merged commit includes the following changes:
312578615  by Menglong Zhu:

    Modify the LSTM feature extractors to be python 3 compatible.

--
311264357  by Menglong Zhu:

    Removes contrib.slim

--
308957207  by Menglong Zhu:

    Automated refactoring to make code Python 3 compatible.

--
306976470  by yongzhe:

    Internal change

306777559  by Menglong Zhu:

    Internal change

--
299232507  by lzyuan:

    Internal update.

--
299221735  by lzyuan:

    Add small epsilon on max_range for quantize_op to prevent range collapse.

--

PiperOrigin-RevId: 312578615

* Merged commit includes the following changes:
310447280  by lzc:

    Internal changes.

--

PiperOrigin-RevId: 310447280
Co-authored-by: default avatarSergio Guadarrama <sguada@google.com>
Co-authored-by: default avatarMenglong Zhu <menglong@google.com>
parent 73b5be67
...@@ -22,7 +22,7 @@ from absl.testing import parameterized ...@@ -22,7 +22,7 @@ from absl.testing import parameterized
import numpy as np import numpy as np
import six import six
from six.moves import range from six.moves import range
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection import eval_util from object_detection import eval_util
from object_detection.core import standard_fields from object_detection.core import standard_fields
from object_detection.utils import object_detection_evaluation from object_detection.utils import object_detection_evaluation
......
...@@ -24,20 +24,13 @@ import six ...@@ -24,20 +24,13 @@ import six
from six.moves import range from six.moves import range
from six.moves import zip from six.moves import zip
import tensorflow as tf import tensorflow.compat.v1 as tf
import tf_slim as slim
from object_detection.core import standard_fields as fields from object_detection.core import standard_fields as fields
from object_detection.utils import shape_utils from object_detection.utils import shape_utils
from object_detection.utils import spatial_transform_ops as spatial_ops from object_detection.utils import spatial_transform_ops as spatial_ops
from object_detection.utils import static_shape from object_detection.utils import static_shape
# pylint: disable=g-import-not-at-top
try:
from tensorflow.contrib import framework as contrib_framework
except ImportError:
# TF 2.0 doesn't ship with contrib.
pass
# pylint: enable=g-import-not-at-top
matmul_crop_and_resize = spatial_ops.matmul_crop_and_resize matmul_crop_and_resize = spatial_ops.matmul_crop_and_resize
multilevel_roi_align = spatial_ops.multilevel_roi_align multilevel_roi_align = spatial_ops.multilevel_roi_align
...@@ -595,7 +588,7 @@ def normalize_to_target(inputs, ...@@ -595,7 +588,7 @@ def normalize_to_target(inputs,
initial_norm = depth * [target_norm_value] initial_norm = depth * [target_norm_value]
else: else:
initial_norm = target_norm_value initial_norm = target_norm_value
target_norm = contrib_framework.model_variable( target_norm = slim.model_variable(
name='weights', name='weights',
dtype=tf.float32, dtype=tf.float32,
initializer=tf.constant(initial_norm, dtype=tf.float32), initializer=tf.constant(initial_norm, dtype=tf.float32),
...@@ -833,7 +826,10 @@ def reframe_box_masks_to_image_masks(box_masks, boxes, image_height, ...@@ -833,7 +826,10 @@ def reframe_box_masks_to_image_masks(box_masks, boxes, image_height,
boxes = tf.reshape(boxes, [-1, 2, 2]) boxes = tf.reshape(boxes, [-1, 2, 2])
min_corner = tf.expand_dims(reference_boxes[:, 0:2], 1) min_corner = tf.expand_dims(reference_boxes[:, 0:2], 1)
max_corner = tf.expand_dims(reference_boxes[:, 2:4], 1) max_corner = tf.expand_dims(reference_boxes[:, 2:4], 1)
transformed_boxes = (boxes - min_corner) / (max_corner - min_corner) denom = max_corner - min_corner
# Prevent a divide by zero.
denom = tf.math.maximum(denom, 1e-4)
transformed_boxes = (boxes - min_corner) / denom
return tf.reshape(transformed_boxes, [-1, 4]) return tf.reshape(transformed_boxes, [-1, 4])
box_masks_expanded = tf.expand_dims(box_masks, axis=3) box_masks_expanded = tf.expand_dims(box_masks, axis=3)
...@@ -841,6 +837,9 @@ def reframe_box_masks_to_image_masks(box_masks, boxes, image_height, ...@@ -841,6 +837,9 @@ def reframe_box_masks_to_image_masks(box_masks, boxes, image_height,
unit_boxes = tf.concat( unit_boxes = tf.concat(
[tf.zeros([num_boxes, 2]), tf.ones([num_boxes, 2])], axis=1) [tf.zeros([num_boxes, 2]), tf.ones([num_boxes, 2])], axis=1)
reverse_boxes = transform_boxes_relative_to_boxes(unit_boxes, boxes) reverse_boxes = transform_boxes_relative_to_boxes(unit_boxes, boxes)
# TODO(vighneshb) Use matmul_crop_and_resize so that the output shape
# is static. This will help us run and test on TPUs.
return tf.image.crop_and_resize( return tf.image.crop_and_resize(
image=box_masks_expanded, image=box_masks_expanded,
boxes=reverse_boxes, boxes=reverse_boxes,
...@@ -1042,28 +1041,30 @@ def fpn_feature_levels(num_levels, unit_scale_index, image_ratio, boxes): ...@@ -1042,28 +1041,30 @@ def fpn_feature_levels(num_levels, unit_scale_index, image_ratio, boxes):
return levels return levels
def bfloat16_to_float32_nested(tensor_nested): def bfloat16_to_float32_nested(input_nested):
"""Convert float32 tensors in a nested structure to bfloat16. """Convert float32 tensors in a nested structure to bfloat16.
Args: Args:
tensor_nested: A Python dict, values being Tensor or Python list/tuple of input_nested: A Python dict, values being Tensor or Python list/tuple of
Tensor. Tensor or Non-Tensor.
Returns: Returns:
A Python dict with the same structure as `tensor_dict`, A Python dict with the same structure as `tensor_dict`,
with all bfloat16 tensors converted to float32. with all bfloat16 tensors converted to float32.
""" """
if isinstance(tensor_nested, tf.Tensor): if isinstance(input_nested, tf.Tensor):
if tensor_nested.dtype == tf.bfloat16: if input_nested.dtype == tf.bfloat16:
return tf.cast(tensor_nested, dtype=tf.float32) return tf.cast(input_nested, dtype=tf.float32)
else: else:
return tensor_nested return input_nested
elif isinstance(tensor_nested, (list, tuple)): elif isinstance(input_nested, (list, tuple)):
out_tensor_dict = [bfloat16_to_float32_nested(t) for t in tensor_nested] out_tensor_dict = [bfloat16_to_float32_nested(t) for t in input_nested]
elif isinstance(tensor_nested, dict): elif isinstance(input_nested, dict):
out_tensor_dict = { out_tensor_dict = {
k: bfloat16_to_float32_nested(v) for k, v in tensor_nested.items() k: bfloat16_to_float32_nested(v) for k, v in input_nested.items()
} }
else:
return input_nested
return out_tensor_dict return out_tensor_dict
...@@ -1101,3 +1102,28 @@ EqualizationLossConfig = collections.namedtuple('EqualizationLossConfig', ...@@ -1101,3 +1102,28 @@ EqualizationLossConfig = collections.namedtuple('EqualizationLossConfig',
['weight', 'exclude_prefixes']) ['weight', 'exclude_prefixes'])
def tile_context_tensors(tensor_dict):
"""Tiles context fields to have num_frames along 0-th dimension."""
num_frames = tf.shape(tensor_dict[fields.InputDataFields.image])[0]
for key in tensor_dict:
if key not in fields.SEQUENCE_FIELDS:
original_tensor = tensor_dict[key]
tensor_shape = shape_utils.combined_static_and_dynamic_shape(
original_tensor)
tensor_dict[key] = tf.tile(
tf.expand_dims(original_tensor, 0),
tf.stack([num_frames] + [1] * len(tensor_shape), axis=0))
return tensor_dict
def decode_image(tensor_dict):
"""Decodes images in a tensor dict."""
tensor_dict[fields.InputDataFields.image] = tf.io.decode_image(
tensor_dict[fields.InputDataFields.image], channels=3)
tensor_dict[fields.InputDataFields.image].set_shape([None, None, 3])
return tensor_dict
...@@ -21,80 +21,75 @@ from __future__ import print_function ...@@ -21,80 +21,75 @@ from __future__ import print_function
import numpy as np import numpy as np
import six import six
from six.moves import range from six.moves import range
import tensorflow as tf import tensorflow.compat.v1 as tf
import tf_slim as slim
from object_detection.core import standard_fields as fields from object_detection.core import standard_fields as fields
from object_detection.utils import ops from object_detection.utils import ops
from object_detection.utils import test_case from object_detection.utils import test_case
# pylint: disable=g-import-not-at-top
try:
from tensorflow.contrib import framework as contrib_framework
from tensorflow.contrib import slim
except ImportError:
# TF 2.0 doesn't ship with contrib.
pass
# pylint: enable=g-import-not-at-top
class NormalizedToImageCoordinatesTest(tf.test.TestCase): class NormalizedToImageCoordinatesTest(test_case.TestCase):
def test_normalized_to_image_coordinates(self): def test_normalized_to_image_coordinates(self):
normalized_boxes = tf.placeholder(tf.float32, shape=(None, 1, 4))
normalized_boxes_np = np.array([[[0.0, 0.0, 1.0, 1.0]], normalized_boxes_np = np.array([[[0.0, 0.0, 1.0, 1.0]],
[[0.5, 0.5, 1.0, 1.0]]]) [[0.5, 0.5, 1.0, 1.0]]])
image_shape = tf.convert_to_tensor([1, 4, 4, 3], dtype=tf.int32)
absolute_boxes = ops.normalized_to_image_coordinates(normalized_boxes, def graph_fn(normalized_boxes):
image_shape, image_shape = tf.convert_to_tensor([1, 4, 4, 3], dtype=tf.int32)
parallel_iterations=2) absolute_boxes = ops.normalized_to_image_coordinates(
normalized_boxes, image_shape, parallel_iterations=2)
return absolute_boxes
expected_boxes = np.array([[[0, 0, 4, 4]], expected_boxes = np.array([[[0, 0, 4, 4]],
[[2, 2, 4, 4]]]) [[2, 2, 4, 4]]])
with self.test_session() as sess:
absolute_boxes = sess.run(absolute_boxes,
feed_dict={normalized_boxes:
normalized_boxes_np})
absolute_boxes = self.execute(graph_fn, [normalized_boxes_np])
self.assertAllEqual(absolute_boxes, expected_boxes) self.assertAllEqual(absolute_boxes, expected_boxes)
class ReduceSumTrailingDimensions(tf.test.TestCase): class ReduceSumTrailingDimensions(test_case.TestCase):
def test_reduce_sum_trailing_dimensions(self): def test_reduce_sum_trailing_dimensions(self):
input_tensor = tf.placeholder(tf.float32, shape=[None, None, None])
reduced_tensor = ops.reduce_sum_trailing_dimensions(input_tensor, ndims=2) def graph_fn(input_tensor):
with self.test_session() as sess: reduced_tensor = ops.reduce_sum_trailing_dimensions(input_tensor, ndims=2)
reduced_np = sess.run(reduced_tensor, return reduced_tensor
feed_dict={input_tensor: np.ones((2, 2, 2),
np.float32)}) reduced_np = self.execute(graph_fn, [np.ones((2, 2, 2), np.float32)])
self.assertAllClose(reduced_np, 2 * np.ones((2, 2), np.float32)) self.assertAllClose(reduced_np, 2 * np.ones((2, 2), np.float32))
class MeshgridTest(tf.test.TestCase): class MeshgridTest(test_case.TestCase):
def test_meshgrid_numpy_comparison(self): def test_meshgrid_numpy_comparison(self):
"""Tests meshgrid op with vectors, for which it should match numpy.""" """Tests meshgrid op with vectors, for which it should match numpy."""
x = np.arange(4) x = np.arange(4)
y = np.arange(6) y = np.arange(6)
def graph_fn():
xgrid, ygrid = ops.meshgrid(x, y)
return xgrid, ygrid
exp_xgrid, exp_ygrid = np.meshgrid(x, y) exp_xgrid, exp_ygrid = np.meshgrid(x, y)
xgrid, ygrid = ops.meshgrid(x, y) xgrid_output, ygrid_output = self.execute(graph_fn, [])
with self.test_session() as sess: self.assertAllEqual(xgrid_output, exp_xgrid)
xgrid_output, ygrid_output = sess.run([xgrid, ygrid]) self.assertAllEqual(ygrid_output, exp_ygrid)
self.assertAllEqual(xgrid_output, exp_xgrid)
self.assertAllEqual(ygrid_output, exp_ygrid)
def test_meshgrid_multidimensional(self): def test_meshgrid_multidimensional(self):
np.random.seed(18) np.random.seed(18)
x = np.random.rand(4, 1, 2).astype(np.float32) x = np.random.rand(4, 1, 2).astype(np.float32)
y = np.random.rand(2, 3).astype(np.float32) y = np.random.rand(2, 3).astype(np.float32)
xgrid, ygrid = ops.meshgrid(x, y)
grid_shape = list(y.shape) + list(x.shape) grid_shape = list(y.shape) + list(x.shape)
self.assertEqual(xgrid.get_shape().as_list(), grid_shape)
self.assertEqual(ygrid.get_shape().as_list(), grid_shape) def graph_fn():
with self.test_session() as sess: xgrid, ygrid = ops.meshgrid(x, y)
xgrid_output, ygrid_output = sess.run([xgrid, ygrid]) self.assertEqual(xgrid.get_shape().as_list(), grid_shape)
self.assertEqual(ygrid.get_shape().as_list(), grid_shape)
return xgrid, ygrid
xgrid_output, ygrid_output = self.execute(graph_fn, [])
# Check the shape of the output grids # Check the shape of the output grids
self.assertEqual(xgrid_output.shape, tuple(grid_shape)) self.assertEqual(xgrid_output.shape, tuple(grid_shape))
...@@ -111,110 +106,150 @@ class MeshgridTest(tf.test.TestCase): ...@@ -111,110 +106,150 @@ class MeshgridTest(tf.test.TestCase):
self.assertEqual(ygrid_output[yind + xind], y[yind]) self.assertEqual(ygrid_output[yind + xind], y[yind])
class OpsTestFixedPadding(tf.test.TestCase): class OpsTestFixedPadding(test_case.TestCase):
def test_3x3_kernel(self): def test_3x3_kernel(self):
tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor = ops.fixed_padding(tensor, 3) def graph_fn():
with self.test_session() as sess: tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor_out = sess.run(padded_tensor) padded_tensor = ops.fixed_padding(tensor, 3)
return padded_tensor
padded_tensor_out = self.execute(graph_fn, [])
self.assertEqual((1, 4, 4, 1), padded_tensor_out.shape) self.assertEqual((1, 4, 4, 1), padded_tensor_out.shape)
def test_5x5_kernel(self): def test_5x5_kernel(self):
tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor = ops.fixed_padding(tensor, 5) def graph_fn():
with self.test_session() as sess: tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor_out = sess.run(padded_tensor) padded_tensor = ops.fixed_padding(tensor, 5)
return padded_tensor
padded_tensor_out = self.execute(graph_fn, [])
self.assertEqual((1, 6, 6, 1), padded_tensor_out.shape) self.assertEqual((1, 6, 6, 1), padded_tensor_out.shape)
def test_3x3_atrous_kernel(self): def test_3x3_atrous_kernel(self):
tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor = ops.fixed_padding(tensor, 3, 2) def graph_fn():
with self.test_session() as sess: tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor_out = sess.run(padded_tensor) padded_tensor = ops.fixed_padding(tensor, 3, 2)
return padded_tensor
padded_tensor_out = self.execute(graph_fn, [])
self.assertEqual((1, 6, 6, 1), padded_tensor_out.shape) self.assertEqual((1, 6, 6, 1), padded_tensor_out.shape)
class OpsTestPadToMultiple(tf.test.TestCase): class OpsTestPadToMultiple(test_case.TestCase):
def test_zero_padding(self): def test_zero_padding(self):
tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor = ops.pad_to_multiple(tensor, 1) def graph_fn():
with self.test_session() as sess: tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor_out = sess.run(padded_tensor) padded_tensor = ops.pad_to_multiple(tensor, 1)
return padded_tensor
padded_tensor_out = self.execute(graph_fn, [])
self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape) self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape)
def test_no_padding(self): def test_no_padding(self):
tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor = ops.pad_to_multiple(tensor, 2) def graph_fn():
with self.test_session() as sess: tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor_out = sess.run(padded_tensor) padded_tensor = ops.pad_to_multiple(tensor, 2)
return padded_tensor
padded_tensor_out = self.execute(graph_fn, [])
self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape) self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape)
def test_non_square_padding(self): def test_non_square_padding(self):
tensor = tf.constant([[[[0.], [0.]]]])
padded_tensor = ops.pad_to_multiple(tensor, 2) def graph_fn():
with self.test_session() as sess: tensor = tf.constant([[[[0.], [0.]]]])
padded_tensor_out = sess.run(padded_tensor) padded_tensor = ops.pad_to_multiple(tensor, 2)
return padded_tensor
padded_tensor_out = self.execute(graph_fn, [])
self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape) self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape)
def test_padding(self): def test_padding(self):
tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor = ops.pad_to_multiple(tensor, 4) def graph_fn():
with self.test_session() as sess: tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]])
padded_tensor_out = sess.run(padded_tensor) padded_tensor = ops.pad_to_multiple(tensor, 4)
return padded_tensor
padded_tensor_out = self.execute(graph_fn, [])
self.assertEqual((1, 4, 4, 1), padded_tensor_out.shape) self.assertEqual((1, 4, 4, 1), padded_tensor_out.shape)
class OpsTestPaddedOneHotEncoding(tf.test.TestCase): class OpsTestPaddedOneHotEncoding(test_case.TestCase):
def test_correct_one_hot_tensor_with_no_pad(self): def test_correct_one_hot_tensor_with_no_pad(self):
indices = tf.constant([1, 2, 3, 5])
one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=0) def graph_fn():
indices = tf.constant([1, 2, 3, 5])
one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=0)
return one_hot_tensor
expected_tensor = np.array([[0, 1, 0, 0, 0, 0], expected_tensor = np.array([[0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 1]], np.float32) [0, 0, 0, 0, 0, 1]], np.float32)
with self.test_session() as sess:
out_one_hot_tensor = sess.run(one_hot_tensor) # Executing on CPU only because output shape is not constant.
self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, out_one_hot_tensor = self.execute_cpu(graph_fn, [])
atol=1e-10) self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10,
atol=1e-10)
def test_correct_one_hot_tensor_with_pad_one(self): def test_correct_one_hot_tensor_with_pad_one(self):
indices = tf.constant([1, 2, 3, 5])
one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=1) def graph_fn():
indices = tf.constant([1, 2, 3, 5])
one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=1)
return one_hot_tensor
expected_tensor = np.array([[0, 0, 1, 0, 0, 0, 0], expected_tensor = np.array([[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1]], np.float32) [0, 0, 0, 0, 0, 0, 1]], np.float32)
with self.test_session() as sess: # Executing on CPU only because output shape is not constant.
out_one_hot_tensor = sess.run(one_hot_tensor) out_one_hot_tensor = self.execute_cpu(graph_fn, [])
self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10,
atol=1e-10) atol=1e-10)
def test_correct_one_hot_tensor_with_pad_three(self): def test_correct_one_hot_tensor_with_pad_three(self):
indices = tf.constant([1, 2, 3, 5])
one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=3) def graph_fn():
indices = tf.constant([1, 2, 3, 5])
one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=3)
return one_hot_tensor
expected_tensor = np.array([[0, 0, 0, 0, 1, 0, 0, 0, 0], expected_tensor = np.array([[0, 0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 1]], np.float32) [0, 0, 0, 0, 0, 0, 0, 0, 1]], np.float32)
with self.test_session() as sess:
out_one_hot_tensor = sess.run(one_hot_tensor) # executing on CPU only because output shape is not constant.
self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, out_one_hot_tensor = self.execute_cpu(graph_fn, [])
atol=1e-10) self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10,
atol=1e-10)
def test_correct_padded_one_hot_tensor_with_empty_indices(self): def test_correct_padded_one_hot_tensor_with_empty_indices(self):
depth = 6 depth = 6
pad = 2 pad = 2
indices = tf.constant([])
one_hot_tensor = ops.padded_one_hot_encoding( def graph_fn():
indices, depth=depth, left_pad=pad) indices = tf.constant([])
one_hot_tensor = ops.padded_one_hot_encoding(
indices, depth=depth, left_pad=pad)
return one_hot_tensor
expected_tensor = np.zeros((0, depth + pad)) expected_tensor = np.zeros((0, depth + pad))
with self.test_session() as sess: # executing on CPU only because output shape is not constant.
out_one_hot_tensor = sess.run(one_hot_tensor) out_one_hot_tensor = self.execute_cpu(graph_fn, [])
self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10,
atol=1e-10) atol=1e-10)
def test_return_none_on_zero_depth(self): def test_return_none_on_zero_depth(self):
indices = tf.constant([1, 2, 3, 4, 5]) indices = tf.constant([1, 2, 3, 4, 5])
...@@ -242,28 +277,27 @@ class OpsTestPaddedOneHotEncoding(tf.test.TestCase): ...@@ -242,28 +277,27 @@ class OpsTestPaddedOneHotEncoding(tf.test.TestCase):
ops.padded_one_hot_encoding(indices, depth=0.1, left_pad=2) ops.padded_one_hot_encoding(indices, depth=0.1, left_pad=2)
class OpsDenseToSparseBoxesTest(tf.test.TestCase): class OpsDenseToSparseBoxesTest(test_case.TestCase):
def test_return_all_boxes_when_all_input_boxes_are_valid(self): def test_return_all_boxes_when_all_input_boxes_are_valid(self):
num_classes = 4 num_classes = 4
num_valid_boxes = 3 num_valid_boxes = 3
code_size = 4 code_size = 4
dense_location_placeholder = tf.placeholder(tf.float32,
shape=(num_valid_boxes, def graph_fn(dense_location, dense_num_boxes):
code_size)) box_locations, box_classes = ops.dense_to_sparse_boxes(
dense_num_boxes_placeholder = tf.placeholder(tf.int32, shape=(num_classes)) dense_location, dense_num_boxes, num_classes)
box_locations, box_classes = ops.dense_to_sparse_boxes( return box_locations, box_classes
dense_location_placeholder, dense_num_boxes_placeholder, num_classes)
feed_dict = {dense_location_placeholder: np.random.uniform( dense_location_np = np.random.uniform(size=[num_valid_boxes, code_size])
size=[num_valid_boxes, code_size]), dense_num_boxes_np = np.array([1, 0, 0, 2], dtype=np.int32)
dense_num_boxes_placeholder: np.array([1, 0, 0, 2],
dtype=np.int32)} expected_box_locations = dense_location_np
expected_box_locations = feed_dict[dense_location_placeholder]
expected_box_classses = np.array([0, 3, 3]) expected_box_classses = np.array([0, 3, 3])
with self.test_session() as sess:
box_locations, box_classes = sess.run([box_locations, box_classes], # Executing on CPU only since output shape is not constant.
feed_dict=feed_dict) box_locations, box_classes = self.execute_cpu(
graph_fn, [dense_location_np, dense_num_boxes_np])
self.assertAllClose(box_locations, expected_box_locations, rtol=1e-6, self.assertAllClose(box_locations, expected_box_locations, rtol=1e-6,
atol=1e-6) atol=1e-6)
...@@ -275,29 +309,27 @@ class OpsDenseToSparseBoxesTest(tf.test.TestCase): ...@@ -275,29 +309,27 @@ class OpsDenseToSparseBoxesTest(tf.test.TestCase):
num_boxes = 10 num_boxes = 10
code_size = 4 code_size = 4
dense_location_placeholder = tf.placeholder(tf.float32, shape=(num_boxes, def graph_fn(dense_location, dense_num_boxes):
code_size)) box_locations, box_classes = ops.dense_to_sparse_boxes(
dense_num_boxes_placeholder = tf.placeholder(tf.int32, shape=(num_classes)) dense_location, dense_num_boxes, num_classes)
box_locations, box_classes = ops.dense_to_sparse_boxes( return box_locations, box_classes
dense_location_placeholder, dense_num_boxes_placeholder, num_classes)
feed_dict = {dense_location_placeholder: np.random.uniform( dense_location_np = np.random.uniform(size=[num_boxes, code_size])
size=[num_boxes, code_size]), dense_num_boxes_np = np.array([1, 0, 0, 2], dtype=np.int32)
dense_num_boxes_placeholder: np.array([1, 0, 0, 2],
dtype=np.int32)} expected_box_locations = dense_location_np[:num_valid_boxes]
expected_box_locations = (feed_dict[dense_location_placeholder]
[:num_valid_boxes])
expected_box_classses = np.array([0, 3, 3]) expected_box_classses = np.array([0, 3, 3])
with self.test_session() as sess:
box_locations, box_classes = sess.run([box_locations, box_classes], # Executing on CPU only since output shape is not constant.
feed_dict=feed_dict) box_locations, box_classes = self.execute_cpu(
graph_fn, [dense_location_np, dense_num_boxes_np])
self.assertAllClose(box_locations, expected_box_locations, rtol=1e-6, self.assertAllClose(box_locations, expected_box_locations, rtol=1e-6,
atol=1e-6) atol=1e-6)
self.assertAllEqual(box_classes, expected_box_classses) self.assertAllEqual(box_classes, expected_box_classses)
class OpsTestIndicesToDenseVector(tf.test.TestCase): class OpsTestIndicesToDenseVector(test_case.TestCase):
def test_indices_to_dense_vector(self): def test_indices_to_dense_vector(self):
size = 10000 size = 10000
...@@ -307,13 +339,14 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase): ...@@ -307,13 +339,14 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase):
expected_output = np.zeros(size, dtype=np.float32) expected_output = np.zeros(size, dtype=np.float32)
expected_output[rand_indices] = 1. expected_output[rand_indices] = 1.
tf_rand_indices = tf.constant(rand_indices) def graph_fn():
indicator = ops.indices_to_dense_vector(tf_rand_indices, size) tf_rand_indices = tf.constant(rand_indices)
indicator = ops.indices_to_dense_vector(tf_rand_indices, size)
return indicator
with self.test_session() as sess: output = self.execute(graph_fn, [])
output = sess.run(indicator) self.assertAllEqual(output, expected_output)
self.assertAllEqual(output, expected_output) self.assertEqual(output.dtype, expected_output.dtype)
self.assertEqual(output.dtype, expected_output.dtype)
def test_indices_to_dense_vector_size_at_inference(self): def test_indices_to_dense_vector_size_at_inference(self):
size = 5000 size = 5000
...@@ -324,16 +357,15 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase): ...@@ -324,16 +357,15 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase):
expected_output = np.zeros(size, dtype=np.float32) expected_output = np.zeros(size, dtype=np.float32)
expected_output[rand_indices] = 1. expected_output[rand_indices] = 1.
tf_all_indices = tf.placeholder(tf.int32) def graph_fn(tf_all_indices):
tf_rand_indices = tf.constant(rand_indices) tf_rand_indices = tf.constant(rand_indices)
indicator = ops.indices_to_dense_vector(tf_rand_indices, indicator = ops.indices_to_dense_vector(tf_rand_indices,
tf.shape(tf_all_indices)[0]) tf.shape(tf_all_indices)[0])
feed_dict = {tf_all_indices: all_indices} return indicator
with self.test_session() as sess: output = self.execute(graph_fn, [all_indices])
output = sess.run(indicator, feed_dict=feed_dict) self.assertAllEqual(output, expected_output)
self.assertAllEqual(output, expected_output) self.assertEqual(output.dtype, expected_output.dtype)
self.assertEqual(output.dtype, expected_output.dtype)
def test_indices_to_dense_vector_int(self): def test_indices_to_dense_vector_int(self):
size = 500 size = 500
...@@ -343,14 +375,15 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase): ...@@ -343,14 +375,15 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase):
expected_output = np.zeros(size, dtype=np.int64) expected_output = np.zeros(size, dtype=np.int64)
expected_output[rand_indices] = 1 expected_output[rand_indices] = 1
tf_rand_indices = tf.constant(rand_indices) def graph_fn():
indicator = ops.indices_to_dense_vector( tf_rand_indices = tf.constant(rand_indices)
tf_rand_indices, size, 1, dtype=tf.int64) indicator = ops.indices_to_dense_vector(
tf_rand_indices, size, 1, dtype=tf.int64)
return indicator
with self.test_session() as sess: output = self.execute(graph_fn, [])
output = sess.run(indicator) self.assertAllEqual(output, expected_output)
self.assertAllEqual(output, expected_output) self.assertEqual(output.dtype, expected_output.dtype)
self.assertEqual(output.dtype, expected_output.dtype)
def test_indices_to_dense_vector_custom_values(self): def test_indices_to_dense_vector_custom_values(self):
size = 100 size = 100
...@@ -362,17 +395,18 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase): ...@@ -362,17 +395,18 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase):
expected_output = np.float32(np.ones(size) * default_value) expected_output = np.float32(np.ones(size) * default_value)
expected_output[rand_indices] = indices_value expected_output[rand_indices] = indices_value
tf_rand_indices = tf.constant(rand_indices) def graph_fn():
indicator = ops.indices_to_dense_vector( tf_rand_indices = tf.constant(rand_indices)
tf_rand_indices, indicator = ops.indices_to_dense_vector(
size, tf_rand_indices,
indices_value=indices_value, size,
default_value=default_value) indices_value=indices_value,
default_value=default_value)
return indicator
with self.test_session() as sess: output = self.execute(graph_fn, [])
output = sess.run(indicator) self.assertAllClose(output, expected_output)
self.assertAllClose(output, expected_output) self.assertEqual(output.dtype, expected_output.dtype)
self.assertEqual(output.dtype, expected_output.dtype)
def test_indices_to_dense_vector_all_indices_as_input(self): def test_indices_to_dense_vector_all_indices_as_input(self):
size = 500 size = 500
...@@ -381,13 +415,14 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase): ...@@ -381,13 +415,14 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase):
expected_output = np.ones(size, dtype=np.float32) expected_output = np.ones(size, dtype=np.float32)
tf_rand_indices = tf.constant(rand_indices) def graph_fn():
indicator = ops.indices_to_dense_vector(tf_rand_indices, size) tf_rand_indices = tf.constant(rand_indices)
indicator = ops.indices_to_dense_vector(tf_rand_indices, size)
return indicator
with self.test_session() as sess: output = self.execute(graph_fn, [])
output = sess.run(indicator) self.assertAllEqual(output, expected_output)
self.assertAllEqual(output, expected_output) self.assertEqual(output.dtype, expected_output.dtype)
self.assertEqual(output.dtype, expected_output.dtype)
def test_indices_to_dense_vector_empty_indices_as_input(self): def test_indices_to_dense_vector_empty_indices_as_input(self):
size = 500 size = 500
...@@ -395,55 +430,58 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase): ...@@ -395,55 +430,58 @@ class OpsTestIndicesToDenseVector(tf.test.TestCase):
expected_output = np.zeros(size, dtype=np.float32) expected_output = np.zeros(size, dtype=np.float32)
tf_rand_indices = tf.constant(rand_indices) def graph_fn():
indicator = ops.indices_to_dense_vector(tf_rand_indices, size) tf_rand_indices = tf.constant(rand_indices)
indicator = ops.indices_to_dense_vector(tf_rand_indices, size)
return indicator
with self.test_session() as sess: output = self.execute(graph_fn, [])
output = sess.run(indicator) self.assertAllEqual(output, expected_output)
self.assertAllEqual(output, expected_output) self.assertEqual(output.dtype, expected_output.dtype)
self.assertEqual(output.dtype, expected_output.dtype)
class GroundtruthFilterTest(tf.test.TestCase): class GroundtruthFilterTest(test_case.TestCase):
def test_filter_groundtruth(self): def test_filter_groundtruth(self):
input_image = tf.placeholder(tf.float32, shape=(None, None, 3))
input_boxes = tf.placeholder(tf.float32, shape=(None, 4)) def graph_fn(input_image, input_boxes, input_classes, input_is_crowd,
input_classes = tf.placeholder(tf.int32, shape=(None,)) input_area, input_difficult, input_label_types,
input_is_crowd = tf.placeholder(tf.bool, shape=(None,)) input_confidences, valid_indices):
input_area = tf.placeholder(tf.float32, shape=(None,)) input_tensors = {
input_difficult = tf.placeholder(tf.float32, shape=(None,)) fields.InputDataFields.image: input_image,
input_label_types = tf.placeholder(tf.string, shape=(None,)) fields.InputDataFields.groundtruth_boxes: input_boxes,
input_confidences = tf.placeholder(tf.float32, shape=(None,)) fields.InputDataFields.groundtruth_classes: input_classes,
valid_indices = tf.placeholder(tf.int32, shape=(None,)) fields.InputDataFields.groundtruth_is_crowd: input_is_crowd,
input_tensors = { fields.InputDataFields.groundtruth_area: input_area,
fields.InputDataFields.image: input_image, fields.InputDataFields.groundtruth_difficult: input_difficult,
fields.InputDataFields.groundtruth_boxes: input_boxes, fields.InputDataFields.groundtruth_label_types: input_label_types,
fields.InputDataFields.groundtruth_classes: input_classes, fields.InputDataFields.groundtruth_confidences: input_confidences,
fields.InputDataFields.groundtruth_is_crowd: input_is_crowd, }
fields.InputDataFields.groundtruth_area: input_area,
fields.InputDataFields.groundtruth_difficult: input_difficult, output_tensors = ops.retain_groundtruth(input_tensors, valid_indices)
fields.InputDataFields.groundtruth_label_types: input_label_types, return output_tensors
fields.InputDataFields.groundtruth_confidences: input_confidences,
} input_image = np.random.rand(224, 224, 3)
output_tensors = ops.retain_groundtruth(input_tensors, valid_indices) input_boxes = np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]],
dtype=np.float32)
image_tensor = np.random.rand(224, 224, 3) input_classes = np.array([1, 2], dtype=np.int32)
feed_dict = { input_is_crowd = np.array([False, True], dtype=np.bool)
input_image: image_tensor, input_area = np.array([32, 48], dtype=np.float32)
input_boxes: input_difficult = np.array([True, False], dtype=np.bool)
np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float), input_label_types = np.array(['APPROPRIATE', 'INCORRECT'],
input_classes: np.array([1, 2], dtype=np.int32), dtype=np.string_)
input_is_crowd: np.array([False, True], dtype=np.bool), input_confidences = np.array([0.99, 0.5], dtype=np.float32)
input_area: np.array([32, 48], dtype=np.float32), valid_indices = np.array([0], dtype=np.int32)
input_difficult: np.array([True, False], dtype=np.bool),
input_label_types: # Strings are not supported on TPU.
np.array(['APPROPRIATE', 'INCORRECT'], dtype=np.string_), output_tensors = self.execute_cpu(
input_confidences: np.array([0.99, 0.5], dtype=np.float32), graph_fn,
valid_indices: np.array([0], dtype=np.int32), [input_image, input_boxes, input_classes, input_is_crowd, input_area,
} input_difficult, input_label_types, input_confidences, valid_indices]
)
expected_tensors = { expected_tensors = {
fields.InputDataFields.image: image_tensor, fields.InputDataFields.image: input_image,
fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]],
fields.InputDataFields.groundtruth_classes: [1], fields.InputDataFields.groundtruth_classes: [1],
fields.InputDataFields.groundtruth_is_crowd: [False], fields.InputDataFields.groundtruth_is_crowd: [False],
...@@ -452,35 +490,24 @@ class GroundtruthFilterTest(tf.test.TestCase): ...@@ -452,35 +490,24 @@ class GroundtruthFilterTest(tf.test.TestCase):
fields.InputDataFields.groundtruth_label_types: [six.b('APPROPRIATE')], fields.InputDataFields.groundtruth_label_types: [six.b('APPROPRIATE')],
fields.InputDataFields.groundtruth_confidences: [0.99], fields.InputDataFields.groundtruth_confidences: [0.99],
} }
with self.test_session() as sess: for key in [fields.InputDataFields.image,
output_tensors = sess.run(output_tensors, feed_dict=feed_dict) fields.InputDataFields.groundtruth_boxes,
for key in [fields.InputDataFields.image, fields.InputDataFields.groundtruth_area,
fields.InputDataFields.groundtruth_boxes, fields.InputDataFields.groundtruth_confidences]:
fields.InputDataFields.groundtruth_area, self.assertAllClose(expected_tensors[key], output_tensors[key])
fields.InputDataFields.groundtruth_confidences]:
self.assertAllClose(expected_tensors[key], output_tensors[key]) for key in [fields.InputDataFields.groundtruth_classes,
for key in [fields.InputDataFields.groundtruth_classes, fields.InputDataFields.groundtruth_is_crowd,
fields.InputDataFields.groundtruth_is_crowd, fields.InputDataFields.groundtruth_label_types]:
fields.InputDataFields.groundtruth_label_types]: self.assertAllEqual(expected_tensors[key], output_tensors[key])
self.assertAllEqual(expected_tensors[key], output_tensors[key])
def test_filter_with_missing_fields(self): def test_filter_with_missing_fields(self):
input_boxes = tf.placeholder(tf.float32, shape=(None, 4))
input_classes = tf.placeholder(tf.int32, shape=(None,)) input_boxes = np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]],
input_tensors = { dtype=np.float)
fields.InputDataFields.groundtruth_boxes: input_boxes, input_classes = np.array([1, 2], dtype=np.int32)
fields.InputDataFields.groundtruth_classes: input_classes valid_indices = np.array([0], dtype=np.int32)
}
valid_indices = tf.placeholder(tf.int32, shape=(None,))
feed_dict = {
input_boxes:
np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float),
input_classes:
np.array([1, 2], dtype=np.int32),
valid_indices:
np.array([0], dtype=np.int32)
}
expected_tensors = { expected_tensors = {
fields.InputDataFields.groundtruth_boxes: fields.InputDataFields.groundtruth_boxes:
[[0.2, 0.4, 0.1, 0.8]], [[0.2, 0.4, 0.1, 0.8]],
...@@ -488,42 +515,46 @@ class GroundtruthFilterTest(tf.test.TestCase): ...@@ -488,42 +515,46 @@ class GroundtruthFilterTest(tf.test.TestCase):
[1] [1]
} }
output_tensors = ops.retain_groundtruth(input_tensors, valid_indices) def graph_fn(input_boxes, input_classes, valid_indices):
with self.test_session() as sess: input_tensors = {
output_tensors = sess.run(output_tensors, feed_dict=feed_dict) fields.InputDataFields.groundtruth_boxes: input_boxes,
for key in [fields.InputDataFields.groundtruth_boxes]: fields.InputDataFields.groundtruth_classes: input_classes
self.assertAllClose(expected_tensors[key], output_tensors[key]) }
for key in [fields.InputDataFields.groundtruth_classes]: output_tensors = ops.retain_groundtruth(input_tensors, valid_indices)
self.assertAllEqual(expected_tensors[key], output_tensors[key]) return output_tensors
output_tensors = self.execute(graph_fn, [input_boxes, input_classes,
valid_indices])
for key in [fields.InputDataFields.groundtruth_boxes]:
self.assertAllClose(expected_tensors[key], output_tensors[key])
for key in [fields.InputDataFields.groundtruth_classes]:
self.assertAllEqual(expected_tensors[key], output_tensors[key])
def test_filter_with_empty_fields(self): def test_filter_with_empty_fields(self):
input_boxes = tf.placeholder(tf.float32, shape=(None, 4))
input_classes = tf.placeholder(tf.int32, shape=(None,)) def graph_fn(input_boxes, input_classes, input_is_crowd, input_area,
input_is_crowd = tf.placeholder(tf.bool, shape=(None,)) input_difficult, input_confidences, valid_indices):
input_area = tf.placeholder(tf.float32, shape=(None,)) input_tensors = {
input_difficult = tf.placeholder(tf.float32, shape=(None,)) fields.InputDataFields.groundtruth_boxes: input_boxes,
input_confidences = tf.placeholder(tf.float32, shape=(None,)) fields.InputDataFields.groundtruth_classes: input_classes,
valid_indices = tf.placeholder(tf.int32, shape=(None,)) fields.InputDataFields.groundtruth_is_crowd: input_is_crowd,
input_tensors = { fields.InputDataFields.groundtruth_area: input_area,
fields.InputDataFields.groundtruth_boxes: input_boxes, fields.InputDataFields.groundtruth_difficult: input_difficult,
fields.InputDataFields.groundtruth_classes: input_classes, fields.InputDataFields.groundtruth_confidences: input_confidences,
fields.InputDataFields.groundtruth_is_crowd: input_is_crowd, }
fields.InputDataFields.groundtruth_area: input_area, output_tensors = ops.retain_groundtruth(input_tensors, valid_indices)
fields.InputDataFields.groundtruth_difficult: input_difficult, return output_tensors
fields.InputDataFields.groundtruth_confidences: input_confidences,
} input_boxes = np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]],
output_tensors = ops.retain_groundtruth(input_tensors, valid_indices) dtype=np.float)
input_classes = np.array([1, 2], dtype=np.int32)
feed_dict = { input_is_crowd = np.array([False, True], dtype=np.bool)
input_boxes: input_area = np.array([], dtype=np.float32)
np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float), input_difficult = np.array([], dtype=np.float32)
input_classes: np.array([1, 2], dtype=np.int32), input_confidences = np.array([0.99, 0.5], dtype=np.float32)
input_is_crowd: np.array([False, True], dtype=np.bool), valid_indices = np.array([0], dtype=np.int32)
input_area: np.array([], dtype=np.float32),
input_difficult: np.array([], dtype=np.float32),
input_confidences: np.array([0.99, 0.5], dtype=np.float32),
valid_indices: np.array([0], dtype=np.int32)
}
expected_tensors = { expected_tensors = {
fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]],
fields.InputDataFields.groundtruth_classes: [1], fields.InputDataFields.groundtruth_classes: [1],
...@@ -532,92 +563,87 @@ class GroundtruthFilterTest(tf.test.TestCase): ...@@ -532,92 +563,87 @@ class GroundtruthFilterTest(tf.test.TestCase):
fields.InputDataFields.groundtruth_difficult: [], fields.InputDataFields.groundtruth_difficult: [],
fields.InputDataFields.groundtruth_confidences: [0.99], fields.InputDataFields.groundtruth_confidences: [0.99],
} }
with self.test_session() as sess: output_tensors = self.execute(graph_fn, [
output_tensors = sess.run(output_tensors, feed_dict=feed_dict) input_boxes, input_classes, input_is_crowd, input_area,
for key in [fields.InputDataFields.groundtruth_boxes, input_difficult, input_confidences, valid_indices])
fields.InputDataFields.groundtruth_area,
fields.InputDataFields.groundtruth_confidences]: for key in [fields.InputDataFields.groundtruth_boxes,
self.assertAllClose(expected_tensors[key], output_tensors[key]) fields.InputDataFields.groundtruth_area,
for key in [fields.InputDataFields.groundtruth_classes, fields.InputDataFields.groundtruth_confidences]:
fields.InputDataFields.groundtruth_is_crowd]: self.assertAllClose(expected_tensors[key], output_tensors[key])
self.assertAllEqual(expected_tensors[key], output_tensors[key]) for key in [fields.InputDataFields.groundtruth_classes,
fields.InputDataFields.groundtruth_is_crowd]:
self.assertAllEqual(expected_tensors[key], output_tensors[key])
def test_filter_with_empty_groundtruth_boxes(self): def test_filter_with_empty_groundtruth_boxes(self):
input_boxes = tf.placeholder(tf.float32, shape=(None, 4))
input_classes = tf.placeholder(tf.int32, shape=(None,))
input_is_crowd = tf.placeholder(tf.bool, shape=(None,))
input_area = tf.placeholder(tf.float32, shape=(None,))
input_difficult = tf.placeholder(tf.float32, shape=(None,))
input_confidences = tf.placeholder(tf.float32, shape=(None,))
valid_indices = tf.placeholder(tf.int32, shape=(None,))
input_tensors = {
fields.InputDataFields.groundtruth_boxes: input_boxes,
fields.InputDataFields.groundtruth_classes: input_classes,
fields.InputDataFields.groundtruth_is_crowd: input_is_crowd,
fields.InputDataFields.groundtruth_area: input_area,
fields.InputDataFields.groundtruth_difficult: input_difficult,
fields.InputDataFields.groundtruth_confidences: input_confidences,
}
output_tensors = ops.retain_groundtruth(input_tensors, valid_indices)
feed_dict = {
input_boxes: np.array([], dtype=np.float).reshape(0, 4),
input_classes: np.array([], dtype=np.int32),
input_is_crowd: np.array([], dtype=np.bool),
input_area: np.array([], dtype=np.float32),
input_difficult: np.array([], dtype=np.float32),
input_confidences: np.array([], dtype=np.float32),
valid_indices: np.array([], dtype=np.int32),
}
with self.test_session() as sess:
output_tensors = sess.run(output_tensors, feed_dict=feed_dict)
for key in input_tensors:
if key == fields.InputDataFields.groundtruth_boxes:
self.assertAllEqual([0, 4], output_tensors[key].shape)
else:
self.assertAllEqual([0], output_tensors[key].shape)
class RetainGroundTruthWithPositiveClasses(tf.test.TestCase): def graph_fn(input_boxes, input_classes, input_is_crowd, input_area,
input_difficult, input_confidences, valid_indices):
input_tensors = {
fields.InputDataFields.groundtruth_boxes: input_boxes,
fields.InputDataFields.groundtruth_classes: input_classes,
fields.InputDataFields.groundtruth_is_crowd: input_is_crowd,
fields.InputDataFields.groundtruth_area: input_area,
fields.InputDataFields.groundtruth_difficult: input_difficult,
fields.InputDataFields.groundtruth_confidences: input_confidences,
}
output_tensors = ops.retain_groundtruth(input_tensors, valid_indices)
return output_tensors
input_boxes = np.array([], dtype=np.float).reshape(0, 4)
input_classes = np.array([], dtype=np.int32)
input_is_crowd = np.array([], dtype=np.bool)
input_area = np.array([], dtype=np.float32)
input_difficult = np.array([], dtype=np.float32)
input_confidences = np.array([], dtype=np.float32)
valid_indices = np.array([], dtype=np.int32)
output_tensors = self.execute(graph_fn, [input_boxes, input_classes,
input_is_crowd, input_area,
input_difficult,
input_confidences,
valid_indices])
for key in output_tensors:
if key == fields.InputDataFields.groundtruth_boxes:
self.assertAllEqual([0, 4], output_tensors[key].shape)
else:
self.assertAllEqual([0], output_tensors[key].shape)
class RetainGroundTruthWithPositiveClasses(test_case.TestCase):
def test_filter_groundtruth_with_positive_classes(self): def test_filter_groundtruth_with_positive_classes(self):
input_image = tf.placeholder(tf.float32, shape=(None, None, 3))
input_boxes = tf.placeholder(tf.float32, shape=(None, 4)) def graph_fn(input_image, input_boxes, input_classes, input_is_crowd,
input_classes = tf.placeholder(tf.int32, shape=(None,)) input_area, input_difficult, input_label_types,
input_is_crowd = tf.placeholder(tf.bool, shape=(None,)) input_confidences):
input_area = tf.placeholder(tf.float32, shape=(None,)) input_tensors = {
input_difficult = tf.placeholder(tf.float32, shape=(None,)) fields.InputDataFields.image: input_image,
input_label_types = tf.placeholder(tf.string, shape=(None,)) fields.InputDataFields.groundtruth_boxes: input_boxes,
input_confidences = tf.placeholder(tf.float32, shape=(None,)) fields.InputDataFields.groundtruth_classes: input_classes,
valid_indices = tf.placeholder(tf.int32, shape=(None,)) fields.InputDataFields.groundtruth_is_crowd: input_is_crowd,
input_tensors = { fields.InputDataFields.groundtruth_area: input_area,
fields.InputDataFields.image: input_image, fields.InputDataFields.groundtruth_difficult: input_difficult,
fields.InputDataFields.groundtruth_boxes: input_boxes, fields.InputDataFields.groundtruth_label_types: input_label_types,
fields.InputDataFields.groundtruth_classes: input_classes, fields.InputDataFields.groundtruth_confidences: input_confidences,
fields.InputDataFields.groundtruth_is_crowd: input_is_crowd, }
fields.InputDataFields.groundtruth_area: input_area, output_tensors = ops.retain_groundtruth_with_positive_classes(
fields.InputDataFields.groundtruth_difficult: input_difficult, input_tensors)
fields.InputDataFields.groundtruth_label_types: input_label_types, return output_tensors
fields.InputDataFields.groundtruth_confidences: input_confidences,
} input_image = np.random.rand(224, 224, 3)
output_tensors = ops.retain_groundtruth_with_positive_classes(input_tensors) input_boxes = np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]],
dtype=np.float)
image_tensor = np.random.rand(224, 224, 3) input_classes = np.array([1, 0], dtype=np.int32)
feed_dict = { input_is_crowd = np.array([False, True], dtype=np.bool)
input_image: image_tensor, input_area = np.array([32, 48], dtype=np.float32)
input_boxes: input_difficult = np.array([True, False], dtype=np.bool)
np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float), input_label_types = np.array(['APPROPRIATE', 'INCORRECT'],
input_classes: np.array([1, 0], dtype=np.int32), dtype=np.string_)
input_is_crowd: np.array([False, True], dtype=np.bool), input_confidences = np.array([0.99, 0.5], dtype=np.float32)
input_area: np.array([32, 48], dtype=np.float32),
input_difficult: np.array([True, False], dtype=np.bool),
input_label_types:
np.array(['APPROPRIATE', 'INCORRECT'], dtype=np.string_),
input_confidences: np.array([0.99, 0.5], dtype=np.float32),
valid_indices: np.array([0], dtype=np.int32),
}
expected_tensors = { expected_tensors = {
fields.InputDataFields.image: image_tensor, fields.InputDataFields.image: input_image,
fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]],
fields.InputDataFields.groundtruth_classes: [1], fields.InputDataFields.groundtruth_classes: [1],
fields.InputDataFields.groundtruth_is_crowd: [False], fields.InputDataFields.groundtruth_is_crowd: [False],
...@@ -626,51 +652,70 @@ class RetainGroundTruthWithPositiveClasses(tf.test.TestCase): ...@@ -626,51 +652,70 @@ class RetainGroundTruthWithPositiveClasses(tf.test.TestCase):
fields.InputDataFields.groundtruth_label_types: [six.b('APPROPRIATE')], fields.InputDataFields.groundtruth_label_types: [six.b('APPROPRIATE')],
fields.InputDataFields.groundtruth_confidences: [0.99], fields.InputDataFields.groundtruth_confidences: [0.99],
} }
with self.test_session() as sess:
output_tensors = sess.run(output_tensors, feed_dict=feed_dict)
for key in [fields.InputDataFields.image,
fields.InputDataFields.groundtruth_boxes,
fields.InputDataFields.groundtruth_area,
fields.InputDataFields.groundtruth_confidences]:
self.assertAllClose(expected_tensors[key], output_tensors[key])
for key in [fields.InputDataFields.groundtruth_classes,
fields.InputDataFields.groundtruth_is_crowd,
fields.InputDataFields.groundtruth_label_types]:
self.assertAllEqual(expected_tensors[key], output_tensors[key])
# Executing on CPU because string types are not supported on TPU.
output_tensors = self.execute_cpu(graph_fn,
[input_image, input_boxes,
input_classes, input_is_crowd,
input_area,
input_difficult, input_label_types,
input_confidences])
class ReplaceNaNGroundtruthLabelScoresWithOnes(tf.test.TestCase): for key in [fields.InputDataFields.image,
fields.InputDataFields.groundtruth_boxes,
fields.InputDataFields.groundtruth_area,
fields.InputDataFields.groundtruth_confidences]:
self.assertAllClose(expected_tensors[key], output_tensors[key])
for key in [fields.InputDataFields.groundtruth_classes,
fields.InputDataFields.groundtruth_is_crowd,
fields.InputDataFields.groundtruth_label_types]:
self.assertAllEqual(expected_tensors[key], output_tensors[key])
class ReplaceNaNGroundtruthLabelScoresWithOnes(test_case.TestCase):
def test_replace_nan_groundtruth_label_scores_with_ones(self): def test_replace_nan_groundtruth_label_scores_with_ones(self):
label_scores = tf.constant([np.nan, 1.0, np.nan])
output_tensor = ops.replace_nan_groundtruth_label_scores_with_ones( def graph_fn():
label_scores) label_scores = tf.constant([np.nan, 1.0, np.nan])
output_tensor = ops.replace_nan_groundtruth_label_scores_with_ones(
label_scores)
return output_tensor
expected_tensor = [1.0, 1.0, 1.0] expected_tensor = [1.0, 1.0, 1.0]
with self.test_session(): output_tensor = self.execute(graph_fn, [])
output_tensor = output_tensor.eval() self.assertAllClose(expected_tensor, output_tensor)
self.assertAllClose(expected_tensor, output_tensor)
def test_input_equals_output_when_no_nans(self): def test_input_equals_output_when_no_nans(self):
input_label_scores = [0.5, 1.0, 1.0] input_label_scores = [0.5, 1.0, 1.0]
label_scores_tensor = tf.constant(input_label_scores) def graph_fn():
output_label_scores = ops.replace_nan_groundtruth_label_scores_with_ones( label_scores_tensor = tf.constant(input_label_scores)
label_scores_tensor) output_label_scores = ops.replace_nan_groundtruth_label_scores_with_ones(
with self.test_session(): label_scores_tensor)
output_label_scores = output_label_scores.eval() return output_label_scores
self.assertAllClose(input_label_scores, output_label_scores)
output_label_scores = self.execute(graph_fn, [])
self.assertAllClose(input_label_scores, output_label_scores)
class GroundtruthFilterWithCrowdBoxesTest(tf.test.TestCase): class GroundtruthFilterWithCrowdBoxesTest(test_case.TestCase):
def test_filter_groundtruth_with_crowd_boxes(self): def test_filter_groundtruth_with_crowd_boxes(self):
input_tensors = {
fields.InputDataFields.groundtruth_boxes: def graph_fn():
[[0.1, 0.2, 0.6, 0.8], [0.2, 0.4, 0.1, 0.8]], input_tensors = {
fields.InputDataFields.groundtruth_classes: [1, 2], fields.InputDataFields.groundtruth_boxes:
fields.InputDataFields.groundtruth_is_crowd: [True, False], [[0.1, 0.2, 0.6, 0.8], [0.2, 0.4, 0.1, 0.8]],
fields.InputDataFields.groundtruth_area: [100.0, 238.7], fields.InputDataFields.groundtruth_classes: [1, 2],
fields.InputDataFields.groundtruth_confidences: [0.5, 0.99], fields.InputDataFields.groundtruth_is_crowd: [True, False],
} fields.InputDataFields.groundtruth_area: [100.0, 238.7],
fields.InputDataFields.groundtruth_confidences: [0.5, 0.99],
}
output_tensors = ops.filter_groundtruth_with_crowd_boxes(
input_tensors)
return output_tensors
expected_tensors = { expected_tensors = {
fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]],
...@@ -680,30 +725,32 @@ class GroundtruthFilterWithCrowdBoxesTest(tf.test.TestCase): ...@@ -680,30 +725,32 @@ class GroundtruthFilterWithCrowdBoxesTest(tf.test.TestCase):
fields.InputDataFields.groundtruth_confidences: [0.99], fields.InputDataFields.groundtruth_confidences: [0.99],
} }
output_tensors = ops.filter_groundtruth_with_crowd_boxes( output_tensors = self.execute(graph_fn, [])
input_tensors) for key in [fields.InputDataFields.groundtruth_boxes,
with self.test_session() as sess: fields.InputDataFields.groundtruth_area,
output_tensors = sess.run(output_tensors) fields.InputDataFields.groundtruth_confidences]:
for key in [fields.InputDataFields.groundtruth_boxes, self.assertAllClose(expected_tensors[key], output_tensors[key])
fields.InputDataFields.groundtruth_area, for key in [fields.InputDataFields.groundtruth_classes,
fields.InputDataFields.groundtruth_confidences]: fields.InputDataFields.groundtruth_is_crowd]:
self.assertAllClose(expected_tensors[key], output_tensors[key]) self.assertAllEqual(expected_tensors[key], output_tensors[key])
for key in [fields.InputDataFields.groundtruth_classes,
fields.InputDataFields.groundtruth_is_crowd]:
self.assertAllEqual(expected_tensors[key], output_tensors[key])
class GroundtruthFilterWithNanBoxTest(tf.test.TestCase): class GroundtruthFilterWithNanBoxTest(test_case.TestCase):
def test_filter_groundtruth_with_nan_box_coordinates(self): def test_filter_groundtruth_with_nan_box_coordinates(self):
input_tensors = {
fields.InputDataFields.groundtruth_boxes: def graph_fn():
[[np.nan, np.nan, np.nan, np.nan], [0.2, 0.4, 0.1, 0.8]], input_tensors = {
fields.InputDataFields.groundtruth_classes: [1, 2], fields.InputDataFields.groundtruth_boxes:
fields.InputDataFields.groundtruth_is_crowd: [False, True], [[np.nan, np.nan, np.nan, np.nan], [0.2, 0.4, 0.1, 0.8]],
fields.InputDataFields.groundtruth_area: [100.0, 238.7], fields.InputDataFields.groundtruth_classes: [1, 2],
fields.InputDataFields.groundtruth_confidences: [0.5, 0.99], fields.InputDataFields.groundtruth_is_crowd: [False, True],
} fields.InputDataFields.groundtruth_area: [100.0, 238.7],
fields.InputDataFields.groundtruth_confidences: [0.5, 0.99],
}
output_tensors = ops.filter_groundtruth_with_nan_box_coordinates(
input_tensors)
return output_tensors
expected_tensors = { expected_tensors = {
fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]],
...@@ -713,30 +760,30 @@ class GroundtruthFilterWithNanBoxTest(tf.test.TestCase): ...@@ -713,30 +760,30 @@ class GroundtruthFilterWithNanBoxTest(tf.test.TestCase):
fields.InputDataFields.groundtruth_confidences: [0.99], fields.InputDataFields.groundtruth_confidences: [0.99],
} }
output_tensors = ops.filter_groundtruth_with_nan_box_coordinates( output_tensors = self.execute(graph_fn, [])
input_tensors) for key in [fields.InputDataFields.groundtruth_boxes,
with self.test_session() as sess: fields.InputDataFields.groundtruth_area,
output_tensors = sess.run(output_tensors) fields.InputDataFields.groundtruth_confidences]:
for key in [fields.InputDataFields.groundtruth_boxes, self.assertAllClose(expected_tensors[key], output_tensors[key])
fields.InputDataFields.groundtruth_area, for key in [fields.InputDataFields.groundtruth_classes,
fields.InputDataFields.groundtruth_confidences]: fields.InputDataFields.groundtruth_is_crowd]:
self.assertAllClose(expected_tensors[key], output_tensors[key]) self.assertAllEqual(expected_tensors[key], output_tensors[key])
for key in [fields.InputDataFields.groundtruth_classes,
fields.InputDataFields.groundtruth_is_crowd]:
self.assertAllEqual(expected_tensors[key], output_tensors[key])
class GroundtruthFilterWithUnrecognizedClassesTest(tf.test.TestCase): class GroundtruthFilterWithUnrecognizedClassesTest(test_case.TestCase):
def test_filter_unrecognized_classes(self): def test_filter_unrecognized_classes(self):
input_tensors = { def graph_fn():
fields.InputDataFields.groundtruth_boxes: input_tensors = {
[[.3, .3, .5, .7], [0.2, 0.4, 0.1, 0.8]], fields.InputDataFields.groundtruth_boxes:
fields.InputDataFields.groundtruth_classes: [-1, 2], [[.3, .3, .5, .7], [0.2, 0.4, 0.1, 0.8]],
fields.InputDataFields.groundtruth_is_crowd: [False, True], fields.InputDataFields.groundtruth_classes: [-1, 2],
fields.InputDataFields.groundtruth_area: [100.0, 238.7], fields.InputDataFields.groundtruth_is_crowd: [False, True],
fields.InputDataFields.groundtruth_confidences: [0.5, 0.99], fields.InputDataFields.groundtruth_area: [100.0, 238.7],
} fields.InputDataFields.groundtruth_confidences: [0.5, 0.99],
}
output_tensors = ops.filter_unrecognized_classes(input_tensors)
return output_tensors
expected_tensors = { expected_tensors = {
fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]],
...@@ -746,28 +793,30 @@ class GroundtruthFilterWithUnrecognizedClassesTest(tf.test.TestCase): ...@@ -746,28 +793,30 @@ class GroundtruthFilterWithUnrecognizedClassesTest(tf.test.TestCase):
fields.InputDataFields.groundtruth_confidences: [0.99], fields.InputDataFields.groundtruth_confidences: [0.99],
} }
output_tensors = ops.filter_unrecognized_classes(input_tensors) output_tensors = self.execute(graph_fn, [])
with self.test_session() as sess: for key in [fields.InputDataFields.groundtruth_boxes,
output_tensors = sess.run(output_tensors) fields.InputDataFields.groundtruth_area,
for key in [fields.InputDataFields.groundtruth_boxes, fields.InputDataFields.groundtruth_confidences]:
fields.InputDataFields.groundtruth_area, self.assertAllClose(expected_tensors[key], output_tensors[key])
fields.InputDataFields.groundtruth_confidences]: for key in [fields.InputDataFields.groundtruth_classes,
self.assertAllClose(expected_tensors[key], output_tensors[key]) fields.InputDataFields.groundtruth_is_crowd]:
for key in [fields.InputDataFields.groundtruth_classes, self.assertAllEqual(expected_tensors[key], output_tensors[key])
fields.InputDataFields.groundtruth_is_crowd]:
self.assertAllEqual(expected_tensors[key], output_tensors[key])
class OpsTestNormalizeToTarget(tf.test.TestCase): class OpsTestNormalizeToTarget(test_case.TestCase):
def test_create_normalize_to_target(self): def test_create_normalize_to_target(self):
if self.is_tf2():
self.skipTest('Skipping as variable names not supported in eager mode.')
inputs = tf.random_uniform([5, 10, 12, 3]) inputs = tf.random_uniform([5, 10, 12, 3])
target_norm_value = 4.0 target_norm_value = 4.0
dim = 3 dim = 3
with self.test_session(): with self.test_session():
output = ops.normalize_to_target(inputs, target_norm_value, dim) output = ops.normalize_to_target(inputs, target_norm_value, dim)
self.assertEqual(output.op.name, 'NormalizeToTarget/mul') self.assertEqual(output.op.name, 'NormalizeToTarget/mul')
var_name = contrib_framework.get_variables()[0].name var_name = slim.get_variables()[0].name
self.assertEqual(var_name, 'NormalizeToTarget/weights:0') self.assertEqual(var_name, 'NormalizeToTarget/weights:0')
def test_invalid_dim(self): def test_invalid_dim(self):
...@@ -788,94 +837,125 @@ class OpsTestNormalizeToTarget(tf.test.TestCase): ...@@ -788,94 +837,125 @@ class OpsTestNormalizeToTarget(tf.test.TestCase):
ops.normalize_to_target(inputs, target_norm_value, dim) ops.normalize_to_target(inputs, target_norm_value, dim)
def test_correct_output_shape(self): def test_correct_output_shape(self):
inputs = tf.random_uniform([5, 10, 12, 3])
target_norm_value = 4.0 if self.is_tf2():
dim = 3 self.skipTest('normalize_to_target not supported in eager mode because,'
with self.test_session(): ' it requires creating variables.')
inputs = np.random.uniform(size=(5, 10, 12, 3)).astype(np.float32)
def graph_fn(inputs):
target_norm_value = 4.0
dim = 3
output = ops.normalize_to_target(inputs, target_norm_value, dim) output = ops.normalize_to_target(inputs, target_norm_value, dim)
self.assertEqual(output.get_shape().as_list(), return output
inputs.get_shape().as_list())
# Executing on CPU since creating a variable inside a conditional is not
# supported.
outputs = self.execute_cpu(graph_fn, [inputs])
self.assertEqual(outputs.shape, inputs.shape)
def test_correct_initial_output_values(self): def test_correct_initial_output_values(self):
inputs = tf.constant([[[[3, 4], [7, 24]],
[[5, -12], [-1, 0]]]], tf.float32) if self.is_tf2():
target_norm_value = 10.0 self.skipTest('normalize_to_target not supported in eager mode because,'
dim = 3 ' it requires creating variables.')
def graph_fn():
inputs = tf.constant([[[[3, 4], [7, 24]],
[[5, -12], [-1, 0]]]], tf.float32)
target_norm_value = 10.0
dim = 3
normalized_inputs = ops.normalize_to_target(inputs, target_norm_value,
dim)
return normalized_inputs
expected_output = [[[[30/5.0, 40/5.0], [70/25.0, 240/25.0]], expected_output = [[[[30/5.0, 40/5.0], [70/25.0, 240/25.0]],
[[50/13.0, -120/13.0], [-10, 0]]]] [[50/13.0, -120/13.0], [-10, 0]]]]
with self.test_session() as sess: # Executing on CPU since creating a variable inside a conditional is not
# supported.
output = self.execute_cpu(graph_fn, [])
self.assertAllClose(output, expected_output)
def test_multiple_target_norm_values(self):
if self.is_tf2():
self.skipTest('normalize_to_target not supported in eager mode because,'
' it requires creating variables.')
def graph_fn():
inputs = tf.constant([[[[3, 4], [7, 24]],
[[5, -12], [-1, 0]]]], tf.float32)
target_norm_value = [10.0, 20.0]
dim = 3
normalized_inputs = ops.normalize_to_target(inputs, target_norm_value, normalized_inputs = ops.normalize_to_target(inputs, target_norm_value,
dim) dim)
sess.run(tf.global_variables_initializer()) return normalized_inputs
output = normalized_inputs.eval()
self.assertAllClose(output, expected_output)
def test_multiple_target_norm_values(self):
inputs = tf.constant([[[[3, 4], [7, 24]],
[[5, -12], [-1, 0]]]], tf.float32)
target_norm_value = [10.0, 20.0]
dim = 3
expected_output = [[[[30/5.0, 80/5.0], [70/25.0, 480/25.0]], expected_output = [[[[30/5.0, 80/5.0], [70/25.0, 480/25.0]],
[[50/13.0, -240/13.0], [-10, 0]]]] [[50/13.0, -240/13.0], [-10, 0]]]]
with self.test_session() as sess:
normalized_inputs = ops.normalize_to_target(inputs, target_norm_value, # Executing on CPU since creating a variable inside a conditional is not
dim) # supported.
sess.run(tf.global_variables_initializer()) output = self.execute_cpu(graph_fn, [])
output = normalized_inputs.eval() self.assertAllClose(output, expected_output)
self.assertAllClose(output, expected_output)
class OpsTestPositionSensitiveCropRegions(tf.test.TestCase): class OpsTestPositionSensitiveCropRegions(test_case.TestCase):
def test_position_sensitive(self): def test_position_sensitive(self):
num_spatial_bins = [3, 2] num_spatial_bins = [3, 2]
image_shape = [3, 2, 6] image_shape = [3, 2, 6]
# First channel is 1's, second channel is 2's, etc.
image = tf.constant(
list(range(1, 3 * 2 + 1)) * 6, dtype=tf.float32, shape=image_shape)
boxes = tf.random_uniform((2, 4))
# The result for both boxes should be [[1, 2], [3, 4], [5, 6]] # The result for both boxes should be [[1, 2], [3, 4], [5, 6]]
# before averaging. # before averaging.
expected_output = np.array([3.5, 3.5]).reshape([2, 1, 1, 1]) expected_output = np.array([3.5, 3.5]).reshape([2, 1, 1, 1])
for crop_size_mult in range(1, 3): for crop_size_mult in range(1, 3):
crop_size = [3 * crop_size_mult, 2 * crop_size_mult] crop_size = [3 * crop_size_mult, 2 * crop_size_mult]
ps_crop_and_pool = ops.position_sensitive_crop_regions(
image, boxes, crop_size, num_spatial_bins, global_pool=True)
with self.test_session() as sess: def graph_fn():
output = sess.run(ps_crop_and_pool) # First channel is 1's, second channel is 2's, etc.
self.assertAllClose(output, expected_output) image = tf.constant(
list(range(1, 3 * 2 + 1)) * 6, dtype=tf.float32, shape=image_shape)
boxes = tf.random_uniform((2, 4))
# pylint:disable=cell-var-from-loop
ps_crop_and_pool = ops.position_sensitive_crop_regions(
image, boxes, crop_size, num_spatial_bins, global_pool=True)
return ps_crop_and_pool
output = self.execute(graph_fn, [])
self.assertAllClose(output, expected_output)
def test_position_sensitive_with_equal_channels(self): def test_position_sensitive_with_equal_channels(self):
num_spatial_bins = [2, 2] num_spatial_bins = [2, 2]
image_shape = [3, 3, 4] image_shape = [3, 3, 4]
crop_size = [2, 2] crop_size = [2, 2]
image = tf.constant( def graph_fn():
list(range(1, 3 * 3 + 1)), dtype=tf.float32, shape=[3, 3, 1]) image = tf.constant(
tiled_image = tf.tile(image, [1, 1, image_shape[2]]) list(range(1, 3 * 3 + 1)), dtype=tf.float32, shape=[3, 3, 1])
boxes = tf.random_uniform((3, 4)) tiled_image = tf.tile(image, [1, 1, image_shape[2]])
box_ind = tf.constant([0, 0, 0], dtype=tf.int32) boxes = tf.random_uniform((3, 4))
box_ind = tf.constant([0, 0, 0], dtype=tf.int32)
# All channels are equal so position-sensitive crop and resize should
# work as the usual crop and resize for just one channel. # All channels are equal so position-sensitive crop and resize should
crop = tf.image.crop_and_resize(tf.expand_dims(image, axis=0), boxes, # work as the usual crop and resize for just one channel.
box_ind, crop_size) crop = tf.image.crop_and_resize(tf.expand_dims(image, axis=0), boxes,
crop_and_pool = tf.reduce_mean(crop, [1, 2], keepdims=True) box_ind, crop_size)
crop_and_pool = tf.reduce_mean(crop, [1, 2], keepdims=True)
ps_crop_and_pool = ops.position_sensitive_crop_regions(
tiled_image, ps_crop_and_pool = ops.position_sensitive_crop_regions(
boxes, tiled_image,
crop_size, boxes,
num_spatial_bins, crop_size,
global_pool=True) num_spatial_bins,
global_pool=True)
with self.test_session() as sess:
expected_output, output = sess.run((crop_and_pool, ps_crop_and_pool)) return crop_and_pool, ps_crop_and_pool
self.assertAllClose(output, expected_output)
# Crop and resize op is not supported in TPUs.
expected_output, output = self.execute_cpu(graph_fn, [])
self.assertAllClose(output, expected_output)
def test_raise_value_error_on_num_bins_less_than_one(self): def test_raise_value_error_on_num_bins_less_than_one(self):
num_spatial_bins = [1, -1] num_spatial_bins = [1, -1]
...@@ -907,24 +987,22 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase): ...@@ -907,24 +987,22 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase):
image_shape = [1, 1, 5] image_shape = [1, 1, 5]
crop_size = [2, 2] crop_size = [2, 2]
image = tf.constant(1, dtype=tf.float32, shape=image_shape) def graph_fn():
boxes = tf.constant([[0, 0, 1, 1]], dtype=tf.float32) image = tf.constant(1, dtype=tf.float32, shape=image_shape)
boxes = tf.constant([[0, 0, 1, 1]], dtype=tf.float32)
return ops.position_sensitive_crop_regions(
image, boxes, crop_size, num_spatial_bins, global_pool=True)
with self.assertRaisesRegexp( with self.assertRaisesRegexp(
ValueError, 'Dimension size must be evenly divisible by 4 but is 5'): ValueError, 'Dimension size must be evenly divisible by 4 but is 5'):
ops.position_sensitive_crop_regions( self.execute(graph_fn, [])
image, boxes, crop_size, num_spatial_bins, global_pool=True)
def test_position_sensitive_with_global_pool_false(self): def test_position_sensitive_with_global_pool_false(self):
num_spatial_bins = [3, 2] num_spatial_bins = [3, 2]
image_shape = [3, 2, 6] image_shape = [3, 2, 6]
num_boxes = 2 num_boxes = 2
# First channel is 1's, second channel is 2's, etc.
image = tf.constant(
list(range(1, 3 * 2 + 1)) * 6, dtype=tf.float32, shape=image_shape)
boxes = tf.random_uniform((num_boxes, 4))
expected_output = [] expected_output = []
# Expected output, when crop_size = [3, 2]. # Expected output, when crop_size = [3, 2].
...@@ -946,10 +1024,19 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase): ...@@ -946,10 +1024,19 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase):
for crop_size_mult in range(1, 3): for crop_size_mult in range(1, 3):
crop_size = [3 * crop_size_mult, 2 * crop_size_mult] crop_size = [3 * crop_size_mult, 2 * crop_size_mult]
ps_crop = ops.position_sensitive_crop_regions( # First channel is 1's, second channel is 2's, etc.
image, boxes, crop_size, num_spatial_bins, global_pool=False)
with self.test_session() as sess: def graph_fn():
output = sess.run(ps_crop) # pylint:disable=cell-var-from-loop
image = tf.constant(
list(range(1, 3 * 2 + 1)) * 6, dtype=tf.float32, shape=image_shape)
boxes = tf.random_uniform((num_boxes, 4))
ps_crop = ops.position_sensitive_crop_regions(
image, boxes, crop_size, num_spatial_bins, global_pool=False)
return ps_crop
output = self.execute(graph_fn, [])
self.assertAllClose(output, expected_output[crop_size_mult - 1]) self.assertAllClose(output, expected_output[crop_size_mult - 1])
def test_position_sensitive_with_global_pool_false_and_do_global_pool(self): def test_position_sensitive_with_global_pool_false_and_do_global_pool(self):
...@@ -957,11 +1044,6 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase): ...@@ -957,11 +1044,6 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase):
image_shape = [3, 2, 6] image_shape = [3, 2, 6]
num_boxes = 2 num_boxes = 2
# First channel is 1's, second channel is 2's, etc.
image = tf.constant(
list(range(1, 3 * 2 + 1)) * 6, dtype=tf.float32, shape=image_shape)
boxes = tf.random_uniform((num_boxes, 4))
expected_output = [] expected_output = []
# Expected output, when crop_size = [3, 2]. # Expected output, when crop_size = [3, 2].
...@@ -988,16 +1070,22 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase): ...@@ -988,16 +1070,22 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase):
for crop_size_mult in range(1, 3): for crop_size_mult in range(1, 3):
crop_size = [3 * crop_size_mult, 2 * crop_size_mult] crop_size = [3 * crop_size_mult, 2 * crop_size_mult]
# Perform global_pooling after running the function with def graph_fn():
# global_pool=False. # pylint:disable=cell-var-from-loop
ps_crop = ops.position_sensitive_crop_regions( # First channel is 1's, second channel is 2's, etc.
image, boxes, crop_size, num_spatial_bins, global_pool=False) image = tf.constant(
ps_crop_and_pool = tf.reduce_mean( list(range(1, 3 * 2 + 1)) * 6, dtype=tf.float32, shape=image_shape)
ps_crop, reduction_indices=(1, 2), keepdims=True) boxes = tf.random_uniform((num_boxes, 4))
with self.test_session() as sess: # Perform global_pooling after running the function with
output = sess.run(ps_crop_and_pool) # global_pool=False.
ps_crop = ops.position_sensitive_crop_regions(
image, boxes, crop_size, num_spatial_bins, global_pool=False)
ps_crop_and_pool = tf.reduce_mean(
ps_crop, reduction_indices=(1, 2), keepdims=True)
return ps_crop_and_pool
output = self.execute(graph_fn, [])
self.assertAllEqual(output, expected_output[crop_size_mult - 1]) self.assertAllEqual(output, expected_output[crop_size_mult - 1])
def test_raise_value_error_on_non_square_block_size(self): def test_raise_value_error_on_non_square_block_size(self):
...@@ -1014,42 +1102,39 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase): ...@@ -1014,42 +1102,39 @@ class OpsTestPositionSensitiveCropRegions(tf.test.TestCase):
image, boxes, crop_size, num_spatial_bins, global_pool=False) image, boxes, crop_size, num_spatial_bins, global_pool=False)
class OpsTestBatchPositionSensitiveCropRegions(tf.test.TestCase): class OpsTestBatchPositionSensitiveCropRegions(test_case.TestCase):
def test_position_sensitive_with_single_bin(self): def test_position_sensitive_with_single_bin(self):
num_spatial_bins = [1, 1] num_spatial_bins = [1, 1]
image_shape = [2, 3, 3, 4] image_shape = [2, 3, 3, 4]
crop_size = [2, 2] crop_size = [2, 2]
image = tf.random_uniform(image_shape) def graph_fn():
boxes = tf.random_uniform((2, 3, 4)) image = tf.random_uniform(image_shape)
box_ind = tf.constant([0, 0, 0, 1, 1, 1], dtype=tf.int32) boxes = tf.random_uniform((2, 3, 4))
box_ind = tf.constant([0, 0, 0, 1, 1, 1], dtype=tf.int32)
# When a single bin is used, position-sensitive crop and pool should be # When a single bin is used, position-sensitive crop and pool should be
# the same as non-position sensitive crop and pool. # the same as non-position sensitive crop and pool.
crop = tf.image.crop_and_resize(image, tf.reshape(boxes, [-1, 4]), box_ind, crop = tf.image.crop_and_resize(image,
crop_size) tf.reshape(boxes, [-1, 4]), box_ind,
crop_and_pool = tf.reduce_mean(crop, [1, 2], keepdims=True) crop_size)
crop_and_pool = tf.reshape(crop_and_pool, [2, 3, 1, 1, 4]) crop_and_pool = tf.reduce_mean(crop, [1, 2], keepdims=True)
crop_and_pool = tf.reshape(crop_and_pool, [2, 3, 1, 1, 4])
ps_crop_and_pool = ops.batch_position_sensitive_crop_regions( ps_crop_and_pool = ops.batch_position_sensitive_crop_regions(
image, boxes, crop_size, num_spatial_bins, global_pool=True) image, boxes, crop_size, num_spatial_bins, global_pool=True)
return crop_and_pool, ps_crop_and_pool
with self.test_session() as sess: # Crop and resize is not supported on TPUs.
expected_output, output = sess.run((crop_and_pool, ps_crop_and_pool)) expected_output, output = self.execute_cpu(graph_fn, [])
self.assertAllClose(output, expected_output) self.assertAllClose(output, expected_output)
def test_position_sensitive_with_global_pool_false_and_known_boxes(self): def test_position_sensitive_with_global_pool_false_and_known_boxes(self):
num_spatial_bins = [2, 2] num_spatial_bins = [2, 2]
image_shape = [2, 2, 2, 4] image_shape = [2, 2, 2, 4]
crop_size = [2, 2] crop_size = [2, 2]
images = tf.constant(
list(range(1, 2 * 2 * 4 + 1)) * 2, dtype=tf.float32, shape=image_shape)
# First box contains whole image, and second box contains only first row.
boxes = tf.constant(np.array([[[0., 0., 1., 1.]],
[[0., 0., 0.5, 1.]]]), dtype=tf.float32)
# box_ind = tf.constant([0, 1], dtype=tf.int32) # box_ind = tf.constant([0, 1], dtype=tf.int32)
expected_output = [] expected_output = []
...@@ -1069,105 +1154,147 @@ class OpsTestBatchPositionSensitiveCropRegions(tf.test.TestCase): ...@@ -1069,105 +1154,147 @@ class OpsTestBatchPositionSensitiveCropRegions(tf.test.TestCase):
) )
expected_output = np.stack(expected_output, axis=0) expected_output = np.stack(expected_output, axis=0)
ps_crop = ops.batch_position_sensitive_crop_regions( def graph_fn():
images, boxes, crop_size, num_spatial_bins, global_pool=False) images = tf.constant(
list(range(1, 2 * 2 * 4 + 1)) * 2, dtype=tf.float32,
shape=image_shape)
with self.test_session() as sess: # First box contains whole image, and second box contains only first row.
output = sess.run(ps_crop) boxes = tf.constant(np.array([[[0., 0., 1., 1.]],
self.assertAllEqual(output, expected_output) [[0., 0., 0.5, 1.]]]), dtype=tf.float32)
ps_crop = ops.batch_position_sensitive_crop_regions(
images, boxes, crop_size, num_spatial_bins, global_pool=False)
return ps_crop
output = self.execute(graph_fn, [])
self.assertAllEqual(output, expected_output)
def test_position_sensitive_with_global_pool_false_and_single_bin(self): def test_position_sensitive_with_global_pool_false_and_single_bin(self):
num_spatial_bins = [1, 1] num_spatial_bins = [1, 1]
image_shape = [2, 3, 3, 4] image_shape = [2, 3, 3, 4]
crop_size = [1, 1] crop_size = [1, 1]
images = tf.random_uniform(image_shape) def graph_fn():
boxes = tf.random_uniform((2, 3, 4)) images = tf.random_uniform(image_shape)
# box_ind = tf.constant([0, 0, 0, 1, 1, 1], dtype=tf.int32) boxes = tf.random_uniform((2, 3, 4))
# box_ind = tf.constant([0, 0, 0, 1, 1, 1], dtype=tf.int32)
# Since single_bin is used and crop_size = [1, 1] (i.e., no crop resize), # Since single_bin is used and crop_size = [1, 1] (i.e., no crop resize),
# the outputs are the same whatever the global_pool value is. # the outputs are the same whatever the global_pool value is.
ps_crop_and_pool = ops.batch_position_sensitive_crop_regions( ps_crop_and_pool = ops.batch_position_sensitive_crop_regions(
images, boxes, crop_size, num_spatial_bins, global_pool=True) images, boxes, crop_size, num_spatial_bins, global_pool=True)
ps_crop = ops.batch_position_sensitive_crop_regions( ps_crop = ops.batch_position_sensitive_crop_regions(
images, boxes, crop_size, num_spatial_bins, global_pool=False) images, boxes, crop_size, num_spatial_bins, global_pool=False)
return ps_crop_and_pool, ps_crop
with self.test_session() as sess: pooled_output, unpooled_output = self.execute(graph_fn, [])
pooled_output, unpooled_output = sess.run((ps_crop_and_pool, ps_crop)) self.assertAllClose(pooled_output, unpooled_output)
self.assertAllClose(pooled_output, unpooled_output)
class ReframeBoxMasksToImageMasksTest(tf.test.TestCase): # The following tests are only executed on CPU because the output
# shape is not constant.
class ReframeBoxMasksToImageMasksTest(test_case.TestCase):
def testZeroImageOnEmptyMask(self): def testZeroImageOnEmptyMask(self):
box_masks = tf.constant([[[0, 0],
[0, 0]]], dtype=tf.float32)
boxes = tf.constant([[0.0, 0.0, 1.0, 1.0]], dtype=tf.float32)
image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes,
image_height=4,
image_width=4)
np_expected_image_masks = np.array([[[0, 0, 0, 0], np_expected_image_masks = np.array([[[0, 0, 0, 0],
[0, 0, 0, 0], [0, 0, 0, 0],
[0, 0, 0, 0], [0, 0, 0, 0],
[0, 0, 0, 0]]], dtype=np.float32) [0, 0, 0, 0]]], dtype=np.float32)
with self.test_session() as sess: def graph_fn():
np_image_masks = sess.run(image_masks) box_masks = tf.constant([[[0, 0],
self.assertAllClose(np_image_masks, np_expected_image_masks) [0, 0]]], dtype=tf.float32)
boxes = tf.constant([[0.0, 0.0, 1.0, 1.0]], dtype=tf.float32)
image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes,
image_height=4,
image_width=4)
return image_masks
np_image_masks = self.execute_cpu(graph_fn, [])
self.assertAllClose(np_image_masks, np_expected_image_masks)
def testZeroBoxMasks(self): def testZeroBoxMasks(self):
box_masks = tf.zeros([0, 3, 3], dtype=tf.float32)
boxes = tf.zeros([0, 4], dtype=tf.float32) def graph_fn():
image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes, box_masks = tf.zeros([0, 3, 3], dtype=tf.float32)
image_height=4, boxes = tf.zeros([0, 4], dtype=tf.float32)
image_width=4) image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes,
with self.test_session() as sess: image_height=4,
np_image_masks = sess.run(image_masks) image_width=4)
self.assertAllEqual(np_image_masks.shape, np.array([0, 4, 4])) return image_masks
np_image_masks = self.execute_cpu(graph_fn, [])
self.assertAllEqual(np_image_masks.shape, np.array([0, 4, 4]))
def testBoxWithZeroArea(self):
def graph_fn():
box_masks = tf.zeros([1, 3, 3], dtype=tf.float32)
boxes = tf.constant([[0.1, 0.2, 0.1, 0.7]], dtype=tf.float32)
image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes,
image_height=4,
image_width=4)
return image_masks
np_image_masks = self.execute_cpu(graph_fn, [])
self.assertAllEqual(np_image_masks.shape, np.array([1, 4, 4]))
def testMaskIsCenteredInImageWhenBoxIsCentered(self): def testMaskIsCenteredInImageWhenBoxIsCentered(self):
box_masks = tf.constant([[[1, 1],
[1, 1]]], dtype=tf.float32) def graph_fn():
boxes = tf.constant([[0.25, 0.25, 0.75, 0.75]], dtype=tf.float32) box_masks = tf.constant([[[1, 1],
image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes, [1, 1]]], dtype=tf.float32)
image_height=4, boxes = tf.constant([[0.25, 0.25, 0.75, 0.75]], dtype=tf.float32)
image_width=4) image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes,
image_height=4,
image_width=4)
return image_masks
np_expected_image_masks = np.array([[[0, 0, 0, 0], np_expected_image_masks = np.array([[[0, 0, 0, 0],
[0, 1, 1, 0], [0, 1, 1, 0],
[0, 1, 1, 0], [0, 1, 1, 0],
[0, 0, 0, 0]]], dtype=np.float32) [0, 0, 0, 0]]], dtype=np.float32)
with self.test_session() as sess: np_image_masks = self.execute_cpu(graph_fn, [])
np_image_masks = sess.run(image_masks) self.assertAllClose(np_image_masks, np_expected_image_masks)
self.assertAllClose(np_image_masks, np_expected_image_masks)
def testMaskOffCenterRemainsOffCenterInImage(self): def testMaskOffCenterRemainsOffCenterInImage(self):
box_masks = tf.constant([[[1, 0],
[0, 1]]], dtype=tf.float32) def graph_fn():
boxes = tf.constant([[0.25, 0.5, 0.75, 1.0]], dtype=tf.float32) box_masks = tf.constant([[[1, 0],
image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes, [0, 1]]], dtype=tf.float32)
image_height=4, boxes = tf.constant([[0.25, 0.5, 0.75, 1.0]], dtype=tf.float32)
image_width=4) image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes,
image_height=4,
image_width=4)
return image_masks
np_expected_image_masks = np.array([[[0, 0, 0, 0], np_expected_image_masks = np.array([[[0, 0, 0, 0],
[0, 0, 0.6111111, 0.16666669], [0, 0, 0.6111111, 0.16666669],
[0, 0, 0.3888889, 0.83333337], [0, 0, 0.3888889, 0.83333337],
[0, 0, 0, 0]]], dtype=np.float32) [0, 0, 0, 0]]], dtype=np.float32)
with self.test_session() as sess: np_image_masks = self.execute_cpu(graph_fn, [])
np_image_masks = sess.run(image_masks) self.assertAllClose(np_image_masks, np_expected_image_masks)
self.assertAllClose(np_image_masks, np_expected_image_masks)
class MergeBoxesWithMultipleLabelsTest(tf.test.TestCase): class MergeBoxesWithMultipleLabelsTest(test_case.TestCase):
def testMergeBoxesWithMultipleLabels(self): def testMergeBoxesWithMultipleLabels(self):
boxes = tf.constant(
[[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75], def graph_fn():
[0.25, 0.25, 0.75, 0.75]], boxes = tf.constant(
dtype=tf.float32) [[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75],
class_indices = tf.constant([0, 4, 2], dtype=tf.int32) [0.25, 0.25, 0.75, 0.75]],
class_confidences = tf.constant([0.8, 0.2, 0.1], dtype=tf.float32) dtype=tf.float32)
num_classes = 5 class_indices = tf.constant([0, 4, 2], dtype=tf.int32)
merged_boxes, merged_classes, merged_confidences, merged_box_indices = ( class_confidences = tf.constant([0.8, 0.2, 0.1], dtype=tf.float32)
ops.merge_boxes_with_multiple_labels( num_classes = 5
boxes, class_indices, class_confidences, num_classes)) merged_boxes, merged_classes, merged_confidences, merged_box_indices = (
ops.merge_boxes_with_multiple_labels(
boxes, class_indices, class_confidences, num_classes))
return (merged_boxes, merged_classes, merged_confidences,
merged_box_indices)
expected_merged_boxes = np.array( expected_merged_boxes = np.array(
[[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75]], dtype=np.float32) [[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75]], dtype=np.float32)
expected_merged_classes = np.array( expected_merged_classes = np.array(
...@@ -1175,28 +1302,32 @@ class MergeBoxesWithMultipleLabelsTest(tf.test.TestCase): ...@@ -1175,28 +1302,32 @@ class MergeBoxesWithMultipleLabelsTest(tf.test.TestCase):
expected_merged_confidences = np.array( expected_merged_confidences = np.array(
[[0.8, 0, 0.1, 0, 0], [0, 0, 0, 0, 0.2]], dtype=np.float32) [[0.8, 0, 0.1, 0, 0], [0, 0, 0, 0, 0.2]], dtype=np.float32)
expected_merged_box_indices = np.array([0, 1], dtype=np.int32) expected_merged_box_indices = np.array([0, 1], dtype=np.int32)
with self.test_session() as sess:
(np_merged_boxes, np_merged_classes, np_merged_confidences, # Running on CPU only as tf.unique is not supported on TPU.
np_merged_box_indices) = sess.run( (np_merged_boxes, np_merged_classes, np_merged_confidences,
[merged_boxes, merged_classes, merged_confidences, np_merged_box_indices) = self.execute_cpu(graph_fn, [])
merged_box_indices]) self.assertAllClose(np_merged_boxes, expected_merged_boxes)
self.assertAllClose(np_merged_boxes, expected_merged_boxes) self.assertAllClose(np_merged_classes, expected_merged_classes)
self.assertAllClose(np_merged_classes, expected_merged_classes) self.assertAllClose(np_merged_confidences, expected_merged_confidences)
self.assertAllClose(np_merged_confidences, expected_merged_confidences) self.assertAllClose(np_merged_box_indices, expected_merged_box_indices)
self.assertAllClose(np_merged_box_indices, expected_merged_box_indices)
def testMergeBoxesWithMultipleLabelsCornerCase(self): def testMergeBoxesWithMultipleLabelsCornerCase(self):
boxes = tf.constant(
[[0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1], def graph_fn():
[1, 1, 1, 1], [1, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]], boxes = tf.constant(
dtype=tf.float32) [[0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1],
class_indices = tf.constant([0, 1, 2, 3, 2, 1, 0, 3], dtype=tf.int32) [1, 1, 1, 1], [1, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]],
class_confidences = tf.constant([0.1, 0.9, 0.2, 0.8, 0.3, 0.7, 0.4, 0.6], dtype=tf.float32)
dtype=tf.float32) class_indices = tf.constant([0, 1, 2, 3, 2, 1, 0, 3], dtype=tf.int32)
num_classes = 4 class_confidences = tf.constant([0.1, 0.9, 0.2, 0.8, 0.3, 0.7, 0.4, 0.6],
merged_boxes, merged_classes, merged_confidences, merged_box_indices = ( dtype=tf.float32)
ops.merge_boxes_with_multiple_labels( num_classes = 4
boxes, class_indices, class_confidences, num_classes)) merged_boxes, merged_classes, merged_confidences, merged_box_indices = (
ops.merge_boxes_with_multiple_labels(
boxes, class_indices, class_confidences, num_classes))
return (merged_boxes, merged_classes, merged_confidences,
merged_box_indices)
expected_merged_boxes = np.array( expected_merged_boxes = np.array(
[[0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]], [[0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]],
dtype=np.float32) dtype=np.float32)
...@@ -1207,35 +1338,42 @@ class MergeBoxesWithMultipleLabelsTest(tf.test.TestCase): ...@@ -1207,35 +1338,42 @@ class MergeBoxesWithMultipleLabelsTest(tf.test.TestCase):
[[0.1, 0, 0, 0.6], [0.4, 0.9, 0, 0], [[0.1, 0, 0, 0.6], [0.4, 0.9, 0, 0],
[0, 0.7, 0.2, 0], [0, 0, 0.3, 0.8]], dtype=np.float32) [0, 0.7, 0.2, 0], [0, 0, 0.3, 0.8]], dtype=np.float32)
expected_merged_box_indices = np.array([0, 1, 2, 3], dtype=np.int32) expected_merged_box_indices = np.array([0, 1, 2, 3], dtype=np.int32)
with self.test_session() as sess:
(np_merged_boxes, np_merged_classes, np_merged_confidences, # Running on CPU only as tf.unique is not supported on TPU.
np_merged_box_indices) = sess.run( (np_merged_boxes, np_merged_classes, np_merged_confidences,
[merged_boxes, merged_classes, merged_confidences, np_merged_box_indices) = self.execute_cpu(graph_fn, [])
merged_box_indices])
self.assertAllClose(np_merged_boxes, expected_merged_boxes) self.assertAllClose(np_merged_boxes, expected_merged_boxes)
self.assertAllClose(np_merged_classes, expected_merged_classes) self.assertAllClose(np_merged_classes, expected_merged_classes)
self.assertAllClose(np_merged_confidences, expected_merged_confidences) self.assertAllClose(np_merged_confidences, expected_merged_confidences)
self.assertAllClose(np_merged_box_indices, expected_merged_box_indices) self.assertAllClose(np_merged_box_indices, expected_merged_box_indices)
def testMergeBoxesWithEmptyInputs(self): def testMergeBoxesWithEmptyInputs(self):
boxes = tf.zeros([0, 4], dtype=tf.float32)
class_indices = tf.constant([], dtype=tf.int32) def graph_fn():
class_confidences = tf.constant([], dtype=tf.float32) boxes = tf.zeros([0, 4], dtype=tf.float32)
num_classes = 5 class_indices = tf.constant([], dtype=tf.int32)
merged_boxes, merged_classes, merged_confidences, merged_box_indices = ( class_confidences = tf.constant([], dtype=tf.float32)
ops.merge_boxes_with_multiple_labels( num_classes = 5
boxes, class_indices, class_confidences, num_classes)) merged_boxes, merged_classes, merged_confidences, merged_box_indices = (
with self.test_session() as sess: ops.merge_boxes_with_multiple_labels(
(np_merged_boxes, np_merged_classes, np_merged_confidences, boxes, class_indices, class_confidences, num_classes))
np_merged_box_indices) = sess.run( return (merged_boxes, merged_classes, merged_confidences,
[merged_boxes, merged_classes, merged_confidences, merged_box_indices)
merged_box_indices])
self.assertAllEqual(np_merged_boxes.shape, [0, 4]) # Running on CPU only as tf.unique is not supported on TPU.
self.assertAllEqual(np_merged_classes.shape, [0, 5]) (np_merged_boxes, np_merged_classes, np_merged_confidences,
self.assertAllEqual(np_merged_confidences.shape, [0, 5]) np_merged_box_indices) = self.execute_cpu(graph_fn, [])
self.assertAllEqual(np_merged_box_indices.shape, [0]) self.assertAllEqual(np_merged_boxes.shape, [0, 4])
self.assertAllEqual(np_merged_classes.shape, [0, 5])
self.assertAllEqual(np_merged_confidences.shape, [0, 5])
self.assertAllEqual(np_merged_box_indices.shape, [0])
def testMergeBoxesWithMultipleLabelsUsesInt64(self): def testMergeBoxesWithMultipleLabelsUsesInt64(self):
if self.is_tf2():
self.skipTest('Getting op names is not supported in eager mode.')
boxes = tf.constant( boxes = tf.constant(
[[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75], [[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75],
[0.25, 0.25, 0.75, 0.75]], [0.25, 0.25, 0.75, 0.75]],
...@@ -1345,20 +1483,18 @@ class MatmulGatherOnZerothAxis(test_case.TestCase): ...@@ -1345,20 +1483,18 @@ class MatmulGatherOnZerothAxis(test_case.TestCase):
self.assertAllClose(gather_output, expected_output) self.assertAllClose(gather_output, expected_output)
def test_gather_with_dynamic_shape_input(self): def test_gather_with_dynamic_shape_input(self):
params_placeholder = tf.placeholder(tf.float32, shape=[None, 4])
indices_placeholder = tf.placeholder(tf.int32, shape=[None]) def graph_fn(params, indices):
gather_result = ops.matmul_gather_on_zeroth_axis( return ops.matmul_gather_on_zeroth_axis(params, indices)
params_placeholder, indices_placeholder)
params = np.array([[1, 2, 3, 4], params = np.array([[1, 2, 3, 4],
[5, 6, 7, 8], [5, 6, 7, 8],
[9, 10, 11, 12], [9, 10, 11, 12],
[0, 1, 0, 0]], dtype=np.float32) [0, 1, 0, 0]], dtype=np.float32)
indices = np.array([0, 0, 0, 0, 0, 0]) indices = np.array([0, 0, 0, 0, 0, 0])
expected_output = np.array(6*[[1, 2, 3, 4]]) expected_output = np.array(6*[[1, 2, 3, 4]])
with self.test_session() as sess: gather_output = self.execute(graph_fn, [params, indices])
gather_output = sess.run(gather_result, feed_dict={ self.assertAllClose(gather_output, expected_output)
params_placeholder: params, indices_placeholder: indices})
self.assertAllClose(gather_output, expected_output)
class FpnFeatureLevelsTest(test_case.TestCase): class FpnFeatureLevelsTest(test_case.TestCase):
...@@ -1419,22 +1555,27 @@ class TestBfloat16ToFloat32(test_case.TestCase): ...@@ -1419,22 +1555,27 @@ class TestBfloat16ToFloat32(test_case.TestCase):
class TestGatherWithPaddingValues(test_case.TestCase): class TestGatherWithPaddingValues(test_case.TestCase):
def test_gather_with_padding_values(self): def test_gather_with_padding_values(self):
indices = tf.constant([1, -1, 0, -1])
input_tensor = tf.constant([[0, 0, 0.1, 0.1], [0, 0, 0.2, 0.2]],
dtype=tf.float32)
expected_gathered_tensor = [ expected_gathered_tensor = [
[0, 0, 0.2, 0.2], [0, 0, 0.2, 0.2],
[0, 0, 0, 0], [0, 0, 0, 0],
[0, 0, 0.1, 0.1], [0, 0, 0.1, 0.1],
[0, 0, 0, 0], [0, 0, 0, 0],
] ]
gathered_tensor = ops.gather_with_padding_values(
input_tensor, def graph_fn():
indices=indices, indices = tf.constant([1, -1, 0, -1])
padding_value=tf.zeros_like(input_tensor[0])) input_tensor = tf.constant([[0, 0, 0.1, 0.1], [0, 0, 0.2, 0.2]],
self.assertEqual(gathered_tensor.dtype, tf.float32) dtype=tf.float32)
with self.test_session():
gathered_tensor_np = gathered_tensor.eval() gathered_tensor = ops.gather_with_padding_values(
input_tensor,
indices=indices,
padding_value=tf.zeros_like(input_tensor[0]))
self.assertEqual(gathered_tensor.dtype, tf.float32)
return gathered_tensor
gathered_tensor_np = self.execute(graph_fn, [])
self.assertAllClose(expected_gathered_tensor, gathered_tensor_np) self.assertAllClose(expected_gathered_tensor, gathered_tensor_np)
......
...@@ -19,7 +19,7 @@ from __future__ import absolute_import ...@@ -19,7 +19,7 @@ from __future__ import absolute_import
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
import tensorflow as tf import tensorflow.compat.v1 as tf
def get_patch_mask(y, x, patch_size, image_shape): def get_patch_mask(y, x, patch_size, image_shape):
......
...@@ -21,7 +21,7 @@ from __future__ import print_function ...@@ -21,7 +21,7 @@ from __future__ import print_function
from absl.testing import parameterized from absl.testing import parameterized
import numpy as np import numpy as np
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import patch_ops from object_detection.utils import patch_ops
from object_detection.utils import test_case from object_detection.utils import test_case
......
...@@ -21,7 +21,7 @@ from __future__ import print_function ...@@ -21,7 +21,7 @@ from __future__ import print_function
import numpy as np import numpy as np
from six.moves import range from six.moves import range
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import per_image_evaluation from object_detection.utils import per_image_evaluation
......
...@@ -19,7 +19,7 @@ from __future__ import division ...@@ -19,7 +19,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import numpy as np import numpy as np
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import per_image_vrd_evaluation from object_detection.utils import per_image_vrd_evaluation
......
...@@ -20,7 +20,7 @@ from __future__ import division ...@@ -20,7 +20,7 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
from six.moves import zip from six.moves import zip
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import static_shape from object_detection.utils import static_shape
...@@ -69,17 +69,18 @@ def pad_tensor(t, length): ...@@ -69,17 +69,18 @@ def pad_tensor(t, length):
is an integer, the first dimension of padded_t is set to length is an integer, the first dimension of padded_t is set to length
statically. statically.
""" """
t_rank = tf.rank(t)
t_shape = tf.shape(t) # Computing the padding statically makes the operation work with XLA.
t_d0 = t_shape[0] rank = len(t.get_shape())
pad_d0 = tf.expand_dims(length - t_d0, 0) paddings = [[0 for _ in range(2)] for _ in range(rank)]
pad_shape = tf.cond( t_d0 = tf.shape(t)[0]
tf.greater(t_rank, 1), lambda: tf.concat([pad_d0, t_shape[1:]], 0),
lambda: tf.expand_dims(length - t_d0, 0)) if isinstance(length, int) or len(length.get_shape()) == 0: # pylint:disable=g-explicit-length-test
padded_t = tf.concat([t, tf.zeros(pad_shape, dtype=t.dtype)], 0) paddings[0][1] = length - t_d0
if not _is_tensor(length): else:
padded_t = _set_dim_0(padded_t, length) paddings[0][1] = length[0] - t_d0
return padded_t
return tf.pad(t, paddings)
def clip_tensor(t, length): def clip_tensor(t, length):
......
...@@ -20,216 +20,215 @@ from __future__ import division ...@@ -20,216 +20,215 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import numpy as np import numpy as np
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import shape_utils from object_detection.utils import shape_utils
from object_detection.utils import test_case
# pylint: disable=g-import-not-at-top
try:
from tensorflow.contrib import framework as contrib_framework
except ImportError:
# TF 2.0 doesn't ship with contrib.
pass
# pylint: enable=g-import-not-at-top
class UtilTest(test_case.TestCase):
class UtilTest(tf.test.TestCase):
def test_pad_tensor_using_integer_input(self): def test_pad_tensor_using_integer_input(self):
t1 = tf.constant([1], dtype=tf.int32)
pad_t1 = shape_utils.pad_tensor(t1, 2)
t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32)
pad_t2 = shape_utils.pad_tensor(t2, 2)
self.assertEqual(2, pad_t1.get_shape()[0]) print('........pad tensor using interger input.')
self.assertEqual(2, pad_t2.get_shape()[0]) def graph_fn():
t1 = tf.constant([1], dtype=tf.int32)
pad_t1 = shape_utils.pad_tensor(t1, 2)
t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32)
pad_t2 = shape_utils.pad_tensor(t2, 2)
return pad_t1, pad_t2
pad_t1_result, pad_t2_result = self.execute(graph_fn, [])
with self.test_session() as sess: self.assertAllEqual([1, 0], pad_t1_result)
pad_t1_result, pad_t2_result = sess.run([pad_t1, pad_t2]) self.assertAllClose([[0.1, 0.2], [0, 0]], pad_t2_result)
self.assertAllEqual([1, 0], pad_t1_result)
self.assertAllClose([[0.1, 0.2], [0, 0]], pad_t2_result)
def test_pad_tensor_using_tensor_input(self): def test_pad_tensor_using_tensor_input(self):
t1 = tf.constant([1], dtype=tf.int32)
pad_t1 = shape_utils.pad_tensor(t1, tf.constant(2))
t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32)
pad_t2 = shape_utils.pad_tensor(t2, tf.constant(2))
with self.test_session() as sess: def graph_fn():
pad_t1_result, pad_t2_result = sess.run([pad_t1, pad_t2]) t1 = tf.constant([1], dtype=tf.int32)
self.assertAllEqual([1, 0], pad_t1_result) pad_t1 = shape_utils.pad_tensor(t1, tf.constant(2))
self.assertAllClose([[0.1, 0.2], [0, 0]], pad_t2_result) t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32)
pad_t2 = shape_utils.pad_tensor(t2, tf.constant(2))
return pad_t1, pad_t2
pad_t1_result, pad_t2_result = self.execute(graph_fn, [])
self.assertAllEqual([1, 0], pad_t1_result)
self.assertAllClose([[0.1, 0.2], [0, 0]], pad_t2_result)
def test_clip_tensor_using_integer_input(self): def test_clip_tensor_using_integer_input(self):
t1 = tf.constant([1, 2, 3], dtype=tf.int32)
clip_t1 = shape_utils.clip_tensor(t1, 2)
t2 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32)
clip_t2 = shape_utils.clip_tensor(t2, 2)
self.assertEqual(2, clip_t1.get_shape()[0]) def graph_fn():
self.assertEqual(2, clip_t2.get_shape()[0]) t1 = tf.constant([1, 2, 3], dtype=tf.int32)
clip_t1 = shape_utils.clip_tensor(t1, 2)
t2 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32)
clip_t2 = shape_utils.clip_tensor(t2, 2)
with self.test_session() as sess: self.assertEqual(2, clip_t1.get_shape()[0])
clip_t1_result, clip_t2_result = sess.run([clip_t1, clip_t2]) self.assertEqual(2, clip_t2.get_shape()[0])
self.assertAllEqual([1, 2], clip_t1_result)
self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], clip_t2_result) return clip_t1, clip_t2
clip_t1_result, clip_t2_result = self.execute(graph_fn, [])
self.assertAllEqual([1, 2], clip_t1_result)
self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], clip_t2_result)
def test_clip_tensor_using_tensor_input(self): def test_clip_tensor_using_tensor_input(self):
t1 = tf.constant([1, 2, 3], dtype=tf.int32)
clip_t1 = shape_utils.clip_tensor(t1, tf.constant(2))
t2 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32)
clip_t2 = shape_utils.clip_tensor(t2, tf.constant(2))
with self.test_session() as sess: def graph_fn():
clip_t1_result, clip_t2_result = sess.run([clip_t1, clip_t2]) t1 = tf.constant([1, 2, 3], dtype=tf.int32)
self.assertAllEqual([1, 2], clip_t1_result) clip_t1 = shape_utils.clip_tensor(t1, tf.constant(2))
self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], clip_t2_result) t2 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32)
clip_t2 = shape_utils.clip_tensor(t2, tf.constant(2))
return clip_t1, clip_t2
clip_t1_result, clip_t2_result = self.execute(graph_fn, [])
self.assertAllEqual([1, 2], clip_t1_result)
self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], clip_t2_result)
def test_pad_or_clip_tensor_using_integer_input(self): def test_pad_or_clip_tensor_using_integer_input(self):
t1 = tf.constant([1], dtype=tf.int32)
tt1 = shape_utils.pad_or_clip_tensor(t1, 2) def graph_fn():
t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32) t1 = tf.constant([1], dtype=tf.int32)
tt2 = shape_utils.pad_or_clip_tensor(t2, 2) tt1 = shape_utils.pad_or_clip_tensor(t1, 2)
t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32)
t3 = tf.constant([1, 2, 3], dtype=tf.int32) tt2 = shape_utils.pad_or_clip_tensor(t2, 2)
tt3 = shape_utils.clip_tensor(t3, 2)
t4 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32) t3 = tf.constant([1, 2, 3], dtype=tf.int32)
tt4 = shape_utils.clip_tensor(t4, 2) tt3 = shape_utils.clip_tensor(t3, 2)
t4 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32)
self.assertEqual(2, tt1.get_shape()[0]) tt4 = shape_utils.clip_tensor(t4, 2)
self.assertEqual(2, tt2.get_shape()[0])
self.assertEqual(2, tt3.get_shape()[0]) self.assertEqual(2, tt1.get_shape()[0])
self.assertEqual(2, tt4.get_shape()[0]) self.assertEqual(2, tt2.get_shape()[0])
self.assertEqual(2, tt3.get_shape()[0])
with self.test_session() as sess: self.assertEqual(2, tt4.get_shape()[0])
tt1_result, tt2_result, tt3_result, tt4_result = sess.run(
[tt1, tt2, tt3, tt4]) return tt1, tt2, tt3, tt4
self.assertAllEqual([1, 0], tt1_result)
self.assertAllClose([[0.1, 0.2], [0, 0]], tt2_result) tt1_result, tt2_result, tt3_result, tt4_result = self.execute(graph_fn, [])
self.assertAllEqual([1, 2], tt3_result) self.assertAllEqual([1, 0], tt1_result)
self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], tt4_result) self.assertAllClose([[0.1, 0.2], [0, 0]], tt2_result)
self.assertAllEqual([1, 2], tt3_result)
self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], tt4_result)
def test_pad_or_clip_tensor_using_tensor_input(self): def test_pad_or_clip_tensor_using_tensor_input(self):
t1 = tf.constant([1], dtype=tf.int32)
tt1 = shape_utils.pad_or_clip_tensor(t1, tf.constant(2)) def graph_fn():
t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32) t1 = tf.constant([1], dtype=tf.int32)
tt2 = shape_utils.pad_or_clip_tensor(t2, tf.constant(2)) tt1 = shape_utils.pad_or_clip_tensor(t1, tf.constant(2))
t2 = tf.constant([[0.1, 0.2]], dtype=tf.float32)
t3 = tf.constant([1, 2, 3], dtype=tf.int32) tt2 = shape_utils.pad_or_clip_tensor(t2, tf.constant(2))
tt3 = shape_utils.clip_tensor(t3, tf.constant(2))
t4 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32) t3 = tf.constant([1, 2, 3], dtype=tf.int32)
tt4 = shape_utils.clip_tensor(t4, tf.constant(2)) tt3 = shape_utils.clip_tensor(t3, tf.constant(2))
t4 = tf.constant([[0.1, 0.2], [0.2, 0.4], [0.5, 0.8]], dtype=tf.float32)
with self.test_session() as sess: tt4 = shape_utils.clip_tensor(t4, tf.constant(2))
tt1_result, tt2_result, tt3_result, tt4_result = sess.run(
[tt1, tt2, tt3, tt4]) return tt1, tt2, tt3, tt4
self.assertAllEqual([1, 0], tt1_result)
self.assertAllClose([[0.1, 0.2], [0, 0]], tt2_result) tt1_result, tt2_result, tt3_result, tt4_result = self.execute(graph_fn, [])
self.assertAllEqual([1, 2], tt3_result) self.assertAllEqual([1, 0], tt1_result)
self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], tt4_result) self.assertAllClose([[0.1, 0.2], [0, 0]], tt2_result)
self.assertAllEqual([1, 2], tt3_result)
def test_combines_static_dynamic_shape(self): self.assertAllClose([[0.1, 0.2], [0.2, 0.4]], tt4_result)
tensor = tf.placeholder(tf.float32, shape=(None, 2, 3))
combined_shape = shape_utils.combined_static_and_dynamic_shape( def test_combined_static_dynamic_shape(self):
tensor)
self.assertTrue(contrib_framework.is_tensor(combined_shape[0])) for n in [2, 3, 4]:
self.assertListEqual(combined_shape[1:], [2, 3]) tensor = tf.zeros((n, 2, 3))
combined_shape = shape_utils.combined_static_and_dynamic_shape(
tensor)
self.assertListEqual(combined_shape[1:], [2, 3])
def test_pad_or_clip_nd_tensor(self): def test_pad_or_clip_nd_tensor(self):
tensor_placeholder = tf.placeholder(tf.float32, [None, 5, 4, 7])
output_tensor = shape_utils.pad_or_clip_nd(
tensor_placeholder, [None, 3, 5, tf.constant(6)])
self.assertAllEqual(output_tensor.shape.as_list(), [None, 3, 5, None]) def graph_fn(input_tensor):
output_tensor = shape_utils.pad_or_clip_nd(
input_tensor, [None, 3, 5, tf.constant(6)])
with self.test_session() as sess: return output_tensor
output_tensor_np = sess.run(
output_tensor,
feed_dict={
tensor_placeholder: np.random.rand(2, 5, 4, 7),
})
self.assertAllEqual(output_tensor_np.shape, [2, 3, 5, 6]) for n in [2, 3, 4, 5]:
input_np = np.zeros((n, 5, 4, 7))
output_tensor_np = self.execute(graph_fn, [input_np])
self.assertAllEqual(output_tensor_np.shape[1:], [3, 5, 6])
class StaticOrDynamicMapFnTest(tf.test.TestCase): class StaticOrDynamicMapFnTest(test_case.TestCase):
def test_with_dynamic_shape(self): def test_with_dynamic_shape(self):
def fn(input_tensor): def fn(input_tensor):
return tf.reduce_sum(input_tensor) return tf.reduce_sum(input_tensor)
input_tensor = tf.placeholder(tf.float32, shape=(None, 2))
map_fn_output = shape_utils.static_or_dynamic_map_fn(fn, input_tensor) def graph_fn(input_tensor):
return shape_utils.static_or_dynamic_map_fn(fn, input_tensor)
op_names = [op.name for op in tf.get_default_graph().get_operations()]
self.assertTrue(any(['map' == op_name[:3] for op_name in op_names])) # The input has different shapes, but due to how self.execute()
# works, the shape is known at graph compile time.
with self.test_session() as sess: result1 = self.execute(
result1 = sess.run( graph_fn, [np.array([[1, 2], [3, 1], [0, 4]]),])
map_fn_output, feed_dict={ result2 = self.execute(
input_tensor: [[1, 2], [3, 1], [0, 4]]}) graph_fn, [np.array([[-1, 1], [0, 9]]),])
result2 = sess.run( self.assertAllEqual(result1, [3, 4, 4])
map_fn_output, feed_dict={ self.assertAllEqual(result2, [0, 9])
input_tensor: [[-1, 1], [0, 9]]})
self.assertAllEqual(result1, [3, 4, 4])
self.assertAllEqual(result2, [0, 9])
def test_with_static_shape(self): def test_with_static_shape(self):
def fn(input_tensor): def fn(input_tensor):
return tf.reduce_sum(input_tensor) return tf.reduce_sum(input_tensor)
input_tensor = tf.constant([[1, 2], [3, 1], [0, 4]], dtype=tf.float32)
map_fn_output = shape_utils.static_or_dynamic_map_fn(fn, input_tensor)
op_names = [op.name for op in tf.get_default_graph().get_operations()] def graph_fn():
self.assertTrue(all(['map' != op_name[:3] for op_name in op_names])) input_tensor = tf.constant([[1, 2], [3, 1], [0, 4]], dtype=tf.float32)
return shape_utils.static_or_dynamic_map_fn(fn, input_tensor)
with self.test_session() as sess: result = self.execute(graph_fn, [])
result = sess.run(map_fn_output) self.assertAllEqual(result, [3, 4, 4])
self.assertAllEqual(result, [3, 4, 4])
def test_with_multiple_dynamic_shapes(self): def test_with_multiple_dynamic_shapes(self):
def fn(elems): def fn(elems):
input_tensor, scalar_index_tensor = elems input_tensor, scalar_index_tensor = elems
return tf.reshape(tf.slice(input_tensor, scalar_index_tensor, [1]), []) return tf.reshape(tf.slice(input_tensor, scalar_index_tensor, [1]), [])
input_tensor = tf.placeholder(tf.float32, shape=(None, 3)) def graph_fn(input_tensor, scalar_index_tensor):
scalar_index_tensor = tf.placeholder(tf.int32, shape=(None, 1)) map_fn_output = shape_utils.static_or_dynamic_map_fn(
map_fn_output = shape_utils.static_or_dynamic_map_fn( fn, [input_tensor, scalar_index_tensor], dtype=tf.float32)
fn, [input_tensor, scalar_index_tensor], dtype=tf.float32) return map_fn_output
op_names = [op.name for op in tf.get_default_graph().get_operations()] # The input has different shapes, but due to how self.execute()
self.assertTrue(any(['map' == op_name[:3] for op_name in op_names])) # works, the shape is known at graph compile time.
with self.test_session() as sess: result1 = self.execute(
result1 = sess.run( graph_fn, [
map_fn_output, feed_dict={ np.array([[1, 2, 3], [4, 5, -1], [0, 6, 9]]),
input_tensor: [[1, 2, 3], [4, 5, -1], [0, 6, 9]], np.array([[0], [2], [1]]),
scalar_index_tensor: [[0], [2], [1]], ])
}) result2 = self.execute(
result2 = sess.run( graph_fn, [
map_fn_output, feed_dict={ np.array([[-1, 1, 0], [3, 9, 30]]),
input_tensor: [[-1, 1, 0], [3, 9, 30]], np.array([[1], [0]])
scalar_index_tensor: [[1], [0]] ])
}) self.assertAllEqual(result1, [1, -1, 6])
self.assertAllEqual(result1, [1, -1, 6]) self.assertAllEqual(result2, [1, 3])
self.assertAllEqual(result2, [1, 3])
def test_with_multiple_static_shapes(self): def test_with_multiple_static_shapes(self):
def fn(elems): def fn(elems):
input_tensor, scalar_index_tensor = elems input_tensor, scalar_index_tensor = elems
return tf.reshape(tf.slice(input_tensor, scalar_index_tensor, [1]), []) return tf.reshape(tf.slice(input_tensor, scalar_index_tensor, [1]), [])
input_tensor = tf.constant([[1, 2, 3], [4, 5, -1], [0, 6, 9]], def graph_fn():
dtype=tf.float32) input_tensor = tf.constant([[1, 2, 3], [4, 5, -1], [0, 6, 9]],
scalar_index_tensor = tf.constant([[0], [2], [1]], dtype=tf.int32) dtype=tf.float32)
map_fn_output = shape_utils.static_or_dynamic_map_fn( scalar_index_tensor = tf.constant([[0], [2], [1]], dtype=tf.int32)
fn, [input_tensor, scalar_index_tensor], dtype=tf.float32) map_fn_output = shape_utils.static_or_dynamic_map_fn(
fn, [input_tensor, scalar_index_tensor], dtype=tf.float32)
return map_fn_output
op_names = [op.name for op in tf.get_default_graph().get_operations()] result = self.execute(graph_fn, [])
self.assertTrue(all(['map' != op_name[:3] for op_name in op_names])) self.assertAllEqual(result, [1, -1, 6])
with self.test_session() as sess:
result = sess.run(map_fn_output)
self.assertAllEqual(result, [1, -1, 6])
def test_fails_with_nested_input(self): def test_fails_with_nested_input(self):
def fn(input_tensor): def fn(input_tensor):
...@@ -242,7 +241,7 @@ class StaticOrDynamicMapFnTest(tf.test.TestCase): ...@@ -242,7 +241,7 @@ class StaticOrDynamicMapFnTest(tf.test.TestCase):
fn, [input_tensor1, [input_tensor2]], dtype=tf.float32) fn, [input_tensor1, [input_tensor2]], dtype=tf.float32)
class CheckMinImageShapeTest(tf.test.TestCase): class CheckMinImageShapeTest(test_case.TestCase):
def test_check_min_image_dim_static_shape(self): def test_check_min_image_dim_static_shape(self):
input_tensor = tf.constant(np.zeros([1, 42, 42, 3])) input_tensor = tf.constant(np.zeros([1, 42, 42, 3]))
...@@ -253,125 +252,151 @@ class CheckMinImageShapeTest(tf.test.TestCase): ...@@ -253,125 +252,151 @@ class CheckMinImageShapeTest(tf.test.TestCase):
_ = shape_utils.check_min_image_dim(64, input_tensor) _ = shape_utils.check_min_image_dim(64, input_tensor)
def test_check_min_image_dim_dynamic_shape(self): def test_check_min_image_dim_dynamic_shape(self):
input_placeholder = tf.placeholder(tf.float32, shape=[1, None, None, 3])
image_tensor = shape_utils.check_min_image_dim(33, input_placeholder)
with self.test_session() as sess: def graph_fn(input_tensor):
sess.run(image_tensor, return shape_utils.check_min_image_dim(33, input_tensor)
feed_dict={input_placeholder: np.zeros([1, 42, 42, 3])})
with self.assertRaises(tf.errors.InvalidArgumentError): self.execute(graph_fn,
sess.run(image_tensor, [np.zeros([1, 42, 42, 3])])
feed_dict={input_placeholder: np.zeros([1, 32, 32, 3])}) self.assertRaises(
ValueError, self.execute,
graph_fn, np.zeros([1, 32, 32, 3])
)
class AssertShapeEqualTest(tf.test.TestCase): class AssertShapeEqualTest(test_case.TestCase):
def test_unequal_static_shape_raises_exception(self): def test_unequal_static_shape_raises_exception(self):
shape_a = tf.constant(np.zeros([4, 2, 2, 1])) shape_a = tf.constant(np.zeros([4, 2, 2, 1]))
shape_b = tf.constant(np.zeros([4, 2, 3, 1])) shape_b = tf.constant(np.zeros([4, 2, 3, 1]))
with self.assertRaisesRegexp( self.assertRaisesRegex(
ValueError, 'Unequal shapes'): ValueError, 'Unequal shapes',
shape_utils.assert_shape_equal( shape_utils.assert_shape_equal,
shape_utils.combined_static_and_dynamic_shape(shape_a), shape_utils.combined_static_and_dynamic_shape(shape_a),
shape_utils.combined_static_and_dynamic_shape(shape_b)) shape_utils.combined_static_and_dynamic_shape(shape_b)
)
def test_equal_static_shape_succeeds(self): def test_equal_static_shape_succeeds(self):
shape_a = tf.constant(np.zeros([4, 2, 2, 1]))
shape_b = tf.constant(np.zeros([4, 2, 2, 1])) def graph_fn():
with self.test_session() as sess: shape_a = tf.constant(np.zeros([4, 2, 2, 1]))
op = shape_utils.assert_shape_equal( shape_b = tf.constant(np.zeros([4, 2, 2, 1]))
shape_utils.assert_shape_equal(
shape_utils.combined_static_and_dynamic_shape(shape_a), shape_utils.combined_static_and_dynamic_shape(shape_a),
shape_utils.combined_static_and_dynamic_shape(shape_b)) shape_utils.combined_static_and_dynamic_shape(shape_b))
sess.run(op)
return tf.constant(0)
self.execute(graph_fn, [])
def test_unequal_dynamic_shape_raises_tf_assert(self): def test_unequal_dynamic_shape_raises_tf_assert(self):
tensor_a = tf.placeholder(tf.float32, shape=[1, None, None, 3])
tensor_b = tf.placeholder(tf.float32, shape=[1, None, None, 3]) def graph_fn(tensor_a, tensor_b):
op = shape_utils.assert_shape_equal( shape_utils.assert_shape_equal(
shape_utils.combined_static_and_dynamic_shape(tensor_a), shape_utils.combined_static_and_dynamic_shape(tensor_a),
shape_utils.combined_static_and_dynamic_shape(tensor_b)) shape_utils.combined_static_and_dynamic_shape(tensor_b))
with self.test_session() as sess: return tf.constant(0)
with self.assertRaises(tf.errors.InvalidArgumentError):
sess.run(op, feed_dict={tensor_a: np.zeros([1, 2, 2, 3]), self.assertRaises(ValueError,
tensor_b: np.zeros([1, 4, 4, 3])}) self.execute, graph_fn,
[np.zeros([1, 2, 2, 3]), np.zeros([1, 4, 4, 3])])
def test_equal_dynamic_shape_succeeds(self): def test_equal_dynamic_shape_succeeds(self):
tensor_a = tf.placeholder(tf.float32, shape=[1, None, None, 3])
tensor_b = tf.placeholder(tf.float32, shape=[1, None, None, 3]) def graph_fn(tensor_a, tensor_b):
op = shape_utils.assert_shape_equal( shape_utils.assert_shape_equal(
shape_utils.combined_static_and_dynamic_shape(tensor_a), shape_utils.combined_static_and_dynamic_shape(tensor_a),
shape_utils.combined_static_and_dynamic_shape(tensor_b)) shape_utils.combined_static_and_dynamic_shape(tensor_b)
with self.test_session() as sess: )
sess.run(op, feed_dict={tensor_a: np.zeros([1, 2, 2, 3]),
tensor_b: np.zeros([1, 2, 2, 3])}) return tf.constant(0)
self.execute(graph_fn, [np.zeros([1, 2, 2, 3]),
np.zeros([1, 2, 2, 3])])
def test_unequal_static_shape_along_first_dim_raises_exception(self): def test_unequal_static_shape_along_first_dim_raises_exception(self):
shape_a = tf.constant(np.zeros([4, 2, 2, 1])) shape_a = tf.constant(np.zeros([4, 2, 2, 1]))
shape_b = tf.constant(np.zeros([6, 2, 3, 1])) shape_b = tf.constant(np.zeros([6, 2, 3, 1]))
with self.assertRaisesRegexp(
ValueError, 'Unequal first dimension'): self.assertRaisesRegexp(
shape_utils.assert_shape_equal_along_first_dimension( ValueError, 'Unequal first dimension',
shape_utils.combined_static_and_dynamic_shape(shape_a), shape_utils.assert_shape_equal_along_first_dimension,
shape_utils.combined_static_and_dynamic_shape(shape_b)) shape_utils.combined_static_and_dynamic_shape(shape_a),
shape_utils.combined_static_and_dynamic_shape(shape_b)
)
def test_equal_static_shape_along_first_dim_succeeds(self): def test_equal_static_shape_along_first_dim_succeeds(self):
shape_a = tf.constant(np.zeros([4, 2, 2, 1]))
shape_b = tf.constant(np.zeros([4, 7, 2])) def graph_fn():
with self.test_session() as sess: shape_a = tf.constant(np.zeros([4, 2, 2, 1]))
op = shape_utils.assert_shape_equal_along_first_dimension( shape_b = tf.constant(np.zeros([4, 7, 2]))
shape_utils.assert_shape_equal_along_first_dimension(
shape_utils.combined_static_and_dynamic_shape(shape_a), shape_utils.combined_static_and_dynamic_shape(shape_a),
shape_utils.combined_static_and_dynamic_shape(shape_b)) shape_utils.combined_static_and_dynamic_shape(shape_b))
sess.run(op) return tf.constant(0)
self.execute(graph_fn, [])
def test_unequal_dynamic_shape_along_first_dim_raises_tf_assert(self): def test_unequal_dynamic_shape_along_first_dim_raises_tf_assert(self):
tensor_a = tf.placeholder(tf.float32, shape=[None, None, None, 3])
tensor_b = tf.placeholder(tf.float32, shape=[None, None, 3]) def graph_fn(tensor_a, tensor_b):
op = shape_utils.assert_shape_equal_along_first_dimension( shape_utils.assert_shape_equal_along_first_dimension(
shape_utils.combined_static_and_dynamic_shape(tensor_a), shape_utils.combined_static_and_dynamic_shape(tensor_a),
shape_utils.combined_static_and_dynamic_shape(tensor_b)) shape_utils.combined_static_and_dynamic_shape(tensor_b))
with self.test_session() as sess:
with self.assertRaises(tf.errors.InvalidArgumentError): return tf.constant(0)
sess.run(op, feed_dict={tensor_a: np.zeros([1, 2, 2, 3]),
tensor_b: np.zeros([2, 4, 3])}) self.assertRaises(ValueError,
self.execute, graph_fn,
[np.zeros([1, 2, 2, 3]), np.zeros([2, 4, 3])])
def test_equal_dynamic_shape_along_first_dim_succeeds(self): def test_equal_dynamic_shape_along_first_dim_succeeds(self):
tensor_a = tf.placeholder(tf.float32, shape=[None, None, None, 3])
tensor_b = tf.placeholder(tf.float32, shape=[None]) def graph_fn(tensor_a, tensor_b):
op = shape_utils.assert_shape_equal_along_first_dimension( shape_utils.assert_shape_equal_along_first_dimension(
shape_utils.combined_static_and_dynamic_shape(tensor_a), shape_utils.combined_static_and_dynamic_shape(tensor_a),
shape_utils.combined_static_and_dynamic_shape(tensor_b)) shape_utils.combined_static_and_dynamic_shape(tensor_b))
with self.test_session() as sess: return tf.constant(0)
sess.run(op, feed_dict={tensor_a: np.zeros([5, 2, 2, 3]),
tensor_b: np.zeros([5])}) self.execute(graph_fn, [np.zeros([5, 2, 2, 3]), np.zeros([5])])
class FlattenExpandDimensionTest(tf.test.TestCase): class FlattenExpandDimensionTest(test_case.TestCase):
def test_flatten_given_dims(self): def test_flatten_given_dims(self):
inputs = tf.random_uniform([5, 2, 10, 10, 3])
actual_flattened = shape_utils.flatten_dimensions(inputs, first=1, last=3) def graph_fn():
expected_flattened = tf.reshape(inputs, [5, 20, 10, 3]) inputs = tf.random_uniform([5, 2, 10, 10, 3])
with self.test_session() as sess: actual_flattened = shape_utils.flatten_dimensions(inputs, first=1, last=3)
(actual_flattened_np, expected_flattened = tf.reshape(inputs, [5, 20, 10, 3])
expected_flattened_np) = sess.run([actual_flattened, expected_flattened])
return actual_flattened, expected_flattened
(actual_flattened_np,
expected_flattened_np) = self.execute(graph_fn, [])
self.assertAllClose(expected_flattened_np, actual_flattened_np) self.assertAllClose(expected_flattened_np, actual_flattened_np)
def test_raises_value_error_incorrect_dimensions(self): def test_raises_value_error_incorrect_dimensions(self):
inputs = tf.random_uniform([5, 2, 10, 10, 3]) inputs = tf.random_uniform([5, 2, 10, 10, 3])
with self.assertRaises(ValueError): self.assertRaises(ValueError,
shape_utils.flatten_dimensions(inputs, first=0, last=6) shape_utils.flatten_dimensions, inputs,
first=0, last=6)
def test_flatten_first_two_dimensions(self): def test_flatten_first_two_dimensions(self):
inputs = tf.constant(
[ def graph_fn():
[[1, 2], [3, 4]], inputs = tf.constant(
[[5, 6], [7, 8]], [
[[9, 10], [11, 12]] [[1, 2], [3, 4]],
], dtype=tf.int32) [[5, 6], [7, 8]],
flattened_tensor = shape_utils.flatten_first_n_dimensions( [[9, 10], [11, 12]]
inputs, 2) ], dtype=tf.int32)
with self.test_session() as sess: flattened_tensor = shape_utils.flatten_first_n_dimensions(
flattened_tensor_out = sess.run(flattened_tensor) inputs, 2)
return flattened_tensor
flattened_tensor_out = self.execute(graph_fn, [])
expected_output = [[1, 2], expected_output = [[1, 2],
[3, 4], [3, 4],
...@@ -382,20 +407,23 @@ class FlattenExpandDimensionTest(tf.test.TestCase): ...@@ -382,20 +407,23 @@ class FlattenExpandDimensionTest(tf.test.TestCase):
self.assertAllEqual(expected_output, flattened_tensor_out) self.assertAllEqual(expected_output, flattened_tensor_out)
def test_expand_first_dimension(self): def test_expand_first_dimension(self):
inputs = tf.constant(
[ def graph_fn():
[1, 2], inputs = tf.constant(
[3, 4], [
[5, 6], [1, 2],
[7, 8], [3, 4],
[9, 10], [5, 6],
[11, 12] [7, 8],
], dtype=tf.int32) [9, 10],
dims = [3, 2] [11, 12]
expanded_tensor = shape_utils.expand_first_dimension( ], dtype=tf.int32)
inputs, dims) dims = [3, 2]
with self.test_session() as sess: expanded_tensor = shape_utils.expand_first_dimension(
expanded_tensor_out = sess.run(expanded_tensor) inputs, dims)
return expanded_tensor
expanded_tensor_out = self.execute(graph_fn, [])
expected_output = [ expected_output = [
[[1, 2], [3, 4]], [[1, 2], [3, 4]],
...@@ -404,19 +432,20 @@ class FlattenExpandDimensionTest(tf.test.TestCase): ...@@ -404,19 +432,20 @@ class FlattenExpandDimensionTest(tf.test.TestCase):
self.assertAllEqual(expected_output, expanded_tensor_out) self.assertAllEqual(expected_output, expanded_tensor_out)
def test_expand_first_dimension_with_incompatible_dims(self): def test_expand_first_dimension_with_incompatible_dims(self):
inputs_default = tf.constant(
[ def graph_fn():
[[1, 2]], inputs = tf.constant(
[[3, 4]], [
[[5, 6]], [[1, 2]],
], dtype=tf.int32) [[3, 4]],
inputs = tf.placeholder_with_default(inputs_default, [None, 1, 2]) [[5, 6]],
dims = [3, 2] ], dtype=tf.int32)
expanded_tensor = shape_utils.expand_first_dimension( dims = [3, 2]
inputs, dims) expanded_tensor = shape_utils.expand_first_dimension(
with self.test_session() as sess: inputs, dims)
with self.assertRaises(tf.errors.InvalidArgumentError): return expanded_tensor
sess.run(expanded_tensor)
self.assertRaises(ValueError, self.execute, graph_fn, [])
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -18,7 +18,7 @@ from __future__ import absolute_import ...@@ -18,7 +18,7 @@ from __future__ import absolute_import
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
import tensorflow as tf import tensorflow.compat.v1 as tf
def _coordinate_vector_1d(start, end, size, align_endpoints): def _coordinate_vector_1d(start, end, size, align_endpoints):
......
...@@ -20,7 +20,7 @@ from __future__ import print_function ...@@ -20,7 +20,7 @@ from __future__ import print_function
import numpy as np import numpy as np
from six.moves import range from six.moves import range
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import spatial_transform_ops as spatial_ops from object_detection.utils import spatial_transform_ops as spatial_ops
from object_detection.utils import test_case from object_detection.utils import test_case
......
...@@ -19,7 +19,7 @@ from __future__ import absolute_import ...@@ -19,7 +19,7 @@ from __future__ import absolute_import
from __future__ import division from __future__ import division
from __future__ import print_function from __future__ import print_function
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import static_shape from object_detection.utils import static_shape
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# ============================================================================== # ==============================================================================
"""Utility functions used by target assigner.""" """Utility functions used by target assigner."""
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import shape_utils from object_detection.utils import shape_utils
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
"""Tests for utils.target_assigner_utils.""" """Tests for utils.target_assigner_utils."""
import numpy as np import numpy as np
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import target_assigner_utils as ta_utils from object_detection.utils import target_assigner_utils as ta_utils
from object_detection.utils import test_case from object_detection.utils import test_case
......
...@@ -18,8 +18,9 @@ from __future__ import absolute_import ...@@ -18,8 +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 six.moves import zip from six.moves import zip
import tensorflow as tf import tensorflow.compat.v1 as tf
from tensorflow.python import tf2 # pylint: disable=import-outside-toplevel from tensorflow.python import tf2 # pylint: disable=import-outside-toplevel
from object_detection.utils import tf_version
if not tf2.enabled(): if not tf2.enabled():
from tensorflow.contrib import tpu as contrib_tpu # pylint: disable=g-import-not-at-top, line-too-long from tensorflow.contrib import tpu as contrib_tpu # pylint: disable=g-import-not-at-top, line-too-long
...@@ -58,9 +59,9 @@ class TestCase(tf.test.TestCase): ...@@ -58,9 +59,9 @@ class TestCase(tf.test.TestCase):
def is_tf2(self): def is_tf2(self):
"""Returns whether TF2 is enabled.""" """Returns whether TF2 is enabled."""
return tf2.enabled() return tf_version.is_tf2()
def execute_tpu_tf1(self, compute_fn, inputs): def execute_tpu_tf1(self, compute_fn, inputs, graph=None):
"""Executes compute_fn on TPU with Tensorflow 1.X. """Executes compute_fn on TPU with Tensorflow 1.X.
Args: Args:
...@@ -68,11 +69,13 @@ class TestCase(tf.test.TestCase): ...@@ -68,11 +69,13 @@ class TestCase(tf.test.TestCase):
of input numpy tensors, performs computation and returns output numpy of input numpy tensors, performs computation and returns output numpy
tensors. tensors.
inputs: a list of numpy arrays to feed input to the `compute_fn`. inputs: a list of numpy arrays to feed input to the `compute_fn`.
graph: (optional) If not None, provided `graph` is used for computation
instead of a brand new tf.Graph().
Returns: Returns:
A list of numpy arrays or a single numpy array. A list of numpy arrays or a single numpy array.
""" """
with self.test_session(graph=tf.Graph()) as sess: with self.session(graph=(graph or tf.Graph())) as sess:
placeholders = [tf.placeholder_with_default(v, v.shape) for v in inputs] placeholders = [tf.placeholder_with_default(v, v.shape) for v in inputs]
def wrap_graph_fn(*args, **kwargs): def wrap_graph_fn(*args, **kwargs):
results = compute_fn(*args, **kwargs) results = compute_fn(*args, **kwargs)
...@@ -117,7 +120,7 @@ class TestCase(tf.test.TestCase): ...@@ -117,7 +120,7 @@ class TestCase(tf.test.TestCase):
tf.tpu.experimental.shutdown_tpu_system() tf.tpu.experimental.shutdown_tpu_system()
return self.maybe_extract_single_output(outputs) return self.maybe_extract_single_output(outputs)
def execute_cpu_tf1(self, compute_fn, inputs): def execute_cpu_tf1(self, compute_fn, inputs, graph=None):
"""Executes compute_fn on CPU with Tensorflow 1.X. """Executes compute_fn on CPU with Tensorflow 1.X.
Args: Args:
...@@ -125,13 +128,15 @@ class TestCase(tf.test.TestCase): ...@@ -125,13 +128,15 @@ class TestCase(tf.test.TestCase):
of input numpy tensors, performs computation and returns output numpy of input numpy tensors, performs computation and returns output numpy
tensors. tensors.
inputs: a list of numpy arrays to feed input to the `compute_fn`. inputs: a list of numpy arrays to feed input to the `compute_fn`.
graph: (optional) If not None, provided `graph` is used for computation
instead of a brand new tf.Graph().
Returns: Returns:
A list of numpy arrays or a single numpy array. A list of numpy arrays or a single numpy array.
""" """
if self.is_tf2(): if self.is_tf2():
raise ValueError('Required version Tenforflow 1.X is not available.') raise ValueError('Required version Tenforflow 1.X is not available.')
with self.test_session(graph=tf.Graph()) as sess: with self.session(graph=(graph or tf.Graph())) as sess:
placeholders = [tf.placeholder_with_default(v, v.shape) for v in inputs] placeholders = [tf.placeholder_with_default(v, v.shape) for v in inputs]
results = compute_fn(*placeholders) results = compute_fn(*placeholders)
if (not (isinstance(results, dict) or isinstance(results, tf.Tensor)) and if (not (isinstance(results, dict) or isinstance(results, tf.Tensor)) and
...@@ -163,7 +168,7 @@ class TestCase(tf.test.TestCase): ...@@ -163,7 +168,7 @@ class TestCase(tf.test.TestCase):
return compute_fn(*tf_inputs) return compute_fn(*tf_inputs)
return self.maybe_extract_single_output(run()) return self.maybe_extract_single_output(run())
def execute_cpu(self, compute_fn, inputs): def execute_cpu(self, compute_fn, inputs, graph=None):
"""Executes compute_fn on CPU. """Executes compute_fn on CPU.
Depending on the underlying TensorFlow installation (build deps) runs in Depending on the underlying TensorFlow installation (build deps) runs in
...@@ -174,6 +179,8 @@ class TestCase(tf.test.TestCase): ...@@ -174,6 +179,8 @@ class TestCase(tf.test.TestCase):
of input numpy tensors, performs computation and returns output numpy of input numpy tensors, performs computation and returns output numpy
tensors. tensors.
inputs: a list of numpy arrays to feed input to the `compute_fn`. inputs: a list of numpy arrays to feed input to the `compute_fn`.
graph: (optional) If not None, provided `graph` is used for computation
instead of a brand new tf.Graph().
Returns: Returns:
A list of numpy arrays or a single tensor. A list of numpy arrays or a single tensor.
...@@ -181,9 +188,9 @@ class TestCase(tf.test.TestCase): ...@@ -181,9 +188,9 @@ class TestCase(tf.test.TestCase):
if self.is_tf2(): if self.is_tf2():
return self.execute_cpu_tf2(compute_fn, inputs) return self.execute_cpu_tf2(compute_fn, inputs)
else: else:
return self.execute_cpu_tf1(compute_fn, inputs) return self.execute_cpu_tf1(compute_fn, inputs, graph)
def execute_tpu(self, compute_fn, inputs): def execute_tpu(self, compute_fn, inputs, graph=None):
"""Executes compute_fn on TPU. """Executes compute_fn on TPU.
Depending on the underlying TensorFlow installation (build deps) runs in Depending on the underlying TensorFlow installation (build deps) runs in
...@@ -194,6 +201,8 @@ class TestCase(tf.test.TestCase): ...@@ -194,6 +201,8 @@ class TestCase(tf.test.TestCase):
of input numpy tensors, performs computation and returns output numpy of input numpy tensors, performs computation and returns output numpy
tensors. tensors.
inputs: a list of numpy arrays to feed input to the `compute_fn`. inputs: a list of numpy arrays to feed input to the `compute_fn`.
graph: (optional) If not None, provided `graph` is used for computation
instead of a brand new tf.Graph().
Returns: Returns:
A list of numpy arrays or a single tensor. A list of numpy arrays or a single tensor.
...@@ -203,7 +212,7 @@ class TestCase(tf.test.TestCase): ...@@ -203,7 +212,7 @@ class TestCase(tf.test.TestCase):
if self.is_tf2(): if self.is_tf2():
return self.execute_tpu_tf2(compute_fn, inputs) return self.execute_tpu_tf2(compute_fn, inputs)
else: else:
return self.execute_tpu_tf1(compute_fn, inputs) return self.execute_tpu_tf1(compute_fn, inputs, graph)
def execute_tf2(self, compute_fn, inputs): def execute_tf2(self, compute_fn, inputs):
"""Runs compute_fn with TensorFlow 2.0. """Runs compute_fn with TensorFlow 2.0.
...@@ -226,7 +235,7 @@ class TestCase(tf.test.TestCase): ...@@ -226,7 +235,7 @@ class TestCase(tf.test.TestCase):
else: else:
return self.execute_cpu_tf2(compute_fn, inputs) return self.execute_cpu_tf2(compute_fn, inputs)
def execute_tf1(self, compute_fn, inputs): def execute_tf1(self, compute_fn, inputs, graph=None):
"""Runs compute_fn with TensorFlow 1.X. """Runs compute_fn with TensorFlow 1.X.
Executes on TPU if available, otherwise executes on CPU. Executes on TPU if available, otherwise executes on CPU.
...@@ -236,6 +245,8 @@ class TestCase(tf.test.TestCase): ...@@ -236,6 +245,8 @@ class TestCase(tf.test.TestCase):
of input numpy tensors, performs computation and returns output numpy of input numpy tensors, performs computation and returns output numpy
tensors. tensors.
inputs: a list of numpy arrays to feed input to the `compute_fn`. inputs: a list of numpy arrays to feed input to the `compute_fn`.
graph: (optional) If not None, provided `graph` is used for computation
instead of a brand new tf.Graph().
Returns: Returns:
A list of numpy arrays or a single tensor. A list of numpy arrays or a single tensor.
...@@ -243,11 +254,11 @@ class TestCase(tf.test.TestCase): ...@@ -243,11 +254,11 @@ class TestCase(tf.test.TestCase):
if self.is_tf2(): if self.is_tf2():
raise ValueError('Required version Tenforflow 1.X is not available.') raise ValueError('Required version Tenforflow 1.X is not available.')
if self.has_tpu(): if self.has_tpu():
return self.execute_tpu_tf1(compute_fn, inputs) return self.execute_tpu_tf1(compute_fn, inputs, graph)
else: else:
return self.execute_cpu_tf1(compute_fn, inputs) return self.execute_cpu_tf1(compute_fn, inputs, graph)
def execute(self, compute_fn, inputs): def execute(self, compute_fn, inputs, graph=None):
"""Runs compute_fn with inputs and returns results. """Runs compute_fn with inputs and returns results.
* Executes in either TF1.X or TF2.X style based on the TensorFlow version. * Executes in either TF1.X or TF2.X style based on the TensorFlow version.
...@@ -258,6 +269,8 @@ class TestCase(tf.test.TestCase): ...@@ -258,6 +269,8 @@ class TestCase(tf.test.TestCase):
of input numpy tensors, performs computation and returns output numpy of input numpy tensors, performs computation and returns output numpy
tensors. tensors.
inputs: a list of numpy arrays to feed input to the `compute_fn`. inputs: a list of numpy arrays to feed input to the `compute_fn`.
graph: (optional) If not None, provided `graph` is used for computation
instead of a brand new tf.Graph().
Returns: Returns:
A list of numpy arrays or a single tensor. A list of numpy arrays or a single tensor.
...@@ -267,6 +280,6 @@ class TestCase(tf.test.TestCase): ...@@ -267,6 +280,6 @@ class TestCase(tf.test.TestCase):
elif not self.has_tpu() and tf2.enabled(): elif not self.has_tpu() and tf2.enabled():
return self.execute_cpu_tf2(compute_fn, inputs) return self.execute_cpu_tf2(compute_fn, inputs)
elif self.has_tpu() and not tf2.enabled(): elif self.has_tpu() and not tf2.enabled():
return self.execute_tpu_tf1(compute_fn, inputs) return self.execute_tpu_tf1(compute_fn, inputs, graph)
else: else:
return self.execute_cpu_tf1(compute_fn, inputs) return self.execute_cpu_tf1(compute_fn, inputs, graph)
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
"""Tests for google3.third_party.tensorflow_models.object_detection.utils.test_case.""" """Tests for google3.third_party.tensorflow_models.object_detection.utils.test_case."""
import numpy as np import numpy as np
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import test_case from object_detection.utils import test_case
......
...@@ -21,7 +21,7 @@ from __future__ import print_function ...@@ -21,7 +21,7 @@ from __future__ import print_function
import numpy as np import numpy as np
from six.moves import range from six.moves import range
from six.moves import zip from six.moves import zip
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.core import anchor_generator from object_detection.core import anchor_generator
from object_detection.core import box_coder from object_detection.core import box_coder
...@@ -29,6 +29,7 @@ from object_detection.core import box_list ...@@ -29,6 +29,7 @@ from object_detection.core import box_list
from object_detection.core import box_predictor from object_detection.core import box_predictor
from object_detection.core import matcher from object_detection.core import matcher
from object_detection.utils import shape_utils from object_detection.utils import shape_utils
from object_detection.utils import tf_version
# Default size (both width and height) used for testing mask predictions. # Default size (both width and height) used for testing mask predictions.
DEFAULT_MASK_SIZE = 5 DEFAULT_MASK_SIZE = 5
...@@ -233,3 +234,40 @@ def first_rows_close_as_set(a, b, k=None, rtol=1e-6, atol=1e-6): ...@@ -233,3 +234,40 @@ def first_rows_close_as_set(a, b, k=None, rtol=1e-6, atol=1e-6):
np.allclose(entry_a, entry_b, rtol, atol) np.allclose(entry_a, entry_b, rtol, atol)
for (entry_a, entry_b) in zip(a_sorted, b_sorted) for (entry_a, entry_b) in zip(a_sorted, b_sorted)
]) ])
class GraphContextOrNone(object):
"""A new Graph context for TF1.X and None for TF2.X.
This is useful to write model tests that work with both TF1.X and TF2.X.
Example test using this pattern:
class ModelTest(test_case.TestCase):
def test_model(self):
with test_utils.GraphContextOrNone() as g:
model = Model()
def compute_fn():
out = model.predict()
return out['detection_boxes']
boxes = self.execute(compute_fn, [], graph=g)
self.assertAllClose(boxes, expected_boxes)
"""
def __init__(self):
if tf_version.is_tf2():
self.graph = None
else:
self.graph = tf.Graph().as_default()
def __enter__(self):
if tf_version.is_tf2():
return None
else:
return self.graph.__enter__()
def __exit__(self, ttype, value, traceback):
if tf_version.is_tf2():
return False
else:
return self.graph.__exit__(ttype, value, traceback)
...@@ -20,12 +20,13 @@ from __future__ import division ...@@ -20,12 +20,13 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import numpy as np import numpy as np
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import test_case
from object_detection.utils import test_utils from object_detection.utils import test_utils
class TestUtilsTest(tf.test.TestCase): class TestUtilsTest(test_case.TestCase):
def test_diagonal_gradient_image(self): def test_diagonal_gradient_image(self):
"""Tests if a good pyramid image is created.""" """Tests if a good pyramid image is created."""
...@@ -67,10 +68,10 @@ class TestUtilsTest(tf.test.TestCase): ...@@ -67,10 +68,10 @@ class TestUtilsTest(tf.test.TestCase):
self.assertAllEqual(boxes[:, 0] < boxes[:, 2], true_column) self.assertAllEqual(boxes[:, 0] < boxes[:, 2], true_column)
self.assertAllEqual(boxes[:, 1] < boxes[:, 3], true_column) self.assertAllEqual(boxes[:, 1] < boxes[:, 3], true_column)
self.assertTrue(boxes[:, 0].min() >= 0) self.assertGreaterEqual(boxes[:, 0].min(), 0)
self.assertTrue(boxes[:, 1].min() >= 0) self.assertGreaterEqual(boxes[:, 1].min(), 0)
self.assertTrue(boxes[:, 2].max() <= max_height) self.assertLessEqual(boxes[:, 2].max(), max_height)
self.assertTrue(boxes[:, 3].max() <= max_width) self.assertLessEqual(boxes[:, 3].max(), max_width)
def test_first_rows_close_as_set(self): def test_first_rows_close_as_set(self):
a = [1, 2, 3, 0, 0] a = [1, 2, 3, 0, 0]
......
...@@ -23,9 +23,9 @@ from __future__ import print_function ...@@ -23,9 +23,9 @@ from __future__ import print_function
import logging import logging
import re import re
import tensorflow as tf import tensorflow.compat.v1 as tf
import tf_slim as slim
from tensorflow.contrib import slim
from tensorflow.python.ops import variables as tf_variables from tensorflow.python.ops import variables as tf_variables
...@@ -47,6 +47,8 @@ def filter_variables(variables, filter_regex_list, invert=False): ...@@ -47,6 +47,8 @@ def filter_variables(variables, filter_regex_list, invert=False):
Returns: Returns:
a list of filtered variables. a list of filtered variables.
""" """
if tf.executing_eagerly():
raise ValueError('Accessing variables is not supported in eager mode.')
kept_vars = [] kept_vars = []
variables_to_ignore_patterns = list([fre for fre in filter_regex_list if fre]) variables_to_ignore_patterns = list([fre for fre in filter_regex_list if fre])
for var in variables: for var in variables:
...@@ -72,6 +74,8 @@ def multiply_gradients_matching_regex(grads_and_vars, regex_list, multiplier): ...@@ -72,6 +74,8 @@ def multiply_gradients_matching_regex(grads_and_vars, regex_list, multiplier):
Returns: Returns:
grads_and_vars: A list of gradient to variable pairs (tuples). grads_and_vars: A list of gradient to variable pairs (tuples).
""" """
if tf.executing_eagerly():
raise ValueError('Accessing variables is not supported in eager mode.')
variables = [pair[1] for pair in grads_and_vars] variables = [pair[1] for pair in grads_and_vars]
matching_vars = filter_variables(variables, regex_list, invert=True) matching_vars = filter_variables(variables, regex_list, invert=True)
for var in matching_vars: for var in matching_vars:
...@@ -93,6 +97,8 @@ def freeze_gradients_matching_regex(grads_and_vars, regex_list): ...@@ -93,6 +97,8 @@ def freeze_gradients_matching_regex(grads_and_vars, regex_list):
grads_and_vars: A list of gradient to variable pairs (tuples) that do not grads_and_vars: A list of gradient to variable pairs (tuples) that do not
contain the variables and gradients matching the regex. contain the variables and gradients matching the regex.
""" """
if tf.executing_eagerly():
raise ValueError('Accessing variables is not supported in eager mode.')
variables = [pair[1] for pair in grads_and_vars] variables = [pair[1] for pair in grads_and_vars]
matching_vars = filter_variables(variables, regex_list, invert=True) matching_vars = filter_variables(variables, regex_list, invert=True)
kept_grads_and_vars = [pair for pair in grads_and_vars kept_grads_and_vars = [pair for pair in grads_and_vars
...@@ -123,6 +129,8 @@ def get_variables_available_in_checkpoint(variables, ...@@ -123,6 +129,8 @@ def get_variables_available_in_checkpoint(variables,
Raises: Raises:
ValueError: if `variables` is not a list or dict. ValueError: if `variables` is not a list or dict.
""" """
if tf.executing_eagerly():
raise ValueError('Accessing variables is not supported in eager mode.')
if isinstance(variables, list): if isinstance(variables, list):
variable_names_map = {} variable_names_map = {}
for variable in variables: for variable in variables:
...@@ -170,6 +178,8 @@ def get_global_variables_safely(): ...@@ -170,6 +178,8 @@ def get_global_variables_safely():
Returns: Returns:
The result of tf.global_variables() The result of tf.global_variables()
""" """
if tf.executing_eagerly():
raise ValueError('Accessing variables is not supported in eager mode.')
with tf.init_scope(): with tf.init_scope():
if tf.executing_eagerly(): if tf.executing_eagerly():
raise ValueError("Global variables collection is not tracked when " raise ValueError("Global variables collection is not tracked when "
......
...@@ -21,12 +21,13 @@ from __future__ import print_function ...@@ -21,12 +21,13 @@ from __future__ import print_function
import os import os
import tensorflow as tf import tensorflow.compat.v1 as tf
from object_detection.utils import test_case
from object_detection.utils import variables_helper from object_detection.utils import variables_helper
class FilterVariablesTest(tf.test.TestCase): class FilterVariablesTest(test_case.TestCase):
def _create_variables(self): def _create_variables(self):
return [tf.Variable(1.0, name='FeatureExtractor/InceptionV3/weights'), return [tf.Variable(1.0, name='FeatureExtractor/InceptionV3/weights'),
...@@ -37,26 +38,26 @@ class FilterVariablesTest(tf.test.TestCase): ...@@ -37,26 +38,26 @@ class FilterVariablesTest(tf.test.TestCase):
def test_return_all_variables_when_empty_regex(self): def test_return_all_variables_when_empty_regex(self):
variables = self._create_variables() variables = self._create_variables()
out_variables = variables_helper.filter_variables(variables, ['']) out_variables = variables_helper.filter_variables(variables, [''])
self.assertItemsEqual(out_variables, variables) self.assertCountEqual(out_variables, variables)
def test_return_variables_which_do_not_match_single_regex(self): def test_return_variables_which_do_not_match_single_regex(self):
variables = self._create_variables() variables = self._create_variables()
out_variables = variables_helper.filter_variables(variables, out_variables = variables_helper.filter_variables(variables,
['FeatureExtractor/.*']) ['FeatureExtractor/.*'])
self.assertItemsEqual(out_variables, variables[2:]) self.assertCountEqual(out_variables, variables[2:])
def test_return_variables_which_do_not_match_any_regex_in_list(self): def test_return_variables_which_do_not_match_any_regex_in_list(self):
variables = self._create_variables() variables = self._create_variables()
out_variables = variables_helper.filter_variables(variables, [ out_variables = variables_helper.filter_variables(variables, [
'FeatureExtractor.*biases', 'StackProposalGenerator.*biases' 'FeatureExtractor.*biases', 'StackProposalGenerator.*biases'
]) ])
self.assertItemsEqual(out_variables, [variables[0], variables[2]]) self.assertCountEqual(out_variables, [variables[0], variables[2]])
def test_return_variables_matching_empty_regex_list(self): def test_return_variables_matching_empty_regex_list(self):
variables = self._create_variables() variables = self._create_variables()
out_variables = variables_helper.filter_variables( out_variables = variables_helper.filter_variables(
variables, [''], invert=True) variables, [''], invert=True)
self.assertItemsEqual(out_variables, []) self.assertCountEqual(out_variables, [])
def test_return_variables_matching_some_regex_in_list(self): def test_return_variables_matching_some_regex_in_list(self):
variables = self._create_variables() variables = self._create_variables()
...@@ -64,7 +65,7 @@ class FilterVariablesTest(tf.test.TestCase): ...@@ -64,7 +65,7 @@ class FilterVariablesTest(tf.test.TestCase):
variables, variables,
['FeatureExtractor.*biases', 'StackProposalGenerator.*biases'], ['FeatureExtractor.*biases', 'StackProposalGenerator.*biases'],
invert=True) invert=True)
self.assertItemsEqual(out_variables, [variables[1], variables[3]]) self.assertCountEqual(out_variables, [variables[1], variables[3]])
class MultiplyGradientsMatchingRegexTest(tf.test.TestCase): class MultiplyGradientsMatchingRegexTest(tf.test.TestCase):
...@@ -90,7 +91,7 @@ class MultiplyGradientsMatchingRegexTest(tf.test.TestCase): ...@@ -90,7 +91,7 @@ class MultiplyGradientsMatchingRegexTest(tf.test.TestCase):
with self.test_session() as sess: with self.test_session() as sess:
sess.run(init_op) sess.run(init_op)
output = sess.run(grads_and_vars) output = sess.run(grads_and_vars)
self.assertItemsEqual(output, exp_output) self.assertCountEqual(output, exp_output)
def test_multiply_all_bias_variables(self): def test_multiply_all_bias_variables(self):
grads_and_vars = self._create_grads_and_vars() grads_and_vars = self._create_grads_and_vars()
...@@ -103,10 +104,10 @@ class MultiplyGradientsMatchingRegexTest(tf.test.TestCase): ...@@ -103,10 +104,10 @@ class MultiplyGradientsMatchingRegexTest(tf.test.TestCase):
with self.test_session() as sess: with self.test_session() as sess:
sess.run(init_op) sess.run(init_op)
output = sess.run(grads_and_vars) output = sess.run(grads_and_vars)
self.assertItemsEqual(output, exp_output) self.assertCountEqual(output, exp_output)
class FreezeGradientsMatchingRegexTest(tf.test.TestCase): class FreezeGradientsMatchingRegexTest(test_case.TestCase):
def _create_grads_and_vars(self): def _create_grads_and_vars(self):
return [(tf.constant(1.0), return [(tf.constant(1.0),
...@@ -128,10 +129,10 @@ class FreezeGradientsMatchingRegexTest(tf.test.TestCase): ...@@ -128,10 +129,10 @@ class FreezeGradientsMatchingRegexTest(tf.test.TestCase):
with self.test_session() as sess: with self.test_session() as sess:
sess.run(init_op) sess.run(init_op)
output = sess.run(grads_and_vars) output = sess.run(grads_and_vars)
self.assertItemsEqual(output, exp_output) self.assertCountEqual(output, exp_output)
class GetVariablesAvailableInCheckpointTest(tf.test.TestCase): class GetVariablesAvailableInCheckpointTest(test_case.TestCase):
def test_return_all_variables_from_checkpoint(self): def test_return_all_variables_from_checkpoint(self):
with tf.Graph().as_default(): with tf.Graph().as_default():
...@@ -147,7 +148,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase): ...@@ -147,7 +148,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase):
saver.save(sess, checkpoint_path) saver.save(sess, checkpoint_path)
out_variables = variables_helper.get_variables_available_in_checkpoint( out_variables = variables_helper.get_variables_available_in_checkpoint(
variables, checkpoint_path) variables, checkpoint_path)
self.assertItemsEqual(out_variables, variables) self.assertCountEqual(out_variables, variables)
def test_return_all_variables_from_checkpoint_with_partition(self): def test_return_all_variables_from_checkpoint_with_partition(self):
with tf.Graph().as_default(): with tf.Graph().as_default():
...@@ -165,7 +166,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase): ...@@ -165,7 +166,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase):
saver.save(sess, checkpoint_path) saver.save(sess, checkpoint_path)
out_variables = variables_helper.get_variables_available_in_checkpoint( out_variables = variables_helper.get_variables_available_in_checkpoint(
variables, checkpoint_path) variables, checkpoint_path)
self.assertItemsEqual(out_variables, variables) self.assertCountEqual(out_variables, variables)
def test_return_variables_available_in_checkpoint(self): def test_return_variables_available_in_checkpoint(self):
checkpoint_path = os.path.join(self.get_temp_dir(), 'model.ckpt') checkpoint_path = os.path.join(self.get_temp_dir(), 'model.ckpt')
...@@ -186,7 +187,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase): ...@@ -186,7 +187,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase):
graph2_variables = graph1_variables + [tf.Variable(1.0, name='biases')] graph2_variables = graph1_variables + [tf.Variable(1.0, name='biases')]
out_variables = variables_helper.get_variables_available_in_checkpoint( out_variables = variables_helper.get_variables_available_in_checkpoint(
graph2_variables, checkpoint_path, include_global_step=False) graph2_variables, checkpoint_path, include_global_step=False)
self.assertItemsEqual(out_variables, [weight_variable]) self.assertCountEqual(out_variables, [weight_variable])
def test_return_variables_available_an_checkpoint_with_dict_inputs(self): def test_return_variables_available_an_checkpoint_with_dict_inputs(self):
checkpoint_path = os.path.join(self.get_temp_dir(), 'model.ckpt') checkpoint_path = os.path.join(self.get_temp_dir(), 'model.ckpt')
...@@ -208,9 +209,9 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase): ...@@ -208,9 +209,9 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase):
out_variables = variables_helper.get_variables_available_in_checkpoint( out_variables = variables_helper.get_variables_available_in_checkpoint(
graph2_variables_dict, checkpoint_path) graph2_variables_dict, checkpoint_path)
self.assertTrue(isinstance(out_variables, dict)) self.assertIsInstance(out_variables, dict)
self.assertItemsEqual(list(out_variables.keys()), ['ckpt_weights']) self.assertCountEqual(list(out_variables.keys()), ['ckpt_weights'])
self.assertTrue(out_variables['ckpt_weights'].op.name == 'weights') self.assertEqual(out_variables['ckpt_weights'].op.name, 'weights')
def test_return_variables_with_correct_sizes(self): def test_return_variables_with_correct_sizes(self):
checkpoint_path = os.path.join(self.get_temp_dir(), 'model.ckpt') checkpoint_path = os.path.join(self.get_temp_dir(), 'model.ckpt')
...@@ -237,7 +238,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase): ...@@ -237,7 +238,7 @@ class GetVariablesAvailableInCheckpointTest(tf.test.TestCase):
out_variables = variables_helper.get_variables_available_in_checkpoint( out_variables = variables_helper.get_variables_available_in_checkpoint(
graph2_variables, checkpoint_path, include_global_step=True) graph2_variables, checkpoint_path, include_global_step=True)
self.assertItemsEqual(out_variables, [bias_variable, global_step]) self.assertCountEqual(out_variables, [bias_variable, global_step])
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment