"examples/vscode:/vscode.git/clone" did not exist on "4fa77623ef2da30198855e31be5b3b8351395d27"
Commit 78d5f8f8 authored by Zhichao Lu's avatar Zhichao Lu Committed by lzc5123016
Browse files

Merged commit includes the following changes:

187187978  by Zhichao Lu:

    Only updating hyperparameters if they have non-null values.

--
187097690  by Zhichao Lu:

    Rewrite some conditions a bit more clearly.

--
187085190  by Zhichao Lu:

    More informative error message.

--
186935376  by Zhichao Lu:

    Added option to evaluator.evaluate to use custom evaluator objects.

--
186808249  by Zhichao Lu:

    Fix documentation re: number of stages.

--
186775014  by Zhichao Lu:

    Change anchor generator interface to return a list of BoxLists containing anchors for different feature map layers.

--
186729028  by Zhichao Lu:

    Minor fixes to object detection.

--
186723716  by Zhichao Lu:

    Fix tf_example_decoder.py initailization issue.

--
186668505  by Zhichao Lu:

    Remove unused import.

--
186475361  by Zhichao Lu:

    Update the box predictor interface to return list of predictions - one from each feature map - instead of stacking them into one large tensor.

--
186410844  by Zhichao Lu:

    Fix PythonPath Dependencies.

--
186365384  by Zhichao Lu:

    Made some of the functions in exporter public so they can be reused.

--
186341438  by Zhichao Lu:

    Re-introducing check that label-map-path must be a valid (non-empty) string prior to overwriting pipeline config.

--
186036984  by Zhichao Lu:

    Adding default hyperparameters and allowing for overriding them via flags.

--
186026006  by Zhichao Lu:

    Strip `eval_` prefix from name argument give to TPUEstimator.evaluate since it adds the same prefix internally.

--
186016042  by Zhichao Lu:

    Add an option to evaluate models on training data.

--
185944986  by Zhichao Lu:

    let _update_label_map_path go through even if the path is empty

--
185860781  by Zhichao Lu:

    Add random normal initializer option to hyperparams builder.

    Scale the regression losses outside of the box encoder by adjusting huber loss delta and regression loss weight.

--
185846325  by Zhichao Lu:

    Add an option to normalize localization loss by the code size(number of box coordinates) in SSD Meta architecture.

--
185761217  by Zhichao Lu:

    Change multiscale_grid_anchor_generator to return anchors in normalized coordinates by default and add option to configure it.

    In SSD meta architecture, TargetAssigner operates in normalized coordinate space (i.e, groundtruth boxes are in normalized coordinates) hence we need the option to generate anchors in normalized coordinates.

--
185747733  by Zhichao Lu:

    Change the smooth L1 localization implementationt to use tf.losses.huber_loss and expose the delta parameter in the proto.

--
185715309  by Zhichao Lu:

    Obviates the need for prepadding on mobilenet v1 and v2 for fully convolutional models.

--
185685695  by Zhichao Lu:

    Fix manual stepping schedule to return first rate when there are no boundaries

--
185621650  by Zhichao Lu:

    Added target assigner proto for configuring negative class weights.

--

PiperOrigin-RevId: 187187978
parent 629adffa
...@@ -40,7 +40,7 @@ EMBEDDED_SSD_MOBILENET_V1_LAYOUT = { ...@@ -40,7 +40,7 @@ EMBEDDED_SSD_MOBILENET_V1_LAYOUT = {
} }
# TODO: add tests with different anchor strides. # TODO(rathodv): add tests with different anchor strides.
class MultiResolutionFeatureMapGeneratorTest(tf.test.TestCase): class MultiResolutionFeatureMapGeneratorTest(tf.test.TestCase):
def test_get_expected_feature_map_shapes_with_inception_v2(self): def test_get_expected_feature_map_shapes_with_inception_v2(self):
......
...@@ -27,13 +27,17 @@ from object_detection.utils import test_case ...@@ -27,13 +27,17 @@ from object_detection.utils import test_case
class SsdFeatureExtractorTestBase(test_case.TestCase): class SsdFeatureExtractorTestBase(test_case.TestCase):
@abstractmethod @abstractmethod
def _create_feature_extractor(self, depth_multiplier, pad_to_multiple): def _create_feature_extractor(self, depth_multiplier, pad_to_multiple,
use_explicit_padding=False):
"""Constructs a new feature extractor. """Constructs a new feature extractor.
Args: Args:
depth_multiplier: float depth multiplier for feature extractor depth_multiplier: float depth multiplier for feature extractor
pad_to_multiple: the nearest multiple to zero pad the input height and pad_to_multiple: the nearest multiple to zero pad the input height and
width dimensions to. width dimensions to.
use_explicit_padding: use 'VALID' padding for convolutions, but prepad
inputs so that the output dimensions are the same as if 'SAME' padding
were used.
Returns: Returns:
an ssd_meta_arch.SSDFeatureExtractor object. an ssd_meta_arch.SSDFeatureExtractor object.
""" """
...@@ -41,10 +45,11 @@ class SsdFeatureExtractorTestBase(test_case.TestCase): ...@@ -41,10 +45,11 @@ class SsdFeatureExtractorTestBase(test_case.TestCase):
def check_extract_features_returns_correct_shape( def check_extract_features_returns_correct_shape(
self, batch_size, image_height, image_width, depth_multiplier, self, batch_size, image_height, image_width, depth_multiplier,
pad_to_multiple, expected_feature_map_shapes): pad_to_multiple, expected_feature_map_shapes, use_explicit_padding=False):
def graph_fn(image_tensor): def graph_fn(image_tensor):
feature_extractor = self._create_feature_extractor(depth_multiplier, feature_extractor = self._create_feature_extractor(depth_multiplier,
pad_to_multiple) pad_to_multiple,
use_explicit_padding)
feature_maps = feature_extractor.extract_features(image_tensor) feature_maps = feature_extractor.extract_features(image_tensor)
return feature_maps return feature_maps
...@@ -57,10 +62,11 @@ class SsdFeatureExtractorTestBase(test_case.TestCase): ...@@ -57,10 +62,11 @@ class SsdFeatureExtractorTestBase(test_case.TestCase):
def check_extract_features_returns_correct_shapes_with_dynamic_inputs( def check_extract_features_returns_correct_shapes_with_dynamic_inputs(
self, batch_size, image_height, image_width, depth_multiplier, self, batch_size, image_height, image_width, depth_multiplier,
pad_to_multiple, expected_feature_map_shapes): pad_to_multiple, expected_feature_map_shapes, use_explicit_padding=False):
def graph_fn(image_height, image_width): def graph_fn(image_height, image_width):
feature_extractor = self._create_feature_extractor(depth_multiplier, feature_extractor = self._create_feature_extractor(depth_multiplier,
pad_to_multiple) pad_to_multiple,
use_explicit_padding)
image_tensor = tf.random_uniform([batch_size, image_height, image_width, image_tensor = tf.random_uniform([batch_size, image_height, image_width,
3], dtype=tf.float32) 3], dtype=tf.float32)
feature_maps = feature_extractor.extract_features(image_tensor) feature_maps = feature_extractor.extract_features(image_tensor)
......
...@@ -53,8 +53,9 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor): ...@@ -53,8 +53,9 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
(e.g. 1), it is desirable to disable batch norm update and use (e.g. 1), it is desirable to disable batch norm update and use
pretrained batch norm params. pretrained batch norm params.
reuse_weights: Whether to reuse variables. Default is None. reuse_weights: Whether to reuse variables. Default is None.
use_explicit_padding: Whether to use explicit padding when extracting use_explicit_padding: Use 'VALID' padding for convolutions, but prepad
features. Default is False. inputs so that the output dimensions are the same as if 'SAME' padding
were used.
use_depthwise: Whether to use depthwise convolutions. Default is False. use_depthwise: Whether to use depthwise convolutions. Default is False.
""" """
super(SSDMobileNetV1FeatureExtractor, self).__init__( super(SSDMobileNetV1FeatureExtractor, self).__init__(
...@@ -100,7 +101,7 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor): ...@@ -100,7 +101,7 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
} }
with slim.arg_scope(self._conv_hyperparams): with slim.arg_scope(self._conv_hyperparams):
# TODO: Enable fused batch norm once quantization supports it. # TODO(skligys): Enable fused batch norm once quantization supports it.
with slim.arg_scope([slim.batch_norm], fused=False): with slim.arg_scope([slim.batch_norm], fused=False):
with tf.variable_scope('MobilenetV1', with tf.variable_scope('MobilenetV1',
reuse=self._reuse_weights) as scope: reuse=self._reuse_weights) as scope:
...@@ -109,6 +110,7 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor): ...@@ -109,6 +110,7 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
final_endpoint='Conv2d_13_pointwise', final_endpoint='Conv2d_13_pointwise',
min_depth=self._min_depth, min_depth=self._min_depth,
depth_multiplier=self._depth_multiplier, depth_multiplier=self._depth_multiplier,
use_explicit_padding=self._use_explicit_padding,
scope=scope) scope=scope)
feature_maps = feature_map_generators.multi_resolution_feature_maps( feature_maps = feature_map_generators.multi_resolution_feature_maps(
feature_map_layout=feature_map_layout, feature_map_layout=feature_map_layout,
......
...@@ -27,7 +27,8 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -27,7 +27,8 @@ class SsdMobilenetV1FeatureExtractorTest(
ssd_feature_extractor_test.SsdFeatureExtractorTestBase): ssd_feature_extractor_test.SsdFeatureExtractorTestBase):
def _create_feature_extractor(self, depth_multiplier, pad_to_multiple, def _create_feature_extractor(self, depth_multiplier, pad_to_multiple,
is_training=True, batch_norm_trainable=True): is_training=True, batch_norm_trainable=True,
use_explicit_padding=False):
"""Constructs a new feature extractor. """Constructs a new feature extractor.
Args: Args:
...@@ -37,6 +38,9 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -37,6 +38,9 @@ class SsdMobilenetV1FeatureExtractorTest(
is_training: whether the network is in training mode. is_training: whether the network is in training mode.
batch_norm_trainable: Whether to update batch norm parameters during batch_norm_trainable: Whether to update batch norm parameters during
training or not. training or not.
use_explicit_padding: Use 'VALID' padding for convolutions, but prepad
inputs so that the output dimensions are the same as if 'SAME' padding
were used.
Returns: Returns:
an ssd_meta_arch.SSDFeatureExtractor object. an ssd_meta_arch.SSDFeatureExtractor object.
""" """
...@@ -45,7 +49,8 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -45,7 +49,8 @@ class SsdMobilenetV1FeatureExtractorTest(
conv_hyperparams = sc conv_hyperparams = sc
return ssd_mobilenet_v1_feature_extractor.SSDMobileNetV1FeatureExtractor( return ssd_mobilenet_v1_feature_extractor.SSDMobileNetV1FeatureExtractor(
is_training, depth_multiplier, min_depth, pad_to_multiple, is_training, depth_multiplier, min_depth, pad_to_multiple,
conv_hyperparams, batch_norm_trainable) conv_hyperparams, batch_norm_trainable=batch_norm_trainable,
use_explicit_padding=use_explicit_padding)
def test_extract_features_returns_correct_shapes_128(self): def test_extract_features_returns_correct_shapes_128(self):
image_height = 128 image_height = 128
...@@ -57,7 +62,10 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -57,7 +62,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 1, 1, 256), (2, 1, 1, 128)] (2, 1, 1, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shape( self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple, 2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape) expected_feature_map_shape, use_explicit_padding=False)
self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape, use_explicit_padding=True)
def test_extract_features_returns_correct_shapes_299(self): def test_extract_features_returns_correct_shapes_299(self):
image_height = 299 image_height = 299
...@@ -69,7 +77,10 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -69,7 +77,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 2, 2, 256), (2, 1, 1, 128)] (2, 2, 2, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shape( self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple, 2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape) expected_feature_map_shape, use_explicit_padding=False)
self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape, use_explicit_padding=True)
def test_extract_features_with_dynamic_image_shape(self): def test_extract_features_with_dynamic_image_shape(self):
image_height = 128 image_height = 128
...@@ -81,7 +92,10 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -81,7 +92,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 1, 1, 256), (2, 1, 1, 128)] (2, 1, 1, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shapes_with_dynamic_inputs( self.check_extract_features_returns_correct_shapes_with_dynamic_inputs(
2, image_height, image_width, depth_multiplier, pad_to_multiple, 2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape) expected_feature_map_shape, use_explicit_padding=False)
self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape, use_explicit_padding=True)
def test_extract_features_returns_correct_shapes_enforcing_min_depth(self): def test_extract_features_returns_correct_shapes_enforcing_min_depth(self):
image_height = 299 image_height = 299
...@@ -93,7 +107,10 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -93,7 +107,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 2, 2, 32), (2, 1, 1, 32)] (2, 2, 2, 32), (2, 1, 1, 32)]
self.check_extract_features_returns_correct_shape( self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple, 2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape) expected_feature_map_shape, use_explicit_padding=False)
self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape, use_explicit_padding=True)
def test_extract_features_returns_correct_shapes_with_pad_to_multiple(self): def test_extract_features_returns_correct_shapes_with_pad_to_multiple(self):
image_height = 299 image_height = 299
...@@ -105,7 +122,10 @@ class SsdMobilenetV1FeatureExtractorTest( ...@@ -105,7 +122,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 2, 2, 256), (2, 1, 1, 128)] (2, 2, 2, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shape( self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple, 2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape) expected_feature_map_shape, use_explicit_padding=False)
self.check_extract_features_returns_correct_shape(
2, image_height, image_width, depth_multiplier, pad_to_multiple,
expected_feature_map_shape, use_explicit_padding=True)
def test_extract_features_raises_error_with_invalid_image_size(self): def test_extract_features_raises_error_with_invalid_image_size(self):
image_height = 32 image_height = 32
......
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""SSD Feature Pyramid Network (FPN) feature extractors based on Resnet v1. """SSD Feature Pyramid Network (FPN) feature extractors based on Resnet v1.
See https://arxiv.org/abs/1708.02002 for details. See https://arxiv.org/abs/1708.02002 for details.
...@@ -87,7 +101,7 @@ class _SSDResnetV1FpnFeatureExtractor(ssd_meta_arch.SSDFeatureExtractor): ...@@ -87,7 +101,7 @@ class _SSDResnetV1FpnFeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
return resized_inputs - [[channel_means]] return resized_inputs - [[channel_means]]
def _filter_features(self, image_features): def _filter_features(self, image_features):
# TODO: Change resnet endpoint to strip scope prefixes instead # TODO(rathodv): Change resnet endpoint to strip scope prefixes instead
# of munging the scope here. # of munging the scope here.
filtered_image_features = dict({}) filtered_image_features = dict({})
for key, feature in image_features.items(): for key, feature in image_features.items():
......
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Tests for ssd resnet v1 FPN feature extractors.""" """Tests for ssd resnet v1 FPN feature extractors."""
import tensorflow as tf import tensorflow as tf
...@@ -10,14 +24,16 @@ class SSDResnet50V1FeatureExtractorTest( ...@@ -10,14 +24,16 @@ class SSDResnet50V1FeatureExtractorTest(
SSDResnetFPNFeatureExtractorTestBase): SSDResnetFPNFeatureExtractorTestBase):
"""SSDResnet50v1Fpn feature extractor test.""" """SSDResnet50v1Fpn feature extractor test."""
def _create_feature_extractor(self, depth_multiplier, pad_to_multiple): def _create_feature_extractor(self, depth_multiplier, pad_to_multiple,
use_explicit_padding=False):
min_depth = 32 min_depth = 32
conv_hyperparams = {} conv_hyperparams = {}
batch_norm_trainable = True batch_norm_trainable = True
is_training = True is_training = True
return ssd_resnet_v1_fpn_feature_extractor.SSDResnet50V1FpnFeatureExtractor( return ssd_resnet_v1_fpn_feature_extractor.SSDResnet50V1FpnFeatureExtractor(
is_training, depth_multiplier, min_depth, pad_to_multiple, is_training, depth_multiplier, min_depth, pad_to_multiple,
conv_hyperparams, batch_norm_trainable) conv_hyperparams, batch_norm_trainable,
use_explicit_padding=use_explicit_padding)
def _resnet_scope_name(self): def _resnet_scope_name(self):
return 'resnet_v1_50' return 'resnet_v1_50'
...@@ -28,7 +44,8 @@ class SSDResnet101V1FeatureExtractorTest( ...@@ -28,7 +44,8 @@ class SSDResnet101V1FeatureExtractorTest(
SSDResnetFPNFeatureExtractorTestBase): SSDResnetFPNFeatureExtractorTestBase):
"""SSDResnet101v1Fpn feature extractor test.""" """SSDResnet101v1Fpn feature extractor test."""
def _create_feature_extractor(self, depth_multiplier, pad_to_multiple): def _create_feature_extractor(self, depth_multiplier, pad_to_multiple,
use_explicit_padding=False):
min_depth = 32 min_depth = 32
conv_hyperparams = {} conv_hyperparams = {}
batch_norm_trainable = True batch_norm_trainable = True
...@@ -36,7 +53,8 @@ class SSDResnet101V1FeatureExtractorTest( ...@@ -36,7 +53,8 @@ class SSDResnet101V1FeatureExtractorTest(
return ( return (
ssd_resnet_v1_fpn_feature_extractor.SSDResnet101V1FpnFeatureExtractor( ssd_resnet_v1_fpn_feature_extractor.SSDResnet101V1FpnFeatureExtractor(
is_training, depth_multiplier, min_depth, pad_to_multiple, is_training, depth_multiplier, min_depth, pad_to_multiple,
conv_hyperparams, batch_norm_trainable)) conv_hyperparams, batch_norm_trainable,
use_explicit_padding=use_explicit_padding))
def _resnet_scope_name(self): def _resnet_scope_name(self):
return 'resnet_v1_101' return 'resnet_v1_101'
...@@ -47,7 +65,8 @@ class SSDResnet152V1FeatureExtractorTest( ...@@ -47,7 +65,8 @@ class SSDResnet152V1FeatureExtractorTest(
SSDResnetFPNFeatureExtractorTestBase): SSDResnetFPNFeatureExtractorTestBase):
"""SSDResnet152v1Fpn feature extractor test.""" """SSDResnet152v1Fpn feature extractor test."""
def _create_feature_extractor(self, depth_multiplier, pad_to_multiple): def _create_feature_extractor(self, depth_multiplier, pad_to_multiple,
use_explicit_padding=False):
min_depth = 32 min_depth = 32
conv_hyperparams = {} conv_hyperparams = {}
batch_norm_trainable = True batch_norm_trainable = True
...@@ -55,7 +74,8 @@ class SSDResnet152V1FeatureExtractorTest( ...@@ -55,7 +74,8 @@ class SSDResnet152V1FeatureExtractorTest(
return ( return (
ssd_resnet_v1_fpn_feature_extractor.SSDResnet152V1FpnFeatureExtractor( ssd_resnet_v1_fpn_feature_extractor.SSDResnet152V1FpnFeatureExtractor(
is_training, depth_multiplier, min_depth, pad_to_multiple, is_training, depth_multiplier, min_depth, pad_to_multiple,
conv_hyperparams, batch_norm_trainable)) conv_hyperparams, batch_norm_trainable,
use_explicit_padding=use_explicit_padding))
def _resnet_scope_name(self): def _resnet_scope_name(self):
return 'resnet_v1_152' return 'resnet_v1_152'
......
# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Tests for ssd resnet v1 FPN feature extractors.""" """Tests for ssd resnet v1 FPN feature extractors."""
import abc import abc
import numpy as np import numpy as np
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# This is needed to display the images.\n", "# This is needed to display the images.\n",
"%matplotlib inline" "%matplotlib inline",
] ]
}, },
{ {
......
# Tensorflow Object Detection API: Configuration protos.
package(
default_visibility = ["//visibility:public"],
)
licenses(["notice"])
proto_library(
name = "argmax_matcher_proto",
srcs = ["argmax_matcher.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "argmax_matcher_py_pb2",
api_version = 2,
deps = [":argmax_matcher_proto"],
)
proto_library(
name = "bipartite_matcher_proto",
srcs = ["bipartite_matcher.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "bipartite_matcher_py_pb2",
api_version = 2,
deps = [":bipartite_matcher_proto"],
)
proto_library(
name = "matcher_proto",
srcs = ["matcher.proto"],
cc_api_version = 2,
deps = [
":argmax_matcher_proto",
":bipartite_matcher_proto",
],
)
py_proto_library(
name = "matcher_py_pb2",
api_version = 2,
deps = [":matcher_proto"],
)
proto_library(
name = "faster_rcnn_box_coder_proto",
srcs = ["faster_rcnn_box_coder.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "faster_rcnn_box_coder_py_pb2",
api_version = 2,
deps = [":faster_rcnn_box_coder_proto"],
)
proto_library(
name = "keypoint_box_coder_proto",
srcs = ["keypoint_box_coder.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "keypoint_box_coder_py_pb2",
api_version = 2,
deps = [":keypoint_box_coder_proto"],
)
proto_library(
name = "mean_stddev_box_coder_proto",
srcs = ["mean_stddev_box_coder.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "mean_stddev_box_coder_py_pb2",
api_version = 2,
deps = [":mean_stddev_box_coder_proto"],
)
proto_library(
name = "square_box_coder_proto",
srcs = ["square_box_coder.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "square_box_coder_py_pb2",
api_version = 2,
deps = [":square_box_coder_proto"],
)
proto_library(
name = "box_coder_proto",
srcs = ["box_coder.proto"],
cc_api_version = 2,
deps = [
":faster_rcnn_box_coder_proto",
":keypoint_box_coder_proto",
":mean_stddev_box_coder_proto",
":square_box_coder_proto",
],
)
py_proto_library(
name = "box_coder_py_pb2",
api_version = 2,
deps = [":box_coder_proto"],
)
proto_library(
name = "grid_anchor_generator_proto",
srcs = ["grid_anchor_generator.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "grid_anchor_generator_py_pb2",
api_version = 2,
deps = [":grid_anchor_generator_proto"],
)
proto_library(
name = "ssd_anchor_generator_proto",
srcs = ["ssd_anchor_generator.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "ssd_anchor_generator_py_pb2",
api_version = 2,
deps = [":ssd_anchor_generator_proto"],
)
proto_library(
name = "multiscale_anchor_generator_proto",
srcs = ["multiscale_anchor_generator.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "multiscale_anchor_generator_py_pb2",
api_version = 2,
deps = [":multiscale_anchor_generator_proto"],
)
proto_library(
name = "anchor_generator_proto",
srcs = ["anchor_generator.proto"],
cc_api_version = 2,
deps = [
":grid_anchor_generator_proto",
":multiscale_anchor_generator_proto",
":ssd_anchor_generator_proto",
],
)
py_proto_library(
name = "anchor_generator_py_pb2",
api_version = 2,
deps = [":anchor_generator_proto"],
)
proto_library(
name = "input_reader_proto",
srcs = ["input_reader.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "input_reader_py_pb2",
api_version = 2,
deps = [":input_reader_proto"],
)
proto_library(
name = "losses_proto",
srcs = ["losses.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "losses_py_pb2",
api_version = 2,
deps = [":losses_proto"],
)
proto_library(
name = "optimizer_proto",
srcs = ["optimizer.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "optimizer_py_pb2",
api_version = 2,
deps = [":optimizer_proto"],
)
proto_library(
name = "post_processing_proto",
srcs = ["post_processing.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "post_processing_py_pb2",
api_version = 2,
deps = [":post_processing_proto"],
)
proto_library(
name = "hyperparams_proto",
srcs = ["hyperparams.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "hyperparams_py_pb2",
api_version = 2,
deps = [":hyperparams_proto"],
)
proto_library(
name = "box_predictor_proto",
srcs = ["box_predictor.proto"],
cc_api_version = 2,
deps = [":hyperparams_proto"],
)
py_proto_library(
name = "box_predictor_py_pb2",
api_version = 2,
deps = [":box_predictor_proto"],
)
proto_library(
name = "region_similarity_calculator_proto",
srcs = ["region_similarity_calculator.proto"],
cc_api_version = 2,
deps = [],
)
py_proto_library(
name = "region_similarity_calculator_py_pb2",
api_version = 2,
deps = [":region_similarity_calculator_proto"],
)
proto_library(
name = "preprocessor_proto",
srcs = ["preprocessor.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "preprocessor_py_pb2",
api_version = 2,
deps = [":preprocessor_proto"],
)
proto_library(
name = "train_proto",
srcs = ["train.proto"],
cc_api_version = 2,
deps = [
":optimizer_proto",
":preprocessor_proto",
],
)
py_proto_library(
name = "train_py_pb2",
api_version = 2,
deps = [":train_proto"],
)
proto_library(
name = "eval_proto",
srcs = ["eval.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "eval_py_pb2",
api_version = 2,
deps = [":eval_proto"],
)
proto_library(
name = "image_resizer_proto",
srcs = ["image_resizer.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "image_resizer_py_pb2",
api_version = 2,
deps = [":image_resizer_proto"],
)
proto_library(
name = "faster_rcnn_proto",
srcs = ["faster_rcnn.proto"],
cc_api_version = 2,
deps = [
":box_predictor_proto",
"//tensorflow/models/research/object_detection/protos:anchor_generator_proto",
"//tensorflow/models/research/object_detection/protos:hyperparams_proto",
"//tensorflow/models/research/object_detection/protos:image_resizer_proto",
"//tensorflow/models/research/object_detection/protos:losses_proto",
"//tensorflow/models/research/object_detection/protos:post_processing_proto",
],
)
proto_library(
name = "ssd_proto",
srcs = ["ssd.proto"],
cc_api_version = 2,
deps = [
":anchor_generator_proto",
":box_coder_proto",
":box_predictor_proto",
":hyperparams_proto",
":image_resizer_proto",
":losses_proto",
":matcher_proto",
":post_processing_proto",
":region_similarity_calculator_proto",
],
)
proto_library(
name = "model_proto",
srcs = ["model.proto"],
cc_api_version = 2,
deps = [
":faster_rcnn_proto",
":ssd_proto",
],
)
py_proto_library(
name = "model_py_pb2",
api_version = 2,
deps = [":model_proto"],
)
proto_library(
name = "pipeline_proto",
srcs = ["pipeline.proto"],
cc_api_version = 2,
deps = [
":eval_proto",
":input_reader_proto",
":model_proto",
":train_proto",
],
)
py_proto_library(
name = "pipeline_py_pb2",
api_version = 2,
deps = [":pipeline_proto"],
)
proto_library(
name = "string_int_label_map_proto",
srcs = ["string_int_label_map.proto"],
cc_api_version = 2,
)
py_proto_library(
name = "string_int_label_map_py_pb2",
api_version = 2,
deps = [":string_int_label_map_proto"],
)
...@@ -65,6 +65,7 @@ message Initializer { ...@@ -65,6 +65,7 @@ message Initializer {
oneof initializer_oneof { oneof initializer_oneof {
TruncatedNormalInitializer truncated_normal_initializer = 1; TruncatedNormalInitializer truncated_normal_initializer = 1;
VarianceScalingInitializer variance_scaling_initializer = 2; VarianceScalingInitializer variance_scaling_initializer = 2;
RandomNormalInitializer random_normal_initializer = 3;
} }
} }
...@@ -89,6 +90,13 @@ message VarianceScalingInitializer { ...@@ -89,6 +90,13 @@ message VarianceScalingInitializer {
optional Mode mode = 3 [default = FAN_IN]; optional Mode mode = 3 [default = FAN_IN];
} }
// Configuration proto for random normal initializer. See
// https://www.tensorflow.org/api_docs/python/tf/random_normal_initializer
message RandomNormalInitializer {
optional float mean = 1 [default = 0.0];
optional float stddev = 2 [default = 1.0];
}
// Configuration proto for batch norm to apply after convolution op. See // Configuration proto for batch norm to apply after convolution op. See
// https://www.tensorflow.org/api_docs/python/tf/contrib/layers/batch_norm // https://www.tensorflow.org/api_docs/python/tf/contrib/layers/batch_norm
message BatchNorm { message BatchNorm {
......
...@@ -38,11 +38,17 @@ message WeightedL2LocalizationLoss { ...@@ -38,11 +38,17 @@ message WeightedL2LocalizationLoss {
optional bool anchorwise_output = 1 [default=false]; optional bool anchorwise_output = 1 [default=false];
} }
// SmoothL1 (Huber) location loss: .5 * x ^ 2 if |x| < 1 else |x| - .5 // SmoothL1 (Huber) location loss.
// The smooth L1_loss is defined elementwise as .5 x^2 if |x| <= delta and
// 0.5 x^2 + delta * (|x|-delta) otherwise, where x is the difference between
// predictions and target.
message WeightedSmoothL1LocalizationLoss { message WeightedSmoothL1LocalizationLoss {
// DEPRECATED, do not use. // DEPRECATED, do not use.
// Output loss per anchor. // Output loss per anchor.
optional bool anchorwise_output = 1 [default=false]; optional bool anchorwise_output = 1 [default=false];
// Delta value for huber loss.
optional float delta = 2 [default=1.0];
} }
// Intersection over union location loss: 1 - IOU // Intersection over union location loss: 1 - IOU
......
...@@ -20,4 +20,7 @@ message MultiscaleAnchorGenerator { ...@@ -20,4 +20,7 @@ message MultiscaleAnchorGenerator {
// Number of intermediate scale each scale octave // Number of intermediate scale each scale octave
optional int32 scales_per_octave = 5 [default = 2]; optional int32 scales_per_octave = 5 [default = 2];
// Whether to produce anchors in normalized coordinates.
optional bool normalize_coordinates = 6 [default = true];
} }
...@@ -36,6 +36,10 @@ message Ssd { ...@@ -36,6 +36,10 @@ message Ssd {
// zeros vector or a one-hot vector (where background is the 0th class). // zeros vector or a one-hot vector (where background is the 0th class).
optional bool encode_background_as_zeros = 12 [default=false]; optional bool encode_background_as_zeros = 12 [default=false];
// classification weight to be associated to negative
// anchors (default: 1.0). The weight must be in [0., 1.].
optional float negative_class_weight = 13 [default = 1.0];
// Box predictor to attach to the features. // Box predictor to attach to the features.
optional BoxPredictor box_predictor = 7; optional BoxPredictor box_predictor = 7;
...@@ -49,6 +53,10 @@ message Ssd { ...@@ -49,6 +53,10 @@ message Ssd {
// the anchors. // the anchors.
optional bool normalize_loss_by_num_matches = 10 [default=true]; optional bool normalize_loss_by_num_matches = 10 [default=true];
// Whether to normalize the localization loss by the code size of the box
// encodings. This is applied along with other normalization factors.
optional bool normalize_loc_loss_by_codesize = 14 [default=false];
// Loss configuration for training. // Loss configuration for training.
optional Loss loss = 11; optional Loss loss = 11;
} }
......
package(
default_visibility = ["//visibility:public"],
)
licenses(["notice"])
exports_files([
"faster_rcnn_resnet50_pets.config",
"ssd_inception_v2_pets.config",
"ssd_mobilenet_v1_focal_loss_pets.config",
])
package(
default_visibility = ["//visibility:public"],
)
licenses(["notice"])
exports_files([
"pets_examples.record",
])
package(
default_visibility = ["//visibility:public"],
)
licenses(["notice"])
exports_files([
"image1.jpg",
"image2.jpg",
])
...@@ -235,7 +235,7 @@ def train(create_tensor_dict_fn, create_model_fn, train_config, master, task, ...@@ -235,7 +235,7 @@ def train(create_tensor_dict_fn, create_model_fn, train_config, master, task,
train_config.prefetch_queue_capacity, data_augmentation_options) train_config.prefetch_queue_capacity, data_augmentation_options)
# Gather initial summaries. # Gather initial summaries.
# TODO: See if summaries can be added/extracted from global tf # TODO(rathodv): See if summaries can be added/extracted from global tf
# collections so that they don't have to be passed around. # collections so that they don't have to be passed around.
summaries = set(tf.get_collection(tf.GraphKeys.SUMMARIES)) summaries = set(tf.get_collection(tf.GraphKeys.SUMMARIES))
global_summaries = set([]) global_summaries = set([])
......
This diff is collapsed.
...@@ -241,6 +241,10 @@ def merge_external_params_with_configs(configs, hparams=None, **kwargs): ...@@ -241,6 +241,10 @@ def merge_external_params_with_configs(configs, hparams=None, **kwargs):
if hparams: if hparams:
kwargs.update(hparams.values()) kwargs.update(hparams.values())
for key, value in kwargs.items(): for key, value in kwargs.items():
# pylint: disable=g-explicit-bool-comparison
if value == "" or value is None:
continue
# pylint: enable=g-explicit-bool-comparison
if key == "learning_rate": if key == "learning_rate":
_update_initial_learning_rate(configs, value) _update_initial_learning_rate(configs, value)
tf.logging.info("Overwriting learning rate: %f", value) tf.logging.info("Overwriting learning rate: %f", value)
...@@ -270,7 +274,6 @@ def merge_external_params_with_configs(configs, hparams=None, **kwargs): ...@@ -270,7 +274,6 @@ def merge_external_params_with_configs(configs, hparams=None, **kwargs):
_update_input_path(configs["eval_input_config"], value) _update_input_path(configs["eval_input_config"], value)
tf.logging.info("Overwriting eval input path: %s", value) tf.logging.info("Overwriting eval input path: %s", value)
if key == "label_map_path": if key == "label_map_path":
if value:
_update_label_map_path(configs, value) _update_label_map_path(configs, value)
tf.logging.info("Overwriting label map path: %s", value) tf.logging.info("Overwriting label map path: %s", value)
if key == "mask_type": if key == "mask_type":
......
...@@ -397,6 +397,27 @@ class ConfigUtilTest(tf.test.TestCase): ...@@ -397,6 +397,27 @@ class ConfigUtilTest(tf.test.TestCase):
self.assertEqual(new_label_map_path, self.assertEqual(new_label_map_path,
configs["eval_input_config"].label_map_path) configs["eval_input_config"].label_map_path)
def testDontOverwriteEmptyLabelMapPath(self):
"""Tests that label map path will not by overwritten with empty string."""
original_label_map_path = "path/to/original/label_map"
new_label_map_path = ""
pipeline_config_path = os.path.join(self.get_temp_dir(), "pipeline.config")
pipeline_config = pipeline_pb2.TrainEvalPipelineConfig()
train_input_reader = pipeline_config.train_input_reader
train_input_reader.label_map_path = original_label_map_path
eval_input_reader = pipeline_config.eval_input_reader
eval_input_reader.label_map_path = original_label_map_path
_write_config(pipeline_config, pipeline_config_path)
configs = config_util.get_configs_from_pipeline_file(pipeline_config_path)
configs = config_util.merge_external_params_with_configs(
configs, label_map_path=new_label_map_path)
self.assertEqual(original_label_map_path,
configs["train_input_config"].label_map_path)
self.assertEqual(original_label_map_path,
configs["eval_input_config"].label_map_path)
def testNewMaskType(self): def testNewMaskType(self):
"""Tests that mask type can be overwritten in input readers.""" """Tests that mask type can be overwritten in input readers."""
original_mask_type = input_reader_pb2.NUMERICAL_MASKS original_mask_type = input_reader_pb2.NUMERICAL_MASKS
......
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