├── README.md ├── dataset └── .gitignore ├── doc └── img │ ├── abraham_grampa_simpson_after.jpg │ ├── abraham_grampa_simpson_before.jpg │ ├── bart_simpson_after.jpg │ ├── bart_simpson_before.jpg │ ├── custom_sample_after.jpg │ ├── kaggle_dataset_main.jpg │ ├── kites_detections_output.jpg │ ├── simpson_dataset.jpg │ └── summary.jpg ├── eval_dir └── .gitignore ├── export_dir └── .gitignore ├── images └── .gitignore ├── label_map.pbtxt ├── main.py ├── model_conf ├── faster_rcnn_inception_resnet_v2_atrous_coco.config ├── faster_rcnn_inception_v2_coco.config ├── faster_rcnn_nas_coco.config ├── faster_rcnn_resnet101_coco.config ├── faster_rcnn_resnet50_coco.config ├── rfcn_resnet101_coco.config ├── ssd_inception_v2_coco.config ├── ssd_mobilenet_v1_coco.config └── ssd_mobilenet_v2_coco.config ├── model_zoo └── .gitignore ├── object_detection ├── CONTRIBUTING.md ├── README.md ├── __init__.py ├── anchor_generators │ ├── __init__.py │ ├── grid_anchor_generator.py │ ├── grid_anchor_generator_test.py │ ├── multiple_grid_anchor_generator.py │ ├── multiple_grid_anchor_generator_test.py │ ├── multiscale_grid_anchor_generator.py │ └── multiscale_grid_anchor_generator_test.py ├── box_coders │ ├── __init__.py │ ├── faster_rcnn_box_coder.py │ ├── faster_rcnn_box_coder_test.py │ ├── keypoint_box_coder.py │ ├── keypoint_box_coder_test.py │ ├── mean_stddev_box_coder.py │ ├── mean_stddev_box_coder_test.py │ ├── square_box_coder.py │ └── square_box_coder_test.py ├── builders │ ├── __init__.py │ ├── anchor_generator_builder.py │ ├── anchor_generator_builder_test.py │ ├── box_coder_builder.py │ ├── box_coder_builder_test.py │ ├── box_predictor_builder.py │ ├── box_predictor_builder_test.py │ ├── dataset_builder.py │ ├── dataset_builder_test.py │ ├── hyperparams_builder.py │ ├── hyperparams_builder_test.py │ ├── image_resizer_builder.py │ ├── image_resizer_builder_test.py │ ├── input_reader_builder.py │ ├── input_reader_builder_test.py │ ├── losses_builder.py │ ├── losses_builder_test.py │ ├── matcher_builder.py │ ├── matcher_builder_test.py │ ├── model_builder.py │ ├── model_builder_test.py │ ├── optimizer_builder.py │ ├── optimizer_builder_test.py │ ├── post_processing_builder.py │ ├── post_processing_builder_test.py │ ├── preprocessor_builder.py │ ├── preprocessor_builder_test.py │ ├── region_similarity_calculator_builder.py │ └── region_similarity_calculator_builder_test.py ├── core │ ├── __init__.py │ ├── anchor_generator.py │ ├── balanced_positive_negative_sampler.py │ ├── balanced_positive_negative_sampler_test.py │ ├── batcher.py │ ├── batcher_test.py │ ├── box_coder.py │ ├── box_coder_test.py │ ├── box_list.py │ ├── box_list_ops.py │ ├── box_list_ops_test.py │ ├── box_list_test.py │ ├── box_predictor.py │ ├── box_predictor_test.py │ ├── data_decoder.py │ ├── data_parser.py │ ├── keypoint_ops.py │ ├── keypoint_ops_test.py │ ├── losses.py │ ├── losses_test.py │ ├── matcher.py │ ├── matcher_test.py │ ├── minibatch_sampler.py │ ├── minibatch_sampler_test.py │ ├── model.py │ ├── post_processing.py │ ├── post_processing_test.py │ ├── prefetcher.py │ ├── prefetcher_test.py │ ├── preprocessor.py │ ├── preprocessor_cache.py │ ├── preprocessor_test.py │ ├── region_similarity_calculator.py │ ├── region_similarity_calculator_test.py │ ├── standard_fields.py │ ├── target_assigner.py │ └── target_assigner_test.py ├── data │ ├── kitti_label_map.pbtxt │ ├── mscoco_label_map.pbtxt │ ├── oid_bbox_trainable_label_map.pbtxt │ ├── pascal_label_map.pbtxt │ └── pet_label_map.pbtxt ├── data_decoders │ ├── __init__.py │ ├── tf_example_decoder.py │ └── tf_example_decoder_test.py ├── dataset_tools │ ├── __init__.py │ ├── create_coco_tf_record.py │ ├── create_coco_tf_record_test.py │ ├── create_kitti_tf_record.py │ ├── create_kitti_tf_record_test.py │ ├── create_oid_tf_record.py │ ├── create_pascal_tf_record.py │ ├── create_pascal_tf_record_test.py │ ├── create_pet_tf_record.py │ ├── download_and_preprocess_mscoco.sh │ ├── oid_tfrecord_creation.py │ └── oid_tfrecord_creation_test.py ├── eval.py ├── eval_util.py ├── eval_util_test.py ├── evaluator.py ├── export_inference_graph.py ├── exporter.py ├── exporter_test.py ├── g3doc │ ├── configuring_jobs.md │ ├── defining_your_own_model.md │ ├── detection_model_zoo.md │ ├── evaluation_protocols.md │ ├── exporting_models.md │ ├── faq.md │ ├── img │ │ ├── dogs_detections_output.jpg │ │ ├── example_cat.jpg │ │ ├── groupof_case_eval.png │ │ ├── kites_detections_output.jpg │ │ ├── kites_with_segment_overlay.png │ │ ├── nongroupof_case_eval.png │ │ ├── oid_bus_72e19c28aac34ed8.jpg │ │ ├── oid_monkey_3b4168c89cecbc5b.jpg │ │ ├── oxford_pet.png │ │ ├── tensorboard.png │ │ ├── tensorboard2.png │ │ └── tf-od-api-logo.png │ ├── installation.md │ ├── instance_segmentation.md │ ├── oid_inference_and_evaluation.md │ ├── preparing_inputs.md │ ├── running_locally.md │ ├── running_notebook.md │ ├── running_on_cloud.md │ ├── running_pets.md │ └── using_your_own_dataset.md ├── inference │ ├── __init__.py │ ├── detection_inference.py │ ├── detection_inference_test.py │ └── infer_detections.py ├── inputs.py ├── inputs_test.py ├── matchers │ ├── __init__.py │ ├── argmax_matcher.py │ ├── argmax_matcher_test.py │ ├── bipartite_matcher.py │ └── bipartite_matcher_test.py ├── meta_architectures │ ├── __init__.py │ ├── faster_rcnn_meta_arch.py │ ├── faster_rcnn_meta_arch_test.py │ ├── faster_rcnn_meta_arch_test_lib.py │ ├── rfcn_meta_arch.py │ ├── rfcn_meta_arch_test.py │ ├── ssd_meta_arch.py │ └── ssd_meta_arch_test.py ├── metrics │ ├── __init__.py │ ├── coco_evaluation.py │ ├── coco_evaluation_test.py │ ├── coco_tools.py │ ├── coco_tools_test.py │ ├── offline_eval_map_corloc.py │ ├── offline_eval_map_corloc_test.py │ ├── tf_example_parser.py │ └── tf_example_parser_test.py ├── model_hparams.py ├── model_lib.py ├── model_lib_test.py ├── model_main.py ├── model_tpu_main.py ├── models │ ├── __init__.py │ ├── embedded_ssd_mobilenet_v1_feature_extractor.py │ ├── embedded_ssd_mobilenet_v1_feature_extractor_test.py │ ├── faster_rcnn_inception_resnet_v2_feature_extractor.py │ ├── faster_rcnn_inception_resnet_v2_feature_extractor_test.py │ ├── faster_rcnn_inception_v2_feature_extractor.py │ ├── faster_rcnn_inception_v2_feature_extractor_test.py │ ├── faster_rcnn_mobilenet_v1_feature_extractor.py │ ├── faster_rcnn_mobilenet_v1_feature_extractor_test.py │ ├── faster_rcnn_nas_feature_extractor.py │ ├── faster_rcnn_nas_feature_extractor_test.py │ ├── faster_rcnn_pnas_feature_extractor.py │ ├── faster_rcnn_pnas_feature_extractor_test.py │ ├── faster_rcnn_resnet_v1_feature_extractor.py │ ├── faster_rcnn_resnet_v1_feature_extractor_test.py │ ├── feature_map_generators.py │ ├── feature_map_generators_test.py │ ├── ssd_feature_extractor_test.py │ ├── ssd_inception_v2_feature_extractor.py │ ├── ssd_inception_v2_feature_extractor_test.py │ ├── ssd_inception_v3_feature_extractor.py │ ├── ssd_inception_v3_feature_extractor_test.py │ ├── ssd_mobilenet_v1_feature_extractor.py │ ├── ssd_mobilenet_v1_feature_extractor_test.py │ ├── ssd_mobilenet_v2_feature_extractor.py │ ├── ssd_mobilenet_v2_feature_extractor_test.py │ ├── ssd_resnet_v1_fpn_feature_extractor.py │ ├── ssd_resnet_v1_fpn_feature_extractor_test.py │ └── ssd_resnet_v1_fpn_feature_extractor_testbase.py ├── object_detection_tutorial.ipynb ├── protos │ ├── __init__.py │ ├── anchor_generator.proto │ ├── anchor_generator_pb2.py │ ├── argmax_matcher.proto │ ├── argmax_matcher_pb2.py │ ├── bipartite_matcher.proto │ ├── bipartite_matcher_pb2.py │ ├── box_coder.proto │ ├── box_coder_pb2.py │ ├── box_predictor.proto │ ├── box_predictor_pb2.py │ ├── eval.proto │ ├── eval_pb2.py │ ├── faster_rcnn.proto │ ├── faster_rcnn_box_coder.proto │ ├── faster_rcnn_box_coder_pb2.py │ ├── faster_rcnn_pb2.py │ ├── grid_anchor_generator.proto │ ├── grid_anchor_generator_pb2.py │ ├── hyperparams.proto │ ├── hyperparams_pb2.py │ ├── image_resizer.proto │ ├── image_resizer_pb2.py │ ├── input_reader.proto │ ├── input_reader_pb2.py │ ├── keypoint_box_coder.proto │ ├── keypoint_box_coder_pb2.py │ ├── losses.proto │ ├── losses_pb2.py │ ├── matcher.proto │ ├── matcher_pb2.py │ ├── mean_stddev_box_coder.proto │ ├── mean_stddev_box_coder_pb2.py │ ├── model.proto │ ├── model_pb2.py │ ├── multiscale_anchor_generator.proto │ ├── multiscale_anchor_generator_pb2.py │ ├── optimizer.proto │ ├── optimizer_pb2.py │ ├── pipeline.proto │ ├── pipeline_pb2.py │ ├── post_processing.proto │ ├── post_processing_pb2.py │ ├── preprocessor.proto │ ├── preprocessor_pb2.py │ ├── region_similarity_calculator.proto │ ├── region_similarity_calculator_pb2.py │ ├── square_box_coder.proto │ ├── square_box_coder_pb2.py │ ├── ssd.proto │ ├── ssd_anchor_generator.proto │ ├── ssd_anchor_generator_pb2.py │ ├── ssd_pb2.py │ ├── string_int_label_map.proto │ ├── string_int_label_map_pb2.py │ ├── train.proto │ └── train_pb2.py ├── samples │ ├── cloud │ │ └── cloud.yml │ └── configs │ │ ├── embedded_ssd_mobilenet_v1_coco.config │ │ ├── faster_rcnn_inception_resnet_v2_atrous_coco.config │ │ ├── faster_rcnn_inception_resnet_v2_atrous_cosine_lr_coco.config │ │ ├── faster_rcnn_inception_resnet_v2_atrous_oid.config │ │ ├── faster_rcnn_inception_resnet_v2_atrous_pets.config │ │ ├── faster_rcnn_inception_v2_coco.config │ │ ├── faster_rcnn_inception_v2_pets.config │ │ ├── faster_rcnn_nas_coco.config │ │ ├── faster_rcnn_resnet101_atrous_coco.config │ │ ├── faster_rcnn_resnet101_coco.config │ │ ├── faster_rcnn_resnet101_kitti.config │ │ ├── faster_rcnn_resnet101_pets.config │ │ ├── faster_rcnn_resnet101_voc07.config │ │ ├── faster_rcnn_resnet152_coco.config │ │ ├── faster_rcnn_resnet152_pets.config │ │ ├── faster_rcnn_resnet50_coco.config │ │ ├── faster_rcnn_resnet50_pets.config │ │ ├── mask_rcnn_inception_resnet_v2_atrous_coco.config │ │ ├── mask_rcnn_inception_v2_coco.config │ │ ├── mask_rcnn_resnet101_atrous_coco.config │ │ ├── mask_rcnn_resnet101_pets.config │ │ ├── mask_rcnn_resnet50_atrous_coco.config │ │ ├── rfcn_resnet101_coco.config │ │ ├── rfcn_resnet101_pets.config │ │ ├── ssd_inception_v2_coco.config │ │ ├── ssd_inception_v2_pets.config │ │ ├── ssd_inception_v3_pets.config │ │ ├── ssd_mobilenet_v1_coco.config │ │ ├── ssd_mobilenet_v1_focal_loss_coco.config │ │ ├── ssd_mobilenet_v1_focal_loss_pets.config │ │ ├── ssd_mobilenet_v1_pets.config │ │ └── ssd_mobilenet_v2_coco.config ├── test_data │ └── pets_examples.record ├── test_images │ ├── image0.jpg │ ├── image1.jpg │ ├── image2.jpg │ ├── image3.jpg │ └── image4.jpg ├── train.py ├── trainer.py ├── trainer_test.py └── utils │ ├── __init__.py │ ├── category_util.py │ ├── category_util_test.py │ ├── config_util.py │ ├── config_util_test.py │ ├── context_manager.py │ ├── context_manager_test.py │ ├── dataset_util.py │ ├── dataset_util_test.py │ ├── json_utils.py │ ├── json_utils_test.py │ ├── label_map_util.py │ ├── label_map_util_test.py │ ├── learning_schedules.py │ ├── learning_schedules_test.py │ ├── metrics.py │ ├── metrics_test.py │ ├── np_box_list.py │ ├── np_box_list_ops.py │ ├── np_box_list_ops_test.py │ ├── np_box_list_test.py │ ├── np_box_mask_list.py │ ├── np_box_mask_list_ops.py │ ├── np_box_mask_list_ops_test.py │ ├── np_box_mask_list_test.py │ ├── np_box_ops.py │ ├── np_box_ops_test.py │ ├── np_mask_ops.py │ ├── np_mask_ops_test.py │ ├── object_detection_evaluation.py │ ├── object_detection_evaluation_test.py │ ├── ops.py │ ├── ops_test.py │ ├── per_image_evaluation.py │ ├── per_image_evaluation_test.py │ ├── per_image_vrd_evaluation.py │ ├── per_image_vrd_evaluation_test.py │ ├── shape_utils.py │ ├── shape_utils_test.py │ ├── static_shape.py │ ├── static_shape_test.py │ ├── test_case.py │ ├── test_utils.py │ ├── test_utils_test.py │ ├── variables_helper.py │ ├── variables_helper_test.py │ ├── visualization_utils.py │ └── visualization_utils_test.py ├── process.log ├── tfgenerator.py ├── train_dir └── .gitignore └── utils ├── __init__.py └── utils.py /dataset/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/dataset/.gitignore -------------------------------------------------------------------------------- /doc/img/abraham_grampa_simpson_after.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/abraham_grampa_simpson_after.jpg -------------------------------------------------------------------------------- /doc/img/abraham_grampa_simpson_before.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/abraham_grampa_simpson_before.jpg -------------------------------------------------------------------------------- /doc/img/bart_simpson_after.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/bart_simpson_after.jpg -------------------------------------------------------------------------------- /doc/img/bart_simpson_before.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/bart_simpson_before.jpg -------------------------------------------------------------------------------- /doc/img/custom_sample_after.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/custom_sample_after.jpg -------------------------------------------------------------------------------- /doc/img/kaggle_dataset_main.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/kaggle_dataset_main.jpg -------------------------------------------------------------------------------- /doc/img/kites_detections_output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/kites_detections_output.jpg -------------------------------------------------------------------------------- /doc/img/simpson_dataset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/simpson_dataset.jpg -------------------------------------------------------------------------------- /doc/img/summary.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/doc/img/summary.jpg -------------------------------------------------------------------------------- /eval_dir/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/eval_dir/.gitignore -------------------------------------------------------------------------------- /export_dir/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/export_dir/.gitignore -------------------------------------------------------------------------------- /images/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/images/.gitignore -------------------------------------------------------------------------------- /label_map.pbtxt: -------------------------------------------------------------------------------- 1 | item { 2 | id: 1 3 | name: 'meerkat' 4 | } 5 | item { 6 | id: 2 7 | name: 'otter' 8 | } 9 | item { 10 | id: 3 11 | name: 'panda' 12 | } 13 | item { 14 | id: 4 15 | name: 'raccoon' 16 | } 17 | item { 18 | id: 5 19 | name: 'pomeranian' 20 | } 21 | -------------------------------------------------------------------------------- /model_conf/faster_rcnn_resnet101_coco.config: -------------------------------------------------------------------------------- 1 | # Faster R-CNN with Resnet-101 (v1), configuration for MSCOCO Dataset. 2 | # Users should configure the fine_tune_checkpoint field in the train config as 3 | # well as the label_map_path and input_path fields in the train_input_reader and 4 | # eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that 5 | # should be configured. 6 | 7 | model { 8 | faster_rcnn { 9 | num_classes: 90 10 | image_resizer { 11 | keep_aspect_ratio_resizer { 12 | min_dimension: 600 13 | max_dimension: 1024 14 | } 15 | } 16 | feature_extractor { 17 | type: 'faster_rcnn_resnet101' 18 | first_stage_features_stride: 16 19 | } 20 | first_stage_anchor_generator { 21 | grid_anchor_generator { 22 | scales: [0.25, 0.5, 1.0, 2.0] 23 | aspect_ratios: [0.5, 1.0, 2.0] 24 | height_stride: 16 25 | width_stride: 16 26 | } 27 | } 28 | first_stage_box_predictor_conv_hyperparams { 29 | op: CONV 30 | regularizer { 31 | l2_regularizer { 32 | weight: 0.0 33 | } 34 | } 35 | initializer { 36 | truncated_normal_initializer { 37 | stddev: 0.01 38 | } 39 | } 40 | } 41 | first_stage_nms_score_threshold: 0.0 42 | first_stage_nms_iou_threshold: 0.7 43 | first_stage_max_proposals: 300 44 | first_stage_localization_loss_weight: 2.0 45 | first_stage_objectness_loss_weight: 1.0 46 | initial_crop_size: 14 47 | maxpool_kernel_size: 2 48 | maxpool_stride: 2 49 | second_stage_box_predictor { 50 | mask_rcnn_box_predictor { 51 | use_dropout: false 52 | dropout_keep_probability: 1.0 53 | fc_hyperparams { 54 | op: FC 55 | regularizer { 56 | l2_regularizer { 57 | weight: 0.0 58 | } 59 | } 60 | initializer { 61 | variance_scaling_initializer { 62 | factor: 1.0 63 | uniform: true 64 | mode: FAN_AVG 65 | } 66 | } 67 | } 68 | } 69 | } 70 | second_stage_post_processing { 71 | batch_non_max_suppression { 72 | score_threshold: 0.0 73 | iou_threshold: 0.6 74 | max_detections_per_class: 100 75 | max_total_detections: 300 76 | } 77 | score_converter: SOFTMAX 78 | } 79 | second_stage_localization_loss_weight: 2.0 80 | second_stage_classification_loss_weight: 1.0 81 | } 82 | } 83 | 84 | train_config: { 85 | batch_size: 1 86 | optimizer { 87 | momentum_optimizer: { 88 | learning_rate: { 89 | manual_step_learning_rate { 90 | initial_learning_rate: 0.0003 91 | schedule { 92 | step: 900000 93 | learning_rate: .00003 94 | } 95 | schedule { 96 | step: 1200000 97 | learning_rate: .000003 98 | } 99 | } 100 | } 101 | momentum_optimizer_value: 0.9 102 | } 103 | use_moving_average: false 104 | } 105 | gradient_clipping_by_norm: 10.0 106 | fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt" 107 | from_detection_checkpoint: true 108 | num_steps: 200000 109 | data_augmentation_options { 110 | random_horizontal_flip { 111 | } 112 | } 113 | } 114 | 115 | train_input_reader: { 116 | tf_record_input_reader { 117 | input_path: "./dataset/train.record" 118 | } 119 | label_map_path: "PATH_TO_BE_CONFIGURED/mscoco_label_map.pbtxt" 120 | } 121 | 122 | eval_config: { 123 | num_examples: 100 124 | # Note: The below line limits the evaluation process to 10 evaluations. 125 | # Remove the below line to evaluate indefinitely. 126 | max_evals: 10 127 | } 128 | 129 | eval_input_reader: { 130 | tf_record_input_reader { 131 | input_path: "./dataset/val.record" 132 | } 133 | label_map_path: "PATH_TO_BE_CONFIGURED/mscoco_label_map.pbtxt" 134 | shuffle: false 135 | num_readers: 1 136 | } 137 | -------------------------------------------------------------------------------- /model_zoo/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/model_zoo/.gitignore -------------------------------------------------------------------------------- /object_detection/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Tensorflow Object Detection API 2 | 3 | Patches to Tensorflow Object Detection API are welcome! 4 | 5 | We require contributors to fill out either the individual or corporate 6 | Contributor License Agreement (CLA). 7 | 8 | * If you are an individual writing original source code and you're sure you own the intellectual property, then you'll need to sign an [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html). 9 | * If you work for a company that wants to allow you to contribute your work, then you'll need to sign a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html). 10 | 11 | Please follow the 12 | [Tensorflow contributing guidelines](https://github.com/tensorflow/tensorflow/blob/master/CONTRIBUTING.md) 13 | when submitting pull requests. 14 | -------------------------------------------------------------------------------- /object_detection/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/__init__.py -------------------------------------------------------------------------------- /object_detection/anchor_generators/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/anchor_generators/__init__.py -------------------------------------------------------------------------------- /object_detection/box_coders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/box_coders/__init__.py -------------------------------------------------------------------------------- /object_detection/box_coders/mean_stddev_box_coder.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Mean stddev box coder. 17 | 18 | This box coder use the following coding schema to encode boxes: 19 | rel_code = (box_corner - anchor_corner_mean) / anchor_corner_stddev. 20 | """ 21 | from object_detection.core import box_coder 22 | from object_detection.core import box_list 23 | 24 | 25 | class MeanStddevBoxCoder(box_coder.BoxCoder): 26 | """Mean stddev box coder.""" 27 | 28 | @property 29 | def code_size(self): 30 | return 4 31 | 32 | def _encode(self, boxes, anchors): 33 | """Encode a box collection with respect to anchor collection. 34 | 35 | Args: 36 | boxes: BoxList holding N boxes to be encoded. 37 | anchors: BoxList of N anchors. We assume that anchors has an associated 38 | stddev field. 39 | 40 | Returns: 41 | a tensor representing N anchor-encoded boxes 42 | Raises: 43 | ValueError: if the anchors BoxList does not have a stddev field 44 | """ 45 | if not anchors.has_field('stddev'): 46 | raise ValueError('anchors must have a stddev field') 47 | box_corners = boxes.get() 48 | means = anchors.get() 49 | stddev = anchors.get_field('stddev') 50 | return (box_corners - means) / stddev 51 | 52 | def _decode(self, rel_codes, anchors): 53 | """Decode. 54 | 55 | Args: 56 | rel_codes: a tensor representing N anchor-encoded boxes. 57 | anchors: BoxList of anchors. We assume that anchors has an associated 58 | stddev field. 59 | 60 | Returns: 61 | boxes: BoxList holding N bounding boxes 62 | Raises: 63 | ValueError: if the anchors BoxList does not have a stddev field 64 | """ 65 | if not anchors.has_field('stddev'): 66 | raise ValueError('anchors must have a stddev field') 67 | means = anchors.get() 68 | stddevs = anchors.get_field('stddev') 69 | box_corners = rel_codes * stddevs + means 70 | return box_list.BoxList(box_corners) 71 | -------------------------------------------------------------------------------- /object_detection/box_coders/mean_stddev_box_coder_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for object_detection.box_coder.mean_stddev_boxcoder.""" 17 | 18 | import tensorflow as tf 19 | 20 | from object_detection.box_coders import mean_stddev_box_coder 21 | from object_detection.core import box_list 22 | 23 | 24 | class MeanStddevBoxCoderTest(tf.test.TestCase): 25 | 26 | def testGetCorrectRelativeCodesAfterEncoding(self): 27 | box_corners = [[0.0, 0.0, 0.5, 0.5], [0.0, 0.0, 0.5, 0.5]] 28 | boxes = box_list.BoxList(tf.constant(box_corners)) 29 | expected_rel_codes = [[0.0, 0.0, 0.0, 0.0], [-5.0, -5.0, -5.0, -3.0]] 30 | prior_means = tf.constant([[0.0, 0.0, 0.5, 0.5], [0.5, 0.5, 1.0, 0.8]]) 31 | prior_stddevs = tf.constant(2 * [4 * [.1]]) 32 | priors = box_list.BoxList(prior_means) 33 | priors.add_field('stddev', prior_stddevs) 34 | 35 | coder = mean_stddev_box_coder.MeanStddevBoxCoder() 36 | rel_codes = coder.encode(boxes, priors) 37 | with self.test_session() as sess: 38 | rel_codes_out = sess.run(rel_codes) 39 | self.assertAllClose(rel_codes_out, expected_rel_codes) 40 | 41 | def testGetCorrectBoxesAfterDecoding(self): 42 | rel_codes = tf.constant([[0.0, 0.0, 0.0, 0.0], [-5.0, -5.0, -5.0, -3.0]]) 43 | expected_box_corners = [[0.0, 0.0, 0.5, 0.5], [0.0, 0.0, 0.5, 0.5]] 44 | prior_means = tf.constant([[0.0, 0.0, 0.5, 0.5], [0.5, 0.5, 1.0, 0.8]]) 45 | prior_stddevs = tf.constant(2 * [4 * [.1]]) 46 | priors = box_list.BoxList(prior_means) 47 | priors.add_field('stddev', prior_stddevs) 48 | 49 | coder = mean_stddev_box_coder.MeanStddevBoxCoder() 50 | decoded_boxes = coder.decode(rel_codes, priors) 51 | decoded_box_corners = decoded_boxes.get() 52 | with self.test_session() as sess: 53 | decoded_out = sess.run(decoded_box_corners) 54 | self.assertAllClose(decoded_out, expected_box_corners) 55 | 56 | 57 | if __name__ == '__main__': 58 | tf.test.main() 59 | -------------------------------------------------------------------------------- /object_detection/builders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/builders/__init__.py -------------------------------------------------------------------------------- /object_detection/builders/box_coder_builder.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """A function to build an object detection box coder from configuration.""" 17 | from object_detection.box_coders import faster_rcnn_box_coder 18 | from object_detection.box_coders import keypoint_box_coder 19 | from object_detection.box_coders import mean_stddev_box_coder 20 | from object_detection.box_coders import square_box_coder 21 | from object_detection.protos import box_coder_pb2 22 | 23 | 24 | def build(box_coder_config): 25 | """Builds a box coder object based on the box coder config. 26 | 27 | Args: 28 | box_coder_config: A box_coder.proto object containing the config for the 29 | desired box coder. 30 | 31 | Returns: 32 | BoxCoder based on the config. 33 | 34 | Raises: 35 | ValueError: On empty box coder proto. 36 | """ 37 | if not isinstance(box_coder_config, box_coder_pb2.BoxCoder): 38 | raise ValueError('box_coder_config not of type box_coder_pb2.BoxCoder.') 39 | 40 | if box_coder_config.WhichOneof('box_coder_oneof') == 'faster_rcnn_box_coder': 41 | return faster_rcnn_box_coder.FasterRcnnBoxCoder(scale_factors=[ 42 | box_coder_config.faster_rcnn_box_coder.y_scale, 43 | box_coder_config.faster_rcnn_box_coder.x_scale, 44 | box_coder_config.faster_rcnn_box_coder.height_scale, 45 | box_coder_config.faster_rcnn_box_coder.width_scale 46 | ]) 47 | if box_coder_config.WhichOneof('box_coder_oneof') == 'keypoint_box_coder': 48 | return keypoint_box_coder.KeypointBoxCoder( 49 | box_coder_config.keypoint_box_coder.num_keypoints, 50 | scale_factors=[ 51 | box_coder_config.keypoint_box_coder.y_scale, 52 | box_coder_config.keypoint_box_coder.x_scale, 53 | box_coder_config.keypoint_box_coder.height_scale, 54 | box_coder_config.keypoint_box_coder.width_scale 55 | ]) 56 | if (box_coder_config.WhichOneof('box_coder_oneof') == 57 | 'mean_stddev_box_coder'): 58 | return mean_stddev_box_coder.MeanStddevBoxCoder() 59 | if box_coder_config.WhichOneof('box_coder_oneof') == 'square_box_coder': 60 | return square_box_coder.SquareBoxCoder(scale_factors=[ 61 | box_coder_config.square_box_coder.y_scale, 62 | box_coder_config.square_box_coder.x_scale, 63 | box_coder_config.square_box_coder.length_scale 64 | ]) 65 | raise ValueError('Empty box coder.') 66 | -------------------------------------------------------------------------------- /object_detection/builders/input_reader_builder.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Input reader builder. 17 | 18 | Creates data sources for DetectionModels from an InputReader config. See 19 | input_reader.proto for options. 20 | 21 | Note: If users wishes to also use their own InputReaders with the Object 22 | Detection configuration framework, they should define their own builder function 23 | that wraps the build function. 24 | """ 25 | 26 | import tensorflow as tf 27 | 28 | from object_detection.data_decoders import tf_example_decoder 29 | from object_detection.protos import input_reader_pb2 30 | 31 | parallel_reader = tf.contrib.slim.parallel_reader 32 | 33 | 34 | def build(input_reader_config): 35 | """Builds a tensor dictionary based on the InputReader config. 36 | 37 | Args: 38 | input_reader_config: A input_reader_pb2.InputReader object. 39 | 40 | Returns: 41 | A tensor dict based on the input_reader_config. 42 | 43 | Raises: 44 | ValueError: On invalid input reader proto. 45 | ValueError: If no input paths are specified. 46 | """ 47 | if not isinstance(input_reader_config, input_reader_pb2.InputReader): 48 | raise ValueError('input_reader_config not of type ' 49 | 'input_reader_pb2.InputReader.') 50 | 51 | if input_reader_config.WhichOneof('input_reader') == 'tf_record_input_reader': 52 | config = input_reader_config.tf_record_input_reader 53 | if not config.input_path: 54 | raise ValueError('At least one input path must be specified in ' 55 | '`input_reader_config`.') 56 | _, string_tensor = parallel_reader.parallel_read( 57 | config.input_path[:], # Convert `RepeatedScalarContainer` to list. 58 | reader_class=tf.TFRecordReader, 59 | num_epochs=(input_reader_config.num_epochs 60 | if input_reader_config.num_epochs else None), 61 | num_readers=input_reader_config.num_readers, 62 | shuffle=input_reader_config.shuffle, 63 | dtypes=[tf.string, tf.string], 64 | capacity=input_reader_config.queue_capacity, 65 | min_after_dequeue=input_reader_config.min_after_dequeue) 66 | 67 | label_map_proto_file = None 68 | if input_reader_config.HasField('label_map_path'): 69 | label_map_proto_file = input_reader_config.label_map_path 70 | decoder = tf_example_decoder.TfExampleDecoder( 71 | load_instance_masks=input_reader_config.load_instance_masks, 72 | instance_mask_type=input_reader_config.mask_type, 73 | label_map_proto_file=label_map_proto_file) 74 | return decoder.decode(string_tensor) 75 | 76 | raise ValueError('Unsupported input_reader_config.') 77 | -------------------------------------------------------------------------------- /object_detection/builders/matcher_builder.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """A function to build an object detection matcher from configuration.""" 17 | 18 | from object_detection.matchers import argmax_matcher 19 | from object_detection.matchers import bipartite_matcher 20 | from object_detection.protos import matcher_pb2 21 | 22 | 23 | def build(matcher_config): 24 | """Builds a matcher object based on the matcher config. 25 | 26 | Args: 27 | matcher_config: A matcher.proto object containing the config for the desired 28 | Matcher. 29 | 30 | Returns: 31 | Matcher based on the config. 32 | 33 | Raises: 34 | ValueError: On empty matcher proto. 35 | """ 36 | if not isinstance(matcher_config, matcher_pb2.Matcher): 37 | raise ValueError('matcher_config not of type matcher_pb2.Matcher.') 38 | if matcher_config.WhichOneof('matcher_oneof') == 'argmax_matcher': 39 | matcher = matcher_config.argmax_matcher 40 | matched_threshold = unmatched_threshold = None 41 | if not matcher.ignore_thresholds: 42 | matched_threshold = matcher.matched_threshold 43 | unmatched_threshold = matcher.unmatched_threshold 44 | return argmax_matcher.ArgMaxMatcher( 45 | matched_threshold=matched_threshold, 46 | unmatched_threshold=unmatched_threshold, 47 | negatives_lower_than_unmatched=matcher.negatives_lower_than_unmatched, 48 | force_match_for_each_row=matcher.force_match_for_each_row, 49 | use_matmul_gather=matcher.use_matmul_gather) 50 | if matcher_config.WhichOneof('matcher_oneof') == 'bipartite_matcher': 51 | matcher = matcher_config.bipartite_matcher 52 | return bipartite_matcher.GreedyBipartiteMatcher(matcher.use_matmul_gather) 53 | raise ValueError('Empty matcher.') 54 | -------------------------------------------------------------------------------- /object_detection/builders/region_similarity_calculator_builder.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Builder for region similarity calculators.""" 17 | 18 | from object_detection.core import region_similarity_calculator 19 | from object_detection.protos import region_similarity_calculator_pb2 20 | 21 | 22 | def build(region_similarity_calculator_config): 23 | """Builds region similarity calculator based on the configuration. 24 | 25 | Builds one of [IouSimilarity, IoaSimilarity, NegSqDistSimilarity] objects. See 26 | core/region_similarity_calculator.proto for details. 27 | 28 | Args: 29 | region_similarity_calculator_config: RegionSimilarityCalculator 30 | configuration proto. 31 | 32 | Returns: 33 | region_similarity_calculator: RegionSimilarityCalculator object. 34 | 35 | Raises: 36 | ValueError: On unknown region similarity calculator. 37 | """ 38 | 39 | if not isinstance( 40 | region_similarity_calculator_config, 41 | region_similarity_calculator_pb2.RegionSimilarityCalculator): 42 | raise ValueError( 43 | 'region_similarity_calculator_config not of type ' 44 | 'region_similarity_calculator_pb2.RegionsSimilarityCalculator') 45 | 46 | similarity_calculator = region_similarity_calculator_config.WhichOneof( 47 | 'region_similarity') 48 | if similarity_calculator == 'iou_similarity': 49 | return region_similarity_calculator.IouSimilarity() 50 | if similarity_calculator == 'ioa_similarity': 51 | return region_similarity_calculator.IoaSimilarity() 52 | if similarity_calculator == 'neg_sq_dist_similarity': 53 | return region_similarity_calculator.NegSqDistSimilarity() 54 | 55 | raise ValueError('Unknown region similarity calculator.') 56 | 57 | -------------------------------------------------------------------------------- /object_detection/builders/region_similarity_calculator_builder_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for region_similarity_calculator_builder.""" 17 | 18 | import tensorflow as tf 19 | 20 | from google.protobuf import text_format 21 | from object_detection.builders import region_similarity_calculator_builder 22 | from object_detection.core import region_similarity_calculator 23 | from object_detection.protos import region_similarity_calculator_pb2 as sim_calc_pb2 24 | 25 | 26 | class RegionSimilarityCalculatorBuilderTest(tf.test.TestCase): 27 | 28 | def testBuildIoaSimilarityCalculator(self): 29 | similarity_calc_text_proto = """ 30 | ioa_similarity { 31 | } 32 | """ 33 | similarity_calc_proto = sim_calc_pb2.RegionSimilarityCalculator() 34 | text_format.Merge(similarity_calc_text_proto, similarity_calc_proto) 35 | similarity_calc = region_similarity_calculator_builder.build( 36 | similarity_calc_proto) 37 | self.assertTrue(isinstance(similarity_calc, 38 | region_similarity_calculator.IoaSimilarity)) 39 | 40 | def testBuildIouSimilarityCalculator(self): 41 | similarity_calc_text_proto = """ 42 | iou_similarity { 43 | } 44 | """ 45 | similarity_calc_proto = sim_calc_pb2.RegionSimilarityCalculator() 46 | text_format.Merge(similarity_calc_text_proto, similarity_calc_proto) 47 | similarity_calc = region_similarity_calculator_builder.build( 48 | similarity_calc_proto) 49 | self.assertTrue(isinstance(similarity_calc, 50 | region_similarity_calculator.IouSimilarity)) 51 | 52 | def testBuildNegSqDistSimilarityCalculator(self): 53 | similarity_calc_text_proto = """ 54 | neg_sq_dist_similarity { 55 | } 56 | """ 57 | similarity_calc_proto = sim_calc_pb2.RegionSimilarityCalculator() 58 | text_format.Merge(similarity_calc_text_proto, similarity_calc_proto) 59 | similarity_calc = region_similarity_calculator_builder.build( 60 | similarity_calc_proto) 61 | self.assertTrue(isinstance(similarity_calc, 62 | region_similarity_calculator. 63 | NegSqDistSimilarity)) 64 | 65 | 66 | if __name__ == '__main__': 67 | tf.test.main() 68 | -------------------------------------------------------------------------------- /object_detection/core/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /object_detection/core/balanced_positive_negative_sampler.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Class to subsample minibatches by balancing positives and negatives. 17 | 18 | Subsamples minibatches based on a pre-specified positive fraction in range 19 | [0,1]. The class presumes there are many more negatives than positive examples: 20 | if the desired batch_size cannot be achieved with the pre-specified positive 21 | fraction, it fills the rest with negative examples. If this is not sufficient 22 | for obtaining the desired batch_size, it returns fewer examples. 23 | 24 | The main function to call is Subsample(self, indicator, labels). For convenience 25 | one can also call SubsampleWeights(self, weights, labels) which is defined in 26 | the minibatch_sampler base class. 27 | """ 28 | 29 | import tensorflow as tf 30 | 31 | from object_detection.core import minibatch_sampler 32 | 33 | 34 | class BalancedPositiveNegativeSampler(minibatch_sampler.MinibatchSampler): 35 | """Subsamples minibatches to a desired balance of positives and negatives.""" 36 | 37 | def __init__(self, positive_fraction=0.5): 38 | """Constructs a minibatch sampler. 39 | 40 | Args: 41 | positive_fraction: desired fraction of positive examples (scalar in [0,1]) 42 | 43 | Raises: 44 | ValueError: if positive_fraction < 0, or positive_fraction > 1 45 | """ 46 | if positive_fraction < 0 or positive_fraction > 1: 47 | raise ValueError('positive_fraction should be in range [0,1]. ' 48 | 'Received: %s.' % positive_fraction) 49 | self._positive_fraction = positive_fraction 50 | 51 | def subsample(self, indicator, batch_size, labels): 52 | """Returns subsampled minibatch. 53 | 54 | Args: 55 | indicator: boolean tensor of shape [N] whose True entries can be sampled. 56 | batch_size: desired batch size. 57 | labels: boolean tensor of shape [N] denoting positive(=True) and negative 58 | (=False) examples. 59 | 60 | Returns: 61 | is_sampled: boolean tensor of shape [N], True for entries which are 62 | sampled. 63 | 64 | Raises: 65 | ValueError: if labels and indicator are not 1D boolean tensors. 66 | """ 67 | if len(indicator.get_shape().as_list()) != 1: 68 | raise ValueError('indicator must be 1 dimensional, got a tensor of ' 69 | 'shape %s' % indicator.get_shape()) 70 | if len(labels.get_shape().as_list()) != 1: 71 | raise ValueError('labels must be 1 dimensional, got a tensor of ' 72 | 'shape %s' % labels.get_shape()) 73 | if labels.dtype != tf.bool: 74 | raise ValueError('labels should be of type bool. Received: %s' % 75 | labels.dtype) 76 | if indicator.dtype != tf.bool: 77 | raise ValueError('indicator should be of type bool. Received: %s' % 78 | indicator.dtype) 79 | 80 | # Only sample from indicated samples 81 | negative_idx = tf.logical_not(labels) 82 | positive_idx = tf.logical_and(labels, indicator) 83 | negative_idx = tf.logical_and(negative_idx, indicator) 84 | 85 | # Sample positive and negative samples separately 86 | max_num_pos = int(self._positive_fraction * batch_size) 87 | sampled_pos_idx = self.subsample_indicator(positive_idx, max_num_pos) 88 | max_num_neg = batch_size - tf.reduce_sum(tf.cast(sampled_pos_idx, tf.int32)) 89 | sampled_neg_idx = self.subsample_indicator(negative_idx, max_num_neg) 90 | 91 | sampled_idx = tf.logical_or(sampled_pos_idx, sampled_neg_idx) 92 | return sampled_idx 93 | -------------------------------------------------------------------------------- /object_detection/core/balanced_positive_negative_sampler_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for object_detection.core.balanced_positive_negative_sampler.""" 17 | 18 | import numpy as np 19 | import tensorflow as tf 20 | 21 | from object_detection.core import balanced_positive_negative_sampler 22 | 23 | 24 | class BalancedPositiveNegativeSamplerTest(tf.test.TestCase): 25 | 26 | def test_subsample_all_examples(self): 27 | numpy_labels = np.random.permutation(300) 28 | indicator = tf.constant(np.ones(300) == 1) 29 | numpy_labels = (numpy_labels - 200) > 0 30 | 31 | labels = tf.constant(numpy_labels) 32 | 33 | sampler = (balanced_positive_negative_sampler. 34 | BalancedPositiveNegativeSampler()) 35 | is_sampled = sampler.subsample(indicator, 64, labels) 36 | with self.test_session() as sess: 37 | is_sampled = sess.run(is_sampled) 38 | self.assertTrue(sum(is_sampled) == 64) 39 | self.assertTrue(sum(np.logical_and(numpy_labels, is_sampled)) == 32) 40 | self.assertTrue(sum(np.logical_and( 41 | np.logical_not(numpy_labels), is_sampled)) == 32) 42 | 43 | def test_subsample_selection(self): 44 | # Test random sampling when only some examples can be sampled: 45 | # 100 samples, 20 positives, 10 positives cannot be sampled 46 | numpy_labels = np.arange(100) 47 | numpy_indicator = numpy_labels < 90 48 | indicator = tf.constant(numpy_indicator) 49 | numpy_labels = (numpy_labels - 80) >= 0 50 | 51 | labels = tf.constant(numpy_labels) 52 | 53 | sampler = (balanced_positive_negative_sampler. 54 | BalancedPositiveNegativeSampler()) 55 | is_sampled = sampler.subsample(indicator, 64, labels) 56 | with self.test_session() as sess: 57 | is_sampled = sess.run(is_sampled) 58 | self.assertTrue(sum(is_sampled) == 64) 59 | self.assertTrue(sum(np.logical_and(numpy_labels, is_sampled)) == 10) 60 | self.assertTrue(sum(np.logical_and( 61 | np.logical_not(numpy_labels), is_sampled)) == 54) 62 | self.assertAllEqual(is_sampled, np.logical_and(is_sampled, 63 | numpy_indicator)) 64 | 65 | def test_raises_error_with_incorrect_label_shape(self): 66 | labels = tf.constant([[True, False, False]]) 67 | indicator = tf.constant([True, False, True]) 68 | sampler = (balanced_positive_negative_sampler. 69 | BalancedPositiveNegativeSampler()) 70 | with self.assertRaises(ValueError): 71 | sampler.subsample(indicator, 64, labels) 72 | 73 | def test_raises_error_with_incorrect_indicator_shape(self): 74 | labels = tf.constant([True, False, False]) 75 | indicator = tf.constant([[True, False, True]]) 76 | sampler = (balanced_positive_negative_sampler. 77 | BalancedPositiveNegativeSampler()) 78 | with self.assertRaises(ValueError): 79 | sampler.subsample(indicator, 64, labels) 80 | 81 | 82 | if __name__ == '__main__': 83 | tf.test.main() 84 | -------------------------------------------------------------------------------- /object_detection/core/box_coder_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for object_detection.core.box_coder.""" 17 | 18 | import tensorflow as tf 19 | 20 | from object_detection.core import box_coder 21 | from object_detection.core import box_list 22 | 23 | 24 | class MockBoxCoder(box_coder.BoxCoder): 25 | """Test BoxCoder that encodes/decodes using the multiply-by-two function.""" 26 | 27 | def code_size(self): 28 | return 4 29 | 30 | def _encode(self, boxes, anchors): 31 | return 2.0 * boxes.get() 32 | 33 | def _decode(self, rel_codes, anchors): 34 | return box_list.BoxList(rel_codes / 2.0) 35 | 36 | 37 | class BoxCoderTest(tf.test.TestCase): 38 | 39 | def test_batch_decode(self): 40 | mock_anchor_corners = tf.constant( 41 | [[0, 0.1, 0.2, 0.3], [0.2, 0.4, 0.4, 0.6]], tf.float32) 42 | mock_anchors = box_list.BoxList(mock_anchor_corners) 43 | mock_box_coder = MockBoxCoder() 44 | 45 | expected_boxes = [[[0.0, 0.1, 0.5, 0.6], [0.5, 0.6, 0.7, 0.8]], 46 | [[0.1, 0.2, 0.3, 0.4], [0.7, 0.8, 0.9, 1.0]]] 47 | 48 | encoded_boxes_list = [mock_box_coder.encode( 49 | box_list.BoxList(tf.constant(boxes)), mock_anchors) 50 | for boxes in expected_boxes] 51 | encoded_boxes = tf.stack(encoded_boxes_list) 52 | decoded_boxes = box_coder.batch_decode( 53 | encoded_boxes, mock_box_coder, mock_anchors) 54 | 55 | with self.test_session() as sess: 56 | decoded_boxes_result = sess.run(decoded_boxes) 57 | self.assertAllClose(expected_boxes, decoded_boxes_result) 58 | 59 | 60 | if __name__ == '__main__': 61 | tf.test.main() 62 | -------------------------------------------------------------------------------- /object_detection/core/data_decoder.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Interface for data decoders. 17 | 18 | Data decoders decode the input data and return a dictionary of tensors keyed by 19 | the entries in core.reader.Fields. 20 | """ 21 | from abc import ABCMeta 22 | from abc import abstractmethod 23 | 24 | 25 | class DataDecoder(object): 26 | """Interface for data decoders.""" 27 | __metaclass__ = ABCMeta 28 | 29 | @abstractmethod 30 | def decode(self, data): 31 | """Return a single image and associated labels. 32 | 33 | Args: 34 | data: a string tensor holding a serialized protocol buffer corresponding 35 | to data for a single image. 36 | 37 | Returns: 38 | tensor_dict: a dictionary containing tensors. Possible keys are defined in 39 | reader.Fields. 40 | """ 41 | pass 42 | -------------------------------------------------------------------------------- /object_detection/core/data_parser.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | """Interface for data parsers. 16 | 17 | Data parser parses input data and returns a dictionary of numpy arrays 18 | keyed by the entries in standard_fields.py. Since the parser parses records 19 | to numpy arrays (materialized tensors) directly, it is used to read data for 20 | evaluation/visualization; to parse the data during training, DataDecoder should 21 | be used. 22 | """ 23 | from abc import ABCMeta 24 | from abc import abstractmethod 25 | 26 | 27 | class DataToNumpyParser(object): 28 | __metaclass__ = ABCMeta 29 | 30 | @abstractmethod 31 | def parse(self, input_data): 32 | """Parses input and returns a numpy array or a dictionary of numpy arrays. 33 | 34 | Args: 35 | input_data: an input data 36 | 37 | Returns: 38 | A numpy array or a dictionary of numpy arrays or None, if input 39 | cannot be parsed. 40 | """ 41 | pass 42 | -------------------------------------------------------------------------------- /object_detection/core/minibatch_sampler.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Base minibatch sampler module. 17 | 18 | The job of the minibatch_sampler is to subsample a minibatch based on some 19 | criterion. 20 | 21 | The main function call is: 22 | subsample(indicator, batch_size, **params). 23 | Indicator is a 1d boolean tensor where True denotes which examples can be 24 | sampled. It returns a boolean indicator where True denotes an example has been 25 | sampled.. 26 | 27 | Subclasses should implement the Subsample function and can make use of the 28 | @staticmethod SubsampleIndicator. 29 | """ 30 | 31 | from abc import ABCMeta 32 | from abc import abstractmethod 33 | 34 | import tensorflow as tf 35 | 36 | from object_detection.utils import ops 37 | 38 | 39 | class MinibatchSampler(object): 40 | """Abstract base class for subsampling minibatches.""" 41 | __metaclass__ = ABCMeta 42 | 43 | def __init__(self): 44 | """Constructs a minibatch sampler.""" 45 | pass 46 | 47 | @abstractmethod 48 | def subsample(self, indicator, batch_size, **params): 49 | """Returns subsample of entries in indicator. 50 | 51 | Args: 52 | indicator: boolean tensor of shape [N] whose True entries can be sampled. 53 | batch_size: desired batch size. 54 | **params: additional keyword arguments for specific implementations of 55 | the MinibatchSampler. 56 | 57 | Returns: 58 | sample_indicator: boolean tensor of shape [N] whose True entries have been 59 | sampled. If sum(indicator) >= batch_size, sum(is_sampled) = batch_size 60 | """ 61 | pass 62 | 63 | @staticmethod 64 | def subsample_indicator(indicator, num_samples): 65 | """Subsample indicator vector. 66 | 67 | Given a boolean indicator vector with M elements set to `True`, the function 68 | assigns all but `num_samples` of these previously `True` elements to 69 | `False`. If `num_samples` is greater than M, the original indicator vector 70 | is returned. 71 | 72 | Args: 73 | indicator: a 1-dimensional boolean tensor indicating which elements 74 | are allowed to be sampled and which are not. 75 | num_samples: int32 scalar tensor 76 | 77 | Returns: 78 | a boolean tensor with the same shape as input (indicator) tensor 79 | """ 80 | indices = tf.where(indicator) 81 | indices = tf.random_shuffle(indices) 82 | indices = tf.reshape(indices, [-1]) 83 | 84 | num_samples = tf.minimum(tf.size(indices), num_samples) 85 | selected_indices = tf.slice(indices, [0], tf.reshape(num_samples, [1])) 86 | 87 | selected_indicator = ops.indices_to_dense_vector(selected_indices, 88 | tf.shape(indicator)[0]) 89 | 90 | return tf.equal(selected_indicator, 1) 91 | -------------------------------------------------------------------------------- /object_detection/core/minibatch_sampler_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for google3.research.vale.object_detection.minibatch_sampler.""" 17 | 18 | import numpy as np 19 | import tensorflow as tf 20 | 21 | from object_detection.core import minibatch_sampler 22 | 23 | 24 | class MinibatchSamplerTest(tf.test.TestCase): 25 | 26 | def test_subsample_indicator_when_more_true_elements_than_num_samples(self): 27 | np_indicator = [True, False, True, False, True, True, False] 28 | indicator = tf.constant(np_indicator) 29 | samples = minibatch_sampler.MinibatchSampler.subsample_indicator( 30 | indicator, 3) 31 | with self.test_session() as sess: 32 | samples_out = sess.run(samples) 33 | self.assertTrue(np.sum(samples_out), 3) 34 | self.assertAllEqual(samples_out, 35 | np.logical_and(samples_out, np_indicator)) 36 | 37 | def test_subsample_when_more_true_elements_than_num_samples_no_shape(self): 38 | np_indicator = [True, False, True, False, True, True, False] 39 | indicator = tf.placeholder(tf.bool) 40 | feed_dict = {indicator: np_indicator} 41 | 42 | samples = minibatch_sampler.MinibatchSampler.subsample_indicator( 43 | indicator, 3) 44 | with self.test_session() as sess: 45 | samples_out = sess.run(samples, feed_dict=feed_dict) 46 | self.assertTrue(np.sum(samples_out), 3) 47 | self.assertAllEqual(samples_out, 48 | np.logical_and(samples_out, np_indicator)) 49 | 50 | def test_subsample_indicator_when_less_true_elements_than_num_samples(self): 51 | np_indicator = [True, False, True, False, True, True, False] 52 | indicator = tf.constant(np_indicator) 53 | samples = minibatch_sampler.MinibatchSampler.subsample_indicator( 54 | indicator, 5) 55 | with self.test_session() as sess: 56 | samples_out = sess.run(samples) 57 | self.assertTrue(np.sum(samples_out), 4) 58 | self.assertAllEqual(samples_out, 59 | np.logical_and(samples_out, np_indicator)) 60 | 61 | def test_subsample_indicator_when_num_samples_is_zero(self): 62 | np_indicator = [True, False, True, False, True, True, False] 63 | indicator = tf.constant(np_indicator) 64 | samples_none = minibatch_sampler.MinibatchSampler.subsample_indicator( 65 | indicator, 0) 66 | with self.test_session() as sess: 67 | samples_none_out = sess.run(samples_none) 68 | self.assertAllEqual( 69 | np.zeros_like(samples_none_out, dtype=bool), 70 | samples_none_out) 71 | 72 | def test_subsample_indicator_when_indicator_all_false(self): 73 | indicator_empty = tf.zeros([0], dtype=tf.bool) 74 | samples_empty = minibatch_sampler.MinibatchSampler.subsample_indicator( 75 | indicator_empty, 4) 76 | with self.test_session() as sess: 77 | samples_empty_out = sess.run(samples_empty) 78 | self.assertEqual(0, samples_empty_out.size) 79 | 80 | 81 | if __name__ == '__main__': 82 | tf.test.main() 83 | -------------------------------------------------------------------------------- /object_detection/core/prefetcher.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Provides functions to prefetch tensors to feed into models.""" 17 | import tensorflow as tf 18 | 19 | 20 | def prefetch(tensor_dict, capacity): 21 | """Creates a prefetch queue for tensors. 22 | 23 | Creates a FIFO queue to asynchronously enqueue tensor_dicts and returns a 24 | dequeue op that evaluates to a tensor_dict. This function is useful in 25 | prefetching preprocessed tensors so that the data is readily available for 26 | consumers. 27 | 28 | Example input pipeline when you don't need batching: 29 | ---------------------------------------------------- 30 | key, string_tensor = slim.parallel_reader.parallel_read(...) 31 | tensor_dict = decoder.decode(string_tensor) 32 | tensor_dict = preprocessor.preprocess(tensor_dict, ...) 33 | prefetch_queue = prefetcher.prefetch(tensor_dict, capacity=20) 34 | tensor_dict = prefetch_queue.dequeue() 35 | outputs = Model(tensor_dict) 36 | ... 37 | ---------------------------------------------------- 38 | 39 | For input pipelines with batching, refer to core/batcher.py 40 | 41 | Args: 42 | tensor_dict: a dictionary of tensors to prefetch. 43 | capacity: the size of the prefetch queue. 44 | 45 | Returns: 46 | a FIFO prefetcher queue 47 | """ 48 | names = list(tensor_dict.keys()) 49 | dtypes = [t.dtype for t in tensor_dict.values()] 50 | shapes = [t.get_shape() for t in tensor_dict.values()] 51 | prefetch_queue = tf.PaddingFIFOQueue(capacity, dtypes=dtypes, 52 | shapes=shapes, 53 | names=names, 54 | name='prefetch_queue') 55 | enqueue_op = prefetch_queue.enqueue(tensor_dict) 56 | tf.train.queue_runner.add_queue_runner(tf.train.queue_runner.QueueRunner( 57 | prefetch_queue, [enqueue_op])) 58 | tf.summary.scalar('queue/%s/fraction_of_%d_full' % (prefetch_queue.name, 59 | capacity), 60 | tf.to_float(prefetch_queue.size()) * (1. / capacity)) 61 | return prefetch_queue 62 | -------------------------------------------------------------------------------- /object_detection/core/region_similarity_calculator_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for region_similarity_calculator.""" 17 | import tensorflow as tf 18 | 19 | from object_detection.core import box_list 20 | from object_detection.core import region_similarity_calculator 21 | 22 | 23 | class RegionSimilarityCalculatorTest(tf.test.TestCase): 24 | 25 | def test_get_correct_pairwise_similarity_based_on_iou(self): 26 | corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]]) 27 | corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0], 28 | [0.0, 0.0, 20.0, 20.0]]) 29 | exp_output = [[2.0 / 16.0, 0, 6.0 / 400.0], [1.0 / 16.0, 0.0, 5.0 / 400.0]] 30 | boxes1 = box_list.BoxList(corners1) 31 | boxes2 = box_list.BoxList(corners2) 32 | iou_similarity_calculator = region_similarity_calculator.IouSimilarity() 33 | iou_similarity = iou_similarity_calculator.compare(boxes1, boxes2) 34 | with self.test_session() as sess: 35 | iou_output = sess.run(iou_similarity) 36 | self.assertAllClose(iou_output, exp_output) 37 | 38 | def test_get_correct_pairwise_similarity_based_on_squared_distances(self): 39 | corners1 = tf.constant([[0.0, 0.0, 0.0, 0.0], 40 | [1.0, 1.0, 0.0, 2.0]]) 41 | corners2 = tf.constant([[3.0, 4.0, 1.0, 0.0], 42 | [-4.0, 0.0, 0.0, 3.0], 43 | [0.0, 0.0, 0.0, 0.0]]) 44 | exp_output = [[-26, -25, 0], [-18, -27, -6]] 45 | boxes1 = box_list.BoxList(corners1) 46 | boxes2 = box_list.BoxList(corners2) 47 | dist_similarity_calc = region_similarity_calculator.NegSqDistSimilarity() 48 | dist_similarity = dist_similarity_calc.compare(boxes1, boxes2) 49 | with self.test_session() as sess: 50 | dist_output = sess.run(dist_similarity) 51 | self.assertAllClose(dist_output, exp_output) 52 | 53 | def test_get_correct_pairwise_similarity_based_on_ioa(self): 54 | corners1 = tf.constant([[4.0, 3.0, 7.0, 5.0], [5.0, 6.0, 10.0, 7.0]]) 55 | corners2 = tf.constant([[3.0, 4.0, 6.0, 8.0], [14.0, 14.0, 15.0, 15.0], 56 | [0.0, 0.0, 20.0, 20.0]]) 57 | exp_output_1 = [[2.0 / 12.0, 0, 6.0 / 400.0], 58 | [1.0 / 12.0, 0.0, 5.0 / 400.0]] 59 | exp_output_2 = [[2.0 / 6.0, 1.0 / 5.0], 60 | [0, 0], 61 | [6.0 / 6.0, 5.0 / 5.0]] 62 | boxes1 = box_list.BoxList(corners1) 63 | boxes2 = box_list.BoxList(corners2) 64 | ioa_similarity_calculator = region_similarity_calculator.IoaSimilarity() 65 | ioa_similarity_1 = ioa_similarity_calculator.compare(boxes1, boxes2) 66 | ioa_similarity_2 = ioa_similarity_calculator.compare(boxes2, boxes1) 67 | with self.test_session() as sess: 68 | iou_output_1, iou_output_2 = sess.run( 69 | [ioa_similarity_1, ioa_similarity_2]) 70 | self.assertAllClose(iou_output_1, exp_output_1) 71 | self.assertAllClose(iou_output_2, exp_output_2) 72 | 73 | 74 | if __name__ == '__main__': 75 | tf.test.main() 76 | -------------------------------------------------------------------------------- /object_detection/data/kitti_label_map.pbtxt: -------------------------------------------------------------------------------- 1 | item { 2 | id: 1 3 | name: 'car' 4 | } 5 | 6 | item { 7 | id: 2 8 | name: 'pedestrian' 9 | } 10 | -------------------------------------------------------------------------------- /object_detection/data/pascal_label_map.pbtxt: -------------------------------------------------------------------------------- 1 | item { 2 | id: 1 3 | name: 'aeroplane' 4 | } 5 | 6 | item { 7 | id: 2 8 | name: 'bicycle' 9 | } 10 | 11 | item { 12 | id: 3 13 | name: 'bird' 14 | } 15 | 16 | item { 17 | id: 4 18 | name: 'boat' 19 | } 20 | 21 | item { 22 | id: 5 23 | name: 'bottle' 24 | } 25 | 26 | item { 27 | id: 6 28 | name: 'bus' 29 | } 30 | 31 | item { 32 | id: 7 33 | name: 'car' 34 | } 35 | 36 | item { 37 | id: 8 38 | name: 'cat' 39 | } 40 | 41 | item { 42 | id: 9 43 | name: 'chair' 44 | } 45 | 46 | item { 47 | id: 10 48 | name: 'cow' 49 | } 50 | 51 | item { 52 | id: 11 53 | name: 'diningtable' 54 | } 55 | 56 | item { 57 | id: 12 58 | name: 'dog' 59 | } 60 | 61 | item { 62 | id: 13 63 | name: 'horse' 64 | } 65 | 66 | item { 67 | id: 14 68 | name: 'motorbike' 69 | } 70 | 71 | item { 72 | id: 15 73 | name: 'person' 74 | } 75 | 76 | item { 77 | id: 16 78 | name: 'pottedplant' 79 | } 80 | 81 | item { 82 | id: 17 83 | name: 'sheep' 84 | } 85 | 86 | item { 87 | id: 18 88 | name: 'sofa' 89 | } 90 | 91 | item { 92 | id: 19 93 | name: 'train' 94 | } 95 | 96 | item { 97 | id: 20 98 | name: 'tvmonitor' 99 | } 100 | -------------------------------------------------------------------------------- /object_detection/data/pet_label_map.pbtxt: -------------------------------------------------------------------------------- 1 | item { 2 | id: 1 3 | name: 'Abyssinian' 4 | } 5 | 6 | item { 7 | id: 2 8 | name: 'american_bulldog' 9 | } 10 | 11 | item { 12 | id: 3 13 | name: 'american_pit_bull_terrier' 14 | } 15 | 16 | item { 17 | id: 4 18 | name: 'basset_hound' 19 | } 20 | 21 | item { 22 | id: 5 23 | name: 'beagle' 24 | } 25 | 26 | item { 27 | id: 6 28 | name: 'Bengal' 29 | } 30 | 31 | item { 32 | id: 7 33 | name: 'Birman' 34 | } 35 | 36 | item { 37 | id: 8 38 | name: 'Bombay' 39 | } 40 | 41 | item { 42 | id: 9 43 | name: 'boxer' 44 | } 45 | 46 | item { 47 | id: 10 48 | name: 'British_Shorthair' 49 | } 50 | 51 | item { 52 | id: 11 53 | name: 'chihuahua' 54 | } 55 | 56 | item { 57 | id: 12 58 | name: 'Egyptian_Mau' 59 | } 60 | 61 | item { 62 | id: 13 63 | name: 'english_cocker_spaniel' 64 | } 65 | 66 | item { 67 | id: 14 68 | name: 'english_setter' 69 | } 70 | 71 | item { 72 | id: 15 73 | name: 'german_shorthaired' 74 | } 75 | 76 | item { 77 | id: 16 78 | name: 'great_pyrenees' 79 | } 80 | 81 | item { 82 | id: 17 83 | name: 'havanese' 84 | } 85 | 86 | item { 87 | id: 18 88 | name: 'japanese_chin' 89 | } 90 | 91 | item { 92 | id: 19 93 | name: 'keeshond' 94 | } 95 | 96 | item { 97 | id: 20 98 | name: 'leonberger' 99 | } 100 | 101 | item { 102 | id: 21 103 | name: 'Maine_Coon' 104 | } 105 | 106 | item { 107 | id: 22 108 | name: 'miniature_pinscher' 109 | } 110 | 111 | item { 112 | id: 23 113 | name: 'newfoundland' 114 | } 115 | 116 | item { 117 | id: 24 118 | name: 'Persian' 119 | } 120 | 121 | item { 122 | id: 25 123 | name: 'pomeranian' 124 | } 125 | 126 | item { 127 | id: 26 128 | name: 'pug' 129 | } 130 | 131 | item { 132 | id: 27 133 | name: 'Ragdoll' 134 | } 135 | 136 | item { 137 | id: 28 138 | name: 'Russian_Blue' 139 | } 140 | 141 | item { 142 | id: 29 143 | name: 'saint_bernard' 144 | } 145 | 146 | item { 147 | id: 30 148 | name: 'samoyed' 149 | } 150 | 151 | item { 152 | id: 31 153 | name: 'scottish_terrier' 154 | } 155 | 156 | item { 157 | id: 32 158 | name: 'shiba_inu' 159 | } 160 | 161 | item { 162 | id: 33 163 | name: 'Siamese' 164 | } 165 | 166 | item { 167 | id: 34 168 | name: 'Sphynx' 169 | } 170 | 171 | item { 172 | id: 35 173 | name: 'staffordshire_bull_terrier' 174 | } 175 | 176 | item { 177 | id: 36 178 | name: 'wheaten_terrier' 179 | } 180 | 181 | item { 182 | id: 37 183 | name: 'yorkshire_terrier' 184 | } 185 | -------------------------------------------------------------------------------- /object_detection/data_decoders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/data_decoders/__init__.py -------------------------------------------------------------------------------- /object_detection/dataset_tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/dataset_tools/__init__.py -------------------------------------------------------------------------------- /object_detection/dataset_tools/download_and_preprocess_mscoco.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ============================================================================== 16 | 17 | # Script to download and preprocess the MSCOCO data set for detection. 18 | # 19 | # The outputs of this script are TFRecord files containing serialized 20 | # tf.Example protocol buffers. See create_coco_tf_record.py for details of how 21 | # the tf.Example protocol buffers are constructed and see 22 | # http://cocodataset.org/#overview for an overview of the dataset. 23 | # 24 | # usage: 25 | # bash object_detection/dataset_tools/download_and_preprocess_mscoco.sh \ 26 | # /tmp/mscoco 27 | set -e 28 | 29 | if [ -z "$1" ]; then 30 | echo "usage download_and_preprocess_mscoco.sh [data dir]" 31 | exit 32 | fi 33 | 34 | if [ "$(uname)" == "Darwin" ]; then 35 | UNZIP="tar -xf" 36 | else 37 | UNZIP="unzip -nq" 38 | fi 39 | 40 | # Create the output directories. 41 | OUTPUT_DIR="${1%/}" 42 | SCRATCH_DIR="${OUTPUT_DIR}/raw-data" 43 | mkdir -p "${OUTPUT_DIR}" 44 | mkdir -p "${SCRATCH_DIR}" 45 | CURRENT_DIR=$(pwd) 46 | 47 | # Helper function to download and unpack a .zip file. 48 | function download_and_unzip() { 49 | local BASE_URL=${1} 50 | local FILENAME=${2} 51 | 52 | if [ ! -f ${FILENAME} ]; then 53 | echo "Downloading ${FILENAME} to $(pwd)" 54 | wget -nd -c "${BASE_URL}/${FILENAME}" 55 | else 56 | echo "Skipping download of ${FILENAME}" 57 | fi 58 | echo "Unzipping ${FILENAME}" 59 | ${UNZIP} ${FILENAME} 60 | } 61 | 62 | cd ${SCRATCH_DIR} 63 | 64 | # Download the images. 65 | BASE_IMAGE_URL="http://images.cocodataset.org/zips" 66 | 67 | TRAIN_IMAGE_FILE="train2017.zip" 68 | download_and_unzip ${BASE_IMAGE_URL} ${TRAIN_IMAGE_FILE} 69 | TRAIN_IMAGE_DIR="${SCRATCH_DIR}/train2017" 70 | 71 | VAL_IMAGE_FILE="val2017.zip" 72 | download_and_unzip ${BASE_IMAGE_URL} ${VAL_IMAGE_FILE} 73 | VAL_IMAGE_DIR="${SCRATCH_DIR}/val2017" 74 | 75 | TEST_IMAGE_FILE="test2017.zip" 76 | download_and_unzip ${BASE_IMAGE_URL} ${TEST_IMAGE_FILE} 77 | TEST_IMAGE_DIR="${SCRATCH_DIR}/test2017" 78 | 79 | # Download the annotations. 80 | BASE_INSTANCES_URL="http://images.cocodataset.org/annotations" 81 | INSTANCES_FILE="annotations_trainval2017.zip" 82 | download_and_unzip ${BASE_INSTANCES_URL} ${INSTANCES_FILE} 83 | 84 | TRAIN_ANNOTATIONS_FILE="${SCRATCH_DIR}/annotations/instances_train2017.json" 85 | VAL_ANNOTATIONS_FILE="${SCRATCH_DIR}/annotations/instances_val2017.json" 86 | 87 | # Download the test image info. 88 | BASE_IMAGE_INFO_URL="http://images.cocodataset.org/annotations" 89 | IMAGE_INFO_FILE="image_info_test2017.zip" 90 | download_and_unzip ${BASE_IMAGE_INFO_URL} ${IMAGE_INFO_FILE} 91 | 92 | TESTDEV_ANNOTATIONS_FILE="${SCRATCH_DIR}/annotations/image_info_test-dev2017.json" 93 | 94 | # Build TFRecords of the image data. 95 | cd "${CURRENT_DIR}" 96 | python object_detection/dataset_tools/create_coco_tf_record.py \ 97 | --logtostderr \ 98 | --include_masks \ 99 | --train_image_dir="${TRAIN_IMAGE_DIR}" \ 100 | --val_image_dir="${VAL_IMAGE_DIR}" \ 101 | --test_image_dir="${TEST_IMAGE_DIR}" \ 102 | --train_annotations_file="${TRAIN_ANNOTATIONS_FILE}" \ 103 | --val_annotations_file="${VAL_ANNOTATIONS_FILE}" \ 104 | --testdev_annotations_file="${TESTDEV_ANNOTATIONS_FILE}" \ 105 | --output_dir="${OUTPUT_DIR}" 106 | 107 | -------------------------------------------------------------------------------- /object_detection/g3doc/exporting_models.md: -------------------------------------------------------------------------------- 1 | # Exporting a trained model for inference 2 | 3 | After your model has been trained, you should export it to a Tensorflow 4 | graph proto. A checkpoint will typically consist of three files: 5 | 6 | * model.ckpt-${CHECKPOINT_NUMBER}.data-00000-of-00001, 7 | * model.ckpt-${CHECKPOINT_NUMBER}.index 8 | * model.ckpt-${CHECKPOINT_NUMBER}.meta 9 | 10 | After you've identified a candidate checkpoint to export, run the following 11 | command from tensorflow/models/research: 12 | 13 | ``` bash 14 | # From tensorflow/models/research/ 15 | python object_detection/export_inference_graph.py \ 16 | --input_type image_tensor \ 17 | --pipeline_config_path ${PIPELINE_CONFIG_PATH} \ 18 | --trained_checkpoint_prefix ${TRAIN_PATH} \ 19 | --output_directory output_inference_graph.pb 20 | ``` 21 | 22 | Afterwards, you should see a graph named output_inference_graph.pb. 23 | -------------------------------------------------------------------------------- /object_detection/g3doc/faq.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | ## Q: AttributeError: 'module' object has no attribute 'BackupHandler' 4 | A: This BackupHandler (tf.contrib.slim.tfexample_decoder.BackupHandler) was 5 | introduced in tensorflow 1.5.0 so runing with earlier versions may cause this 6 | issue. It now has been replaced by 7 | object_detection.data_decoders.tf_example_decoder.BackupHandler. Whoever sees 8 | this issue should be able to resolve it by syncing your fork to HEAD. 9 | Same for LookupTensor. 10 | 11 | ## Q: AttributeError: 'module' object has no attribute 'LookupTensor' 12 | A: Similar to BackupHandler, syncing your fork to HEAD should make it work. 13 | 14 | ## Q: Why can't I get the inference time as reported in model zoo? 15 | A: The inference time reported in model zoo is mean time of testing hundreds of 16 | images with an internal machine. As mentioned in 17 | [Tensorflow detection model zoo](detection_model_zoo.md), this speed depends 18 | highly on one's specific hardware configuration and should be treated more as 19 | relative timing. 20 | -------------------------------------------------------------------------------- /object_detection/g3doc/img/dogs_detections_output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/dogs_detections_output.jpg -------------------------------------------------------------------------------- /object_detection/g3doc/img/example_cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/example_cat.jpg -------------------------------------------------------------------------------- /object_detection/g3doc/img/groupof_case_eval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/groupof_case_eval.png -------------------------------------------------------------------------------- /object_detection/g3doc/img/kites_detections_output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/kites_detections_output.jpg -------------------------------------------------------------------------------- /object_detection/g3doc/img/kites_with_segment_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/kites_with_segment_overlay.png -------------------------------------------------------------------------------- /object_detection/g3doc/img/nongroupof_case_eval.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/nongroupof_case_eval.png -------------------------------------------------------------------------------- /object_detection/g3doc/img/oid_bus_72e19c28aac34ed8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/oid_bus_72e19c28aac34ed8.jpg -------------------------------------------------------------------------------- /object_detection/g3doc/img/oid_monkey_3b4168c89cecbc5b.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/oid_monkey_3b4168c89cecbc5b.jpg -------------------------------------------------------------------------------- /object_detection/g3doc/img/oxford_pet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/oxford_pet.png -------------------------------------------------------------------------------- /object_detection/g3doc/img/tensorboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/tensorboard.png -------------------------------------------------------------------------------- /object_detection/g3doc/img/tensorboard2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/tensorboard2.png -------------------------------------------------------------------------------- /object_detection/g3doc/img/tf-od-api-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/g3doc/img/tf-od-api-logo.png -------------------------------------------------------------------------------- /object_detection/g3doc/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Dependencies 4 | 5 | Tensorflow Object Detection API depends on the following libraries: 6 | 7 | * Protobuf 2.6 8 | * Python-tk 9 | * Pillow 1.0 10 | * lxml 11 | * tf Slim (which is included in the "tensorflow/models/research/" checkout) 12 | * Jupyter notebook 13 | * Matplotlib 14 | * Tensorflow 15 | * Cython 16 | * cocoapi 17 | 18 | For detailed steps to install Tensorflow, follow the [Tensorflow installation 19 | instructions](https://www.tensorflow.org/install/). A typical user can install 20 | Tensorflow using one of the following commands: 21 | 22 | ``` bash 23 | # For CPU 24 | pip install tensorflow 25 | # For GPU 26 | pip install tensorflow-gpu 27 | ``` 28 | 29 | The remaining libraries can be installed on Ubuntu 16.04 using via apt-get: 30 | 31 | ``` bash 32 | sudo apt-get install protobuf-compiler python-pil python-lxml python-tk 33 | sudo pip install Cython 34 | sudo pip install jupyter 35 | sudo pip install matplotlib 36 | ``` 37 | 38 | Alternatively, users can install dependencies using pip: 39 | 40 | ``` bash 41 | sudo pip install Cython 42 | sudo pip install pillow 43 | sudo pip install lxml 44 | sudo pip install jupyter 45 | sudo pip install matplotlib 46 | ``` 47 | 48 | ## COCO API installation 49 | 50 | Download the 51 | cocoapi and 52 | copy the pycocotools subfolder to the tensorflow/models/research directory if 53 | you are interested in using COCO evaluation metrics. The default metrics are 54 | based on those used in Pascal VOC evaluation. To use the COCO object detection 55 | metrics add `metrics_set: "coco_detection_metrics"` to the `eval_config` message 56 | in the config file. To use the COCO instance segmentation metrics add 57 | `metrics_set: "coco_mask_metrics"` to the `eval_config` message in the config 58 | file. 59 | 60 | ```bash 61 | git clone https://github.com/cocodataset/cocoapi.git 62 | cd cocoapi/PythonAPI 63 | make 64 | cp -r pycocotools /models/research/ 65 | ``` 66 | 67 | ## Protobuf Compilation 68 | 69 | The Tensorflow Object Detection API uses Protobufs to configure model and 70 | training parameters. Before the framework can be used, the Protobuf libraries 71 | must be compiled. This should be done by running the following command from 72 | the tensorflow/models/research/ directory: 73 | 74 | 75 | ``` bash 76 | # From tensorflow/models/research/ 77 | protoc object_detection/protos/*.proto --python_out=. 78 | ``` 79 | 80 | ## Add Libraries to PYTHONPATH 81 | 82 | When running locally, the tensorflow/models/research/ and slim directories 83 | should be appended to PYTHONPATH. This can be done by running the following from 84 | tensorflow/models/research/: 85 | 86 | 87 | ``` bash 88 | # From tensorflow/models/research/ 89 | export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim 90 | ``` 91 | 92 | Note: This command needs to run from every new terminal you start. If you wish 93 | to avoid running this manually, you can add it as a new line to the end of your 94 | ~/.bashrc file. 95 | 96 | # Testing the Installation 97 | 98 | You can test that you have correctly installed the Tensorflow Object Detection\ 99 | API by running the following command: 100 | 101 | ```bash 102 | python object_detection/builders/model_builder_test.py 103 | ``` 104 | -------------------------------------------------------------------------------- /object_detection/g3doc/preparing_inputs.md: -------------------------------------------------------------------------------- 1 | # Preparing Inputs 2 | 3 | Tensorflow Object Detection API reads data using the TFRecord file format. Two 4 | sample scripts (`create_pascal_tf_record.py` and `create_pet_tf_record.py`) are 5 | provided to convert from the PASCAL VOC dataset and Oxford-IIIT Pet dataset to 6 | TFRecords. 7 | 8 | ## Generating the PASCAL VOC TFRecord files. 9 | 10 | The raw 2012 PASCAL VOC data set is located 11 | [here](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar). 12 | To download, extract and convert it to TFRecords, run the following commands 13 | below: 14 | 15 | ```bash 16 | # From tensorflow/models/research/ 17 | wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar 18 | tar -xvf VOCtrainval_11-May-2012.tar 19 | python object_detection/dataset_tools/create_pascal_tf_record.py \ 20 | --label_map_path=object_detection/data/pascal_label_map.pbtxt \ 21 | --data_dir=VOCdevkit --year=VOC2012 --set=train \ 22 | --output_path=pascal_train.record 23 | python object_detection/dataset_tools/create_pascal_tf_record.py \ 24 | --label_map_path=object_detection/data/pascal_label_map.pbtxt \ 25 | --data_dir=VOCdevkit --year=VOC2012 --set=val \ 26 | --output_path=pascal_val.record 27 | ``` 28 | 29 | You should end up with two TFRecord files named `pascal_train.record` and 30 | `pascal_val.record` in the `tensorflow/models/research/` directory. 31 | 32 | The label map for the PASCAL VOC data set can be found at 33 | `object_detection/data/pascal_label_map.pbtxt`. 34 | 35 | ## Generating the Oxford-IIIT Pet TFRecord files. 36 | 37 | The Oxford-IIIT Pet data set is located 38 | [here](http://www.robots.ox.ac.uk/~vgg/data/pets/). To download, extract and 39 | convert it to TFRecrods, run the following commands below: 40 | 41 | ```bash 42 | # From tensorflow/models/research/ 43 | wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz 44 | wget http://www.robots.ox.ac.uk/~vgg/data/pets/data/annotations.tar.gz 45 | tar -xvf annotations.tar.gz 46 | tar -xvf images.tar.gz 47 | python object_detection/dataset_tools/create_pet_tf_record.py \ 48 | --label_map_path=object_detection/data/pet_label_map.pbtxt \ 49 | --data_dir=`pwd` \ 50 | --output_dir=`pwd` 51 | ``` 52 | 53 | You should end up with two TFRecord files named `pet_train.record` and 54 | `pet_val.record` in the `tensorflow/models/research/` directory. 55 | 56 | The label map for the Pet dataset can be found at 57 | `object_detection/data/pet_label_map.pbtxt`. 58 | -------------------------------------------------------------------------------- /object_detection/g3doc/running_locally.md: -------------------------------------------------------------------------------- 1 | # Running Locally 2 | 3 | This page walks through the steps required to train an object detection model 4 | on a local machine. It assumes the reader has completed the 5 | following prerequisites: 6 | 7 | 1. The Tensorflow Object Detection API has been installed as documented in the 8 | [installation instructions](installation.md). This includes installing library 9 | dependencies, compiling the configuration protobufs and setting up the Python 10 | environment. 11 | 2. A valid data set has been created. See [this page](preparing_inputs.md) for 12 | instructions on how to generate a dataset for the PASCAL VOC challenge or the 13 | Oxford-IIIT Pet dataset. 14 | 3. A Object Detection pipeline configuration has been written. See 15 | [this page](configuring_jobs.md) for details on how to write a pipeline configuration. 16 | 17 | ## Recommended Directory Structure for Training and Evaluation 18 | 19 | ``` 20 | +data 21 | -label_map file 22 | -train TFRecord file 23 | -eval TFRecord file 24 | +models 25 | + model 26 | -pipeline config file 27 | +train 28 | +eval 29 | ``` 30 | 31 | ## Running the Training Job 32 | 33 | A local training job can be run with the following command: 34 | 35 | ```bash 36 | # From the tensorflow/models/research/ directory 37 | python object_detection/train.py \ 38 | --logtostderr \ 39 | --pipeline_config_path=${PATH_TO_YOUR_PIPELINE_CONFIG} \ 40 | --train_dir=${PATH_TO_TRAIN_DIR} 41 | ``` 42 | 43 | where `${PATH_TO_YOUR_PIPELINE_CONFIG}` points to the pipeline config and 44 | `${PATH_TO_TRAIN_DIR}` points to the directory in which training checkpoints 45 | and events will be written to. By default, the training job will 46 | run indefinitely until the user kills it. 47 | 48 | ## Running the Evaluation Job 49 | 50 | Evaluation is run as a separate job. The eval job will periodically poll the 51 | train directory for new checkpoints and evaluate them on a test dataset. The 52 | job can be run using the following command: 53 | 54 | ```bash 55 | # From the tensorflow/models/research/ directory 56 | python object_detection/eval.py \ 57 | --logtostderr \ 58 | --pipeline_config_path=${PATH_TO_YOUR_PIPELINE_CONFIG} \ 59 | --checkpoint_dir=${PATH_TO_TRAIN_DIR} \ 60 | --eval_dir=${PATH_TO_EVAL_DIR} 61 | ``` 62 | 63 | where `${PATH_TO_YOUR_PIPELINE_CONFIG}` points to the pipeline config, 64 | `${PATH_TO_TRAIN_DIR}` points to the directory in which training checkpoints 65 | were saved (same as the training job) and `${PATH_TO_EVAL_DIR}` points to the 66 | directory in which evaluation events will be saved. As with the training job, 67 | the eval job run until terminated by default. 68 | 69 | ## Running Tensorboard 70 | 71 | Progress for training and eval jobs can be inspected using Tensorboard. If 72 | using the recommended directory structure, Tensorboard can be run using the 73 | following command: 74 | 75 | ```bash 76 | tensorboard --logdir=${PATH_TO_MODEL_DIRECTORY} 77 | ``` 78 | 79 | where `${PATH_TO_MODEL_DIRECTORY}` points to the directory that contains the 80 | train and eval directories. Please note it may take Tensorboard a couple minutes 81 | to populate with data. 82 | -------------------------------------------------------------------------------- /object_detection/g3doc/running_notebook.md: -------------------------------------------------------------------------------- 1 | # Quick Start: Jupyter notebook for off-the-shelf inference 2 | 3 | If you'd like to hit the ground running and run detection on a few example 4 | images right out of the box, we recommend trying out the Jupyter notebook demo. 5 | To run the Jupyter notebook, run the following command from 6 | `tensorflow/models/research/object_detection`: 7 | 8 | ``` 9 | # From tensorflow/models/research/object_detection 10 | jupyter notebook 11 | ``` 12 | 13 | The notebook should open in your favorite web browser. Click the 14 | [`object_detection_tutorial.ipynb`](../object_detection_tutorial.ipynb) link to 15 | open the demo. 16 | -------------------------------------------------------------------------------- /object_detection/inference/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/inference/__init__.py -------------------------------------------------------------------------------- /object_detection/matchers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/matchers/__init__.py -------------------------------------------------------------------------------- /object_detection/matchers/bipartite_matcher.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Bipartite matcher implementation.""" 17 | 18 | import tensorflow as tf 19 | 20 | from tensorflow.contrib.image.python.ops import image_ops 21 | from object_detection.core import matcher 22 | 23 | 24 | class GreedyBipartiteMatcher(matcher.Matcher): 25 | """Wraps a Tensorflow greedy bipartite matcher.""" 26 | 27 | def __init__(self, use_matmul_gather=False): 28 | """Constructs a Matcher. 29 | 30 | Args: 31 | use_matmul_gather: Force constructed match objects to use matrix 32 | multiplication based gather instead of standard tf.gather. 33 | (Default: False). 34 | """ 35 | super(GreedyBipartiteMatcher, self).__init__( 36 | use_matmul_gather=use_matmul_gather) 37 | 38 | def _match(self, similarity_matrix, num_valid_rows=-1): 39 | """Bipartite matches a collection rows and columns. A greedy bi-partite. 40 | 41 | TODO(rathodv): Add num_valid_columns options to match only that many columns 42 | with all the rows. 43 | 44 | Args: 45 | similarity_matrix: Float tensor of shape [N, M] with pairwise similarity 46 | where higher values mean more similar. 47 | num_valid_rows: A scalar or a 1-D tensor with one element describing the 48 | number of valid rows of similarity_matrix to consider for the bipartite 49 | matching. If set to be negative, then all rows from similarity_matrix 50 | are used. 51 | 52 | Returns: 53 | match_results: int32 tensor of shape [M] with match_results[i]=-1 54 | meaning that column i is not matched and otherwise that it is matched to 55 | row match_results[i]. 56 | """ 57 | # Convert similarity matrix to distance matrix as tf.image.bipartite tries 58 | # to find minimum distance matches. 59 | distance_matrix = -1 * similarity_matrix 60 | _, match_results = image_ops.bipartite_match( 61 | distance_matrix, num_valid_rows) 62 | match_results = tf.reshape(match_results, [-1]) 63 | match_results = tf.cast(match_results, tf.int32) 64 | return match_results 65 | -------------------------------------------------------------------------------- /object_detection/matchers/bipartite_matcher_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for object_detection.core.bipartite_matcher.""" 17 | 18 | import tensorflow as tf 19 | 20 | from object_detection.matchers import bipartite_matcher 21 | 22 | 23 | class GreedyBipartiteMatcherTest(tf.test.TestCase): 24 | 25 | def test_get_expected_matches_when_all_rows_are_valid(self): 26 | similarity_matrix = tf.constant([[0.50, 0.1, 0.8], [0.15, 0.2, 0.3]]) 27 | num_valid_rows = 2 28 | expected_match_results = [-1, 1, 0] 29 | 30 | matcher = bipartite_matcher.GreedyBipartiteMatcher() 31 | match = matcher.match(similarity_matrix, num_valid_rows=num_valid_rows) 32 | with self.test_session() as sess: 33 | match_results_out = sess.run(match._match_results) 34 | self.assertAllEqual(match_results_out, expected_match_results) 35 | 36 | def test_get_expected_matches_with_valid_rows_set_to_minus_one(self): 37 | similarity_matrix = tf.constant([[0.50, 0.1, 0.8], [0.15, 0.2, 0.3]]) 38 | num_valid_rows = -1 39 | expected_match_results = [-1, 1, 0] 40 | 41 | matcher = bipartite_matcher.GreedyBipartiteMatcher() 42 | match = matcher.match(similarity_matrix, num_valid_rows=num_valid_rows) 43 | with self.test_session() as sess: 44 | match_results_out = sess.run(match._match_results) 45 | self.assertAllEqual(match_results_out, expected_match_results) 46 | 47 | def test_get_no_matches_with_zero_valid_rows(self): 48 | similarity_matrix = tf.constant([[0.50, 0.1, 0.8], [0.15, 0.2, 0.3]]) 49 | num_valid_rows = 0 50 | expected_match_results = [-1, -1, -1] 51 | 52 | matcher = bipartite_matcher.GreedyBipartiteMatcher() 53 | match = matcher.match(similarity_matrix, num_valid_rows=num_valid_rows) 54 | with self.test_session() as sess: 55 | match_results_out = sess.run(match._match_results) 56 | self.assertAllEqual(match_results_out, expected_match_results) 57 | 58 | def test_get_expected_matches_with_only_one_valid_row(self): 59 | similarity_matrix = tf.constant([[0.50, 0.1, 0.8], [0.15, 0.2, 0.3]]) 60 | num_valid_rows = 1 61 | expected_match_results = [-1, -1, 0] 62 | 63 | matcher = bipartite_matcher.GreedyBipartiteMatcher() 64 | match = matcher.match(similarity_matrix, num_valid_rows=num_valid_rows) 65 | with self.test_session() as sess: 66 | match_results_out = sess.run(match._match_results) 67 | self.assertAllEqual(match_results_out, expected_match_results) 68 | 69 | 70 | if __name__ == '__main__': 71 | tf.test.main() 72 | -------------------------------------------------------------------------------- /object_detection/meta_architectures/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/meta_architectures/__init__.py -------------------------------------------------------------------------------- /object_detection/meta_architectures/rfcn_meta_arch_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | 16 | """Tests for object_detection.meta_architectures.rfcn_meta_arch.""" 17 | 18 | import tensorflow as tf 19 | 20 | from object_detection.meta_architectures import faster_rcnn_meta_arch_test_lib 21 | from object_detection.meta_architectures import rfcn_meta_arch 22 | 23 | 24 | class RFCNMetaArchTest( 25 | faster_rcnn_meta_arch_test_lib.FasterRCNNMetaArchTestBase): 26 | 27 | def _get_second_stage_box_predictor_text_proto(self): 28 | box_predictor_text_proto = """ 29 | rfcn_box_predictor { 30 | conv_hyperparams { 31 | op: CONV 32 | activation: NONE 33 | regularizer { 34 | l2_regularizer { 35 | weight: 0.0005 36 | } 37 | } 38 | initializer { 39 | variance_scaling_initializer { 40 | factor: 1.0 41 | uniform: true 42 | mode: FAN_AVG 43 | } 44 | } 45 | } 46 | } 47 | """ 48 | return box_predictor_text_proto 49 | 50 | def _get_model(self, box_predictor, **common_kwargs): 51 | return rfcn_meta_arch.RFCNMetaArch( 52 | second_stage_rfcn_box_predictor=box_predictor, **common_kwargs) 53 | 54 | def _get_box_classifier_features_shape(self, 55 | image_size, 56 | batch_size, 57 | max_num_proposals, 58 | initial_crop_size, 59 | maxpool_stride, 60 | num_features): 61 | return (batch_size, image_size, image_size, num_features) 62 | 63 | 64 | if __name__ == '__main__': 65 | tf.test.main() 66 | -------------------------------------------------------------------------------- /object_detection/metrics/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/metrics/__init__.py -------------------------------------------------------------------------------- /object_detection/metrics/offline_eval_map_corloc_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | """Tests for utilities in offline_eval_map_corloc binary.""" 16 | 17 | import tensorflow as tf 18 | 19 | from object_detection.metrics import offline_eval_map_corloc as offline_eval 20 | 21 | 22 | class OfflineEvalMapCorlocTest(tf.test.TestCase): 23 | 24 | def test_generateShardedFilenames(self): 25 | test_filename = '/path/to/file' 26 | result = offline_eval._generate_sharded_filenames(test_filename) 27 | self.assertEqual(result, [test_filename]) 28 | 29 | test_filename = '/path/to/file-00000-of-00050' 30 | result = offline_eval._generate_sharded_filenames(test_filename) 31 | self.assertEqual(result, [test_filename]) 32 | 33 | result = offline_eval._generate_sharded_filenames('/path/to/@3.record') 34 | self.assertEqual(result, [ 35 | '/path/to/-00000-of-00003.record', '/path/to/-00001-of-00003.record', 36 | '/path/to/-00002-of-00003.record' 37 | ]) 38 | 39 | result = offline_eval._generate_sharded_filenames('/path/to/abc@3') 40 | self.assertEqual(result, [ 41 | '/path/to/abc-00000-of-00003', '/path/to/abc-00001-of-00003', 42 | '/path/to/abc-00002-of-00003' 43 | ]) 44 | 45 | result = offline_eval._generate_sharded_filenames('/path/to/@1') 46 | self.assertEqual(result, ['/path/to/-00000-of-00001']) 47 | 48 | def test_generateFilenames(self): 49 | test_filenames = ['/path/to/file', '/path/to/@3.record'] 50 | result = offline_eval._generate_filenames(test_filenames) 51 | self.assertEqual(result, [ 52 | '/path/to/file', '/path/to/-00000-of-00003.record', 53 | '/path/to/-00001-of-00003.record', '/path/to/-00002-of-00003.record' 54 | ]) 55 | 56 | 57 | if __name__ == '__main__': 58 | tf.test.main() 59 | -------------------------------------------------------------------------------- /object_detection/model_hparams.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | """Hyperparameters for the object detection model in TF.learn. 16 | 17 | This file consolidates and documents the hyperparameters used by the model. 18 | """ 19 | 20 | from __future__ import absolute_import 21 | from __future__ import division 22 | from __future__ import print_function 23 | 24 | import tensorflow as tf 25 | 26 | 27 | def create_hparams(hparams_overrides=None): 28 | """Returns hyperparameters, including any flag value overrides. 29 | 30 | Args: 31 | hparams_overrides: Optional hparams overrides, represented as a 32 | string containing comma-separated hparam_name=value pairs. 33 | 34 | Returns: 35 | The hyperparameters as a tf.HParams object. 36 | """ 37 | hparams = tf.contrib.training.HParams( 38 | # Whether a fine tuning checkpoint (provided in the pipeline config) 39 | # should be loaded for training. 40 | load_pretrained=True) 41 | # Override any of the preceding hyperparameter values. 42 | if hparams_overrides: 43 | hparams = hparams.parse(hparams_overrides) 44 | return hparams 45 | -------------------------------------------------------------------------------- /object_detection/model_main.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | """Binary to run train and evaluation on object detection model.""" 16 | 17 | from __future__ import absolute_import 18 | from __future__ import division 19 | from __future__ import print_function 20 | 21 | from absl import flags 22 | 23 | import tensorflow as tf 24 | 25 | from object_detection import model_hparams 26 | from object_detection import model_lib 27 | 28 | flags.DEFINE_string( 29 | 'model_dir', None, 'Path to output model directory ' 30 | 'where event and checkpoint files will be written.') 31 | flags.DEFINE_string('pipeline_config_path', None, 'Path to pipeline config ' 32 | 'file.') 33 | flags.DEFINE_integer('num_train_steps', None, 'Number of train steps.') 34 | flags.DEFINE_integer('num_eval_steps', None, 'Number of train steps.') 35 | flags.DEFINE_string( 36 | 'hparams_overrides', None, 'Hyperparameter overrides, ' 37 | 'represented as a string containing comma-separated ' 38 | 'hparam_name=value pairs.') 39 | 40 | FLAGS = flags.FLAGS 41 | 42 | 43 | def main(unused_argv): 44 | flags.mark_flag_as_required('model_dir') 45 | flags.mark_flag_as_required('pipeline_config_path') 46 | config = tf.estimator.RunConfig(model_dir=FLAGS.model_dir) 47 | 48 | train_and_eval_dict = model_lib.create_estimator_and_inputs( 49 | run_config=config, 50 | hparams=model_hparams.create_hparams(FLAGS.hparams_overrides), 51 | pipeline_config_path=FLAGS.pipeline_config_path, 52 | train_steps=FLAGS.num_train_steps, 53 | eval_steps=FLAGS.num_eval_steps) 54 | estimator = train_and_eval_dict['estimator'] 55 | train_input_fn = train_and_eval_dict['train_input_fn'] 56 | eval_input_fn = train_and_eval_dict['eval_input_fn'] 57 | eval_on_train_input_fn = train_and_eval_dict['eval_on_train_input_fn'] 58 | predict_input_fn = train_and_eval_dict['predict_input_fn'] 59 | train_steps = train_and_eval_dict['train_steps'] 60 | eval_steps = train_and_eval_dict['eval_steps'] 61 | 62 | train_spec, eval_specs = model_lib.create_train_and_eval_specs( 63 | train_input_fn, 64 | eval_input_fn, 65 | eval_on_train_input_fn, 66 | predict_input_fn, 67 | train_steps, 68 | eval_steps, 69 | eval_on_train_data=False) 70 | 71 | # Currently only a single Eval Spec is allowed. 72 | tf.estimator.train_and_evaluate(estimator, train_spec, eval_specs[0]) 73 | 74 | 75 | if __name__ == '__main__': 76 | tf.app.run() 77 | -------------------------------------------------------------------------------- /object_detection/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/models/__init__.py -------------------------------------------------------------------------------- /object_detection/models/ssd_resnet_v1_fpn_feature_extractor_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | """Tests for ssd resnet v1 FPN feature extractors.""" 16 | import tensorflow as tf 17 | 18 | from object_detection.models import ssd_resnet_v1_fpn_feature_extractor 19 | from object_detection.models import ssd_resnet_v1_fpn_feature_extractor_testbase 20 | 21 | 22 | class SSDResnet50V1FeatureExtractorTest( 23 | ssd_resnet_v1_fpn_feature_extractor_testbase. 24 | SSDResnetFPNFeatureExtractorTestBase): 25 | """SSDResnet50v1Fpn feature extractor test.""" 26 | 27 | def _create_feature_extractor(self, depth_multiplier, pad_to_multiple, 28 | use_explicit_padding=False): 29 | min_depth = 32 30 | is_training = True 31 | return ssd_resnet_v1_fpn_feature_extractor.SSDResnet50V1FpnFeatureExtractor( 32 | is_training, depth_multiplier, min_depth, pad_to_multiple, 33 | self.conv_hyperparams_fn, use_explicit_padding=use_explicit_padding) 34 | 35 | def _resnet_scope_name(self): 36 | return 'resnet_v1_50' 37 | 38 | 39 | class SSDResnet101V1FeatureExtractorTest( 40 | ssd_resnet_v1_fpn_feature_extractor_testbase. 41 | SSDResnetFPNFeatureExtractorTestBase): 42 | """SSDResnet101v1Fpn feature extractor test.""" 43 | 44 | def _create_feature_extractor(self, depth_multiplier, pad_to_multiple, 45 | use_explicit_padding=False): 46 | min_depth = 32 47 | is_training = True 48 | return ( 49 | ssd_resnet_v1_fpn_feature_extractor.SSDResnet101V1FpnFeatureExtractor( 50 | is_training, 51 | depth_multiplier, 52 | min_depth, 53 | pad_to_multiple, 54 | self.conv_hyperparams_fn, 55 | use_explicit_padding=use_explicit_padding)) 56 | 57 | def _resnet_scope_name(self): 58 | return 'resnet_v1_101' 59 | 60 | 61 | class SSDResnet152V1FeatureExtractorTest( 62 | ssd_resnet_v1_fpn_feature_extractor_testbase. 63 | SSDResnetFPNFeatureExtractorTestBase): 64 | """SSDResnet152v1Fpn feature extractor test.""" 65 | 66 | def _create_feature_extractor(self, depth_multiplier, pad_to_multiple, 67 | use_explicit_padding=False): 68 | min_depth = 32 69 | is_training = True 70 | return ( 71 | ssd_resnet_v1_fpn_feature_extractor.SSDResnet152V1FpnFeatureExtractor( 72 | is_training, 73 | depth_multiplier, 74 | min_depth, 75 | pad_to_multiple, 76 | self.conv_hyperparams_fn, 77 | use_explicit_padding=use_explicit_padding)) 78 | 79 | def _resnet_scope_name(self): 80 | return 'resnet_v1_152' 81 | 82 | 83 | if __name__ == '__main__': 84 | tf.test.main() 85 | -------------------------------------------------------------------------------- /object_detection/protos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/5taku/tensorflow_object_detection_helper_tool/f82a4159d58a7a051cb36bac2b302bb93f3b19bc/object_detection/protos/__init__.py -------------------------------------------------------------------------------- /object_detection/protos/anchor_generator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | import "object_detection/protos/grid_anchor_generator.proto"; 6 | import "object_detection/protos/ssd_anchor_generator.proto"; 7 | import "object_detection/protos/multiscale_anchor_generator.proto"; 8 | 9 | // Configuration proto for the anchor generator to use in the object detection 10 | // pipeline. See core/anchor_generator.py for details. 11 | message AnchorGenerator { 12 | oneof anchor_generator_oneof { 13 | GridAnchorGenerator grid_anchor_generator = 1; 14 | SsdAnchorGenerator ssd_anchor_generator = 2; 15 | MultiscaleAnchorGenerator multiscale_anchor_generator = 3; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /object_detection/protos/argmax_matcher.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for ArgMaxMatcher. See 6 | // matchers/argmax_matcher.py for details. 7 | message ArgMaxMatcher { 8 | // Threshold for positive matches. 9 | optional float matched_threshold = 1 [default = 0.5]; 10 | 11 | // Threshold for negative matches. 12 | optional float unmatched_threshold = 2 [default = 0.5]; 13 | 14 | // Whether to construct ArgMaxMatcher without thresholds. 15 | optional bool ignore_thresholds = 3 [default = false]; 16 | 17 | // If True then negative matches are the ones below the unmatched_threshold, 18 | // whereas ignored matches are in between the matched and umatched 19 | // threshold. If False, then negative matches are in between the matched 20 | // and unmatched threshold, and everything lower than unmatched is ignored. 21 | optional bool negatives_lower_than_unmatched = 4 [default = true]; 22 | 23 | // Whether to ensure each row is matched to at least one column. 24 | optional bool force_match_for_each_row = 5 [default = false]; 25 | 26 | // Force constructed match objects to use matrix multiplication based gather 27 | // instead of standard tf.gather 28 | optional bool use_matmul_gather = 6 [default = false]; 29 | } 30 | -------------------------------------------------------------------------------- /object_detection/protos/bipartite_matcher.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for bipartite matcher. See 6 | // matchers/bipartite_matcher.py for details. 7 | message BipartiteMatcher { 8 | // Force constructed match objects to use matrix multiplication based gather 9 | // instead of standard tf.gather 10 | optional bool use_matmul_gather = 6 [default = false]; 11 | } 12 | -------------------------------------------------------------------------------- /object_detection/protos/bipartite_matcher_pb2.py: -------------------------------------------------------------------------------- 1 | # Generated by the protocol buffer compiler. DO NOT EDIT! 2 | # source: object_detection/protos/bipartite_matcher.proto 3 | 4 | import sys 5 | _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import message as _message 8 | from google.protobuf import reflection as _reflection 9 | from google.protobuf import symbol_database as _symbol_database 10 | from google.protobuf import descriptor_pb2 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | 17 | 18 | DESCRIPTOR = _descriptor.FileDescriptor( 19 | name='object_detection/protos/bipartite_matcher.proto', 20 | package='object_detection.protos', 21 | syntax='proto2', 22 | serialized_pb=_b('\n/object_detection/protos/bipartite_matcher.proto\x12\x17object_detection.protos\"4\n\x10\x42ipartiteMatcher\x12 \n\x11use_matmul_gather\x18\x06 \x01(\x08:\x05\x66\x61lse') 23 | ) 24 | 25 | 26 | 27 | 28 | _BIPARTITEMATCHER = _descriptor.Descriptor( 29 | name='BipartiteMatcher', 30 | full_name='object_detection.protos.BipartiteMatcher', 31 | filename=None, 32 | file=DESCRIPTOR, 33 | containing_type=None, 34 | fields=[ 35 | _descriptor.FieldDescriptor( 36 | name='use_matmul_gather', full_name='object_detection.protos.BipartiteMatcher.use_matmul_gather', index=0, 37 | number=6, type=8, cpp_type=7, label=1, 38 | has_default_value=True, default_value=False, 39 | message_type=None, enum_type=None, containing_type=None, 40 | is_extension=False, extension_scope=None, 41 | options=None), 42 | ], 43 | extensions=[ 44 | ], 45 | nested_types=[], 46 | enum_types=[ 47 | ], 48 | options=None, 49 | is_extendable=False, 50 | syntax='proto2', 51 | extension_ranges=[], 52 | oneofs=[ 53 | ], 54 | serialized_start=76, 55 | serialized_end=128, 56 | ) 57 | 58 | DESCRIPTOR.message_types_by_name['BipartiteMatcher'] = _BIPARTITEMATCHER 59 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 60 | 61 | BipartiteMatcher = _reflection.GeneratedProtocolMessageType('BipartiteMatcher', (_message.Message,), dict( 62 | DESCRIPTOR = _BIPARTITEMATCHER, 63 | __module__ = 'object_detection.protos.bipartite_matcher_pb2' 64 | # @@protoc_insertion_point(class_scope:object_detection.protos.BipartiteMatcher) 65 | )) 66 | _sym_db.RegisterMessage(BipartiteMatcher) 67 | 68 | 69 | # @@protoc_insertion_point(module_scope) 70 | -------------------------------------------------------------------------------- /object_detection/protos/box_coder.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | import "object_detection/protos/faster_rcnn_box_coder.proto"; 6 | import "object_detection/protos/keypoint_box_coder.proto"; 7 | import "object_detection/protos/mean_stddev_box_coder.proto"; 8 | import "object_detection/protos/square_box_coder.proto"; 9 | 10 | // Configuration proto for the box coder to be used in the object detection 11 | // pipeline. See core/box_coder.py for details. 12 | message BoxCoder { 13 | oneof box_coder_oneof { 14 | FasterRcnnBoxCoder faster_rcnn_box_coder = 1; 15 | MeanStddevBoxCoder mean_stddev_box_coder = 2; 16 | SquareBoxCoder square_box_coder = 3; 17 | KeypointBoxCoder keypoint_box_coder = 4; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /object_detection/protos/eval.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Message for configuring DetectionModel evaluation jobs (eval.py). 6 | message EvalConfig { 7 | // Number of visualization images to generate. 8 | optional uint32 num_visualizations = 1 [default=10]; 9 | 10 | // Number of examples to process of evaluation. 11 | optional uint32 num_examples = 2 [default=5000]; 12 | 13 | // How often to run evaluation. 14 | optional uint32 eval_interval_secs = 3 [default=300]; 15 | 16 | // Maximum number of times to run evaluation. If set to 0, will run forever. 17 | optional uint32 max_evals = 4 [default=0]; 18 | 19 | // Whether the TensorFlow graph used for evaluation should be saved to disk. 20 | optional bool save_graph = 5 [default=false]; 21 | 22 | // Path to directory to store visualizations in. If empty, visualization 23 | // images are not exported (only shown on Tensorboard). 24 | optional string visualization_export_dir = 6 [default=""]; 25 | 26 | // BNS name of the TensorFlow master. 27 | optional string eval_master = 7 [default=""]; 28 | 29 | // Type of metrics to use for evaluation. 30 | repeated string metrics_set = 8; 31 | 32 | // Path to export detections to COCO compatible JSON format. 33 | optional string export_path = 9 [default='']; 34 | 35 | // Option to not read groundtruth labels and only export detections to 36 | // COCO-compatible JSON file. 37 | optional bool ignore_groundtruth = 10 [default=false]; 38 | 39 | // Use exponential moving averages of variables for evaluation. 40 | // TODO(rathodv): When this is false make sure the model is constructed 41 | // without moving averages in restore_fn. 42 | optional bool use_moving_averages = 11 [default=false]; 43 | 44 | // Whether to evaluate instance masks. 45 | // Note that since there is no evaluation code currently for instance 46 | // segmenation this option is unused. 47 | optional bool eval_instance_masks = 12 [default=false]; 48 | 49 | // Minimum score threshold for a detected object box to be visualized 50 | optional float min_score_threshold = 13 [default=0.5]; 51 | 52 | // Maximum number of detections to visualize 53 | optional int32 max_num_boxes_to_visualize = 14 [default=20]; 54 | 55 | // When drawing a single detection, each label is by default visualized as 56 | //