├── 001.jpg ├── 002.jpg ├── LICENSE ├── README.md ├── annotations ├── creat_name.py ├── label_map_person.pbtxt └── trainval_person.txt ├── creat_name.py ├── embedded_ssd_mobilenet_v1_coco.config ├── label_map_person.pbtxt ├── object_detection ├── CONTRIBUTING.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 │ ├── graph_rewriter_builder.py │ ├── graph_rewriter_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 │ ├── data_decoder.py │ ├── data_parser.py │ ├── freezable_batch_norm.py │ ├── freezable_batch_norm_test.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 ├── create_tf_record.py ├── 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 │ ├── create_pycocotools_package.sh │ ├── download_and_preprocess_mscoco.sh │ ├── oid_hierarchical_labels_expansion.py │ ├── oid_hierarchical_labels_expansion_test.py │ ├── oid_tfrecord_creation.py │ ├── oid_tfrecord_creation_test.py │ ├── tf_record_creation_util.py │ └── tf_record_creation_util_test.py ├── dockerfiles │ └── android │ │ ├── Dockerfile │ │ └── README.md ├── eval_util.py ├── eval_util_test.py ├── export_inference_graph.py ├── export_inference_graph.sh ├── export_tflite_ssd_graph.py ├── export_tflite_ssd_graph_lib.py ├── export_tflite_ssd_graph_lib_test.py ├── exporter.py ├── exporter_test.py ├── inference │ ├── __init__.py │ ├── detection_inference.py │ ├── detection_inference_test.py │ └── infer_detections.py ├── inputs.py ├── inputs_test.py ├── legacy │ ├── __init__.py │ ├── eval.py │ ├── evaluator.py │ ├── train.py │ ├── trainer.py │ └── trainer_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 │ ├── io_utils.py │ ├── offline_eval_map_corloc.py │ ├── offline_eval_map_corloc_test.py │ ├── oid_od_challenge_evaluation.py │ ├── oid_od_challenge_evaluation_utils.py │ ├── oid_od_challenge_evaluation_utils_test.py │ ├── oid_vrd_challenge_evaluation.py │ ├── oid_vrd_challenge_evaluation_utils.py │ ├── oid_vrd_challenge_evaluation_utils_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_v1_fpn_feature_extractor.py │ ├── ssd_mobilenet_v1_fpn_feature_extractor_test.py │ ├── ssd_mobilenet_v1_ppn_feature_extractor.py │ ├── ssd_mobilenet_v1_ppn_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 │ ├── ssd_resnet_v1_ppn_feature_extractor.py │ ├── ssd_resnet_v1_ppn_feature_extractor_test.py │ └── ssd_resnet_v1_ppn_feature_extractor_testbase.py ├── object_detection.py ├── predictors │ ├── __init__.py │ ├── convolutional_box_predictor.py │ ├── convolutional_box_predictor_test.py │ ├── heads │ │ ├── __init__.py │ │ ├── box_head.py │ │ ├── box_head_test.py │ │ ├── class_head.py │ │ ├── class_head_test.py │ │ ├── head.py │ │ ├── keypoint_head.py │ │ ├── keypoint_head_test.py │ │ ├── mask_head.py │ │ └── mask_head_test.py │ ├── mask_rcnn_box_predictor.py │ ├── mask_rcnn_box_predictor_test.py │ ├── rfcn_box_predictor.py │ └── rfcn_box_predictor_test.py ├── 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 │ ├── graph_rewriter.proto │ ├── graph_rewriter_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 ├── train.py ├── train.sh ├── trainer.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 │ ├── vrd_evaluation.py │ └── vrd_evaluation_test.py ├── oilplot_pr.png ├── oiltank_155.jpg ├── readme_ch.md ├── setup.py ├── slim ├── WORKSPACE ├── __init__.py ├── datasets │ ├── __init__.py │ ├── build_imagenet_data.py │ ├── cifar10.py │ ├── dataset_classification.py │ ├── dataset_factory.py │ ├── dataset_utils.py │ ├── download_and_convert_cifar10.py │ ├── download_and_convert_flowers.py │ ├── download_and_convert_imagenet.sh │ ├── download_and_convert_mnist.py │ ├── download_imagenet.sh │ ├── flowers.py │ ├── imagenet.py │ ├── imagenet_2012_validation_synset_labels.txt │ ├── imagenet_lsvrc_2015_synsets.txt │ ├── imagenet_metadata.txt │ ├── mnist.py │ ├── preprocess_imagenet_validation_data.py │ └── process_bounding_boxes.py ├── deployment │ ├── __init__.py │ ├── model_deploy.py │ └── model_deploy_test.py ├── download_and_convert_data.py ├── eval_image_classifier.py ├── export_inference_graph.py ├── export_inference_graph_test.py ├── exporter.py ├── nets │ ├── __init__.py │ ├── alexnet.py │ ├── alexnet_test.py │ ├── cifarnet.py │ ├── cyclegan.py │ ├── cyclegan_test.py │ ├── dcgan.py │ ├── dcgan_test.py │ ├── inception.py │ ├── inception_resnet_v2.py │ ├── inception_resnet_v2_test.py │ ├── inception_utils.py │ ├── inception_v1.py │ ├── inception_v1_test.py │ ├── inception_v2.py │ ├── inception_v2_test.py │ ├── inception_v3.py │ ├── inception_v3_test.py │ ├── inception_v4.py │ ├── inception_v4_test.py │ ├── lenet.py │ ├── mobilenet │ │ ├── README.md │ │ ├── __init__.py │ │ ├── conv_blocks.py │ │ ├── madds_top1_accuracy.png │ │ ├── mnet_v1_vs_v2_pixel1_latency.png │ │ ├── mobilenet.py │ │ ├── mobilenet_example.ipynb │ │ ├── mobilenet_v2.py │ │ └── mobilenet_v2_test.py │ ├── mobilenet_v1.md │ ├── mobilenet_v1.png │ ├── mobilenet_v1.py │ ├── mobilenet_v1_eval.py │ ├── mobilenet_v1_test.py │ ├── mobilenet_v1_train.py │ ├── nasnet │ │ ├── README.md │ │ ├── __init__.py │ │ ├── nasnet.py │ │ ├── nasnet_test.py │ │ ├── nasnet_utils.py │ │ ├── nasnet_utils_test.py │ │ ├── pnasnet.py │ │ └── pnasnet_test.py │ ├── nets_factory.py │ ├── nets_factory_test.py │ ├── overfeat.py │ ├── overfeat_test.py │ ├── pix2pix.py │ ├── pix2pix_test.py │ ├── resnet_utils.py │ ├── resnet_v1.py │ ├── resnet_v1_test.py │ ├── resnet_v2.py │ ├── resnet_v2_test.py │ ├── vgg.py │ └── vgg_test.py ├── preprocessing │ ├── __init__.py │ ├── cifarnet_preprocessing.py │ ├── inception_preprocessing.py │ ├── lenet_preprocessing.py │ ├── preprocessing_factory.py │ └── vgg_preprocessing.py ├── scripts │ ├── export_mobilenet.sh │ ├── finetune_inception_resnet_v2_on_flowers.sh │ ├── finetune_inception_v1_on_flowers.sh │ ├── finetune_inception_v3_on_flowers.sh │ ├── finetune_resnet_v1_50_on_flowers.sh │ ├── train_cifarnet_on_cifar10.sh │ └── train_lenet_on_mnist.sh ├── setup.py ├── test_images_classifier.py ├── train_image_classifier.py └── train_image_classifier_defind.py ├── trainval_person.txt ├── zcreate_record.sh ├── zfrozen.sh └── ztrain.sh /001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/001.jpg -------------------------------------------------------------------------------- /002.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/002.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Nick Bourdakos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Embedded target detection based on mobilenet SSD 2 | 1. The performance of this model for embedded design in small object detection will be better, such as Northwest University of technology aircraft data set (sparse small target). 3 | 4 | 2. In the detection of the new aspect ratio, the coarse and large resolution channel is used to add attention, and the performance of the sample layer target is improved greatly (multi-scale: playground, aircraft, aisle). 5 | 6 | 3. In our model, we first use the deconvolution structure for multi-source rough high-resolution, and the sampling layer is faster. 7 | 8 | 4. Up sampling adopts label smoothing and training initialization weight, resulting in loss transformation modification, which makes frame drawing more accurate。 9 | 10 | ## VOC Dataset 11 | voc2007 format 12 | 13 | ## Training 14 | Tensorflow-gpu==1.10.0&Tensorflow-gpu==1.12.0 15 | cuda =8/9 16 | opencv-python==3.4.0 17 | pillow 18 | matplotlib 19 | 20 | 1、datsets 21 | imges ,imgs files; 22 | ammitations,xml files; 23 | 24 | 2、label_map_person.txt ;id,name. 25 | creat_name.py 26 | 27 | slim files 28 | python setup.py build 29 | python setup.py install 30 | 31 | python setup.py build 32 | python setup.py install 33 | 34 | 3、object_detection 35 | create_tf_record.py,146、149、162、167 rows 36 | train.record 37 | val.record 38 | 39 | 4、embedded_ssd_mobilenet_v1_coco.config中9、141、146、156、172、182、184 rows。 40 | 41 | 5、object_detection 42 | train.sh 43 | 44 | 6、reference resources readme_ch.md 45 | 46 | ## Evaluation 47 | python export_inference_graph.py --input_type image_tensor --pipeline_config_path ./rfcn_resnet101_coco.config 48 | --trained_checkpoint_prefix ./models/train/model.ckpt-5000 --output_directory ./fine_tuned_model 49 | 50 | ## Citing mini_SSD 51 | This project realizes high-speed detection of mobile terminal from the comprehensive optimization method of engineering hardware. I declare that this model is modified by referring to a sub model of Google's object detection API model and integrating mobilnetv1 and slim methods. It is mainly for an engineering product. We realize the use of embedded system, taking into account the calculation balance burden and thread synchronization between chip modules We have made the corresponding design. 52 | 53 | At present, there are still some small problems in speed and accuracy. I hope to communicate with you to solve this problem and achieve the goal of 95fps. The biggest advantage of the model is that the weight volume is about 100 / 1 of the ordinary model when the speed is relatively superior. For ordinary problems, we can use this model to realize the deployment of the model within 5m, and the weight problem is generally within 2m. 54 | 55 | i7 CPU on a single PC 300 ms, 1200*960 size pictures. I will complete other relevant parameters. Recently, we have been busy with our own measurement. The accuracy and speed of this target can be further optimized. I will tell you the details in the second edition. Open source will be used to solve the problem of deployment on ARMLinux with a large model and to produce your own idea. In the process of using the model, we need to compile tensorflow source code and deploy TF on related arm. 56 | 57 | If you are not familiar with Google's target detection API, please strictly follow my tutorial, otherwise many problems will lead to compilation problems between various components. 58 | 59 | ![result](https://github.com/Eric3911/miniDetection/blob/master/oilplot_pr.png) 60 | ![result](https://github.com/Eric3911/miniDetection/blob/master/oiltank_155.jpg) 61 | ![result](https://github.com/Eric3911/mini_SSD/blob/master/001.jpg) 62 | -------------------------------------------------------------------------------- /annotations/creat_name.py: -------------------------------------------------------------------------------- 1 | #2、生成名称目录脚本 2 | import os 3 | imglst = os.listdir("./annotations/xmls/") 4 | with open("./annotations/trainval_person.txt","w") as ff: 5 | for img_path in imglst: 6 | name = img_path.split(".")[0] 7 | print(name) 8 | ff.write(name+"\n") -------------------------------------------------------------------------------- /annotations/label_map_person.pbtxt: -------------------------------------------------------------------------------- 1 | item { 2 | id: 1 3 | name: 'Person' 4 | } 5 | -------------------------------------------------------------------------------- /annotations/trainval_person.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/annotations/trainval_person.txt -------------------------------------------------------------------------------- /creat_name.py: -------------------------------------------------------------------------------- 1 | #2、生成名称目录脚本 2 | import os 3 | imglst = os.listdir("./annotations/xmls/") 4 | with open("./annotations/trainval_person.txt","w") as ff: 5 | for img_path in imglst: 6 | name = img_path.split(".")[0] 7 | print(name) 8 | ff.write(name+"\n") -------------------------------------------------------------------------------- /label_map_person.pbtxt: -------------------------------------------------------------------------------- 1 | item { 2 | id: 1 3 | name: 'Person' 4 | } 5 | -------------------------------------------------------------------------------- /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/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/__init__.py -------------------------------------------------------------------------------- /object_detection/anchor_generators/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/anchor_generators/__init__.py -------------------------------------------------------------------------------- /object_detection/box_coders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/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 | def __init__(self, stddev=0.01): 29 | """Constructor for MeanStddevBoxCoder. 30 | 31 | Args: 32 | stddev: The standard deviation used to encode and decode boxes. 33 | """ 34 | self._stddev = stddev 35 | 36 | @property 37 | def code_size(self): 38 | return 4 39 | 40 | def _encode(self, boxes, anchors): 41 | """Encode a box collection with respect to anchor collection. 42 | 43 | Args: 44 | boxes: BoxList holding N boxes to be encoded. 45 | anchors: BoxList of N anchors. 46 | 47 | Returns: 48 | a tensor representing N anchor-encoded boxes 49 | 50 | Raises: 51 | ValueError: if the anchors still have deprecated stddev field. 52 | """ 53 | box_corners = boxes.get() 54 | if anchors.has_field('stddev'): 55 | raise ValueError("'stddev' is a parameter of MeanStddevBoxCoder and " 56 | "should not be specified in the box list.") 57 | means = anchors.get() 58 | return (box_corners - means) / self._stddev 59 | 60 | def _decode(self, rel_codes, anchors): 61 | """Decode. 62 | 63 | Args: 64 | rel_codes: a tensor representing N anchor-encoded boxes. 65 | anchors: BoxList of anchors. 66 | 67 | Returns: 68 | boxes: BoxList holding N bounding boxes 69 | 70 | Raises: 71 | ValueError: if the anchors still have deprecated stddev field and expects 72 | the decode method to use stddev value from that field. 73 | """ 74 | means = anchors.get() 75 | if anchors.has_field('stddev'): 76 | raise ValueError("'stddev' is a parameter of MeanStddevBoxCoder and " 77 | "should not be specified in the box list.") 78 | box_corners = rel_codes * self._stddev + means 79 | return box_list.BoxList(box_corners) 80 | -------------------------------------------------------------------------------- /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 | priors = box_list.BoxList(prior_means) 32 | 33 | coder = mean_stddev_box_coder.MeanStddevBoxCoder(stddev=0.1) 34 | rel_codes = coder.encode(boxes, priors) 35 | with self.test_session() as sess: 36 | rel_codes_out = sess.run(rel_codes) 37 | self.assertAllClose(rel_codes_out, expected_rel_codes) 38 | 39 | def testGetCorrectBoxesAfterDecoding(self): 40 | rel_codes = tf.constant([[0.0, 0.0, 0.0, 0.0], [-5.0, -5.0, -5.0, -3.0]]) 41 | expected_box_corners = [[0.0, 0.0, 0.5, 0.5], [0.0, 0.0, 0.5, 0.5]] 42 | prior_means = tf.constant([[0.0, 0.0, 0.5, 0.5], [0.5, 0.5, 1.0, 0.8]]) 43 | priors = box_list.BoxList(prior_means) 44 | 45 | coder = mean_stddev_box_coder.MeanStddevBoxCoder(stddev=0.1) 46 | decoded_boxes = coder.decode(rel_codes, priors) 47 | decoded_box_corners = decoded_boxes.get() 48 | with self.test_session() as sess: 49 | decoded_out = sess.run(decoded_box_corners) 50 | self.assertAllClose(decoded_out, expected_box_corners) 51 | 52 | 53 | if __name__ == '__main__': 54 | tf.test.main() 55 | -------------------------------------------------------------------------------- /object_detection/builders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/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 | stddev=box_coder_config.mean_stddev_box_coder.stddev) 60 | if box_coder_config.WhichOneof('box_coder_oneof') == 'square_box_coder': 61 | return square_box_coder.SquareBoxCoder(scale_factors=[ 62 | box_coder_config.square_box_coder.y_scale, 63 | box_coder_config.square_box_coder.x_scale, 64 | box_coder_config.square_box_coder.length_scale 65 | ]) 66 | raise ValueError('Empty box coder.') 67 | -------------------------------------------------------------------------------- /object_detection/builders/graph_rewriter_builder.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 | """Functions for quantized training and evaluation.""" 16 | 17 | import tensorflow as tf 18 | 19 | 20 | def build(graph_rewriter_config, is_training): 21 | """Returns a function that modifies default graph based on options. 22 | 23 | Args: 24 | graph_rewriter_config: graph_rewriter_pb2.GraphRewriter proto. 25 | is_training: whether in training of eval mode. 26 | """ 27 | def graph_rewrite_fn(): 28 | """Function to quantize weights and activation of the default graph.""" 29 | if (graph_rewriter_config.quantization.weight_bits != 8 or 30 | graph_rewriter_config.quantization.activation_bits != 8): 31 | raise ValueError('Only 8bit quantization is supported') 32 | 33 | # Quantize the graph by inserting quantize ops for weights and activations 34 | if is_training: 35 | tf.contrib.quantize.create_training_graph( 36 | input_graph=tf.get_default_graph(), 37 | quant_delay=graph_rewriter_config.quantization.delay) 38 | else: 39 | tf.contrib.quantize.create_eval_graph(input_graph=tf.get_default_graph()) 40 | 41 | tf.contrib.layers.summarize_collection('quant_vars') 42 | return graph_rewrite_fn 43 | -------------------------------------------------------------------------------- /object_detection/builders/graph_rewriter_builder_test.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 | """Tests for graph_rewriter_builder.""" 16 | import mock 17 | import tensorflow as tf 18 | from object_detection.builders import graph_rewriter_builder 19 | from object_detection.protos import graph_rewriter_pb2 20 | 21 | 22 | class QuantizationBuilderTest(tf.test.TestCase): 23 | 24 | def testQuantizationBuilderSetsUpCorrectTrainArguments(self): 25 | with mock.patch.object( 26 | tf.contrib.quantize, 'create_training_graph') as mock_quant_fn: 27 | with mock.patch.object(tf.contrib.layers, 28 | 'summarize_collection') as mock_summarize_col: 29 | graph_rewriter_proto = graph_rewriter_pb2.GraphRewriter() 30 | graph_rewriter_proto.quantization.delay = 10 31 | graph_rewriter_proto.quantization.weight_bits = 8 32 | graph_rewriter_proto.quantization.activation_bits = 8 33 | graph_rewrite_fn = graph_rewriter_builder.build( 34 | graph_rewriter_proto, is_training=True) 35 | graph_rewrite_fn() 36 | _, kwargs = mock_quant_fn.call_args 37 | self.assertEqual(kwargs['input_graph'], tf.get_default_graph()) 38 | self.assertEqual(kwargs['quant_delay'], 10) 39 | mock_summarize_col.assert_called_with('quant_vars') 40 | 41 | def testQuantizationBuilderSetsUpCorrectEvalArguments(self): 42 | with mock.patch.object(tf.contrib.quantize, 43 | 'create_eval_graph') as mock_quant_fn: 44 | with mock.patch.object(tf.contrib.layers, 45 | 'summarize_collection') as mock_summarize_col: 46 | graph_rewriter_proto = graph_rewriter_pb2.GraphRewriter() 47 | graph_rewriter_proto.quantization.delay = 10 48 | graph_rewrite_fn = graph_rewriter_builder.build( 49 | graph_rewriter_proto, is_training=False) 50 | graph_rewrite_fn() 51 | _, kwargs = mock_quant_fn.call_args 52 | self.assertEqual(kwargs['input_graph'], tf.get_default_graph()) 53 | mock_summarize_col.assert_called_with('quant_vars') 54 | 55 | 56 | if __name__ == '__main__': 57 | tf.test.main() 58 | -------------------------------------------------------------------------------- /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 | if similarity_calculator == 'thresholded_iou_similarity': 55 | return region_similarity_calculator.ThresholdedIouSimilarity( 56 | region_similarity_calculator_config.thresholded_iou_similarity.threshold 57 | ) 58 | 59 | raise ValueError('Unknown region similarity calculator.') 60 | -------------------------------------------------------------------------------- /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/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/freezable_batch_norm.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 | 16 | """A freezable batch norm layer that uses Keras batch normalization.""" 17 | import tensorflow as tf 18 | 19 | 20 | class FreezableBatchNorm(tf.keras.layers.BatchNormalization): 21 | """Batch normalization layer (Ioffe and Szegedy, 2014). 22 | 23 | This is a `freezable` batch norm layer that supports setting the `training` 24 | parameter in the __init__ method rather than having to set it either via 25 | the Keras learning phase or via the `call` method parameter. This layer will 26 | forward all other parameters to the default Keras `BatchNormalization` 27 | layer 28 | 29 | This is class is necessary because Object Detection model training sometimes 30 | requires batch normalization layers to be `frozen` and used as if it was 31 | evaluation time, despite still training (and potentially using dropout layers) 32 | 33 | Like the default Keras BatchNormalization layer, this will normalize the 34 | activations of the previous layer at each batch, 35 | i.e. applies a transformation that maintains the mean activation 36 | close to 0 and the activation standard deviation close to 1. 37 | 38 | Arguments: 39 | training: Boolean or None. If True, the batch normalization layer will 40 | normalize the input batch using the batch mean and standard deviation, 41 | and update the total moving mean and standard deviations. If False, the 42 | layer will normalize using the moving average and std. dev, without 43 | updating the learned avg and std. dev. 44 | If None, the layer will follow the keras BatchNormalization layer 45 | strategy of checking the Keras learning phase at `call` time to decide 46 | what to do. 47 | **kwargs: The keyword arguments to forward to the keras BatchNormalization 48 | layer constructor. 49 | 50 | Input shape: 51 | Arbitrary. Use the keyword argument `input_shape` 52 | (tuple of integers, does not include the samples axis) 53 | when using this layer as the first layer in a model. 54 | 55 | Output shape: 56 | Same shape as input. 57 | 58 | References: 59 | - [Batch Normalization: Accelerating Deep Network Training by Reducing 60 | Internal Covariate Shift](https://arxiv.org/abs/1502.03167) 61 | """ 62 | 63 | def __init__(self, training=None, **kwargs): 64 | super(FreezableBatchNorm, self).__init__(**kwargs) 65 | self._training = training 66 | 67 | def call(self, inputs, training=None): 68 | if training is None: 69 | training = self._training 70 | return super(FreezableBatchNorm, self).call(inputs, training=training) 71 | -------------------------------------------------------------------------------- /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/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/data_decoders/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/data_decoders/__init__.py -------------------------------------------------------------------------------- /object_detection/dataset_tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/dataset_tools/__init__.py -------------------------------------------------------------------------------- /object_detection/dataset_tools/create_pycocotools_package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 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 pycocotools and make package for CMLE jobs. 18 | # 19 | # usage: 20 | # bash object_detection/dataset_tools/create_pycocotools_package.sh \ 21 | # /tmp/pycocotools 22 | set -e 23 | 24 | if [ -z "$1" ]; then 25 | echo "usage create_pycocotools_package.sh [output dir]" 26 | exit 27 | fi 28 | 29 | # Create the output directory. 30 | OUTPUT_DIR="${1%/}" 31 | SCRATCH_DIR="${OUTPUT_DIR}/raw" 32 | mkdir -p "${OUTPUT_DIR}" 33 | mkdir -p "${SCRATCH_DIR}" 34 | 35 | cd ${SCRATCH_DIR} 36 | git clone https://github.com/cocodataset/cocoapi.git 37 | cd cocoapi/PythonAPI && mv ../common ./ 38 | 39 | sed "s/\.\.\/common/common/g" setup.py > setup.py.updated 40 | cp -f setup.py.updated setup.py 41 | rm setup.py.updated 42 | 43 | sed "s/\.\.\/common/common/g" pycocotools/_mask.pyx > _mask.pyx.updated 44 | cp -f _mask.pyx.updated pycocotools/_mask.pyx 45 | rm _mask.pyx.updated 46 | 47 | sed "s/import matplotlib\.pyplot as plt/import matplotlib\nmatplotlib\.use\(\'Agg\'\)\nimport matplotlib\.pyplot as plt/g" pycocotools/coco.py > coco.py.updated 48 | cp -f coco.py.updated pycocotools/coco.py 49 | rm coco.py.updated 50 | 51 | cd "${OUTPUT_DIR}" 52 | tar -czf pycocotools-2.0.tar.gz -C "${SCRATCH_DIR}/cocoapi/" PythonAPI/ 53 | rm -rf ${SCRATCH_DIR} 54 | -------------------------------------------------------------------------------- /object_detection/dataset_tools/oid_hierarchical_labels_expansion_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 the OpenImages label expansion (OIDHierarchicalLabelsExpansion).""" 16 | 17 | from __future__ import absolute_import 18 | from __future__ import division 19 | from __future__ import print_function 20 | 21 | import tensorflow as tf 22 | 23 | from object_detection.dataset_tools import oid_hierarchical_labels_expansion 24 | 25 | 26 | def create_test_data(): 27 | hierarchy = { 28 | 'LabelName': 29 | 'a', 30 | 'Subcategory': [{ 31 | 'LabelName': 'b' 32 | }, { 33 | 'LabelName': 'c', 34 | 'Subcategory': [{ 35 | 'LabelName': 'd' 36 | }, { 37 | 'LabelName': 'e' 38 | }] 39 | }, { 40 | 'LabelName': 'f', 41 | 'Subcategory': [{ 42 | 'LabelName': 'd' 43 | },] 44 | }] 45 | } 46 | bbox_rows = [ 47 | '123,xclick,b,1,0.1,0.2,0.1,0.2,1,1,0,0,0', 48 | '123,xclick,d,1,0.2,0.3,0.1,0.2,1,1,0,0,0' 49 | ] 50 | label_rows = [ 51 | '123,verification,b,0', '123,verification,c,0', '124,verification,d,1' 52 | ] 53 | return hierarchy, bbox_rows, label_rows 54 | 55 | 56 | class HierarchicalLabelsExpansionTest(tf.test.TestCase): 57 | 58 | def test_bbox_expansion(self): 59 | hierarchy, bbox_rows, _ = create_test_data() 60 | expansion_generator = ( 61 | oid_hierarchical_labels_expansion.OIDHierarchicalLabelsExpansion( 62 | hierarchy)) 63 | all_result_rows = [] 64 | for row in bbox_rows: 65 | all_result_rows.extend(expansion_generator.expand_boxes_from_csv(row)) 66 | self.assertItemsEqual([ 67 | '123,xclick,b,1,0.1,0.2,0.1,0.2,1,1,0,0,0', 68 | '123,xclick,d,1,0.2,0.3,0.1,0.2,1,1,0,0,0', 69 | '123,xclick,f,1,0.2,0.3,0.1,0.2,1,1,0,0,0', 70 | '123,xclick,c,1,0.2,0.3,0.1,0.2,1,1,0,0,0' 71 | ], all_result_rows) 72 | 73 | def test_labels_expansion(self): 74 | hierarchy, _, label_rows = create_test_data() 75 | expansion_generator = ( 76 | oid_hierarchical_labels_expansion.OIDHierarchicalLabelsExpansion( 77 | hierarchy)) 78 | all_result_rows = [] 79 | for row in label_rows: 80 | all_result_rows.extend(expansion_generator.expand_labels_from_csv(row)) 81 | self.assertItemsEqual([ 82 | '123,verification,b,0', '123,verification,c,0', '123,verification,d,0', 83 | '123,verification,e,0', '124,verification,d,1', '124,verification,f,1', 84 | '124,verification,c,1' 85 | ], all_result_rows) 86 | 87 | if __name__ == '__main__': 88 | tf.test.main() 89 | -------------------------------------------------------------------------------- /object_detection/dataset_tools/tf_record_creation_util.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 | r"""Utilities for creating TFRecords of TF examples for the Open Images dataset. 16 | """ 17 | from __future__ import absolute_import 18 | from __future__ import division 19 | from __future__ import print_function 20 | 21 | import tensorflow as tf 22 | 23 | 24 | def open_sharded_output_tfrecords(exit_stack, base_path, num_shards): 25 | """Opens all TFRecord shards for writing and adds them to an exit stack. 26 | 27 | Args: 28 | exit_stack: A context2.ExitStack used to automatically closed the TFRecords 29 | opened in this function. 30 | base_path: The base path for all shards 31 | num_shards: The number of shards 32 | 33 | Returns: 34 | The list of opened TFRecords. Position k in the list corresponds to shard k. 35 | """ 36 | tf_record_output_filenames = [ 37 | '{}-{:05d}-of-{:05d}'.format(base_path, idx, num_shards) 38 | for idx in range(num_shards) 39 | ] 40 | 41 | tfrecords = [ 42 | exit_stack.enter_context(tf.python_io.TFRecordWriter(file_name)) 43 | for file_name in tf_record_output_filenames 44 | ] 45 | 46 | return tfrecords 47 | -------------------------------------------------------------------------------- /object_detection/dataset_tools/tf_record_creation_util_test.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 | """Tests for tf_record_creation_util.py.""" 16 | 17 | import os 18 | import contextlib2 19 | import tensorflow as tf 20 | 21 | from object_detection.dataset_tools import tf_record_creation_util 22 | 23 | 24 | class OpenOutputTfrecordsTests(tf.test.TestCase): 25 | 26 | def test_sharded_tfrecord_writes(self): 27 | with contextlib2.ExitStack() as tf_record_close_stack: 28 | output_tfrecords = tf_record_creation_util.open_sharded_output_tfrecords( 29 | tf_record_close_stack, 30 | os.path.join(tf.test.get_temp_dir(), 'test.tfrec'), 10) 31 | for idx in range(10): 32 | output_tfrecords[idx].write('test_{}'.format(idx)) 33 | 34 | for idx in range(10): 35 | tf_record_path = '{}-{:05d}-of-00010'.format( 36 | os.path.join(tf.test.get_temp_dir(), 'test.tfrec'), idx) 37 | records = list(tf.python_io.tf_record_iterator(tf_record_path)) 38 | self.assertAllEqual(records, ['test_{}'.format(idx)]) 39 | 40 | 41 | if __name__ == '__main__': 42 | tf.test.main() 43 | -------------------------------------------------------------------------------- /object_detection/dockerfiles/android/README.md: -------------------------------------------------------------------------------- 1 | # Dockerfile for the TPU and TensorFlow Lite Object Detection tutorial 2 | 3 | This Docker image automates the setup involved with training 4 | object detection models on Google Cloud and building the Android TensorFlow Lite 5 | demo app. We recommend using this container if you decide to work through our 6 | tutorial on ["Training and serving a real-time mobile object detector in 7 | 30 minutes with Cloud TPUs"](https://medium.com/tensorflow/training-and-serving-a-realtime-mobile-object-detector-in-30-minutes-with-cloud-tpus-b78971cf1193), though of course it may be useful even if you would 8 | like to use the Object Detection API outside the context of the tutorial. 9 | 10 | A couple words of warning: 11 | 12 | 1. Docker containers do not have persistent storage. This means that any changes 13 | you make to files inside the container will not persist if you restart 14 | the container. When running through the tutorial, 15 | **do not close the container**. 16 | 2. To be able to deploy the [Android app]( 17 | https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/lite/examples/android/app) 18 | (which you will build at the end of the tutorial), 19 | you will need to kill any instances of `adb` running on the host machine. You 20 | can accomplish this by closing all instances of Android Studio, and then 21 | running `adb kill-server`. 22 | 23 | You can install Docker by following the [instructions here]( 24 | https://docs.docker.com/install/). 25 | 26 | ## Running The Container 27 | 28 | From this directory, build the Dockerfile as follows (this takes a while): 29 | 30 | ``` 31 | docker build --tag detect-tf . 32 | ``` 33 | 34 | Run the container: 35 | 36 | ``` 37 | docker run --rm -it --privileged -p 6006:6006 detect-tf 38 | ``` 39 | 40 | When running the container, you will find yourself inside the `/tensorflow` 41 | directory, which is the path to the TensorFlow [source 42 | tree](https://github.com/tensorflow/tensorflow). 43 | 44 | ## Text Editing 45 | 46 | The tutorial also 47 | requires you to occasionally edit files inside the source tree. 48 | This Docker images comes with `vim`, `nano`, and `emacs` preinstalled for your 49 | convenience. 50 | 51 | ## What's In This Container 52 | 53 | This container is derived from the nightly build of TensorFlow, and contains the 54 | sources for TensorFlow at `/tensorflow`, as well as the 55 | [TensorFlow Models](https://github.com/tensorflow/models) which are available at 56 | `/tensorflow/models` (and contain the Object Detection API as a subdirectory 57 | at `/tensorflow/models/research/object_detection`). 58 | The Oxford-IIIT Pets dataset, the COCO pre-trained SSD + MobileNet (v1) 59 | checkpoint, and example 60 | trained model are all available in `/tmp` in their respective folders. 61 | 62 | This container also has the `gsutil` and `gcloud` utilities, the `bazel` build 63 | tool, and all dependencies necessary to use the Object Detection API, and 64 | compile and install the TensorFlow Lite Android demo app. 65 | 66 | At various points throughout the tutorial, you may see references to the 67 | *research directory*. This refers to the `research` folder within the 68 | models repository, located at 69 | `/tensorflow/models/resesarch`. 70 | -------------------------------------------------------------------------------- /object_detection/export_inference_graph.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from google.protobuf import text_format 3 | from object_detection import exporter 4 | from object_detection.protos import pipeline_pb2 5 | 6 | slim = tf.contrib.slim 7 | flags = tf.app.flags 8 | 9 | flags.DEFINE_string('input_type', 'image_tensor', 'Type of input node. Can be ' 10 | 'one of [`image_tensor`, `encoded_image_string_tensor`, ' 11 | '`tf_example`]') 12 | flags.DEFINE_string('input_shape', None, 13 | 'If input_type is `image_tensor`, this can explicitly set ' 14 | 'the shape of this input tensor to a fixed size. The ' 15 | 'dimensions are to be provided as a comma-separated list ' 16 | 'of integers. A value of -1 can be used for unknown ' 17 | 'dimensions. If not specified, for an `image_tensor, the ' 18 | 'default shape will be partially specified as ' 19 | '`[None, None, None, 3]`.') 20 | flags.DEFINE_string('pipeline_config_path', None, 21 | 'Path to a pipeline_pb2.TrainEvalPipelineConfig config ' 22 | 'file.') 23 | flags.DEFINE_string('trained_checkpoint_prefix', None, 24 | 'Path to trained checkpoint, typically of the form ' 25 | 'path/to/model.ckpt') 26 | flags.DEFINE_string('output_directory', None, 'Path to write outputs.') 27 | flags.DEFINE_string('config_override', '', 28 | 'pipeline_pb2.TrainEvalPipelineConfig ' 29 | 'text proto to override pipeline_config_path.') 30 | flags.DEFINE_boolean('write_inference_graph', False, 31 | 'If true, writes inference graph to disk.') 32 | tf.app.flags.mark_flag_as_required('pipeline_config_path') 33 | tf.app.flags.mark_flag_as_required('trained_checkpoint_prefix') 34 | tf.app.flags.mark_flag_as_required('output_directory') 35 | FLAGS = flags.FLAGS 36 | 37 | 38 | def main(_): 39 | pipeline_config = pipeline_pb2.TrainEvalPipelineConfig() 40 | with tf.gfile.GFile(FLAGS.pipeline_config_path, 'r') as f: 41 | text_format.Merge(f.read(), pipeline_config) 42 | text_format.Merge(FLAGS.config_override, pipeline_config) 43 | if FLAGS.input_shape: 44 | input_shape = [ 45 | int(dim) if dim != '-1' else None 46 | for dim in FLAGS.input_shape.split(',') 47 | ] 48 | else: 49 | input_shape = None 50 | exporter.export_inference_graph( 51 | FLAGS.input_type, pipeline_config, FLAGS.trained_checkpoint_prefix, 52 | FLAGS.output_directory, input_shape=input_shape, 53 | write_inference_graph=FLAGS.write_inference_graph) 54 | 55 | 56 | if __name__ == '__main__': 57 | tf.app.run() 58 | -------------------------------------------------------------------------------- /object_detection/export_inference_graph.sh: -------------------------------------------------------------------------------- 1 | python export_inference_graph.py --input_type image_tensor --pipeline_config_path=/path/to/ssd_inception_v2.config --trained_checkpoint_prefix=/path/to/model.ckpt --output_directory=/path/to/exported_model_directory -------------------------------------------------------------------------------- /object_detection/inference/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/inference/__init__.py -------------------------------------------------------------------------------- /object_detection/legacy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/legacy/__init__.py -------------------------------------------------------------------------------- /object_detection/matchers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/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/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/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/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/metrics/__init__.py -------------------------------------------------------------------------------- /object_detection/metrics/io_utils.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 | """Common IO utils used in offline metric computation. 16 | """ 17 | 18 | from __future__ import absolute_import 19 | from __future__ import division 20 | from __future__ import print_function 21 | 22 | import csv 23 | 24 | 25 | def write_csv(fid, metrics): 26 | """Writes metrics key-value pairs to CSV file. 27 | 28 | Args: 29 | fid: File identifier of an opened file. 30 | metrics: A dictionary with metrics to be written. 31 | """ 32 | metrics_writer = csv.writer(fid, delimiter=',') 33 | for metric_name, metric_value in metrics.items(): 34 | metrics_writer.writerow([metric_name, str(metric_value)]) 35 | -------------------------------------------------------------------------------- /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/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/models/__init__.py -------------------------------------------------------------------------------- /object_detection/models/ssd_mobilenet_v1_ppn_feature_extractor.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 | 16 | """SSDFeatureExtractor for MobilenetV1 PPN features.""" 17 | 18 | import tensorflow as tf 19 | 20 | from object_detection.meta_architectures import ssd_meta_arch 21 | from object_detection.models import feature_map_generators 22 | from object_detection.utils import context_manager 23 | from object_detection.utils import ops 24 | from object_detection.utils import shape_utils 25 | from nets import mobilenet_v1 26 | 27 | slim = tf.contrib.slim 28 | 29 | 30 | class SSDMobileNetV1PpnFeatureExtractor(ssd_meta_arch.SSDFeatureExtractor): 31 | """SSD Feature Extractor using MobilenetV1 PPN features.""" 32 | 33 | def preprocess(self, resized_inputs): 34 | """SSD preprocessing. 35 | 36 | Maps pixel values to the range [-1, 1]. 37 | 38 | Args: 39 | resized_inputs: a [batch, height, width, channels] float tensor 40 | representing a batch of images. 41 | 42 | Returns: 43 | preprocessed_inputs: a [batch, height, width, channels] float tensor 44 | representing a batch of images. 45 | """ 46 | return (2.0 / 255.0) * resized_inputs - 1.0 47 | 48 | def extract_features(self, preprocessed_inputs): 49 | """Extract features from preprocessed inputs. 50 | 51 | Args: 52 | preprocessed_inputs: a [batch, height, width, channels] float tensor 53 | representing a batch of images. 54 | 55 | Returns: 56 | feature_maps: a list of tensors where the ith tensor has shape 57 | [batch, height_i, width_i, depth_i] 58 | """ 59 | preprocessed_inputs = shape_utils.check_min_image_dim( 60 | 33, preprocessed_inputs) 61 | 62 | with tf.variable_scope('MobilenetV1', 63 | reuse=self._reuse_weights) as scope: 64 | with slim.arg_scope( 65 | mobilenet_v1.mobilenet_v1_arg_scope( 66 | is_training=None, regularize_depthwise=True)): 67 | with (slim.arg_scope(self._conv_hyperparams_fn()) 68 | if self._override_base_feature_extractor_hyperparams 69 | else context_manager.IdentityContextManager()): 70 | _, image_features = mobilenet_v1.mobilenet_v1_base( 71 | ops.pad_to_multiple(preprocessed_inputs, self._pad_to_multiple), 72 | final_endpoint='Conv2d_13_pointwise', 73 | min_depth=self._min_depth, 74 | depth_multiplier=self._depth_multiplier, 75 | use_explicit_padding=self._use_explicit_padding, 76 | scope=scope) 77 | with slim.arg_scope(self._conv_hyperparams_fn()): 78 | feature_maps = feature_map_generators.pooling_pyramid_feature_maps( 79 | base_feature_map_depth=0, 80 | num_layers=6, 81 | image_features={ 82 | 'image_features': image_features['Conv2d_11_pointwise'] 83 | }) 84 | return feature_maps.values() 85 | -------------------------------------------------------------------------------- /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/models/ssd_resnet_v1_ppn_feature_extractor_test.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 | """Tests for ssd resnet v1 feature extractors.""" 16 | import tensorflow as tf 17 | 18 | from object_detection.models import ssd_resnet_v1_ppn_feature_extractor 19 | from object_detection.models import ssd_resnet_v1_ppn_feature_extractor_testbase 20 | 21 | 22 | class SSDResnet50V1PpnFeatureExtractorTest( 23 | ssd_resnet_v1_ppn_feature_extractor_testbase. 24 | SSDResnetPpnFeatureExtractorTestBase): 25 | """SSDResnet50v1 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_ppn_feature_extractor.SSDResnet50V1PpnFeatureExtractor( 32 | is_training, 33 | depth_multiplier, 34 | min_depth, 35 | pad_to_multiple, 36 | self.conv_hyperparams_fn, 37 | use_explicit_padding=use_explicit_padding) 38 | 39 | def _scope_name(self): 40 | return 'resnet_v1_50' 41 | 42 | 43 | class SSDResnet101V1PpnFeatureExtractorTest( 44 | ssd_resnet_v1_ppn_feature_extractor_testbase. 45 | SSDResnetPpnFeatureExtractorTestBase): 46 | """SSDResnet101v1 feature extractor test.""" 47 | 48 | def _create_feature_extractor(self, depth_multiplier, pad_to_multiple, 49 | use_explicit_padding=False): 50 | min_depth = 32 51 | is_training = True 52 | return ( 53 | ssd_resnet_v1_ppn_feature_extractor.SSDResnet101V1PpnFeatureExtractor( 54 | is_training, 55 | depth_multiplier, 56 | min_depth, 57 | pad_to_multiple, 58 | self.conv_hyperparams_fn, 59 | use_explicit_padding=use_explicit_padding)) 60 | 61 | def _scope_name(self): 62 | return 'resnet_v1_101' 63 | 64 | 65 | class SSDResnet152V1PpnFeatureExtractorTest( 66 | ssd_resnet_v1_ppn_feature_extractor_testbase. 67 | SSDResnetPpnFeatureExtractorTestBase): 68 | """SSDResnet152v1 feature extractor test.""" 69 | 70 | def _create_feature_extractor(self, depth_multiplier, pad_to_multiple, 71 | use_explicit_padding=False): 72 | min_depth = 32 73 | is_training = True 74 | return ( 75 | ssd_resnet_v1_ppn_feature_extractor.SSDResnet152V1PpnFeatureExtractor( 76 | is_training, 77 | depth_multiplier, 78 | min_depth, 79 | pad_to_multiple, 80 | self.conv_hyperparams_fn, 81 | use_explicit_padding=use_explicit_padding)) 82 | 83 | def _scope_name(self): 84 | return 'resnet_v1_152' 85 | 86 | 87 | if __name__ == '__main__': 88 | tf.test.main() 89 | -------------------------------------------------------------------------------- /object_detection/models/ssd_resnet_v1_ppn_feature_extractor_testbase.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 | """Tests for ssd resnet v1 feature extractors.""" 16 | import abc 17 | import numpy as np 18 | 19 | from object_detection.models import ssd_feature_extractor_test 20 | 21 | 22 | class SSDResnetPpnFeatureExtractorTestBase( 23 | ssd_feature_extractor_test.SsdFeatureExtractorTestBase): 24 | """Helper test class for SSD Resnet PPN feature extractors.""" 25 | 26 | @abc.abstractmethod 27 | def _scope_name(self): 28 | pass 29 | 30 | def test_extract_features_returns_correct_shapes_289(self): 31 | image_height = 289 32 | image_width = 289 33 | depth_multiplier = 1.0 34 | pad_to_multiple = 1 35 | expected_feature_map_shape = [(2, 19, 19, 1024), (2, 10, 10, 1024), 36 | (2, 5, 5, 1024), (2, 3, 3, 1024), 37 | (2, 2, 2, 1024), (2, 1, 1, 1024)] 38 | self.check_extract_features_returns_correct_shape( 39 | 2, image_height, image_width, depth_multiplier, pad_to_multiple, 40 | expected_feature_map_shape) 41 | 42 | def test_extract_features_returns_correct_shapes_with_dynamic_inputs(self): 43 | image_height = 289 44 | image_width = 289 45 | depth_multiplier = 1.0 46 | pad_to_multiple = 1 47 | expected_feature_map_shape = [(2, 19, 19, 1024), (2, 10, 10, 1024), 48 | (2, 5, 5, 1024), (2, 3, 3, 1024), 49 | (2, 2, 2, 1024), (2, 1, 1, 1024)] 50 | self.check_extract_features_returns_correct_shapes_with_dynamic_inputs( 51 | 2, image_height, image_width, depth_multiplier, pad_to_multiple, 52 | expected_feature_map_shape) 53 | 54 | def test_extract_features_raises_error_with_invalid_image_size(self): 55 | image_height = 32 56 | image_width = 32 57 | depth_multiplier = 1.0 58 | pad_to_multiple = 1 59 | self.check_extract_features_raises_error_with_invalid_image_size( 60 | image_height, image_width, depth_multiplier, pad_to_multiple) 61 | 62 | def test_preprocess_returns_correct_value_range(self): 63 | image_height = 128 64 | image_width = 128 65 | depth_multiplier = 1 66 | pad_to_multiple = 1 67 | test_image = np.random.rand(4, image_height, image_width, 3) 68 | feature_extractor = self._create_feature_extractor(depth_multiplier, 69 | pad_to_multiple) 70 | preprocessed_image = feature_extractor.preprocess(test_image) 71 | self.assertAllClose(preprocessed_image, 72 | test_image - [[123.68, 116.779, 103.939]]) 73 | 74 | def test_variables_only_created_in_scope(self): 75 | depth_multiplier = 1 76 | pad_to_multiple = 1 77 | self.check_feature_extractor_variables_under_scope( 78 | depth_multiplier, pad_to_multiple, self._scope_name()) 79 | -------------------------------------------------------------------------------- /object_detection/predictors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/predictors/__init__.py -------------------------------------------------------------------------------- /object_detection/predictors/heads/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/object_detection/predictors/heads/__init__.py -------------------------------------------------------------------------------- /object_detection/predictors/heads/head.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 head class. 17 | 18 | All the different kinds of prediction heads in different models will inherit 19 | from this class. What is in common between all head classes is that they have a 20 | `predict` function that receives `features` as its first argument. 21 | 22 | How to add a new prediction head to an existing meta architecture? 23 | For example, how can we add a `3d shape` prediction head to Mask RCNN? 24 | 25 | We have to take the following steps to add a new prediction head to an 26 | existing meta arch: 27 | (a) Add a class for predicting the head. This class should inherit from the 28 | `Head` class below and have a `predict` function that receives the features 29 | and predicts the output. The output is always a tf.float32 tensor. 30 | (b) Add the head to the meta architecture. For example in case of Mask RCNN, 31 | go to box_predictor_builder and put in the logic for adding the new head to the 32 | Mask RCNN box predictor. 33 | (c) Add the logic for computing the loss for the new head. 34 | (d) Add the necessary metrics for the new head. 35 | (e) (optional) Add visualization for the new head. 36 | """ 37 | from abc import abstractmethod 38 | 39 | 40 | class Head(object): 41 | """Mask RCNN head base class.""" 42 | 43 | def __init__(self): 44 | """Constructor.""" 45 | pass 46 | 47 | @abstractmethod 48 | def predict(self, features, num_predictions_per_location): 49 | """Returns the head's predictions. 50 | 51 | Args: 52 | features: A float tensor of features. 53 | num_predictions_per_location: Int containing number of predictions per 54 | location. 55 | 56 | Returns: 57 | A tf.float32 tensor. 58 | """ 59 | pass 60 | -------------------------------------------------------------------------------- /object_detection/predictors/heads/keypoint_head_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.predictors.heads.keypoint_head.""" 17 | import tensorflow as tf 18 | 19 | from google.protobuf import text_format 20 | from object_detection.builders import hyperparams_builder 21 | from object_detection.predictors.heads import keypoint_head 22 | from object_detection.protos import hyperparams_pb2 23 | from object_detection.utils import test_case 24 | 25 | 26 | class MaskRCNNKeypointHeadTest(test_case.TestCase): 27 | 28 | def _build_arg_scope_with_hyperparams(self, 29 | op_type=hyperparams_pb2.Hyperparams.FC): 30 | hyperparams = hyperparams_pb2.Hyperparams() 31 | hyperparams_text_proto = """ 32 | activation: NONE 33 | regularizer { 34 | l2_regularizer { 35 | } 36 | } 37 | initializer { 38 | truncated_normal_initializer { 39 | } 40 | } 41 | """ 42 | text_format.Merge(hyperparams_text_proto, hyperparams) 43 | hyperparams.op = op_type 44 | return hyperparams_builder.build(hyperparams, is_training=True) 45 | 46 | def test_prediction_size(self): 47 | keypoint_prediction_head = keypoint_head.MaskRCNNKeypointHead( 48 | conv_hyperparams_fn=self._build_arg_scope_with_hyperparams()) 49 | roi_pooled_features = tf.random_uniform( 50 | [64, 14, 14, 1024], minval=-2.0, maxval=2.0, dtype=tf.float32) 51 | prediction = keypoint_prediction_head.predict( 52 | features=roi_pooled_features, num_predictions_per_location=1) 53 | self.assertAllEqual([64, 1, 17, 56, 56], prediction.get_shape().as_list()) 54 | 55 | 56 | if __name__ == '__main__': 57 | tf.test.main() 58 | -------------------------------------------------------------------------------- /object_detection/predictors/rfcn_box_predictor_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.predictors.rfcn_box_predictor.""" 17 | import numpy as np 18 | import tensorflow as tf 19 | 20 | from google.protobuf import text_format 21 | from object_detection.builders import hyperparams_builder 22 | from object_detection.predictors import rfcn_box_predictor as box_predictor 23 | from object_detection.protos import hyperparams_pb2 24 | from object_detection.utils import test_case 25 | 26 | 27 | class RfcnBoxPredictorTest(test_case.TestCase): 28 | 29 | def _build_arg_scope_with_conv_hyperparams(self): 30 | conv_hyperparams = hyperparams_pb2.Hyperparams() 31 | conv_hyperparams_text_proto = """ 32 | regularizer { 33 | l2_regularizer { 34 | } 35 | } 36 | initializer { 37 | truncated_normal_initializer { 38 | } 39 | } 40 | """ 41 | text_format.Merge(conv_hyperparams_text_proto, conv_hyperparams) 42 | return hyperparams_builder.build(conv_hyperparams, is_training=True) 43 | 44 | def test_get_correct_box_encoding_and_class_prediction_shapes(self): 45 | 46 | def graph_fn(image_features, proposal_boxes): 47 | rfcn_box_predictor = box_predictor.RfcnBoxPredictor( 48 | is_training=False, 49 | num_classes=2, 50 | conv_hyperparams_fn=self._build_arg_scope_with_conv_hyperparams(), 51 | num_spatial_bins=[3, 3], 52 | depth=4, 53 | crop_size=[12, 12], 54 | box_code_size=4 55 | ) 56 | box_predictions = rfcn_box_predictor.predict( 57 | [image_features], num_predictions_per_location=[1], 58 | scope='BoxPredictor', 59 | proposal_boxes=proposal_boxes) 60 | box_encodings = tf.concat( 61 | box_predictions[box_predictor.BOX_ENCODINGS], axis=1) 62 | class_predictions_with_background = tf.concat( 63 | box_predictions[box_predictor.CLASS_PREDICTIONS_WITH_BACKGROUND], 64 | axis=1) 65 | return (box_encodings, class_predictions_with_background) 66 | 67 | image_features = np.random.rand(4, 8, 8, 64).astype(np.float32) 68 | proposal_boxes = np.random.rand(4, 2, 4).astype(np.float32) 69 | (box_encodings, class_predictions_with_background) = self.execute( 70 | graph_fn, [image_features, proposal_boxes]) 71 | 72 | self.assertAllEqual(box_encodings.shape, [8, 1, 2, 4]) 73 | self.assertAllEqual(class_predictions_with_background.shape, [8, 1, 3]) 74 | 75 | 76 | if __name__ == '__main__': 77 | tf.test.main() 78 | -------------------------------------------------------------------------------- /object_detection/protos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric3911/Mini-SSD/6fb6e1bce3ab6e4adb832b37e78325803c7424b6/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 | //