Commit b968a6ce authored by Mark Sandler's avatar Mark Sandler Committed by Jonathan Huang
Browse files

Merged commit includes the following changes: (#7800)

280142968  by Zhichao Lu:

    Opensource MobilenetEdgeTPU + ssdlite into third-party object detection APIs on EdgeTPU.

--
280134001  by Zhichao Lu:

    Adds MobilenetEdgeTpu + ssdlite into internal object detection APIs on EdgeTPU.

--
278941778  by Zhichao Lu:

    Add support for fixed input shapes for 'encoded_image_string_tensor' and 'tf_example' inputs.

--
278933274  by Zhichao Lu:

      Adding fool proof check to avoid using 1x1 depthwise conv op.

--
278762192  by Zhichao Lu:

    Ensure correct number of iterations after training resumes.

--
278746440  by Zhichao Lu:

    Internal change.

--
278006953  by Zhichao Lu:

    Internal changes to tf.contrib symbols

--
278006330  by Zhichao Lu:

    Internal changes to tf.contrib symbols

--
277593959  by Zhichao Lu:

      Make the ssd_feature_extractor_test.py PY3 compatible. The "six.zip" will use "itertools.izip" in Python 2 and "zip" in Python 3.

--
277344551  by Zhichao Lu:

    Internal change.

--
277154953  by Zhichao Lu:

    Conditionally use keras based optimizers so that check-pointing works correctly.
    This change also enables summaries on TPU which were previously not enabled
    due to a bug.

--
277087572  by Zhichao Lu:

    Fix resizing boxes when using keep_aspect_ratio_rezier with padding.

--
275898543  by Zhichao Lu:

    Support label_map_proto as input in label_map_util.

--
275347137  by Zhichao Lu:

    Add force_no_resize flag in eval.proto which replaces
    the resize config with identity resizer. This is useful
    when we want to test at the original image resolution.

--

PiperOrigin-RevId: 280142968
parent c3bd5082
......@@ -101,6 +101,19 @@ reporting an issue.
## Release information
### Nov 13th, 2019
We have released MobileNetEdgeTPU SSDLite model.
* SSDLite with MobileNetEdgeTPU backbone, which achieves 10% mAP higher than
MobileNetV2 SSDLite (24.3 mAP vs 22 mAP) on a Google Pixel4 at comparable
latency (6.6ms vs 6.8ms).
Along with the model definition, we are also releasing model checkpoints
trained on the COCO dataset.
<b>Thanks to contributors</b>: Yunyang Xiong, Bo Chen, Suyog Gupta, Hanxiao Liu,
Gabriel Bender, Mingxing Tan, Berkin Akin, Zhichao Lu, Quoc Le
### Oct 15th, 2019
We have released two MobileNet V3 SSDLite models (presented in
[Searching for MobileNetV3](https://arxiv.org/abs/1905.02244)).
......
......@@ -44,6 +44,7 @@ from object_detection.models import ssd_resnet_v1_ppn_feature_extractor as ssd_r
from object_detection.models.embedded_ssd_mobilenet_v1_feature_extractor import EmbeddedSSDMobileNetV1FeatureExtractor
from object_detection.models.ssd_inception_v2_feature_extractor import SSDInceptionV2FeatureExtractor
from object_detection.models.ssd_inception_v3_feature_extractor import SSDInceptionV3FeatureExtractor
from object_detection.models.ssd_mobilenet_edgetpu_feature_extractor import SSDMobileNetEdgeTPUFeatureExtractor
from object_detection.models.ssd_mobilenet_v1_feature_extractor import SSDMobileNetV1FeatureExtractor
from object_detection.models.ssd_mobilenet_v1_fpn_feature_extractor import SSDMobileNetV1FpnFeatureExtractor
from object_detection.models.ssd_mobilenet_v1_fpn_keras_feature_extractor import SSDMobileNetV1FpnKerasFeatureExtractor
......@@ -73,6 +74,7 @@ SSD_FEATURE_EXTRACTOR_CLASS_MAP = {
'ssd_mobilenet_v2_fpn': SSDMobileNetV2FpnFeatureExtractor,
'ssd_mobilenet_v3_large': SSDMobileNetV3LargeFeatureExtractor,
'ssd_mobilenet_v3_small': SSDMobileNetV3SmallFeatureExtractor,
'ssd_mobilenet_edgetpu': SSDMobileNetEdgeTPUFeatureExtractor,
'ssd_resnet50_v1_fpn': ssd_resnet_v1_fpn.SSDResnet50V1FpnFeatureExtractor,
'ssd_resnet101_v1_fpn': ssd_resnet_v1_fpn.SSDResnet101V1FpnFeatureExtractor,
'ssd_resnet152_v1_fpn': ssd_resnet_v1_fpn.SSDResnet152V1FpnFeatureExtractor,
......
......@@ -21,8 +21,8 @@ import tensorflow as tf
from object_detection.utils import learning_schedules
def build(optimizer_config, global_step=None):
"""Create optimizer based on config.
def build_optimizers_tf_v1(optimizer_config, global_step=None):
"""Create a TF v1 compatible optimizer based on config.
Args:
optimizer_config: A Optimizer proto message.
......@@ -77,6 +77,68 @@ def build(optimizer_config, global_step=None):
return optimizer, summary_vars
def build_optimizers_tf_v2(optimizer_config, global_step=None):
"""Create a TF v2 compatible optimizer based on config.
Args:
optimizer_config: A Optimizer proto message.
global_step: A variable representing the current step.
If None, defaults to tf.train.get_or_create_global_step()
Returns:
An optimizer and a list of variables for summary.
Raises:
ValueError: when using an unsupported input data type.
"""
optimizer_type = optimizer_config.WhichOneof('optimizer')
optimizer = None
summary_vars = []
if optimizer_type == 'rms_prop_optimizer':
config = optimizer_config.rms_prop_optimizer
learning_rate = _create_learning_rate(config.learning_rate,
global_step=global_step)
summary_vars.append(learning_rate)
optimizer = tf.keras.optimizers.RMSprop(
learning_rate,
decay=config.decay,
momentum=config.momentum_optimizer_value,
epsilon=config.epsilon)
if optimizer_type == 'momentum_optimizer':
config = optimizer_config.momentum_optimizer
learning_rate = _create_learning_rate(config.learning_rate,
global_step=global_step)
summary_vars.append(learning_rate)
optimizer = tf.keras.optimizers.SGD(
learning_rate,
momentum=config.momentum_optimizer_value)
if optimizer_type == 'adam_optimizer':
config = optimizer_config.adam_optimizer
learning_rate = _create_learning_rate(config.learning_rate,
global_step=global_step)
summary_vars.append(learning_rate)
optimizer = tf.keras.optimizers.Adam(learning_rate)
if optimizer is None:
raise ValueError('Optimizer %s not supported.' % optimizer_type)
if optimizer_config.use_moving_average:
raise ValueError('Moving average not supported in eager mode.')
return optimizer, summary_vars
def build(config, global_step=None):
if tf.executing_eagerly():
return build_optimizers_tf_v2(config, global_step)
else:
return build_optimizers_tf_v1(config, global_step)
def _create_learning_rate(learning_rate_config, global_step=None):
"""Create optimizer learning rate based on config.
......
......@@ -101,7 +101,9 @@ def _build_non_max_suppressor(nms_config):
max_classes_per_detection=nms_config.max_classes_per_detection,
soft_nms_sigma=nms_config.soft_nms_sigma,
use_partitioned_nms=nms_config.use_partitioned_nms,
use_combined_nms=nms_config.use_combined_nms)
use_combined_nms=nms_config.use_combined_nms,
change_coordinate_frame=True)
return non_max_suppressor_fn
......
......@@ -846,8 +846,28 @@ def result_dict_for_batched_example(images,
dtype=tf.uint8))
output_dict.update(groundtruth)
if scale_to_absolute:
image_shape = tf.cast(tf.shape(images), tf.float32)
image_height, image_width = image_shape[1], image_shape[2]
def _scale_box_to_normalized_true_image(args):
"""Scale the box coordinates to be relative to the true image shape."""
boxes, true_image_shape = args
true_image_shape = tf.cast(true_image_shape, tf.float32)
true_height, true_width = true_image_shape[0], true_image_shape[1]
normalized_window = tf.stack([0.0, 0.0, true_height / image_height,
true_width / image_width])
return box_list_ops.change_coordinate_frame(
box_list.BoxList(boxes), normalized_window).get()
groundtruth_boxes = groundtruth[input_data_fields.groundtruth_boxes]
groundtruth_boxes = shape_utils.static_or_dynamic_map_fn(
_scale_box_to_normalized_true_image,
elems=[groundtruth_boxes, true_image_shapes], dtype=tf.float32)
output_dict[input_data_fields.groundtruth_boxes] = groundtruth_boxes
if scale_to_absolute:
groundtruth_boxes = output_dict[input_data_fields.groundtruth_boxes]
output_dict[input_data_fields.groundtruth_boxes] = (
shape_utils.static_or_dynamic_map_fn(
_scale_box_to_absolute,
......
......@@ -20,6 +20,7 @@ from __future__ import print_function
from absl.testing import parameterized
import numpy as np
import six
from six.moves import range
import tensorflow as tf
......@@ -254,6 +255,56 @@ class EvalUtilTest(test_case.TestCase, parameterized.TestCase):
self.assertAlmostEqual(evaluator[1]._recall_lower_bound, 0.0)
self.assertAlmostEqual(evaluator[1]._recall_upper_bound, 1.0)
def test_padded_image_result_dict(self):
input_data_fields = fields.InputDataFields
detection_fields = fields.DetectionResultFields
key = tf.constant([str(i) for i in range(2)])
detection_boxes = np.array([[[0., 0., 1., 1.]], [[0.0, 0.0, 0.5, 0.5]]],
dtype=np.float32)
detections = {
detection_fields.detection_boxes:
tf.constant(detection_boxes),
detection_fields.detection_scores:
tf.constant([[1.], [1.]]),
detection_fields.detection_classes:
tf.constant([[1], [2]]),
detection_fields.num_detections:
tf.constant([1, 1])
}
gt_boxes = detection_boxes
groundtruth = {
input_data_fields.groundtruth_boxes:
tf.constant(gt_boxes),
input_data_fields.groundtruth_classes:
tf.constant([[1.], [1.]]),
}
image = tf.zeros((2, 100, 100, 3), dtype=tf.float32)
true_image_shapes = tf.constant([[100, 100, 3], [50, 100, 3]])
original_image_spatial_shapes = tf.constant([[200, 200], [150, 300]])
result = eval_util.result_dict_for_batched_example(
image, key, detections, groundtruth,
scale_to_absolute=True,
true_image_shapes=true_image_shapes,
original_image_spatial_shapes=original_image_spatial_shapes,
max_gt_boxes=tf.constant(1))
with self.test_session() as sess:
result = sess.run(result)
self.assertAllEqual(
[[[0., 0., 200., 200.]], [[0.0, 0.0, 150., 150.]]],
result[input_data_fields.groundtruth_boxes])
# Predictions from the model are not scaled.
self.assertAllEqual(
[[[0., 0., 200., 200.]], [[0.0, 0.0, 75., 150.]]],
result[detection_fields.detection_boxes])
if __name__ == '__main__':
tf.test.main()
......@@ -123,9 +123,12 @@ def _image_tensor_input_placeholder(input_shape=None):
return input_tensor, input_tensor
def _tf_example_input_placeholder():
def _tf_example_input_placeholder(input_shape=None):
"""Returns input that accepts a batch of strings with tf examples.
Args:
input_shape: the shape to resize the output decoded images to (optional).
Returns:
a tuple of input placeholder and the output decoded images.
"""
......@@ -135,6 +138,8 @@ def _tf_example_input_placeholder():
tensor_dict = tf_example_decoder.TfExampleDecoder().decode(
tf_example_string_tensor)
image_tensor = tensor_dict[fields.InputDataFields.image]
if input_shape is not None:
image_tensor = tf.image.resize(image_tensor, input_shape[1:3])
return image_tensor
return (batch_tf_example_placeholder,
shape_utils.static_or_dynamic_map_fn(
......@@ -145,9 +150,12 @@ def _tf_example_input_placeholder():
back_prop=False))
def _encoded_image_string_tensor_input_placeholder():
def _encoded_image_string_tensor_input_placeholder(input_shape=None):
"""Returns input that accepts a batch of PNG or JPEG strings.
Args:
input_shape: the shape to resize the output decoded images to (optional).
Returns:
a tuple of input placeholder and the output decoded images.
"""
......@@ -159,6 +167,8 @@ def _encoded_image_string_tensor_input_placeholder():
image_tensor = tf.image.decode_image(encoded_image_string_tensor,
channels=3)
image_tensor.set_shape((None, None, 3))
if input_shape is not None:
image_tensor = tf.image.resize(image_tensor, input_shape[1:3])
return image_tensor
return (batch_image_str_placeholder,
tf.map_fn(
......@@ -355,8 +365,11 @@ def build_detection_graph(input_type, detection_model, input_shape,
raise ValueError('Unknown input type: {}'.format(input_type))
placeholder_args = {}
if input_shape is not None:
if input_type != 'image_tensor':
raise ValueError('Can only specify input shape for `image_tensor` '
if (input_type != 'image_tensor' and
input_type != 'encoded_image_string_tensor' and
input_type != 'tf_example'):
raise ValueError('Can only specify input shape for `image_tensor`, '
'`encoded_image_string_tensor`, or `tf_example` '
'inputs.')
placeholder_args['input_shape'] = input_shape
placeholder_tensor, input_tensors = input_placeholder_fn_map[input_type](
......
......@@ -246,6 +246,29 @@ class ExportInferenceGraphTest(tf.test.TestCase):
self.assertTrue(os.path.exists(os.path.join(
output_directory, 'saved_model', 'saved_model.pb')))
def test_export_graph_with_fixed_size_tf_example_input(self):
input_shape = [1, 320, 320, 3]
tmp_dir = self.get_temp_dir()
trained_checkpoint_prefix = os.path.join(tmp_dir, 'model.ckpt')
self._save_checkpoint_from_mock_model(
trained_checkpoint_prefix, use_moving_averages=False)
with mock.patch.object(
model_builder, 'build', autospec=True) as mock_builder:
mock_builder.return_value = FakeModel()
output_directory = os.path.join(tmp_dir, 'output')
pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
pipeline_config.eval_config.use_moving_averages = False
exporter.export_inference_graph(
input_type='tf_example',
pipeline_config=pipeline_config,
trained_checkpoint_prefix=trained_checkpoint_prefix,
output_directory=output_directory,
input_shape=input_shape)
saved_model_path = os.path.join(output_directory, 'saved_model')
self.assertTrue(
os.path.exists(os.path.join(saved_model_path, 'saved_model.pb')))
def test_export_graph_with_encoded_image_string_input(self):
tmp_dir = self.get_temp_dir()
trained_checkpoint_prefix = os.path.join(tmp_dir, 'model.ckpt')
......@@ -265,6 +288,29 @@ class ExportInferenceGraphTest(tf.test.TestCase):
self.assertTrue(os.path.exists(os.path.join(
output_directory, 'saved_model', 'saved_model.pb')))
def test_export_graph_with_fixed_size_encoded_image_string_input(self):
input_shape = [1, 320, 320, 3]
tmp_dir = self.get_temp_dir()
trained_checkpoint_prefix = os.path.join(tmp_dir, 'model.ckpt')
self._save_checkpoint_from_mock_model(
trained_checkpoint_prefix, use_moving_averages=False)
with mock.patch.object(
model_builder, 'build', autospec=True) as mock_builder:
mock_builder.return_value = FakeModel()
output_directory = os.path.join(tmp_dir, 'output')
pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
pipeline_config.eval_config.use_moving_averages = False
exporter.export_inference_graph(
input_type='encoded_image_string_tensor',
pipeline_config=pipeline_config,
trained_checkpoint_prefix=trained_checkpoint_prefix,
output_directory=output_directory,
input_shape=input_shape)
saved_model_path = os.path.join(output_directory, 'saved_model')
self.assertTrue(
os.path.exists(os.path.join(saved_model_path, 'saved_model.pb')))
def _get_variables_in_checkpoint(self, checkpoint_file):
return set([
var_name
......
......@@ -103,6 +103,7 @@ Note: The asterisk (☆) at the end of model name indicates that this model supp
Note: If you download the tar.gz file of quantized models and un-tar, you will get different set of files - a checkpoint, a config file and tflite frozen graphs (txt/binary).
### Mobile models
Model name | Pixel 1 Latency (ms) | COCO mAP | Outputs
......@@ -110,6 +111,11 @@ Model name
[ssd_mobilenet_v3_large_coco](http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v3_large_coco_2019_08_14.tar.gz) | 119 | 22.3 | Boxes
[ssd_mobilenet_v3_small_coco](http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v3_small_coco_2019_08_14.tar.gz) | 43 | 15.6 | Boxes
### Pixel4 Edge TPU models
Model name | Pixel 4 Edge TPU Latency (ms) | COCO mAP | Outputs
----------------------------------------------------------------------------------------------------------------------------------- | :------------------: | :------: | :-----:
[ssd_mobilenet_edgetpu_coco](https://storage.cloud.google.com/mobilenet_edgetpu/checkpoints/ssdlite_mobilenet_edgetpu_coco_quant.tar.gz) | 6.6 | 24.3 | Boxes
## Kitti-trained models
Model name | Speed (ms) | Pascal mAP@0.5 | Outputs
......
......@@ -25,10 +25,14 @@ from object_detection.builders import dataset_builder
from object_detection.builders import image_resizer_builder
from object_detection.builders import model_builder
from object_detection.builders import preprocessor_builder
from object_detection.core import box_list
from object_detection.core import box_list_ops
from object_detection.core import keypoint_ops
from object_detection.core import preprocessor
from object_detection.core import standard_fields as fields
from object_detection.data_decoders import tf_example_decoder
from object_detection.protos import eval_pb2
from object_detection.protos import image_resizer_pb2
from object_detection.protos import input_reader_pb2
from object_detection.protos import model_pb2
from object_detection.protos import train_pb2
......@@ -155,6 +159,30 @@ def transform_input_data(tensor_dict,
image = out_tensor_dict[fields.InputDataFields.image]
preprocessed_resized_image, true_image_shape = model_preprocess_fn(
tf.expand_dims(tf.cast(image, dtype=tf.float32), axis=0))
preprocessed_shape = tf.shape(preprocessed_resized_image)
new_height, new_width = preprocessed_shape[1], preprocessed_shape[2]
im_box = tf.stack([
0.0, 0.0,
tf.to_float(new_height) / tf.to_float(true_image_shape[0, 0]),
tf.to_float(new_width) / tf.to_float(true_image_shape[0, 1])
])
if fields.InputDataFields.groundtruth_boxes in tensor_dict:
bboxes = out_tensor_dict[fields.InputDataFields.groundtruth_boxes]
boxlist = box_list.BoxList(bboxes)
realigned_bboxes = box_list_ops.change_coordinate_frame(boxlist, im_box)
out_tensor_dict[
fields.InputDataFields.groundtruth_boxes] = realigned_bboxes.get()
if fields.InputDataFields.groundtruth_keypoints in tensor_dict:
keypoints = out_tensor_dict[fields.InputDataFields.groundtruth_keypoints]
realigned_keypoints = keypoint_ops.change_coordinate_frame(keypoints,
im_box)
out_tensor_dict[
fields.InputDataFields.groundtruth_keypoints] = realigned_keypoints
if use_bfloat16:
preprocessed_resized_image = tf.cast(
preprocessed_resized_image, tf.bfloat16)
......@@ -655,6 +683,14 @@ def eval_input(eval_config, eval_input_config, model_config,
raise TypeError('The `model_config` must be a '
'model_pb2.DetectionModel.')
if eval_config.force_no_resize:
arch = model_config.WhichOneof('model')
arch_config = getattr(model_config, arch)
image_resizer_proto = image_resizer_pb2.ImageResizer()
image_resizer_proto.identity_resizer.CopyFrom(
image_resizer_pb2.IdentityResizer())
arch_config.image_resizer.CopyFrom(image_resizer_proto)
if model is None:
model_preprocess_fn = INPUT_BUILDER_UTIL_MAP['model_build'](
model_config, is_training=False).preprocess
......
......@@ -468,7 +468,7 @@ class InputsTest(test_case.TestCase, parameterized.TestCase):
replaced_string = inputs._replace_empty_string_with_random_number(
string_placeholder)
test_string = 'hello world'
test_string = b'hello world'
feed_dict = {string_placeholder: test_string}
with self.test_session() as sess:
......@@ -493,7 +493,34 @@ class InputsTest(test_case.TestCase, parameterized.TestCase):
# Test whether out_string is a string which represents an integer.
int(out_string) # throws an error if out_string is not castable to int.
self.assertEqual(out_string, '2798129067578209328')
self.assertEqual(out_string, b'2798129067578209328')
def test_force_no_resize(self):
"""Tests the functionality of force_no_reisze option."""
configs = _get_configs_for_model('ssd_inception_v2_pets')
configs['eval_config'].force_no_resize = True
eval_input_fn = inputs.create_eval_input_fn(
eval_config=configs['eval_config'],
eval_input_config=configs['eval_input_configs'][0],
model_config=configs['model']
)
train_input_fn = inputs.create_train_input_fn(
train_config=configs['train_config'],
train_input_config=configs['train_input_config'],
model_config=configs['model']
)
features_train, _ = _make_initializable_iterator(
train_input_fn()).get_next()
features_eval, _ = _make_initializable_iterator(
eval_input_fn()).get_next()
images_train, images_eval = features_train['image'], features_eval['image']
self.assertEqual([1, None, None, 3], images_eval.shape.as_list())
self.assertEqual([24, 300, 300, 3], images_train.shape.as_list())
class DataAugmentationFnTest(test_case.TestCase):
......@@ -646,6 +673,14 @@ def _fake_image_resizer_fn(image, mask):
return (image, mask, tf.shape(image))
def _fake_resize50_preprocess_fn(image):
image = image[0]
image, shape = preprocessor.resize_to_range(
image, min_dimension=50, max_dimension=50, pad_to_max_dimension=True)
return tf.expand_dims(image, 0), tf.expand_dims(shape, axis=0)
class DataTransformationFnTest(test_case.TestCase):
def test_combine_additional_channels_if_present(self):
......@@ -1014,6 +1049,37 @@ class DataTransformationFnTest(test_case.TestCase):
self.assertAllEqual(augmented_tensor_dict[fields.InputDataFields.image],
(np_image + 5) * 2)
def test_resize_with_padding(self):
tensor_dict = {
fields.InputDataFields.image:
tf.constant(np.random.rand(100, 50, 3).astype(np.float32)),
fields.InputDataFields.groundtruth_boxes:
tf.constant(np.array([[.5, .5, 1, 1], [.0, .0, .5, .5]],
np.float32)),
fields.InputDataFields.groundtruth_classes:
tf.constant(np.array([1, 2], np.int32)),
fields.InputDataFields.groundtruth_keypoints:
tf.constant([[0.1, 0.2], [0.3, 0.4]]),
}
num_classes = 3
input_transformation_fn = functools.partial(
inputs.transform_input_data,
model_preprocess_fn=_fake_resize50_preprocess_fn,
image_resizer_fn=_fake_image_resizer_fn,
num_classes=num_classes,)
with self.test_session() as sess:
transformed_inputs = sess.run(
input_transformation_fn(tensor_dict=tensor_dict))
self.assertAllClose(
transformed_inputs[fields.InputDataFields.groundtruth_boxes],
[[.5, .25, 1., .5], [.0, .0, .5, .25]])
self.assertAllClose(
transformed_inputs[fields.InputDataFields.groundtruth_keypoints],
[[[.1, .1], [.3, .2]]])
class PadInputDataToStaticShapesFnTest(test_case.TestCase):
......
......@@ -45,6 +45,7 @@ Example usage:
import functools
import os
import tensorflow as tf
from tensorflow.contrib import framework as contrib_framework
from object_detection.builders import dataset_builder
from object_detection.builders import graph_rewriter_builder
......@@ -80,7 +81,7 @@ flags.DEFINE_boolean(
FLAGS = flags.FLAGS
@tf.contrib.framework.deprecated(None, 'Use object_detection/model_main.py.')
@contrib_framework.deprecated(None, 'Use object_detection/model_main.py.')
def main(unused_argv):
assert FLAGS.checkpoint_dir, '`checkpoint_dir` is missing.'
assert FLAGS.eval_dir, '`eval_dir` is missing.'
......
......@@ -45,6 +45,7 @@ import functools
import json
import os
import tensorflow as tf
from tensorflow.contrib import framework as contrib_framework
from object_detection.builders import dataset_builder
from object_detection.builders import graph_rewriter_builder
......@@ -84,7 +85,7 @@ flags.DEFINE_string('model_config_path', '',
FLAGS = flags.FLAGS
@tf.contrib.framework.deprecated(None, 'Use object_detection/model_main.py.')
@contrib_framework.deprecated(None, 'Use object_detection/model_main.py.')
def main(_):
assert FLAGS.train_dir, '`train_dir` is missing.'
if FLAGS.task == 0: tf.gfile.MakeDirs(FLAGS.train_dir)
......
......@@ -22,6 +22,7 @@ DetectionModel.
import functools
import tensorflow as tf
from tensorflow.contrib import slim as contrib_slim
from object_detection.builders import optimizer_builder
from object_detection.builders import preprocessor_builder
......@@ -32,7 +33,7 @@ from object_detection.utils import ops as util_ops
from object_detection.utils import variables_helper
from deployment import model_deploy
slim = tf.contrib.slim
slim = contrib_slim
def create_input_queue(batch_size_per_clone, create_tensor_dict_fn,
......
......@@ -18,6 +18,7 @@
import tensorflow as tf
from google.protobuf import text_format
from tensorflow.contrib import layers as contrib_layers
from object_detection.core import losses
from object_detection.core import model
......@@ -89,10 +90,10 @@ class FakeDetectionModel(model.DetectionModel):
prediction_dict: a dictionary holding prediction tensors to be
passed to the Loss or Postprocess functions.
"""
flattened_inputs = tf.contrib.layers.flatten(preprocessed_inputs)
class_prediction = tf.contrib.layers.fully_connected(
flattened_inputs, self._num_classes)
box_prediction = tf.contrib.layers.fully_connected(flattened_inputs, 4)
flattened_inputs = contrib_layers.flatten(preprocessed_inputs)
class_prediction = contrib_layers.fully_connected(flattened_inputs,
self._num_classes)
box_prediction = contrib_layers.fully_connected(flattened_inputs, 4)
return {
'class_predictions_with_background': tf.reshape(
......
......@@ -95,6 +95,8 @@ configured in the meta architecture:
import abc
import functools
import tensorflow as tf
from tensorflow.contrib import framework as contrib_framework
from tensorflow.contrib import slim as contrib_slim
from object_detection.anchor_generators import grid_anchor_generator
from object_detection.builders import box_predictor_builder
......@@ -110,7 +112,7 @@ from object_detection.utils import ops
from object_detection.utils import shape_utils
from object_detection.utils import variables_helper
slim = tf.contrib.slim
slim = contrib_slim
_UNINITIALIZED_FEATURE_EXTRACTOR = '__uninitialized__'
......@@ -2772,7 +2774,7 @@ class FasterRCNNMetaArch(model.DetectionModel):
self.first_stage_feature_extractor_scope,
self.second_stage_feature_extractor_scope
]
feature_extractor_variables = tf.contrib.framework.filter_variables(
feature_extractor_variables = contrib_framework.filter_variables(
variables_to_restore, include_patterns=include_patterns)
return {var.op.name: var for var in feature_extractor_variables}
......
......@@ -21,6 +21,7 @@ import numpy as np
import tensorflow as tf
from google.protobuf import text_format
from tensorflow.contrib import slim as contrib_slim
from object_detection.anchor_generators import grid_anchor_generator
from object_detection.builders import box_predictor_builder
from object_detection.builders import hyperparams_builder
......@@ -37,7 +38,7 @@ from object_detection.utils import ops
from object_detection.utils import test_case
from object_detection.utils import test_utils
slim = tf.contrib.slim
slim = contrib_slim
BOX_CODE_SIZE = 4
......
......@@ -19,6 +19,8 @@ models.
"""
import abc
import tensorflow as tf
from tensorflow.contrib import slim as contrib_slim
from tensorflow.contrib import tpu as contrib_tpu
from object_detection.core import box_list
from object_detection.core import box_list_ops
......@@ -31,7 +33,7 @@ from object_detection.utils import shape_utils
from object_detection.utils import variables_helper
from object_detection.utils import visualization_utils
slim = tf.contrib.slim
slim = contrib_slim
class SSDFeatureExtractor(object):
......@@ -778,11 +780,18 @@ class SSDMetaArch(model.DetectionModel):
detection_keypoints, 'raw_keypoint_locations')
additional_fields[fields.BoxListFields.keypoints] = detection_keypoints
with tf.init_scope():
if tf.executing_eagerly():
# soft device placement in eager mode will automatically handle
# outside compilation.
def _non_max_suppression_wrapper(kwargs):
return self._non_max_suppression_fn(**kwargs)
else:
def _non_max_suppression_wrapper(kwargs):
if self._nms_on_host:
# Note: NMS is not memory efficient on TPU. This force the NMS to run
# outside of TPU.
return tf.contrib.tpu.outside_compilation(
# Note: NMS is not memory efficient on TPU. This force the NMS
# to run outside of TPU.
return contrib_tpu.outside_compilation(
lambda x: self._non_max_suppression_fn(**x), kwargs)
else:
return self._non_max_suppression_fn(**kwargs)
......
......@@ -19,13 +19,14 @@ from absl.testing import parameterized
import numpy as np
import tensorflow as tf
from tensorflow.contrib import slim as contrib_slim
from object_detection.meta_architectures import ssd_meta_arch
from object_detection.meta_architectures import ssd_meta_arch_test_lib
from object_detection.protos import model_pb2
from object_detection.utils import test_utils
slim = tf.contrib.slim
slim = contrib_slim
keras = tf.keras.layers
......
......@@ -17,6 +17,7 @@
import functools
import tensorflow as tf
from google.protobuf import text_format
from tensorflow.contrib import slim as contrib_slim
from object_detection.builders import post_processing_builder
from object_detection.core import anchor_generator
......@@ -33,7 +34,7 @@ from object_detection.utils import ops
from object_detection.utils import test_case
from object_detection.utils import test_utils
slim = tf.contrib.slim
slim = contrib_slim
keras = tf.keras.layers
......
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