def _create_model( self, apply_hard_mining=True, normalize_loc_loss_by_codesize=False, add_background_class=True, random_example_sampling=False, expected_loss_weights=model_pb2.DetectionModel().ssd.loss.NONE, min_num_negative_samples=1, desired_negative_sampling_ratio=3, use_keras=False, predict_mask=False, use_static_shapes=False, nms_max_size_per_class=5): return super(SsdMetaArchTest, self)._create_model( model_fn=ssd_meta_arch.SSDMetaArch, apply_hard_mining=apply_hard_mining, normalize_loc_loss_by_codesize=normalize_loc_loss_by_codesize, add_background_class=add_background_class, random_example_sampling=random_example_sampling, expected_loss_weights=expected_loss_weights, min_num_negative_samples=min_num_negative_samples, desired_negative_sampling_ratio=desired_negative_sampling_ratio, use_keras=use_keras, predict_mask=predict_mask, use_static_shapes=use_static_shapes, nms_max_size_per_class=nms_max_size_per_class)
def testGetImageResizerConfig(self): """Tests that number of classes can be retrieved.""" model_config = model_pb2.DetectionModel() model_config.faster_rcnn.image_resizer.fixed_shape_resizer.height = 100 model_config.faster_rcnn.image_resizer.fixed_shape_resizer.width = 300 image_resizer_config = config_util.get_image_resizer_config( model_config) self.assertEqual(image_resizer_config.fixed_shape_resizer.height, 100) self.assertEqual(image_resizer_config.fixed_shape_resizer.width, 300)
def get_configs_from_multiple_files(model_config_path="", train_config_path="", train_input_config_path="", eval_config_path="", eval_input_config_path="", graph_rewriter_config_path=""): """Reads training configuration from multiple config files. Args: model_config_path: Path to model_pb2.DetectionModel. train_config_path: Path to train_pb2.TrainConfig. train_input_config_path: Path to input_reader_pb2.InputReader. eval_config_path: Path to eval_pb2.EvalConfig. eval_input_config_path: Path to input_reader_pb2.InputReader. graph_rewriter_config_path: Path to graph_rewriter_pb2.GraphRewriter. Returns: Dictionary of configuration objects. Keys are `model`, `train_config`, `train_input_config`, `eval_config`, `eval_input_config`. Key/Values are returned only for valid (non-empty) strings. """ configs = {} if model_config_path: model_config = model_pb2.DetectionModel() with tf.gfile.GFile(model_config_path, "r") as f: text_format.Merge(f.read(), model_config) configs["model"] = model_config if train_config_path: train_config = train_pb2.TrainConfig() with tf.gfile.GFile(train_config_path, "r") as f: text_format.Merge(f.read(), train_config) configs["train_config"] = train_config if train_input_config_path: train_input_config = input_reader_pb2.InputReader() with tf.gfile.GFile(train_input_config_path, "r") as f: text_format.Merge(f.read(), train_input_config) configs["train_input_config"] = train_input_config if eval_config_path: eval_config = eval_pb2.EvalConfig() with tf.gfile.GFile(eval_config_path, "r") as f: text_format.Merge(f.read(), eval_config) configs["eval_config"] = eval_config if eval_input_config_path: eval_input_config = input_reader_pb2.InputReader() with tf.gfile.GFile(eval_input_config_path, "r") as f: text_format.Merge(f.read(), eval_input_config) configs["eval_input_configs"] = [eval_input_config] if graph_rewriter_config_path: configs["graph_rewriter_config"] = get_graph_rewriter_config_from_file( graph_rewriter_config_path) return configs
def test_create_faster_rcnn_model_from_config_with_example_miner(self): model_text_proto = """ faster_rcnn { num_classes: 3 feature_extractor { type: 'faster_rcnn_inception_resnet_v2' } image_resizer { keep_aspect_ratio_resizer { min_dimension: 600 max_dimension: 1024 } } first_stage_anchor_generator { grid_anchor_generator { scales: [0.25, 0.5, 1.0, 2.0] aspect_ratios: [0.5, 1.0, 2.0] height_stride: 16 width_stride: 16 } } first_stage_box_predictor_conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } second_stage_box_predictor { mask_rcnn_box_predictor { fc_hyperparams { op: FC regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } } hard_example_miner { num_hard_examples: 10 iou_threshold: 0.99 } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) model = model_builder.build(model_proto, is_training=True) self.assertIsNotNone(model._hard_example_miner)
def test_get_configs_from_multiple_files(self): """Tests that proto configs can be read from multiple files.""" temp_dir = self.get_temp_dir() # Write model config file. model_config_path = os.path.join(temp_dir, "model.config") model = model_pb2.DetectionModel() model.faster_rcnn.num_classes = 10 _write_config(model, model_config_path) # Write train config file. train_config_path = os.path.join(temp_dir, "train.config") train_config = train_config = train_pb2.TrainConfig() train_config.batch_size = 32 _write_config(train_config, train_config_path) # Write train input config file. train_input_config_path = os.path.join(temp_dir, "train_input.config") train_input_config = input_reader_pb2.InputReader() train_input_config.label_map_path = "path/to/label_map" _write_config(train_input_config, train_input_config_path) # Write eval config file. eval_config_path = os.path.join(temp_dir, "eval.config") eval_config = eval_pb2.EvalConfig() eval_config.num_examples = 20 _write_config(eval_config, eval_config_path) # Write eval input config file. eval_input_config_path = os.path.join(temp_dir, "eval_input.config") eval_input_config = input_reader_pb2.InputReader() eval_input_config.label_map_path = "path/to/another/label_map" _write_config(eval_input_config, eval_input_config_path) configs = config_util.get_configs_from_multiple_files( model_config_path=model_config_path, train_config_path=train_config_path, train_input_config_path=train_input_config_path, eval_config_path=eval_config_path, eval_input_config_path=eval_input_config_path) self.assertProtoEquals(model, configs["model"]) self.assertProtoEquals(train_config, configs["train_config"]) self.assertProtoEquals(train_input_config, configs["train_input_config"]) self.assertProtoEquals(eval_config, configs["eval_config"]) self.assertProtoEquals(eval_input_config, configs["eval_input_configs"][0])
def _create_model( self, model_fn=ssd_meta_arch.SSDMetaArch, apply_hard_mining=True, normalize_loc_loss_by_codesize=False, add_background_class=True, random_example_sampling=False, expected_loss_weights=model_pb2.DetectionModel().ssd.loss.NONE, min_num_negative_samples=1, desired_negative_sampling_ratio=3, use_keras=False, predict_mask=False, use_static_shapes=False, nms_max_size_per_class=5): is_training = False num_classes = 1 mock_anchor_generator = MockAnchorGenerator2x2() if use_keras: mock_box_predictor = test_utils.MockKerasBoxPredictor( is_training, num_classes, add_background_class=add_background_class) else: mock_box_predictor = test_utils.MockBoxPredictor( is_training, num_classes, add_background_class=add_background_class) mock_box_coder = test_utils.MockBoxCoder() if use_keras: fake_feature_extractor = FakeSSDKerasFeatureExtractor() else: fake_feature_extractor = FakeSSDFeatureExtractor() mock_matcher = test_utils.MockMatcher() region_similarity_calculator = sim_calc.IouSimilarity() encode_background_as_zeros = False def image_resizer_fn(image): return [tf.identity(image), tf.shape(image)] classification_loss = losses.WeightedSigmoidClassificationLoss() localization_loss = losses.WeightedSmoothL1LocalizationLoss() non_max_suppression_fn = functools.partial( post_processing.batch_multiclass_non_max_suppression, score_thresh=-20.0, iou_thresh=1.0, max_size_per_class=nms_max_size_per_class, max_total_size=nms_max_size_per_class, use_static_shapes=use_static_shapes) classification_loss_weight = 1.0 localization_loss_weight = 1.0 negative_class_weight = 1.0 normalize_loss_by_num_matches = False hard_example_miner = None if apply_hard_mining: # This hard example miner is expected to be a no-op. hard_example_miner = losses.HardExampleMiner( num_hard_examples=None, iou_threshold=1.0) random_example_sampler = None if random_example_sampling: random_example_sampler = sampler.BalancedPositiveNegativeSampler( positive_fraction=0.5) target_assigner_instance = target_assigner.TargetAssigner( region_similarity_calculator, mock_matcher, mock_box_coder, negative_class_weight=negative_class_weight) model_config = model_pb2.DetectionModel() if expected_loss_weights == model_config.ssd.loss.NONE: expected_loss_weights_fn = None else: raise ValueError('Not a valid value for expected_loss_weights.') code_size = 4 kwargs = {} if predict_mask: kwargs.update({ 'mask_prediction_fn': test_utils.MockMaskHead(num_classes=1).predict, }) model = model_fn( is_training=is_training, anchor_generator=mock_anchor_generator, box_predictor=mock_box_predictor, box_coder=mock_box_coder, feature_extractor=fake_feature_extractor, encode_background_as_zeros=encode_background_as_zeros, image_resizer_fn=image_resizer_fn, non_max_suppression_fn=non_max_suppression_fn, score_conversion_fn=tf.identity, classification_loss=classification_loss, localization_loss=localization_loss, classification_loss_weight=classification_loss_weight, localization_loss_weight=localization_loss_weight, normalize_loss_by_num_matches=normalize_loss_by_num_matches, hard_example_miner=hard_example_miner, target_assigner_instance=target_assigner_instance, add_summaries=False, normalize_loc_loss_by_codesize=normalize_loc_loss_by_codesize, freeze_batchnorm=False, inplace_batchnorm_update=False, add_background_class=add_background_class, random_example_sampler=random_example_sampler, expected_loss_weights_fn=expected_loss_weights_fn, **kwargs) return model, num_classes, mock_anchor_generator.num_anchors(), code_size
def test_create_embedded_ssd_mobilenet_v1_model_from_config(self): model_text_proto = """ ssd { feature_extractor { type: 'embedded_ssd_mobilenet_v1' conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } box_coder { faster_rcnn_box_coder { } } matcher { argmax_matcher { } } similarity_calculator { iou_similarity { } } anchor_generator { ssd_anchor_generator { aspect_ratios: 1.0 } } image_resizer { fixed_shape_resizer { height: 256 width: 256 } } box_predictor { convolutional_box_predictor { conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } } loss { classification_loss { weighted_softmax { } } localization_loss { weighted_smooth_l1 { } } } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) model = self.create_model(model_proto) self.assertIsInstance(model, ssd_meta_arch.SSDMetaArch) self.assertIsInstance(model._feature_extractor, EmbeddedSSDMobileNetV1FeatureExtractor)
def test_create_ssd_mobilenet_v2_fpnlite_model_from_config(self): model_text_proto = """ ssd { freeze_batchnorm: true inplace_batchnorm_update: true feature_extractor { type: 'ssd_mobilenet_v2_fpn' use_depthwise: true fpn { min_level: 3 max_level: 7 additional_layer_depth: 128 } conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } box_coder { faster_rcnn_box_coder { } } matcher { argmax_matcher { } } similarity_calculator { iou_similarity { } } anchor_generator { ssd_anchor_generator { aspect_ratios: 1.0 } } image_resizer { fixed_shape_resizer { height: 320 width: 320 } } box_predictor { convolutional_box_predictor { conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } } normalize_loc_loss_by_codesize: true loss { classification_loss { weighted_softmax { } } localization_loss { weighted_smooth_l1 { } } } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) model = self.create_model(model_proto) self.assertIsInstance(model, ssd_meta_arch.SSDMetaArch) self.assertIsInstance(model._feature_extractor, SSDMobileNetV2FpnFeatureExtractor) self.assertTrue(model._normalize_loc_loss_by_codesize) self.assertTrue(model._freeze_batchnorm) self.assertTrue(model._inplace_batchnorm_update)
def test_create_ssd_inception_v2_model_from_config(self): model_text_proto = """ ssd { feature_extractor { type: 'ssd_inception_v2' conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } override_base_feature_extractor_hyperparams: true } box_coder { faster_rcnn_box_coder { } } matcher { argmax_matcher { } } similarity_calculator { iou_similarity { } } anchor_generator { ssd_anchor_generator { aspect_ratios: 1.0 } } image_resizer { fixed_shape_resizer { height: 320 width: 320 } } box_predictor { convolutional_box_predictor { conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } } loss { classification_loss { weighted_softmax { } } localization_loss { weighted_smooth_l1 { } } } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) model = self.create_model(model_proto) self.assertIsInstance(model, ssd_meta_arch.SSDMetaArch) self.assertIsInstance(model._feature_extractor, SSDInceptionV2FeatureExtractor) self.assertIsNone(model._expected_loss_weights_fn)
def test_create_ssd_resnet_v1_ppn_model_from_config(self): model_text_proto = """ ssd { feature_extractor { type: 'ssd_resnet_v1_50_ppn' conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } box_coder { mean_stddev_box_coder { } } matcher { bipartite_matcher { } } similarity_calculator { iou_similarity { } } anchor_generator { ssd_anchor_generator { aspect_ratios: 1.0 } } image_resizer { fixed_shape_resizer { height: 320 width: 320 } } box_predictor { weight_shared_convolutional_box_predictor { depth: 1024 class_prediction_bias_init: -4.6 conv_hyperparams { activation: RELU_6, regularizer { l2_regularizer { weight: 0.0004 } } initializer { variance_scaling_initializer { } } } num_layers_before_predictor: 2 kernel_size: 1 } } loss { classification_loss { weighted_softmax { } } localization_loss { weighted_l2 { } } classification_weight: 1.0 localization_weight: 1.0 } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) for extractor_type, extractor_class in SSD_RESNET_V1_PPN_FEAT_MAPS.items( ): model_proto.ssd.feature_extractor.type = extractor_type model = model_builder.build(model_proto, is_training=True) self.assertIsInstance(model, ssd_meta_arch.SSDMetaArch) self.assertIsInstance(model._feature_extractor, extractor_class)
def test_create_ssd_resnet_v1_fpn_model_from_config(self): model_text_proto = """ ssd { feature_extractor { type: 'ssd_resnet50_v1_fpn' fpn { min_level: 3 max_level: 7 } conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } box_coder { faster_rcnn_box_coder { } } matcher { argmax_matcher { } } similarity_calculator { iou_similarity { } } encode_background_as_zeros: true anchor_generator { multiscale_anchor_generator { aspect_ratios: [1.0, 2.0, 0.5] scales_per_octave: 2 } } image_resizer { fixed_shape_resizer { height: 320 width: 320 } } box_predictor { weight_shared_convolutional_box_predictor { depth: 32 conv_hyperparams { regularizer { l2_regularizer { } } initializer { random_normal_initializer { } } } num_layers_before_predictor: 1 } } normalize_loss_by_num_matches: true normalize_loc_loss_by_codesize: true loss { classification_loss { weighted_sigmoid_focal { alpha: 0.25 gamma: 2.0 } } localization_loss { weighted_smooth_l1 { delta: 0.1 } } classification_weight: 1.0 localization_weight: 1.0 } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) for extractor_type, extractor_class in SSD_RESNET_V1_FPN_FEAT_MAPS.items( ): model_proto.ssd.feature_extractor.type = extractor_type model = model_builder.build(model_proto, is_training=True) self.assertIsInstance(model, ssd_meta_arch.SSDMetaArch) self.assertIsInstance(model._feature_extractor, extractor_class)
def test_create_rfcn_resnet_v1_model_from_config(self): model_text_proto = """ faster_rcnn { num_classes: 3 image_resizer { keep_aspect_ratio_resizer { min_dimension: 600 max_dimension: 1024 } } feature_extractor { type: 'faster_rcnn_resnet101' } first_stage_anchor_generator { grid_anchor_generator { scales: [0.25, 0.5, 1.0, 2.0] aspect_ratios: [0.5, 1.0, 2.0] height_stride: 16 width_stride: 16 } } first_stage_box_predictor_conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } initial_crop_size: 14 maxpool_kernel_size: 2 maxpool_stride: 2 second_stage_box_predictor { rfcn_box_predictor { conv_hyperparams { op: CONV regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } } second_stage_post_processing { batch_non_max_suppression { score_threshold: 0.01 iou_threshold: 0.6 max_detections_per_class: 100 max_total_detections: 300 } score_converter: SOFTMAX } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) for extractor_type, extractor_class in FRCNN_RESNET_FEAT_MAPS.items(): model_proto.faster_rcnn.feature_extractor.type = extractor_type model = model_builder.build(model_proto, is_training=True) self.assertIsInstance(model, rfcn_meta_arch.RFCNMetaArch) self.assertIsInstance(model._feature_extractor, extractor_class)
def test_create_faster_rcnn_inception_v2_model_from_config(self): model_text_proto = """ faster_rcnn { num_classes: 3 image_resizer { keep_aspect_ratio_resizer { min_dimension: 600 max_dimension: 1024 } } feature_extractor { type: 'faster_rcnn_inception_v2' } first_stage_anchor_generator { grid_anchor_generator { scales: [0.25, 0.5, 1.0, 2.0] aspect_ratios: [0.5, 1.0, 2.0] height_stride: 16 width_stride: 16 } } first_stage_box_predictor_conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } initial_crop_size: 14 maxpool_kernel_size: 2 maxpool_stride: 2 second_stage_box_predictor { mask_rcnn_box_predictor { fc_hyperparams { op: FC regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } } } second_stage_post_processing { batch_non_max_suppression { score_threshold: 0.01 iou_threshold: 0.6 max_detections_per_class: 100 max_total_detections: 300 } score_converter: SOFTMAX } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) model = model_builder.build(model_proto, is_training=True) self.assertIsInstance(model, faster_rcnn_meta_arch.FasterRCNNMetaArch) self.assertIsInstance( model._feature_extractor, frcnn_inc_v2.FasterRCNNInceptionV2FeatureExtractor)
def test_create_faster_rcnn_resnet101_with_mask_prediction_enabled( self, use_matmul_crop_and_resize): model_text_proto = """ faster_rcnn { num_classes: 3 image_resizer { keep_aspect_ratio_resizer { min_dimension: 600 max_dimension: 1024 } } feature_extractor { type: 'faster_rcnn_resnet101' } first_stage_anchor_generator { grid_anchor_generator { scales: [0.25, 0.5, 1.0, 2.0] aspect_ratios: [0.5, 1.0, 2.0] height_stride: 16 width_stride: 16 } } first_stage_box_predictor_conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } initial_crop_size: 14 maxpool_kernel_size: 2 maxpool_stride: 2 second_stage_box_predictor { mask_rcnn_box_predictor { fc_hyperparams { op: FC regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } conv_hyperparams { regularizer { l2_regularizer { } } initializer { truncated_normal_initializer { } } } predict_instance_masks: true } } second_stage_mask_prediction_loss_weight: 3.0 second_stage_post_processing { batch_non_max_suppression { score_threshold: 0.01 iou_threshold: 0.6 max_detections_per_class: 100 max_total_detections: 300 } score_converter: SOFTMAX } }""" model_proto = model_pb2.DetectionModel() text_format.Merge(model_text_proto, model_proto) model_proto.faster_rcnn.use_matmul_crop_and_resize = ( use_matmul_crop_and_resize) model = model_builder.build(model_proto, is_training=True) self.assertAlmostEqual(model._second_stage_mask_loss_weight, 3.0)