Пример #1
0
def _build_ssd_feature_extractor(feature_extractor_config, is_training,
                                 reuse_weights=None):
    """Builds a ssd_meta_arch.SSDFeatureExtractor based on config.

    Args:
      feature_extractor_config: A SSDFeatureExtractor proto config from ssd.proto.
      is_training: True if this feature extractor is being built for training.
      reuse_weights: if the feature extractor should reuse weights.

    Returns:
      ssd_meta_arch.SSDFeatureExtractor based on config.

    Raises:
      ValueError: On invalid feature extractor type.
    """
    feature_type = feature_extractor_config.type
    depth_multiplier = feature_extractor_config.depth_multiplier
    min_depth = feature_extractor_config.min_depth
    conv_hyperparams = hyperparams_builder.build(
        feature_extractor_config.conv_hyperparams, is_training)

    if feature_type not in SSD_FEATURE_EXTRACTOR_CLASS_MAP:
        raise ValueError('Unknown ssd feature_extractor: {}'.format(feature_type))

    feature_extractor_class = SSD_FEATURE_EXTRACTOR_CLASS_MAP[feature_type]
    return feature_extractor_class(depth_multiplier, min_depth, conv_hyperparams,
                                   reuse_weights)
def build(config, is_training):
    if not isinstance(config, bidirectional_rnn_pb2.BidirectionalRnn):
        raise ValueError(
            'config not of type bidirectional_rnn_pb2.BidirectionalRnn')

    if config.static:
        brnn_class = bidirectional_rnn.StaticBidirectionalRnn
    else:
        brnn_class = bidirectional_rnn.DynamicBidirectionalRnn

    fw_cell_object = rnn_cell_builder.build(config.fw_bw_rnn_cell)
    bw_cell_object = rnn_cell_builder.build(config.fw_bw_rnn_cell)
    rnn_regularizer_object = hyperparams_builder._build_regularizer(
        config.rnn_regularizer)
    fc_hyperparams_object = None
    if config.num_output_units > 0:
        if config.fc_hyperparams.op != hyperparams_pb2.Hyperparams.FC:
            raise ValueError('op type must be FC')
        fc_hyperparams_object = hyperparams_builder.build(
            config.fc_hyperparams, is_training)

    return brnn_class(fw_cell_object,
                      bw_cell_object,
                      rnn_regularizer=rnn_regularizer_object,
                      num_output_units=config.num_output_units,
                      fc_hyperparams=fc_hyperparams_object,
                      summarize_activations=config.summarize_activations)
 def test_return_batch_norm_params_with_notrain_when_train_is_false(self):
     conv_hyperparams_text_proto = """
   regularizer {
     l2_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
   batch_norm {
     decay: 0.7
     center: false
     scale: true
     epsilon: 0.03
     train: false
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     conv_scope_arguments = scope.values()[0]
     self.assertEqual(conv_scope_arguments['normalizer_fn'],
                      slim.batch_norm)
     batch_norm_params = conv_scope_arguments['normalizer_params']
     self.assertAlmostEqual(batch_norm_params['decay'], 0.7)
     self.assertAlmostEqual(batch_norm_params['epsilon'], 0.03)
     self.assertFalse(batch_norm_params['center'])
     self.assertTrue(batch_norm_params['scale'])
     self.assertFalse(batch_norm_params['is_training'])
Пример #4
0
def _build_stn_resnet(config, is_training):
    if not isinstance(config, convnet_pb2.StnResnet):
        raise ValueError('config is not of type convnet_pb2.StnResnet')
    return resnet.ResnetForSTN(
        conv_hyperparams=hyperparams_builder.build(config.conv_hyperparams,
                                                   is_training),
        summarize_activations=config.summarize_activations,
        is_training=is_training)
Пример #5
0
def _build_stn_convnet(config, is_training):
    if not isinstance(config, convnet_pb2.StnConvnet):
        raise ValueError('config is not of type convnet_pb2.StnConvnet')
    convnet_class = stn_convnet.StnConvnet
    if config.tiny == True:
        convnet_class = stn_convnet.StnConvnetTiny
    return convnet_class(conv_hyperparams=hyperparams_builder.build(
        config.conv_hyperparams, is_training),
                         summarize_activations=config.summarize_activations,
                         is_training=is_training)
 def _build_arg_scope_with_conv_hyperparams(self):
     conv_hyperparams = hyperparams_pb2.Hyperparams()
     conv_hyperparams_text_proto = """
   regularizer {
     l2_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
 """
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams)
     return hyperparams_builder.build(conv_hyperparams, is_training=True)
 def test_default_arg_scope_has_conv2d_transpose_op(self):
     conv_hyperparams_text_proto = """
   regularizer {
     l1_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     self.assertTrue(self._get_scope_key(slim.conv2d_transpose) in scope)
 def test_explicit_fc_op_arg_scope_has_fully_connected_op(self):
     conv_hyperparams_text_proto = """
   op: FC
   regularizer {
     l1_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     self.assertTrue(self._get_scope_key(slim.fully_connected) in scope)
 def _build_arg_scope_with_hyperparams(
         self, op_type=hyperparams_pb2.Hyperparams.FC):
     hyperparams = hyperparams_pb2.Hyperparams()
     hyperparams_text_proto = """
   activation: NONE
   regularizer {
     l2_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
 """
     text_format.Merge(hyperparams_text_proto, hyperparams)
     hyperparams.op = op_type
     return hyperparams_builder.build(hyperparams, is_training=True)
 def test_use_relu_6_activation(self):
     conv_hyperparams_text_proto = """
   regularizer {
     l2_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
   activation: RELU_6
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     conv_scope_arguments = scope.values()[0]
     self.assertEqual(conv_scope_arguments['activation_fn'], tf.nn.relu6)
 def test_do_not_use_batch_norm_if_default(self):
     conv_hyperparams_text_proto = """
   regularizer {
     l2_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     conv_scope_arguments = scope.values()[0]
     self.assertEqual(conv_scope_arguments['normalizer_fn'], None)
     self.assertEqual(conv_scope_arguments['normalizer_params'], None)
 def test_separable_conv2d_and_conv2d_and_transpose_have_same_parameters(
         self):
     conv_hyperparams_text_proto = """
   regularizer {
     l1_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     kwargs_1, kwargs_2, kwargs_3 = scope.values()
     self.assertDictEqual(kwargs_1, kwargs_2)
     self.assertDictEqual(kwargs_1, kwargs_3)
Пример #13
0
def _build_resnet(config, is_training):
    if not isinstance(config, convnet_pb2.ResNet):
        raise ValueError('config is not of type convnet_pb2.ResNet')

    if config.net_type != convnet_pb2.ResNet.SINGLE_BRANCH:
        raise ValueError('Only SINGLE_BRANCH is supported for ResNet')

    resnet_depth = config.net_depth
    if resnet_depth == convnet_pb2.ResNet.RESNET_50:
        resnet_class = resnet.Resnet50Layer
    else:
        raise ValueError('Unknown resnet depth: {}'.format(resnet_depth))

    conv_hyperparams = hyperparams_builder.build(config.conv_hyperparams,
                                                 is_training)
    return resnet_class(
        conv_hyperparams=conv_hyperparams,
        summarize_activations=config.summarize_activations,
        is_training=is_training,
    )
Пример #14
0
def _build_crnn_net(config, is_training):
    if not isinstance(config, convnet_pb2.CrnnNet):
        raise ValueError('config is not of type convnet_pb2.CrnnNet')

    if config.net_type == convnet_pb2.CrnnNet.SINGLE_BRANCH:
        crnn_net_class = crnn_net.CrnnNet
    elif config.net_type == convnet_pb2.CrnnNet.TWO_BRANCHES:
        crnn_net_class = crnn_net.CrnnNetTwoBranches
    elif config.net_type == convnet_pb2.CrnnNet.THREE_BRANCHES:
        crnn_net_class = crnn_net.CrnnNetThreeBranches
    else:
        raise ValueError('Unknown net_type: {}'.format(config.net_type))

    if config.tiny == True:
        crnn_net_class = crnn_net.CrnnNetTiny

    hyperparams_object = hyperparams_builder.build(config.conv_hyperparams,
                                                   is_training)

    return crnn_net_class(conv_hyperparams=hyperparams_object,
                          summarize_activations=config.summarize_activations,
                          is_training=is_training)
 def test_return_l1_regularized_weights(self):
     conv_hyperparams_text_proto = """
   regularizer {
     l1_regularizer {
       weight: 0.5
     }
   }
   initializer {
     truncated_normal_initializer {
     }
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     conv_scope_arguments = scope.values()[0]
     regularizer = conv_scope_arguments['weights_regularizer']
     weights = np.array([1., -1, 4., 2.])
     with self.test_session() as sess:
         result = sess.run(regularizer(tf.constant(weights)))
     self.assertAllClose(np.abs(weights).sum() * 0.5, result)
 def test_variance_in_range_with_truncated_normal_initializer(self):
     conv_hyperparams_text_proto = """
   regularizer {
     l2_regularizer {
     }
   }
   initializer {
     truncated_normal_initializer {
       mean: 0.0
       stddev: 0.8
     }
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     conv_scope_arguments = scope.values()[0]
     initializer = conv_scope_arguments['weights_initializer']
     self._assert_variance_in_range(initializer,
                                    shape=[100, 40],
                                    variance=0.49,
                                    tol=1e-1)
 def test_variance_in_range_with_variance_scaling_initializer_uniform(self):
     conv_hyperparams_text_proto = """
   regularizer {
     l2_regularizer {
     }
   }
   initializer {
     variance_scaling_initializer {
       factor: 2.0
       mode: FAN_IN
       uniform: true
     }
   }
 """
     conv_hyperparams_proto = hyperparams_pb2.Hyperparams()
     text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams_proto)
     scope = hyperparams_builder.build(conv_hyperparams_proto,
                                       is_training=True)
     conv_scope_arguments = scope.values()[0]
     initializer = conv_scope_arguments['weights_initializer']
     self._assert_variance_in_range(initializer,
                                    shape=[100, 40],
                                    variance=2. / 100.)
Пример #18
0
def _build_faster_rcnn_model(frcnn_config, is_training):
    """Builds a Faster R-CNN or R-FCN detection model based on the model config.

    Builds R-FCN model if the second_stage_box_predictor in the config is of type
    `rfcn_box_predictor` else builds a Faster R-CNN model.

    Args:
      frcnn_config: A faster_rcnn.proto object containing the config for the
      desired FasterRCNNMetaArch or RFCNMetaArch.
      is_training: True if this model is being built for training purposes.

    Returns:
      FasterRCNNMetaArch based on the config.
    Raises:
      ValueError: If frcnn_config.type is not recognized (i.e. not registered in
        model_class_map).
    """
    num_classes = frcnn_config.num_classes
    image_resizer_fn = image_resizer_builder.build(frcnn_config.image_resizer)

    feature_extractor = _build_faster_rcnn_feature_extractor(
        frcnn_config.feature_extractor, is_training)

    first_stage_only = frcnn_config.first_stage_only
    first_stage_anchor_generator = anchor_generator_builder.build(
        frcnn_config.first_stage_anchor_generator)

    first_stage_atrous_rate = frcnn_config.first_stage_atrous_rate
    first_stage_box_predictor_arg_scope = hyperparams_builder.build(
        frcnn_config.first_stage_box_predictor_conv_hyperparams, is_training)
    first_stage_box_predictor_kernel_size = (
        frcnn_config.first_stage_box_predictor_kernel_size)
    first_stage_box_predictor_depth = frcnn_config.first_stage_box_predictor_depth
    first_stage_minibatch_size = frcnn_config.first_stage_minibatch_size
    first_stage_positive_balance_fraction = (
        frcnn_config.first_stage_positive_balance_fraction)
    first_stage_nms_score_threshold = frcnn_config.first_stage_nms_score_threshold
    first_stage_nms_iou_threshold = frcnn_config.first_stage_nms_iou_threshold
    first_stage_max_proposals = frcnn_config.first_stage_max_proposals
    first_stage_loc_loss_weight = (
        frcnn_config.first_stage_localization_loss_weight)
    first_stage_obj_loss_weight = frcnn_config.first_stage_objectness_loss_weight

    initial_crop_size = frcnn_config.initial_crop_size
    maxpool_kernel_size = frcnn_config.maxpool_kernel_size
    maxpool_stride = frcnn_config.maxpool_stride

    second_stage_box_predictor = box_predictor_builder.build(
        hyperparams_builder.build,
        frcnn_config.second_stage_box_predictor,
        is_training=is_training,
        num_classes=num_classes)
    second_stage_batch_size = frcnn_config.second_stage_batch_size
    second_stage_balance_fraction = frcnn_config.second_stage_balance_fraction
    (second_stage_non_max_suppression_fn, second_stage_score_conversion_fn
     ) = post_processing_builder.build(frcnn_config.second_stage_post_processing)
    second_stage_localization_loss_weight = (
        frcnn_config.second_stage_localization_loss_weight)
    second_stage_classification_loss_weight = (
        frcnn_config.second_stage_classification_loss_weight)

    hard_example_miner = None
    if frcnn_config.HasField('hard_example_miner'):
        hard_example_miner = losses_builder.build_hard_example_miner(
            frcnn_config.hard_example_miner,
            second_stage_classification_loss_weight,
            second_stage_localization_loss_weight)

    common_kwargs = {
        'is_training': is_training,
        'num_classes': num_classes,
        'image_resizer_fn': image_resizer_fn,
        'feature_extractor': feature_extractor,
        'first_stage_only': first_stage_only,
        'first_stage_anchor_generator': first_stage_anchor_generator,
        'first_stage_atrous_rate': first_stage_atrous_rate,
        'first_stage_box_predictor_arg_scope':
            first_stage_box_predictor_arg_scope,
        'first_stage_box_predictor_kernel_size':
            first_stage_box_predictor_kernel_size,
        'first_stage_box_predictor_depth': first_stage_box_predictor_depth,
        'first_stage_minibatch_size': first_stage_minibatch_size,
        'first_stage_positive_balance_fraction':
            first_stage_positive_balance_fraction,
        'first_stage_nms_score_threshold': first_stage_nms_score_threshold,
        'first_stage_nms_iou_threshold': first_stage_nms_iou_threshold,
        'first_stage_max_proposals': first_stage_max_proposals,
        'first_stage_localization_loss_weight': first_stage_loc_loss_weight,
        'first_stage_objectness_loss_weight': first_stage_obj_loss_weight,
        'second_stage_batch_size': second_stage_batch_size,
        'second_stage_balance_fraction': second_stage_balance_fraction,
        'second_stage_non_max_suppression_fn':
            second_stage_non_max_suppression_fn,
        'second_stage_score_conversion_fn': second_stage_score_conversion_fn,
        'second_stage_localization_loss_weight':
            second_stage_localization_loss_weight,
        'second_stage_classification_loss_weight':
            second_stage_classification_loss_weight,
        'hard_example_miner': hard_example_miner}

    if isinstance(second_stage_box_predictor, box_predictor.RfcnBoxPredictor):
        return rfcn_meta_arch.RFCNMetaArch(
            second_stage_rfcn_box_predictor=second_stage_box_predictor,
            **common_kwargs)
    else:
        return faster_rcnn_meta_arch.FasterRCNNMetaArch(
            initial_crop_size=initial_crop_size,
            maxpool_kernel_size=maxpool_kernel_size,
            maxpool_stride=maxpool_stride,
            second_stage_mask_rcnn_box_predictor=second_stage_box_predictor,
            **common_kwargs)
def _build_pspnet_icnet_model(model_config,
                              is_training,
                              add_summaries,
                              build_baseline_psp=False):
    num_classes = model_config.num_classes
    if not num_classes:
        raise ValueError('"num_classes" must be greater than 0.')

    in_filter_scale = model_config.filter_scale
    if in_filter_scale > 1 or in_filter_scale < 0:
        raise ValueError('"filter_scale" must be in the range (0,1].')
    filter_scale = 1.0 / in_filter_scale

    should_downsample_extractor = False
    if not build_baseline_psp:
        pretrain_single_branch_mode = model_config.pretrain_single_branch_mode
        should_downsample_extractor = not pretrain_single_branch_mode

    feature_extractor = _build_pspnet_icnet_extractor(
        model_config.feature_extractor,
        filter_scale,
        is_training,
        mid_downsample=should_downsample_extractor)

    model_arg_scope = hyperparams_builder.build(model_config.hyperparams,
                                                is_training)

    loss_config = model_config.loss
    classification_loss = (losses_builder.build(loss_config))
    use_aux_loss = loss_config.use_auxiliary_loss

    common_kwargs = {
        'is_training': is_training,
        'num_classes': num_classes,
        'model_arg_scope': model_arg_scope,
        'num_classes': num_classes,
        'feature_extractor': feature_extractor,
        'classification_loss': classification_loss,
        'use_aux_loss': use_aux_loss,
        'add_summaries': add_summaries
    }

    if not build_baseline_psp:
        if use_aux_loss:
            common_kwargs['main_loss_weight'] = (
                model_config.main_branch_loss_weight)
            common_kwargs['second_branch_loss_weight'] = (
                model_config.second_branch_loss_weight)
            common_kwargs['first_branch_loss_weight'] = (
                model_config.first_branch_loss_weight)
        model = (num_classes,
                 icnet_architecture.ICNetArchitecture(
                     filter_scale=filter_scale,
                     pretrain_single_branch_mode=pretrain_single_branch_mode,
                     **common_kwargs))
    else:
        if use_aux_loss:
            # TODO: remove hardcoded values here
            common_kwargs['main_loss_weight'] = 1.0
            common_kwargs['aux_loss_weight'] = 0.4
        model = (num_classes,
                 pspnet_architecture.PSPNetArchitecture(**common_kwargs))
    return model
 def _build_arg_scope_with_hyperparams(self,
                                       hyperparams_text_proto,
                                       is_training):
     hyperparams = hyperparams_pb2.Hyperparams()
     text_format.Merge(hyperparams_text_proto, hyperparams)
     return hyperparams_builder.build(hyperparams, is_training=is_training)
Пример #21
0
def _build_ssd_feature_extractor(feature_extractor_config,
                                 is_training,
                                 freeze_batchnorm,
                                 reuse_weights=None):
    """Builds a ssd_meta_arch.SSDFeatureExtractor based on config.

  Args:
    feature_extractor_config: A SSDFeatureExtractor proto config from ssd.proto.
    is_training: True if this feature extractor is being built for training.
    freeze_batchnorm: Whether to freeze batch norm parameters during
      training or not. When training with a small batch size (e.g. 1), it is
      desirable to freeze batch norm update and use pretrained batch norm
      params.
    reuse_weights: if the feature extractor should reuse weights.

  Returns:
    ssd_meta_arch.SSDFeatureExtractor based on config.

  Raises:
    ValueError: On invalid feature extractor type.
  """
    feature_type = feature_extractor_config.type
    is_keras_extractor = feature_type in SSD_KERAS_FEATURE_EXTRACTOR_CLASS_MAP
    depth_multiplier = feature_extractor_config.depth_multiplier
    min_depth = feature_extractor_config.min_depth
    pad_to_multiple = feature_extractor_config.pad_to_multiple
    use_explicit_padding = feature_extractor_config.use_explicit_padding
    use_depthwise = feature_extractor_config.use_depthwise

    if is_keras_extractor:
        conv_hyperparams = hyperparams_builder.KerasLayerHyperparams(
            feature_extractor_config.conv_hyperparams)
    else:
        conv_hyperparams = hyperparams_builder.build(
            feature_extractor_config.conv_hyperparams, is_training)
    override_base_feature_extractor_hyperparams = (
        feature_extractor_config.override_base_feature_extractor_hyperparams)

    if (feature_type not in SSD_FEATURE_EXTRACTOR_CLASS_MAP) and (
            not is_keras_extractor):
        raise ValueError(
            'Unknown ssd feature_extractor: {}'.format(feature_type))

    if is_keras_extractor:
        feature_extractor_class = SSD_KERAS_FEATURE_EXTRACTOR_CLASS_MAP[
            feature_type]
    else:
        feature_extractor_class = SSD_FEATURE_EXTRACTOR_CLASS_MAP[feature_type]
    kwargs = {
        'is_training':
        is_training,
        'depth_multiplier':
        depth_multiplier,
        'min_depth':
        min_depth,
        'pad_to_multiple':
        pad_to_multiple,
        'use_explicit_padding':
        use_explicit_padding,
        'use_depthwise':
        use_depthwise,
        'override_base_feature_extractor_hyperparams':
        override_base_feature_extractor_hyperparams
    }

    if is_keras_extractor:
        kwargs.update({
            'conv_hyperparams': conv_hyperparams,
            'inplace_batchnorm_update': False,
            'freeze_batchnorm': freeze_batchnorm
        })
    else:
        kwargs.update({
            'conv_hyperparams_fn': conv_hyperparams,
            'reuse_weights': reuse_weights,
        })

    if feature_extractor_config.HasField('fpn'):
        kwargs.update({
            'fpn_min_level':
            feature_extractor_config.fpn.min_level,
            'fpn_max_level':
            feature_extractor_config.fpn.max_level,
            'additional_layer_depth':
            feature_extractor_config.fpn.additional_layer_depth,
        })

    return feature_extractor_class(**kwargs)
Пример #22
0
def _build_faster_rcnn_model(frcnn_config, is_training, add_summaries):
    """Builds a Faster R-CNN or R-FCN detection model based on the model config.

  Builds R-FCN model if the second_stage_box_predictor in the config is of type
  `rfcn_box_predictor` else builds a Faster R-CNN model.

  Args:
    frcnn_config: A faster_rcnn.proto object containing the config for the
      desired FasterRCNNMetaArch or RFCNMetaArch.
    is_training: True if this model is being built for training purposes.
    add_summaries: Whether to add tf summaries in the model.

  Returns:
    FasterRCNNMetaArch based on the config.

  Raises:
    ValueError: If frcnn_config.type is not recognized (i.e. not registered in
      model_class_map).
  """
    num_classes = frcnn_config.num_classes
    image_resizer_fn = image_resizer_builder.build(frcnn_config.image_resizer)

    feature_extractor = _build_faster_rcnn_feature_extractor(
        frcnn_config.feature_extractor,
        is_training,
        inplace_batchnorm_update=frcnn_config.inplace_batchnorm_update)

    number_of_stages = frcnn_config.number_of_stages
    first_stage_anchor_generator = anchor_generator_builder.build(
        frcnn_config.first_stage_anchor_generator)

    first_stage_target_assigner = target_assigner.create_target_assigner(
        'FasterRCNN',
        'proposal',
        use_matmul_gather=frcnn_config.use_matmul_gather_in_matcher)
    first_stage_atrous_rate = frcnn_config.first_stage_atrous_rate
    first_stage_box_predictor_arg_scope_fn = hyperparams_builder.build(
        frcnn_config.first_stage_box_predictor_conv_hyperparams, is_training)
    first_stage_box_predictor_kernel_size = (
        frcnn_config.first_stage_box_predictor_kernel_size)
    first_stage_box_predictor_depth = frcnn_config.first_stage_box_predictor_depth
    first_stage_minibatch_size = frcnn_config.first_stage_minibatch_size
    use_static_shapes = frcnn_config.use_static_shapes and (
        frcnn_config.use_static_shapes_for_eval or is_training)
    first_stage_sampler = sampler.BalancedPositiveNegativeSampler(
        positive_fraction=frcnn_config.first_stage_positive_balance_fraction,
        is_static=(frcnn_config.use_static_balanced_label_sampler
                   and use_static_shapes))
    first_stage_max_proposals = frcnn_config.first_stage_max_proposals
    if (frcnn_config.first_stage_nms_iou_threshold < 0
            or frcnn_config.first_stage_nms_iou_threshold > 1.0):
        raise ValueError('iou_threshold not in [0, 1.0].')
    if (is_training and
            frcnn_config.second_stage_batch_size > first_stage_max_proposals):
        raise ValueError('second_stage_batch_size should be no greater than '
                         'first_stage_max_proposals.')
    first_stage_non_max_suppression_fn = functools.partial(
        post_processing.batch_multiclass_non_max_suppression,
        score_thresh=frcnn_config.first_stage_nms_score_threshold,
        iou_thresh=frcnn_config.first_stage_nms_iou_threshold,
        max_size_per_class=frcnn_config.first_stage_max_proposals,
        max_total_size=frcnn_config.first_stage_max_proposals,
        use_static_shapes=use_static_shapes)
    first_stage_loc_loss_weight = (
        frcnn_config.first_stage_localization_loss_weight)
    first_stage_obj_loss_weight = frcnn_config.first_stage_objectness_loss_weight

    initial_crop_size = frcnn_config.initial_crop_size
    maxpool_kernel_size = frcnn_config.maxpool_kernel_size
    maxpool_stride = frcnn_config.maxpool_stride

    second_stage_target_assigner = target_assigner.create_target_assigner(
        'FasterRCNN',
        'detection',
        use_matmul_gather=frcnn_config.use_matmul_gather_in_matcher)
    second_stage_box_predictor = box_predictor_builder.build(
        hyperparams_builder.build,
        frcnn_config.second_stage_box_predictor,
        is_training=is_training,
        num_classes=num_classes)
    second_stage_batch_size = frcnn_config.second_stage_batch_size
    second_stage_sampler = sampler.BalancedPositiveNegativeSampler(
        positive_fraction=frcnn_config.second_stage_balance_fraction,
        is_static=(frcnn_config.use_static_balanced_label_sampler
                   and use_static_shapes))
    (second_stage_non_max_suppression_fn,
     second_stage_score_conversion_fn) = post_processing_builder.build(
         frcnn_config.second_stage_post_processing)
    second_stage_localization_loss_weight = (
        frcnn_config.second_stage_localization_loss_weight)
    second_stage_classification_loss = (
        losses_builder.build_faster_rcnn_classification_loss(
            frcnn_config.second_stage_classification_loss))
    second_stage_classification_loss_weight = (
        frcnn_config.second_stage_classification_loss_weight)
    second_stage_mask_prediction_loss_weight = (
        frcnn_config.second_stage_mask_prediction_loss_weight)

    hard_example_miner = None
    if frcnn_config.HasField('hard_example_miner'):
        hard_example_miner = losses_builder.build_hard_example_miner(
            frcnn_config.hard_example_miner,
            second_stage_classification_loss_weight,
            second_stage_localization_loss_weight)

    crop_and_resize_fn = (ops.matmul_crop_and_resize
                          if frcnn_config.use_matmul_crop_and_resize else
                          ops.native_crop_and_resize)
    clip_anchors_to_image = (frcnn_config.clip_anchors_to_image)

    common_kwargs = {
        'is_training': is_training,
        'num_classes': num_classes,
        'image_resizer_fn': image_resizer_fn,
        'feature_extractor': feature_extractor,
        'number_of_stages': number_of_stages,
        'first_stage_anchor_generator': first_stage_anchor_generator,
        'first_stage_target_assigner': first_stage_target_assigner,
        'first_stage_atrous_rate': first_stage_atrous_rate,
        'first_stage_box_predictor_arg_scope_fn':
        first_stage_box_predictor_arg_scope_fn,
        'first_stage_box_predictor_kernel_size':
        first_stage_box_predictor_kernel_size,
        'first_stage_box_predictor_depth': first_stage_box_predictor_depth,
        'first_stage_minibatch_size': first_stage_minibatch_size,
        'first_stage_sampler': first_stage_sampler,
        'first_stage_non_max_suppression_fn':
        first_stage_non_max_suppression_fn,
        'first_stage_max_proposals': first_stage_max_proposals,
        'first_stage_localization_loss_weight': first_stage_loc_loss_weight,
        'first_stage_objectness_loss_weight': first_stage_obj_loss_weight,
        'second_stage_target_assigner': second_stage_target_assigner,
        'second_stage_batch_size': second_stage_batch_size,
        'second_stage_sampler': second_stage_sampler,
        'second_stage_non_max_suppression_fn':
        second_stage_non_max_suppression_fn,
        'second_stage_score_conversion_fn': second_stage_score_conversion_fn,
        'second_stage_localization_loss_weight':
        second_stage_localization_loss_weight,
        'second_stage_classification_loss': second_stage_classification_loss,
        'second_stage_classification_loss_weight':
        second_stage_classification_loss_weight,
        'hard_example_miner': hard_example_miner,
        'add_summaries': add_summaries,
        'crop_and_resize_fn': crop_and_resize_fn,
        'clip_anchors_to_image': clip_anchors_to_image,
        'use_static_shapes': use_static_shapes,
        'resize_masks': frcnn_config.resize_masks
    }

    if isinstance(second_stage_box_predictor,
                  rfcn_box_predictor.RfcnBoxPredictor):
        return rfcn_meta_arch.RFCNMetaArch(
            second_stage_rfcn_box_predictor=second_stage_box_predictor,
            **common_kwargs)
    else:
        return faster_rcnn_meta_arch.FasterRCNNMetaArch(
            initial_crop_size=initial_crop_size,
            maxpool_kernel_size=maxpool_kernel_size,
            maxpool_stride=maxpool_stride,
            second_stage_mask_rcnn_box_predictor=second_stage_box_predictor,
            second_stage_mask_prediction_loss_weight=(
                second_stage_mask_prediction_loss_weight),
            **common_kwargs)