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 Zhich...
parent 629adffa
......@@ -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):
def test_get_expected_feature_map_shapes_with_inception_v2(self):
......
......@@ -27,13 +27,17 @@ from object_detection.utils import test_case
class SsdFeatureExtractorTestBase(test_case.TestCase):
@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.
Args:
depth_multiplier: float depth multiplier for feature extractor
pad_to_multiple: the nearest multiple to zero pad the input height and
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:
an ssd_meta_arch.SSDFeatureExtractor object.
"""
......@@ -41,10 +45,11 @@ class SsdFeatureExtractorTestBase(test_case.TestCase):
def check_extract_features_returns_correct_shape(
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):
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)
return feature_maps
......@@ -57,10 +62,11 @@ class SsdFeatureExtractorTestBase(test_case.TestCase):
def check_extract_features_returns_correct_shapes_with_dynamic_inputs(
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):
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,
3], dtype=tf.float32)
feature_maps = feature_extractor.extract_features(image_tensor)
......
......@@ -53,8 +53,9 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
(e.g. 1), it is desirable to disable batch norm update and use
pretrained batch norm params.
reuse_weights: Whether to reuse variables. Default is None.
use_explicit_padding: Whether to use explicit padding when extracting
features. Default is False.
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.
use_depthwise: Whether to use depthwise convolutions. Default is False.
"""
super(SSDMobileNetV1FeatureExtractor, self).__init__(
......@@ -100,7 +101,7 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
}
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 tf.variable_scope('MobilenetV1',
reuse=self._reuse_weights) as scope:
......@@ -109,6 +110,7 @@ class SSDMobileNetV1FeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
final_endpoint='Conv2d_13_pointwise',
min_depth=self._min_depth,
depth_multiplier=self._depth_multiplier,
use_explicit_padding=self._use_explicit_padding,
scope=scope)
feature_maps = feature_map_generators.multi_resolution_feature_maps(
feature_map_layout=feature_map_layout,
......
......@@ -27,7 +27,8 @@ class SsdMobilenetV1FeatureExtractorTest(
ssd_feature_extractor_test.SsdFeatureExtractorTestBase):
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.
Args:
......@@ -37,6 +38,9 @@ class SsdMobilenetV1FeatureExtractorTest(
is_training: whether the network is in training mode.
batch_norm_trainable: Whether to update batch norm parameters during
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:
an ssd_meta_arch.SSDFeatureExtractor object.
"""
......@@ -45,7 +49,8 @@ class SsdMobilenetV1FeatureExtractorTest(
conv_hyperparams = sc
return ssd_mobilenet_v1_feature_extractor.SSDMobileNetV1FeatureExtractor(
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):
image_height = 128
......@@ -57,7 +62,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 1, 1, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shape(
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):
image_height = 299
......@@ -69,7 +77,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 2, 2, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shape(
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):
image_height = 128
......@@ -81,7 +92,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 1, 1, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shapes_with_dynamic_inputs(
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):
image_height = 299
......@@ -93,7 +107,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 2, 2, 32), (2, 1, 1, 32)]
self.check_extract_features_returns_correct_shape(
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):
image_height = 299
......@@ -105,7 +122,10 @@ class SsdMobilenetV1FeatureExtractorTest(
(2, 2, 2, 256), (2, 1, 1, 128)]
self.check_extract_features_returns_correct_shape(
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):
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.
See https://arxiv.org/abs/1708.02002 for details.
......@@ -87,7 +101,7 @@ class _SSDResnetV1FpnFeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
return resized_inputs - [[channel_means]]
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.
filtered_image_features = dict({})
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."""
import tensorflow as tf
......@@ -10,14 +24,16 @@ class SSDResnet50V1FeatureExtractorTest(
SSDResnetFPNFeatureExtractorTestBase):
"""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
conv_hyperparams = {}
batch_norm_trainable = True
is_training = True
return ssd_resnet_v1_fpn_feature_extractor.SSDResnet50V1FpnFeatureExtractor(
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):
return 'resnet_v1_50'
......@@ -28,7 +44,8 @@ class SSDResnet101V1FeatureExtractorTest(
SSDResnetFPNFeatureExtractorTestBase):
"""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
conv_hyperparams = {}
batch_norm_trainable = True
......@@ -36,7 +53,8 @@ class SSDResnet101V1FeatureExtractorTest(
return (
ssd_resnet_v1_fpn_feature_extractor.SSDResnet101V1FpnFeatureExtractor(
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):
return 'resnet_v1_101'
......@@ -47,7 +65,8 @@ class SSDResnet152V1FeatureExtractorTest(
SSDResnetFPNFeatureExtractorTestBase):
"""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
conv_hyperparams = {}
batch_norm_trainable = True
......@@ -55,7 +74,8 @@ class SSDResnet152V1FeatureExtractorTest(
return (
ssd_resnet_v1_fpn_feature_extractor.SSDResnet152V1FpnFeatureExtractor(
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):
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."""
import abc
import numpy as np
......
......@@ -58,7 +58,7 @@
"outputs": [],
"source": [
"# 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 {
oneof initializer_oneof {
TruncatedNormalInitializer truncated_normal_initializer = 1;
VarianceScalingInitializer variance_scaling_initializer = 2;
RandomNormalInitializer random_normal_initializer = 3;
}
}
......@@ -89,6 +90,13 @@ message VarianceScalingInitializer {
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
// https://www.tensorflow.org/api_docs/python/tf/contrib/layers/batch_norm
message BatchNorm {
......
......@@ -38,11 +38,17 @@ message WeightedL2LocalizationLoss {
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 {
// DEPRECATED, do not use.
// Output loss per anchor.
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
......
......@@ -20,4 +20,7 @@ message MultiscaleAnchorGenerator {
// Number of intermediate scale each scale octave
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 {
// zeros vector or a one-hot vector (where background is the 0th class).
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.
optional BoxPredictor box_predictor = 7;
......@@ -49,6 +53,10 @@ message Ssd {
// the anchors.
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.
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,
train_config.prefetch_queue_capacity, data_augmentation_options)
# 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.
summaries = set(tf.get_collection(tf.GraphKeys.SUMMARIES))
global_summaries = set([])
......
# Tensorflow Object Detection API: Utility functions.
package(
default_visibility = ["//visibility:public"],
)
licenses(["notice"])
# Apache 2.0
py_library(
name = "test_case",
srcs = ["test_case.py"],
deps = ["//tensorflow"],
)
py_library(
name = "category_util",
srcs = ["category_util.py"],
deps = ["//tensorflow"],
)
py_library(
name = "config_util",
srcs = ["config_util.py"],
deps = [
"//pyglib/logging",
"//tensorflow",
"//tensorflow/models/research/object_detection/protos:eval_py_pb2",
"//tensorflow/models/research/object_detection/protos:image_resizer_py_pb2",
"//tensorflow/models/research/object_detection/protos:input_reader_py_pb2",
"//tensorflow/models/research/object_detection/protos:model_py_pb2",
"//tensorflow/models/research/object_detection/protos:pipeline_py_pb2",
"//tensorflow/models/research/object_detection/protos:train_py_pb2",
],
)
py_library(
name = "dataset_util",
srcs = ["dataset_util.py"],
deps = [
"//tensorflow",
],
)
py_library(
name = "json_utils",
srcs = ["json_utils.py"],
deps = [],
)
py_test(
name = "json_utils_test",
srcs = ["json_utils_test.py"],
deps = [
":json_utils",
"//tensorflow",
],
)
py_library(
name = "label_map_util",
srcs = ["label_map_util.py"],
deps = [
"//google/protobuf",
"//tensorflow",
"//tensorflow/models/research/object_detection/protos:string_int_label_map_py_pb2",
],
)
py_library(
name = "learning_schedules",
srcs = ["learning_schedules.py"],
deps = [
"//tensorflow",
],
)
py_library(
name = "metrics",
srcs = ["metrics.py"],
deps = ["//numpy"],
)
py_library(
name = "np_box_list",
srcs = ["np_box_list.py"],
deps = ["//numpy"],
)
py_library(
name = "np_box_mask_list",
srcs = ["np_box_mask_list.py"],
deps = [
":np_box_list",
"//numpy",
],
)
py_library(
name = "np_box_list_ops",
srcs = ["np_box_list_ops.py"],
deps = [
":np_box_list",
":np_box_ops",
"//numpy",
],
)
py_library(
name = "np_box_mask_list_ops",
srcs = ["np_box_mask_list_ops.py"],
deps = [
":np_box_list_ops",
":np_box_mask_list",
":np_mask_ops",
"//numpy",
],
)
py_library(
name = "np_box_ops",
srcs = ["np_box_ops.py"],
deps = ["//tensorflow"],
)
py_library(
name = "np_mask_ops",
srcs = ["np_mask_ops.py"],
deps = ["//numpy"],
)
py_library(
name = "object_detection_evaluation",
srcs = ["object_detection_evaluation.py"],
deps = [
":label_map_util",
":metrics",
":per_image_evaluation",
"//tensorflow",
"//tensorflow/models/research/object_detection/core:standard_fields",
],
)
py_library(
name = "ops",
srcs = ["ops.py"],
deps = [
":shape_utils",
":static_shape",
"//tensorflow",
"//tensorflow/models/research/object_detection/core:box_list",
"//tensorflow/models/research/object_detection/core:box_list_ops",
"//tensorflow/models/research/object_detection/core:standard_fields",
],
)
py_library(
name = "per_image_evaluation",
srcs = ["per_image_evaluation.py"],
deps = [
":np_box_list",
":np_box_list_ops",
":np_box_mask_list",
":np_box_mask_list_ops",
"//tensorflow",
],
)
py_library(
name = "shape_utils",
srcs = ["shape_utils.py"],
deps = [
":static_shape",
"//tensorflow",
],
)
py_library(
name = "static_shape",
srcs = ["static_shape.py"],
deps = [],
)
py_library(
name = "test_utils",
srcs = ["test_utils.py"],
deps = [
"//tensorflow",
"//tensorflow/models/research/object_detection/core:anchor_generator",
"//tensorflow/models/research/object_detection/core:box_coder",
"//tensorflow/models/research/object_detection/core:box_list",
"//tensorflow/models/research/object_detection/core:box_predictor",
"//tensorflow/models/research/object_detection/core:matcher",
"//tensorflow/models/research/object_detection/utils:shape_utils",
],
)
py_library(
name = "variables_helper",
srcs = ["variables_helper.py"],
deps = [
"//tensorflow",
],
)
py_library(
name = "visualization_utils",
srcs = ["visualization_utils.py"],
deps = [
"//PIL:pil",
"//Tkinter", # buildcleaner: keep
"//matplotlib",
"//six",
"//tensorflow",
"//tensorflow/models/research/object_detection/core:standard_fields",
],
)
py_test(
name = "category_util_test",
srcs = ["category_util_test.py"],
deps = [
":category_util",
"//tensorflow",
],
)
py_test(
name = "config_util_test",
srcs = ["config_util_test.py"],
deps = [
":config_util",
"//tensorflow",
"//tensorflow/models/research/object_detection/protos:image_resizer_py_pb2",
"//tensorflow/models/research/object_detection/protos:input_reader_py_pb2",
"//tensorflow/models/research/object_detection/protos:model_py_pb2",
"//tensorflow/models/research/object_detection/protos:pipeline_py_pb2",
"//tensorflow/models/research/object_detection/protos:train_py_pb2",
],
)
py_test(
name = "dataset_util_test",
srcs = ["dataset_util_test.py"],
deps = [
":dataset_util",
"//tensorflow",
"//tensorflow/models/research/object_detection/protos:input_reader_py_pb2",
],
)
py_test(
name = "label_map_util_test",
srcs = ["label_map_util_test.py"],
deps = [
":label_map_util",
"//tensorflow",
],
)
py_test(
name = "learning_schedules_test",
srcs = ["learning_schedules_test.py"],
deps = [
":learning_schedules",
":test_case",
"//tensorflow",
],
)
py_test(
name = "metrics_test",
srcs = ["metrics_test.py"],
deps = [
":metrics",
"//tensorflow",
],
)
py_test(
name = "np_box_list_test",
srcs = ["np_box_list_test.py"],
deps = [
":np_box_list",
"//numpy",
"//tensorflow",
],
)
py_test(
name = "np_box_mask_list_test",
srcs = ["np_box_mask_list_test.py"],
deps = [
":np_box_mask_list",
"//numpy",
"//tensorflow",
],
)
py_test(
name = "np_box_list_ops_test",
srcs = ["np_box_list_ops_test.py"],
deps = [
":np_box_list",
":np_box_list_ops",
"//numpy",
"//tensorflow",
],
)
py_test(
name = "np_box_mask_list_ops_test",
srcs = ["np_box_mask_list_ops_test.py"],
deps = [
":np_box_mask_list",
":np_box_mask_list_ops",
"//numpy",
"//tensorflow",
],
)
py_test(
name = "np_box_ops_test",
srcs = ["np_box_ops_test.py"],
deps = [
":np_box_ops",
"//tensorflow",
],
)
py_test(
name = "np_mask_ops_test",
srcs = ["np_mask_ops_test.py"],
deps = [
":np_mask_ops",
"//tensorflow",
],
)
py_test(
name = "object_detection_evaluation_test",
srcs = ["object_detection_evaluation_test.py"],
deps = [
":object_detection_evaluation",
"//tensorflow",
"//tensorflow/models/research/object_detection/core:standard_fields",
],
)
py_test(
name = "ops_test",
srcs = ["ops_test.py"],
deps = [
":ops",
":test_case",
"//tensorflow",
"//tensorflow/models/research/object_detection/core:standard_fields",
],
)
py_test(
name = "per_image_evaluation_test",
srcs = ["per_image_evaluation_test.py"],
deps = [
":per_image_evaluation",
"//tensorflow",
],
)
py_test(
name = "shape_utils_test",
srcs = ["shape_utils_test.py"],
deps = [
":shape_utils",
"//numpy",
"//tensorflow",
],
)
py_test(
name = "static_shape_test",
srcs = ["static_shape_test.py"],
deps = [
":static_shape",
"//tensorflow",
],
)
py_test(
name = "test_utils_test",
srcs = ["test_utils_test.py"],
deps = [
":test_utils",
"//tensorflow",
],
)
py_test(
name = "variables_helper_test",
srcs = ["variables_helper_test.py"],
deps = [
":variables_helper",
"//tensorflow",
],
)
py_test(
name = "visualization_utils_test",
srcs = ["visualization_utils_test.py"],
data = [
"//tensorflow/models/research/object_detection/test_images:image1.jpg",
],
deps = [
":visualization_utils",
"//pyglib/flags",
"//PIL:pil",
],
)
......@@ -241,6 +241,10 @@ def merge_external_params_with_configs(configs, hparams=None, **kwargs):
if hparams:
kwargs.update(hparams.values())
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":
_update_initial_learning_rate(configs, value)
tf.logging.info("Overwriting learning rate: %f", value)
......@@ -270,9 +274,8 @@ def merge_external_params_with_configs(configs, hparams=None, **kwargs):
_update_input_path(configs["eval_input_config"], value)
tf.logging.info("Overwriting eval input path: %s", value)
if key == "label_map_path":
if value:
_update_label_map_path(configs, value)
tf.logging.info("Overwriting label map path: %s", value)
_update_label_map_path(configs, value)
tf.logging.info("Overwriting label map path: %s", value)
if key == "mask_type":
_update_mask_type(configs, value)
tf.logging.info("Overwritten mask type: %s", value)
......
......@@ -397,6 +397,27 @@ class ConfigUtilTest(tf.test.TestCase):
self.assertEqual(new_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):
"""Tests that mask type can be overwritten in input readers."""
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