text: # Copyright 2018 The TensorFlow Authors. All Rights Reserved.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  # ==============================================================================
  
  """SSDFeatureExtractor for MobilenetV1 PPN features."""
  
  import tensorflow as tf
  
  from nets import mobilenet_v1
  from tfold.object_detection.meta_architectures import ssd_meta_arch
  from tfold.object_detection.models import feature_map_generators
  from tfold.object_detection.utils import context_manager
  from tfold.object_detection.utils import ops
  from tfold.object_detection.utils import shape_utils
  
  slim = tf.contrib.slim
  
  
  class SSDMobileNetV1PpnFeatureExtractor(ssd_meta_arch.SSDFeatureExtractor):
      """SSD Feature Extractor using MobilenetV1 PPN features."""
  
      def preprocess(self, resized_inputs):
          """SSD preprocessing.
  
          Maps pixel values to the range [-1, 1].
  
          Args:
            resized_inputs: a [batch, height, width, channels] float tensor
              representing a batch of images.
  
          Returns:
            preprocessed_inputs: a [batch, height, width, channels] float tensor
              representing a batch of images.
          """
          return (2.0 / 255.0) * resized_inputs - 1.0
  
      def extract_features(self, preprocessed_inputs):
          """Extract features from preprocessed inputs.
  
          Args:
            preprocessed_inputs: a [batch, height, width, channels] float tensor
              representing a batch of images.
  
          Returns:
            feature_maps: a list of tensors where the ith tensor has shape
              [batch, height_i, width_i, depth_i]
          """
          preprocessed_inputs = shape_utils.check_min_image_dim(
              33, preprocessed_inputs)
  
          with tf.variable_scope('MobilenetV1',
                                 reuse=self._reuse_weights) as scope:
              with slim.arg_scope(
                      mobilenet_v1.mobilenet_v1_arg_scope(
                          is_training=None, regularize_depthwise=True)):
                  with (slim.arg_scope(self._conv_hyperparams_fn())
                  if self._override_base_feature_extractor_hyperparams
                  else context_manager.IdentityContextManager()):
                      _, image_features = mobilenet_v1.mobilenet_v1_base(
                          ops.pad_to_multiple(preprocessed_inputs, self._pad_to_multiple),
                          final_endpoint='Conv2d_13_pointwise',
                          min_depth=self._min_depth,
                          depth_multiplier=self._depth_multiplier,
                          use_explicit_padding=self._use_explicit_padding,
                          scope=scope)
              with slim.arg_scope(self._conv_hyperparams_fn()):
                  feature_maps = feature_map_generators.pooling_pyramid_feature_maps(
                      base_feature_map_depth=0,
                      num_layers=6,
                      image_features={
                          'image_features': image_features['Conv2d_11_pointwise']
                      })
          return feature_maps.values()
  