├── LICENSE ├── MANIFEST.in ├── README.md ├── configs ├── _base_ │ ├── datasets │ │ ├── cityscapes_detection.py │ │ ├── cityscapes_instance.py │ │ ├── coco_detection.py │ │ ├── coco_instance.py │ │ ├── coco_instance_semantic.py │ │ ├── coco_panoptic.py │ │ ├── deepfashion.py │ │ ├── lvis_v0.5_instance.py │ │ ├── lvis_v1_instance.py │ │ ├── openimages_detection.py │ │ ├── voc0712.py │ │ └── wider_face.py │ ├── default_runtime.py │ ├── models │ │ ├── cascade_mask_rcnn_r50_fpn.py │ │ ├── cascade_rcnn_r50_fpn.py │ │ ├── fast_rcnn_r50_fpn.py │ │ ├── faster_rcnn_r50_caffe_c4.py │ │ ├── faster_rcnn_r50_caffe_dc5.py │ │ ├── faster_rcnn_r50_fpn.py │ │ ├── mask_rcnn_r50_caffe_c4.py │ │ ├── mask_rcnn_r50_fpn.py │ │ ├── retinanet_r50_fpn.py │ │ ├── rpn_r50_caffe_c4.py │ │ ├── rpn_r50_fpn.py │ │ └── ssd300.py │ └── schedules │ │ ├── schedule_1x.py │ │ ├── schedule_20e.py │ │ └── schedule_2x.py └── rvc │ ├── ablation │ ├── cascade_rcnn_bifpn_32gf_1x_coco.py │ ├── cascade_rcnn_bifpn_crpn_32gf_1x_coco.py │ ├── cascade_rcnn_fpn_32gf_1x_coco.py │ ├── cascade_rcnn_nasfpn_32gf_1x_coco.py │ ├── cascade_rcnn_nasfpn_crpn_32gf_1x_coco.py │ ├── cascade_rcnn_pafpn_32gf_1x_coco.py │ ├── cascade_rcnn_pafpn_crpn_32gf_1x_coco.py │ └── faster_rcnn_fpn_32gf_1x_coco_frozen.py │ ├── cascade_rcnn_nasfpn_crpn_256gf_1x_rvc.py │ ├── cascade_rcnn_nasfpn_crpn_32gf_1x_rvc.py │ └── finetune │ ├── cascade_rcnn_nasfpn_crpn_32gf_0.5x_oid.py │ ├── cascade_rcnn_nasfpn_crpn_32gf_2x_coco.py │ └── cascade_rcnn_nasfpn_crpn_32gf_2x_mvt.py ├── demo ├── MMDet_InstanceSeg_Tutorial.ipynb ├── MMDet_Tutorial.ipynb ├── create_result_gif.py ├── demo.jpg ├── demo.mp4 ├── image_demo.py ├── inference_demo.ipynb ├── video_demo.py ├── video_gpuaccel_demo.py └── webcam_demo.py ├── docker ├── Dockerfile └── serve │ ├── Dockerfile │ ├── config.properties │ └── entrypoint.sh ├── docs ├── en │ ├── 1_exist_data_model.md │ ├── 2_new_data_model.md │ ├── 3_exist_data_new_model.md │ ├── Makefile │ ├── _static │ │ ├── css │ │ │ └── readthedocs.css │ │ └── image │ │ │ └── mmdet-logo.png │ ├── api.rst │ ├── changelog.md │ ├── compatibility.md │ ├── conf.py │ ├── conventions.md │ ├── faq.md │ ├── get_started.md │ ├── index.rst │ ├── make.bat │ ├── model_zoo.md │ ├── projects.md │ ├── robustness_benchmarking.md │ ├── stat.py │ ├── switch_language.md │ ├── tutorials │ │ ├── config.md │ │ ├── customize_dataset.md │ │ ├── customize_losses.md │ │ ├── customize_models.md │ │ ├── customize_runtime.md │ │ ├── data_pipeline.md │ │ ├── finetune.md │ │ ├── how_to.md │ │ ├── index.rst │ │ ├── init_cfg.md │ │ ├── onnx2tensorrt.md │ │ ├── pytorch2onnx.md │ │ ├── test_results_submission.md │ │ └── useful_hooks.md │ └── useful_tools.md ├── top.jpg ├── visualization.jpg └── zh_cn │ ├── 1_exist_data_model.md │ ├── 2_new_data_model.md │ ├── 3_exist_data_new_model.md │ ├── Makefile │ ├── _static │ ├── css │ │ └── readthedocs.css │ └── image │ │ └── mmdet-logo.png │ ├── api.rst │ ├── article.md │ ├── compatibility.md │ ├── conf.py │ ├── conventions.md │ ├── faq.md │ ├── get_started.md │ ├── index.rst │ ├── make.bat │ ├── model_zoo.md │ ├── projects.md │ ├── robustness_benchmarking.md │ ├── stat.py │ ├── switch_language.md │ ├── tutorials │ ├── config.md │ ├── customize_dataset.md │ ├── customize_losses.md │ ├── customize_models.md │ ├── customize_runtime.md │ ├── data_pipeline.md │ ├── finetune.md │ ├── how_to.md │ ├── index.rst │ ├── init_cfg.md │ ├── onnx2tensorrt.md │ └── pytorch2onnx.md │ └── useful_tools.md ├── label_spaces ├── challenge-2019-label500-hierarchy.json ├── class_names.txt ├── gen_hierarchy.py ├── hierarchy_oid.json ├── hierarchy_rvc.json └── obj_det_mapping_540.csv ├── mmdet ├── __init__.py ├── apis │ ├── __init__.py │ ├── inference.py │ ├── test.py │ └── train.py ├── core │ ├── __init__.py │ ├── anchor │ │ ├── __init__.py │ │ ├── anchor_generator.py │ │ ├── builder.py │ │ ├── point_generator.py │ │ └── utils.py │ ├── bbox │ │ ├── __init__.py │ │ ├── assigners │ │ │ ├── __init__.py │ │ │ ├── approx_max_iou_assigner.py │ │ │ ├── assign_result.py │ │ │ ├── atss_assigner.py │ │ │ ├── base_assigner.py │ │ │ ├── center_region_assigner.py │ │ │ ├── grid_assigner.py │ │ │ ├── hungarian_assigner.py │ │ │ ├── mask_hungarian_assigner.py │ │ │ ├── max_iou_assigner.py │ │ │ ├── point_assigner.py │ │ │ ├── region_assigner.py │ │ │ ├── sim_ota_assigner.py │ │ │ ├── task_aligned_assigner.py │ │ │ └── uniform_assigner.py │ │ ├── builder.py │ │ ├── coder │ │ │ ├── __init__.py │ │ │ ├── base_bbox_coder.py │ │ │ ├── bucketing_bbox_coder.py │ │ │ ├── delta_xywh_bbox_coder.py │ │ │ ├── distance_point_bbox_coder.py │ │ │ ├── legacy_delta_xywh_bbox_coder.py │ │ │ ├── pseudo_bbox_coder.py │ │ │ ├── tblr_bbox_coder.py │ │ │ └── yolo_bbox_coder.py │ │ ├── demodata.py │ │ ├── iou_calculators │ │ │ ├── __init__.py │ │ │ ├── builder.py │ │ │ └── iou2d_calculator.py │ │ ├── match_costs │ │ │ ├── __init__.py │ │ │ ├── builder.py │ │ │ └── match_cost.py │ │ ├── samplers │ │ │ ├── __init__.py │ │ │ ├── base_sampler.py │ │ │ ├── combined_sampler.py │ │ │ ├── instance_balanced_pos_sampler.py │ │ │ ├── iou_balanced_neg_sampler.py │ │ │ ├── mask_pseudo_sampler.py │ │ │ ├── mask_sampling_result.py │ │ │ ├── ohem_sampler.py │ │ │ ├── pseudo_sampler.py │ │ │ ├── random_sampler.py │ │ │ ├── sampling_result.py │ │ │ └── score_hlr_sampler.py │ │ └── transforms.py │ ├── data_structures │ │ ├── __init__.py │ │ ├── general_data.py │ │ └── instance_data.py │ ├── evaluation │ │ ├── __init__.py │ │ ├── bbox_overlaps.py │ │ ├── class_names.py │ │ ├── eval_hooks.py │ │ ├── mean_ap.py │ │ ├── panoptic_utils.py │ │ └── recall.py │ ├── export │ │ ├── __init__.py │ │ ├── model_wrappers.py │ │ ├── onnx_helper.py │ │ └── pytorch2onnx.py │ ├── hook │ │ ├── __init__.py │ │ ├── checkloss_hook.py │ │ ├── ema.py │ │ ├── memory_profiler_hook.py │ │ ├── set_epoch_info_hook.py │ │ ├── sync_norm_hook.py │ │ ├── sync_random_size_hook.py │ │ ├── wandblogger_hook.py │ │ ├── yolox_lrupdater_hook.py │ │ └── yolox_mode_switch_hook.py │ ├── mask │ │ ├── __init__.py │ │ ├── mask_target.py │ │ ├── structures.py │ │ └── utils.py │ ├── optimizers │ │ ├── __init__.py │ │ ├── builder.py │ │ └── layer_decay_optimizer_constructor.py │ ├── post_processing │ │ ├── __init__.py │ │ ├── bbox_nms.py │ │ ├── matrix_nms.py │ │ └── merge_augs.py │ ├── utils │ │ ├── __init__.py │ │ ├── dist_utils.py │ │ └── misc.py │ └── visualization │ │ ├── __init__.py │ │ ├── image.py │ │ └── palette.py ├── datasets │ ├── __init__.py │ ├── api_wrappers │ │ ├── __init__.py │ │ ├── coco_api.py │ │ └── panoptic_evaluation.py │ ├── builder.py │ ├── cityscapes.py │ ├── coco.py │ ├── coco_panoptic.py │ ├── custom.py │ ├── dataset_wrappers.py │ ├── deepfashion.py │ ├── lvis.py │ ├── openimages.py │ ├── pipelines │ │ ├── __init__.py │ │ ├── auto_augment.py │ │ ├── compose.py │ │ ├── formating.py │ │ ├── formatting.py │ │ ├── instaboost.py │ │ ├── loading.py │ │ ├── test_time_aug.py │ │ └── transforms.py │ ├── samplers │ │ ├── __init__.py │ │ ├── class_aware_sampler.py │ │ ├── distributed_sampler.py │ │ ├── group_sampler.py │ │ └── infinite_sampler.py │ ├── utils.py │ ├── voc.py │ ├── wider_face.py │ └── xml_style.py ├── models │ ├── __init__.py │ ├── backbones │ │ ├── __init__.py │ │ ├── csp_darknet.py │ │ ├── darknet.py │ │ ├── detectors_resnet.py │ │ ├── detectors_resnext.py │ │ ├── efficientnet.py │ │ ├── hourglass.py │ │ ├── hrnet.py │ │ ├── mobilenet_v2.py │ │ ├── pvt.py │ │ ├── regnet.py │ │ ├── regnet10b.py │ │ ├── regnet256gf.py │ │ ├── regnet32gf.py │ │ ├── res2net.py │ │ ├── resnest.py │ │ ├── resnet.py │ │ ├── resnext.py │ │ ├── ssd_vgg.py │ │ ├── swin.py │ │ └── trident_resnet.py │ ├── builder.py │ ├── dense_heads │ │ ├── __init__.py │ │ ├── anchor_free_head.py │ │ ├── anchor_head.py │ │ ├── atss_head.py │ │ ├── autoassign_head.py │ │ ├── base_dense_head.py │ │ ├── base_mask_head.py │ │ ├── cascade_rpn_head.py │ │ ├── cascade_rpn_head_ms.py │ │ ├── centernet_head.py │ │ ├── centripetal_head.py │ │ ├── corner_head.py │ │ ├── ddod_head.py │ │ ├── deformable_detr_head.py │ │ ├── dense_test_mixins.py │ │ ├── detr_head.py │ │ ├── embedding_rpn_head.py │ │ ├── fcos_head.py │ │ ├── fovea_head.py │ │ ├── free_anchor_retina_head.py │ │ ├── fsaf_head.py │ │ ├── ga_retina_head.py │ │ ├── ga_rpn_head.py │ │ ├── gfl_head.py │ │ ├── guided_anchor_head.py │ │ ├── lad_head.py │ │ ├── ld_head.py │ │ ├── mask2former_head.py │ │ ├── maskformer_head.py │ │ ├── nasfcos_head.py │ │ ├── paa_head.py │ │ ├── pisa_retinanet_head.py │ │ ├── pisa_ssd_head.py │ │ ├── reppoints_head.py │ │ ├── retina_head.py │ │ ├── retina_sepbn_head.py │ │ ├── rpn_head.py │ │ ├── sabl_retina_head.py │ │ ├── solo_head.py │ │ ├── solov2_head.py │ │ ├── ssd_head.py │ │ ├── tood_head.py │ │ ├── vfnet_head.py │ │ ├── yolact_head.py │ │ ├── yolo_head.py │ │ ├── yolof_head.py │ │ └── yolox_head.py │ ├── detectors │ │ ├── __init__.py │ │ ├── atss.py │ │ ├── autoassign.py │ │ ├── base.py │ │ ├── cascade_rcnn.py │ │ ├── centernet.py │ │ ├── cornernet.py │ │ ├── ddod.py │ │ ├── deformable_detr.py │ │ ├── detr.py │ │ ├── fast_rcnn.py │ │ ├── faster_rcnn.py │ │ ├── fcos.py │ │ ├── fovea.py │ │ ├── fsaf.py │ │ ├── gfl.py │ │ ├── grid_rcnn.py │ │ ├── htc.py │ │ ├── kd_one_stage.py │ │ ├── lad.py │ │ ├── mask2former.py │ │ ├── mask_rcnn.py │ │ ├── mask_scoring_rcnn.py │ │ ├── maskformer.py │ │ ├── nasfcos.py │ │ ├── paa.py │ │ ├── panoptic_fpn.py │ │ ├── panoptic_two_stage_segmentor.py │ │ ├── point_rend.py │ │ ├── queryinst.py │ │ ├── reppoints_detector.py │ │ ├── retinanet.py │ │ ├── rpn.py │ │ ├── scnet.py │ │ ├── single_stage.py │ │ ├── single_stage_instance_seg.py │ │ ├── solo.py │ │ ├── solov2.py │ │ ├── sparse_rcnn.py │ │ ├── tood.py │ │ ├── trident_faster_rcnn.py │ │ ├── two_stage.py │ │ ├── vfnet.py │ │ ├── yolact.py │ │ ├── yolo.py │ │ ├── yolof.py │ │ └── yolox.py │ ├── losses │ │ ├── __init__.py │ │ ├── accuracy.py │ │ ├── ae_loss.py │ │ ├── balanced_l1_loss.py │ │ ├── cross_entropy_loss.py │ │ ├── dice_loss.py │ │ ├── focal_loss.py │ │ ├── gaussian_focal_loss.py │ │ ├── gfocal_loss.py │ │ ├── ghm_loss.py │ │ ├── hierarchy_loss.py │ │ ├── iou_loss.py │ │ ├── kd_loss.py │ │ ├── mse_loss.py │ │ ├── pisa_loss.py │ │ ├── seesaw_loss.py │ │ ├── smooth_l1_loss.py │ │ ├── utils.py │ │ └── varifocal_loss.py │ ├── necks │ │ ├── __init__.py │ │ ├── bfp.py │ │ ├── bifpn.py │ │ ├── channel_mapper.py │ │ ├── ct_resnet_neck.py │ │ ├── dilated_encoder.py │ │ ├── dyhead.py │ │ ├── fpg.py │ │ ├── fpn.py │ │ ├── fpn_carafe.py │ │ ├── hrfpn.py │ │ ├── nas_fpn.py │ │ ├── nasfcos_fpn.py │ │ ├── pafpn.py │ │ ├── rfp.py │ │ ├── ssd_neck.py │ │ ├── yolo_neck.py │ │ └── yolox_pafpn.py │ ├── plugins │ │ ├── __init__.py │ │ ├── dropblock.py │ │ ├── msdeformattn_pixel_decoder.py │ │ └── pixel_decoder.py │ ├── roi_heads │ │ ├── __init__.py │ │ ├── base_roi_head.py │ │ ├── bbox_heads │ │ │ ├── __init__.py │ │ │ ├── bbox_head.py │ │ │ ├── convfc_bbox_head.py │ │ │ ├── dii_head.py │ │ │ ├── double_bbox_head.py │ │ │ ├── sabl_head.py │ │ │ └── scnet_bbox_head.py │ │ ├── cascade_roi_head.py │ │ ├── double_roi_head.py │ │ ├── dynamic_roi_head.py │ │ ├── grid_roi_head.py │ │ ├── htc_roi_head.py │ │ ├── mask_heads │ │ │ ├── __init__.py │ │ │ ├── coarse_mask_head.py │ │ │ ├── dynamic_mask_head.py │ │ │ ├── fcn_mask_head.py │ │ │ ├── feature_relay_head.py │ │ │ ├── fused_semantic_head.py │ │ │ ├── global_context_head.py │ │ │ ├── grid_head.py │ │ │ ├── htc_mask_head.py │ │ │ ├── mask_point_head.py │ │ │ ├── maskiou_head.py │ │ │ ├── scnet_mask_head.py │ │ │ └── scnet_semantic_head.py │ │ ├── mask_scoring_roi_head.py │ │ ├── pisa_roi_head.py │ │ ├── point_rend_roi_head.py │ │ ├── roi_extractors │ │ │ ├── __init__.py │ │ │ ├── base_roi_extractor.py │ │ │ ├── generic_roi_extractor.py │ │ │ └── single_level_roi_extractor.py │ │ ├── scnet_roi_head.py │ │ ├── shared_heads │ │ │ ├── __init__.py │ │ │ └── res_layer.py │ │ ├── sparse_roi_head.py │ │ ├── standard_roi_head.py │ │ ├── test_mixins.py │ │ └── trident_roi_head.py │ ├── seg_heads │ │ ├── __init__.py │ │ ├── base_semantic_head.py │ │ ├── panoptic_fpn_head.py │ │ └── panoptic_fusion_heads │ │ │ ├── __init__.py │ │ │ ├── base_panoptic_fusion_head.py │ │ │ ├── heuristic_fusion_head.py │ │ │ └── maskformer_fusion_head.py │ └── utils │ │ ├── __init__.py │ │ ├── brick_wrappers.py │ │ ├── builder.py │ │ ├── ckpt_convert.py │ │ ├── conv_upsample.py │ │ ├── csp_layer.py │ │ ├── gaussian_target.py │ │ ├── inverted_residual.py │ │ ├── make_divisible.py │ │ ├── misc.py │ │ ├── normed_predictor.py │ │ ├── panoptic_gt_processing.py │ │ ├── point_sample.py │ │ ├── positional_encoding.py │ │ ├── res_layer.py │ │ ├── se_layer.py │ │ └── transformer.py ├── utils │ ├── __init__.py │ ├── collect_env.py │ ├── compat_config.py │ ├── contextmanagers.py │ ├── logger.py │ ├── memory.py │ ├── misc.py │ ├── profiling.py │ ├── replace_cfg_vals.py │ ├── setup_env.py │ ├── split_batch.py │ ├── util_distribution.py │ ├── util_mixins.py │ └── util_random.py └── version.py ├── openimages2coco-master ├── LICENSE ├── README.md ├── convert_annotations.py ├── convert_predictions.py ├── convert_predictions_custom.py ├── data │ ├── test-rvc2020_sizes-00000-of-00001.csv │ └── validation_sizes-00000-of-00001.csv ├── requirements.txt ├── utils.py └── visualize_examples.ipynb ├── pytest.ini ├── requirements.txt ├── requirements ├── albu.txt ├── build.txt ├── docs.txt ├── mminstall.txt ├── optional.txt ├── readthedocs.txt ├── runtime.txt └── tests.txt ├── resources ├── coco_test_12510.jpg ├── corruptions_sev_3.png ├── data_pipeline.png ├── loss_curve.png ├── mmdet-logo.png └── zhihu_qrcode.jpg ├── setup.cfg ├── setup.py ├── tests ├── data │ ├── VOCdevkit │ │ ├── VOC2007 │ │ │ ├── Annotations │ │ │ │ └── 000001.xml │ │ │ ├── ImageSets │ │ │ │ └── Main │ │ │ │ │ ├── test.txt │ │ │ │ │ └── trainval.txt │ │ │ └── JPEGImages │ │ │ │ └── 000001.jpg │ │ └── VOC2012 │ │ │ ├── Annotations │ │ │ └── 000001.xml │ │ │ ├── ImageSets │ │ │ └── Main │ │ │ │ ├── test.txt │ │ │ │ └── trainval.txt │ │ │ └── JPEGImages │ │ │ └── 000001.jpg │ ├── coco_sample.json │ ├── color.jpg │ ├── configs_mmtrack │ │ ├── faster_rcnn_r50_dc5.py │ │ ├── faster_rcnn_r50_fpn.py │ │ ├── mot_challenge.py │ │ ├── selsa_faster_rcnn_r101_dc5_1x.py │ │ └── tracktor_faster-rcnn_r50_fpn_4e.py │ ├── custom_dataset │ │ ├── images │ │ │ ├── 000001.jpg │ │ │ └── 000001.xml │ │ ├── test.txt │ │ └── trainval.txt │ └── gray.jpg ├── test_data │ ├── test_datasets │ │ ├── test_coco_dataset.py │ │ ├── test_common.py │ │ ├── test_custom_dataset.py │ │ ├── test_dataset_wrapper.py │ │ ├── test_openimages_dataset.py │ │ ├── test_panoptic_dataset.py │ │ └── test_xml_dataset.py │ ├── test_pipelines │ │ ├── test_formatting.py │ │ ├── test_loading.py │ │ ├── test_sampler.py │ │ └── test_transform │ │ │ ├── __init__.py │ │ │ ├── test_img_augment.py │ │ │ ├── test_models_aug_test.py │ │ │ ├── test_rotate.py │ │ │ ├── test_shear.py │ │ │ ├── test_transform.py │ │ │ ├── test_translate.py │ │ │ └── utils.py │ └── test_utils.py ├── test_downstream │ └── test_mmtrack.py ├── test_metrics │ ├── test_box_overlap.py │ ├── test_losses.py │ ├── test_mean_ap.py │ └── test_recall.py ├── test_models │ ├── test_backbones │ │ ├── __init__.py │ │ ├── test_csp_darknet.py │ │ ├── test_detectors_resnet.py │ │ ├── test_efficientnet.py │ │ ├── test_hourglass.py │ │ ├── test_hrnet.py │ │ ├── test_mobilenet_v2.py │ │ ├── test_pvt.py │ │ ├── test_regnet.py │ │ ├── test_renext.py │ │ ├── test_res2net.py │ │ ├── test_resnest.py │ │ ├── test_resnet.py │ │ ├── test_swin.py │ │ ├── test_trident_resnet.py │ │ └── utils.py │ ├── test_dense_heads │ │ ├── test_anchor_head.py │ │ ├── test_atss_head.py │ │ ├── test_autoassign_head.py │ │ ├── test_centernet_head.py │ │ ├── test_corner_head.py │ │ ├── test_ddod_head.py │ │ ├── test_dense_heads_attr.py │ │ ├── test_detr_head.py │ │ ├── test_fcos_head.py │ │ ├── test_fsaf_head.py │ │ ├── test_ga_anchor_head.py │ │ ├── test_gfl_head.py │ │ ├── test_lad_head.py │ │ ├── test_ld_head.py │ │ ├── test_mask2former_head.py │ │ ├── test_maskformer_head.py │ │ ├── test_paa_head.py │ │ ├── test_pisa_head.py │ │ ├── test_sabl_retina_head.py │ │ ├── test_solo_head.py │ │ ├── test_tood_head.py │ │ ├── test_vfnet_head.py │ │ ├── test_yolact_head.py │ │ ├── test_yolof_head.py │ │ └── test_yolox_head.py │ ├── test_forward.py │ ├── test_loss.py │ ├── test_loss_compatibility.py │ ├── test_necks.py │ ├── test_plugins.py │ ├── test_roi_heads │ │ ├── __init__.py │ │ ├── test_bbox_head.py │ │ ├── test_mask_head.py │ │ ├── test_roi_extractor.py │ │ ├── test_sabl_bbox_head.py │ │ └── utils.py │ ├── test_seg_heads │ │ └── test_maskformer_fusion_head.py │ └── test_utils │ │ ├── test_brick_wrappers.py │ │ ├── test_conv_upsample.py │ │ ├── test_inverted_residual.py │ │ ├── test_model_misc.py │ │ ├── test_position_encoding.py │ │ ├── test_se_layer.py │ │ └── test_transformer.py ├── test_onnx │ ├── __init__.py │ ├── data │ │ ├── fsaf_head_get_bboxes.pkl │ │ ├── retina_head_get_bboxes.pkl │ │ ├── ssd_head_get_bboxes.pkl │ │ ├── yolov3_head_get_bboxes.pkl │ │ └── yolov3_neck.pkl │ ├── test_head.py │ ├── test_neck.py │ └── utils.py ├── test_runtime │ ├── async_benchmark.py │ ├── test_apis.py │ ├── test_async.py │ ├── test_config.py │ ├── test_eval_hook.py │ └── test_fp16.py └── test_utils │ ├── test_anchor.py │ ├── test_assigner.py │ ├── test_coder.py │ ├── test_compat_config.py │ ├── test_general_data.py │ ├── test_hook.py │ ├── test_layer_decay_optimizer_constructor.py │ ├── test_logger.py │ ├── test_masks.py │ ├── test_memory.py │ ├── test_misc.py │ ├── test_nms.py │ ├── test_replace_cfg_vals.py │ ├── test_setup_env.py │ ├── test_split_batch.py │ ├── test_version.py │ └── test_visualization.py └── tools ├── analysis_tools ├── analyze_logs.py ├── analyze_results.py ├── benchmark.py ├── coco_error_analysis.py ├── confusion_matrix.py ├── eval_metric.py ├── get_flops.py ├── optimize_anchors.py ├── robustness_eval.py └── test_robustness.py ├── dataset_converters ├── cityscapes.py ├── images2coco.py └── pascal_voc.py ├── deployment ├── mmdet2torchserve.py ├── mmdet_handler.py ├── onnx2tensorrt.py ├── pytorch2onnx.py ├── test.py └── test_torchserver.py ├── dist_test.sh ├── dist_train.sh ├── eval_tools └── oid │ ├── eval.sh │ ├── io_utils.py │ ├── metrics.py │ ├── np_box_list.py │ ├── np_box_list_ops.py │ ├── np_box_mask_list.py │ ├── np_box_mask_list_ops.py │ ├── np_box_ops.py │ ├── np_mask_ops.py │ ├── object_detection_evaluation.py │ ├── oid_challenge_evaluation_utils.py │ ├── oid_eval.py │ ├── oid_hierarchical_labels_expansion.py │ ├── oid_object_detection_challenge_500_label_map.pbtxt │ ├── per_image_evaluation.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 │ ├── calibration.proto │ ├── calibration_pb2.py │ ├── center_net.proto │ ├── center_net_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 │ ├── flexible_grid_anchor_generator.proto │ ├── flexible_grid_anchor_generator_pb2.py │ ├── fpn.proto │ ├── fpn_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 │ ├── target_assigner.proto │ ├── target_assigner_pb2.py │ ├── train.proto │ └── train_pb2.py │ └── standard_fields.py ├── misc ├── browse_dataset.py ├── download_dataset.py ├── gen_coco_panoptic_test_info.py ├── get_image_metas.py ├── print_config.py └── split_coco.py ├── model_converters ├── detectron2pytorch.py ├── publish_model.py ├── regnet2mmdet.py ├── selfsup2mmdet.py ├── upgrade_model_version.py └── upgrade_ssd_version.py ├── slurm_test.sh ├── slurm_train.sh ├── test.py └── train.py /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements/*.txt 2 | include mmdet/VERSION 3 | include mmdet/.mim/model-index.yml 4 | include mmdet/.mim/demo/*/* 5 | recursive-include mmdet/.mim/configs *.py *.yml 6 | recursive-include mmdet/.mim/tools *.sh *.py 7 | -------------------------------------------------------------------------------- /configs/_base_/datasets/coco_detection.py: -------------------------------------------------------------------------------- 1 | # dataset settings 2 | dataset_type = 'CocoDataset' 3 | data_root = 'data/coco/' 4 | img_norm_cfg = dict( 5 | mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) 6 | train_pipeline = [ 7 | dict(type='LoadImageFromFile'), 8 | dict(type='LoadAnnotations', with_bbox=True), 9 | dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), 10 | dict(type='RandomFlip', flip_ratio=0.5), 11 | dict(type='Normalize', **img_norm_cfg), 12 | dict(type='Pad', size_divisor=32), 13 | dict(type='DefaultFormatBundle'), 14 | dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']), 15 | ] 16 | test_pipeline = [ 17 | dict(type='LoadImageFromFile'), 18 | dict( 19 | type='MultiScaleFlipAug', 20 | img_scale=(1333, 800), 21 | flip=False, 22 | transforms=[ 23 | dict(type='Resize', keep_ratio=True), 24 | dict(type='RandomFlip'), 25 | dict(type='Normalize', **img_norm_cfg), 26 | dict(type='Pad', size_divisor=32), 27 | dict(type='ImageToTensor', keys=['img']), 28 | dict(type='Collect', keys=['img']), 29 | ]) 30 | ] 31 | data = dict( 32 | samples_per_gpu=2, 33 | workers_per_gpu=2, 34 | train=dict( 35 | type=dataset_type, 36 | ann_file=data_root + 'annotations/instances_train2017.json', 37 | img_prefix=data_root + 'train2017/', 38 | pipeline=train_pipeline), 39 | val=dict( 40 | type=dataset_type, 41 | ann_file=data_root + 'annotations/instances_val2017.json', 42 | img_prefix=data_root + 'val2017/', 43 | pipeline=test_pipeline), 44 | test=dict( 45 | type=dataset_type, 46 | ann_file=data_root + 'annotations/instances_val2017.json', 47 | img_prefix=data_root + 'val2017/', 48 | pipeline=test_pipeline)) 49 | evaluation = dict(interval=1, metric='bbox') 50 | -------------------------------------------------------------------------------- /configs/_base_/datasets/coco_instance.py: -------------------------------------------------------------------------------- 1 | # dataset settings 2 | dataset_type = 'CocoDataset' 3 | data_root = 'data/coco/' 4 | img_norm_cfg = dict( 5 | mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) 6 | train_pipeline = [ 7 | dict(type='LoadImageFromFile'), 8 | dict(type='LoadAnnotations', with_bbox=True, with_mask=True), 9 | dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), 10 | dict(type='RandomFlip', flip_ratio=0.5), 11 | dict(type='Normalize', **img_norm_cfg), 12 | dict(type='Pad', size_divisor=32), 13 | dict(type='DefaultFormatBundle'), 14 | dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks']), 15 | ] 16 | test_pipeline = [ 17 | dict(type='LoadImageFromFile'), 18 | dict( 19 | type='MultiScaleFlipAug', 20 | img_scale=(1333, 800), 21 | flip=False, 22 | transforms=[ 23 | dict(type='Resize', keep_ratio=True), 24 | dict(type='RandomFlip'), 25 | dict(type='Normalize', **img_norm_cfg), 26 | dict(type='Pad', size_divisor=32), 27 | dict(type='ImageToTensor', keys=['img']), 28 | dict(type='Collect', keys=['img']), 29 | ]) 30 | ] 31 | data = dict( 32 | samples_per_gpu=2, 33 | workers_per_gpu=2, 34 | train=dict( 35 | type=dataset_type, 36 | ann_file=data_root + 'annotations/instances_train2017.json', 37 | img_prefix=data_root + 'train2017/', 38 | pipeline=train_pipeline), 39 | val=dict( 40 | type=dataset_type, 41 | ann_file=data_root + 'annotations/instances_val2017.json', 42 | img_prefix=data_root + 'val2017/', 43 | pipeline=test_pipeline), 44 | test=dict( 45 | type=dataset_type, 46 | ann_file=data_root + 'annotations/instances_val2017.json', 47 | img_prefix=data_root + 'val2017/', 48 | pipeline=test_pipeline)) 49 | evaluation = dict(metric=['bbox', 'segm']) 50 | -------------------------------------------------------------------------------- /configs/_base_/datasets/deepfashion.py: -------------------------------------------------------------------------------- 1 | # dataset settings 2 | dataset_type = 'DeepFashionDataset' 3 | data_root = 'data/DeepFashion/In-shop/' 4 | img_norm_cfg = dict( 5 | mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) 6 | train_pipeline = [ 7 | dict(type='LoadImageFromFile'), 8 | dict(type='LoadAnnotations', with_bbox=True, with_mask=True), 9 | dict(type='Resize', img_scale=(750, 1101), keep_ratio=True), 10 | dict(type='RandomFlip', flip_ratio=0.5), 11 | dict(type='Normalize', **img_norm_cfg), 12 | dict(type='Pad', size_divisor=32), 13 | dict(type='DefaultFormatBundle'), 14 | dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks']), 15 | ] 16 | test_pipeline = [ 17 | dict(type='LoadImageFromFile'), 18 | dict( 19 | type='MultiScaleFlipAug', 20 | img_scale=(750, 1101), 21 | flip=False, 22 | transforms=[ 23 | dict(type='Resize', keep_ratio=True), 24 | dict(type='RandomFlip'), 25 | dict(type='Normalize', **img_norm_cfg), 26 | dict(type='Pad', size_divisor=32), 27 | dict(type='ImageToTensor', keys=['img']), 28 | dict(type='Collect', keys=['img']), 29 | ]) 30 | ] 31 | data = dict( 32 | imgs_per_gpu=2, 33 | workers_per_gpu=1, 34 | train=dict( 35 | type=dataset_type, 36 | ann_file=data_root + 'annotations/DeepFashion_segmentation_query.json', 37 | img_prefix=data_root + 'Img/', 38 | pipeline=train_pipeline, 39 | data_root=data_root), 40 | val=dict( 41 | type=dataset_type, 42 | ann_file=data_root + 'annotations/DeepFashion_segmentation_query.json', 43 | img_prefix=data_root + 'Img/', 44 | pipeline=test_pipeline, 45 | data_root=data_root), 46 | test=dict( 47 | type=dataset_type, 48 | ann_file=data_root + 49 | 'annotations/DeepFashion_segmentation_gallery.json', 50 | img_prefix=data_root + 'Img/', 51 | pipeline=test_pipeline, 52 | data_root=data_root)) 53 | evaluation = dict(interval=5, metric=['bbox', 'segm']) 54 | -------------------------------------------------------------------------------- /configs/_base_/datasets/lvis_v0.5_instance.py: -------------------------------------------------------------------------------- 1 | # dataset settings 2 | _base_ = 'coco_instance.py' 3 | dataset_type = 'LVISV05Dataset' 4 | data_root = 'data/lvis_v0.5/' 5 | data = dict( 6 | samples_per_gpu=2, 7 | workers_per_gpu=2, 8 | train=dict( 9 | _delete_=True, 10 | type='ClassBalancedDataset', 11 | oversample_thr=1e-3, 12 | dataset=dict( 13 | type=dataset_type, 14 | ann_file=data_root + 'annotations/lvis_v0.5_train.json', 15 | img_prefix=data_root + 'train2017/')), 16 | val=dict( 17 | type=dataset_type, 18 | ann_file=data_root + 'annotations/lvis_v0.5_val.json', 19 | img_prefix=data_root + 'val2017/'), 20 | test=dict( 21 | type=dataset_type, 22 | ann_file=data_root + 'annotations/lvis_v0.5_val.json', 23 | img_prefix=data_root + 'val2017/')) 24 | evaluation = dict(metric=['bbox', 'segm']) 25 | -------------------------------------------------------------------------------- /configs/_base_/datasets/lvis_v1_instance.py: -------------------------------------------------------------------------------- 1 | # dataset settings 2 | _base_ = 'coco_instance.py' 3 | dataset_type = 'LVISV1Dataset' 4 | data_root = 'data/lvis_v1/' 5 | data = dict( 6 | samples_per_gpu=2, 7 | workers_per_gpu=2, 8 | train=dict( 9 | _delete_=True, 10 | type='ClassBalancedDataset', 11 | oversample_thr=1e-3, 12 | dataset=dict( 13 | type=dataset_type, 14 | ann_file=data_root + 'annotations/lvis_v1_train.json', 15 | img_prefix=data_root)), 16 | val=dict( 17 | type=dataset_type, 18 | ann_file=data_root + 'annotations/lvis_v1_val.json', 19 | img_prefix=data_root), 20 | test=dict( 21 | type=dataset_type, 22 | ann_file=data_root + 'annotations/lvis_v1_val.json', 23 | img_prefix=data_root)) 24 | evaluation = dict(metric=['bbox', 'segm']) 25 | -------------------------------------------------------------------------------- /configs/_base_/default_runtime.py: -------------------------------------------------------------------------------- 1 | checkpoint_config = dict(interval=1) 2 | # yapf:disable 3 | log_config = dict( 4 | interval=50, 5 | hooks=[ 6 | dict(type='TextLoggerHook'), 7 | # dict(type='TensorboardLoggerHook') 8 | ]) 9 | # yapf:enable 10 | custom_hooks = [dict(type='NumClassCheckHook')] 11 | 12 | dist_params = dict(backend='nccl') 13 | log_level = 'INFO' 14 | load_from = None 15 | resume_from = None 16 | workflow = [('train', 1)] 17 | 18 | # disable opencv multithreading to avoid system being overloaded 19 | opencv_num_threads = 0 20 | # set multi-process start method as `fork` to speed up the training 21 | mp_start_method = 'fork' 22 | 23 | # Default setting for scaling LR automatically 24 | # - `enable` means enable scaling LR automatically 25 | # or not by default. 26 | # - `base_batch_size` = (8 GPUs) x (2 samples per GPU). 27 | auto_scale_lr = dict(enable=False, base_batch_size=16) 28 | -------------------------------------------------------------------------------- /configs/_base_/models/retinanet_r50_fpn.py: -------------------------------------------------------------------------------- 1 | # model settings 2 | model = dict( 3 | type='RetinaNet', 4 | backbone=dict( 5 | type='ResNet', 6 | depth=50, 7 | num_stages=4, 8 | out_indices=(0, 1, 2, 3), 9 | frozen_stages=1, 10 | norm_cfg=dict(type='BN', requires_grad=True), 11 | norm_eval=True, 12 | style='pytorch', 13 | init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')), 14 | neck=dict( 15 | type='FPN', 16 | in_channels=[256, 512, 1024, 2048], 17 | out_channels=256, 18 | start_level=1, 19 | add_extra_convs='on_input', 20 | num_outs=5), 21 | bbox_head=dict( 22 | type='RetinaHead', 23 | num_classes=80, 24 | in_channels=256, 25 | stacked_convs=4, 26 | feat_channels=256, 27 | anchor_generator=dict( 28 | type='AnchorGenerator', 29 | octave_base_scale=4, 30 | scales_per_octave=3, 31 | ratios=[0.5, 1.0, 2.0], 32 | strides=[8, 16, 32, 64, 128]), 33 | bbox_coder=dict( 34 | type='DeltaXYWHBBoxCoder', 35 | target_means=[.0, .0, .0, .0], 36 | target_stds=[1.0, 1.0, 1.0, 1.0]), 37 | loss_cls=dict( 38 | type='FocalLoss', 39 | use_sigmoid=True, 40 | gamma=2.0, 41 | alpha=0.25, 42 | loss_weight=1.0), 43 | loss_bbox=dict(type='L1Loss', loss_weight=1.0)), 44 | # model training and testing settings 45 | train_cfg=dict( 46 | assigner=dict( 47 | type='MaxIoUAssigner', 48 | pos_iou_thr=0.5, 49 | neg_iou_thr=0.4, 50 | min_pos_iou=0, 51 | ignore_iof_thr=-1), 52 | allowed_border=-1, 53 | pos_weight=-1, 54 | debug=False), 55 | test_cfg=dict( 56 | nms_pre=1000, 57 | min_bbox_size=0, 58 | score_thr=0.05, 59 | nms=dict(type='nms', iou_threshold=0.5), 60 | max_per_img=100)) 61 | -------------------------------------------------------------------------------- /configs/_base_/models/rpn_r50_caffe_c4.py: -------------------------------------------------------------------------------- 1 | # model settings 2 | model = dict( 3 | type='RPN', 4 | backbone=dict( 5 | type='ResNet', 6 | depth=50, 7 | num_stages=3, 8 | strides=(1, 2, 2), 9 | dilations=(1, 1, 1), 10 | out_indices=(2, ), 11 | frozen_stages=1, 12 | norm_cfg=dict(type='BN', requires_grad=False), 13 | norm_eval=True, 14 | style='caffe', 15 | init_cfg=dict( 16 | type='Pretrained', 17 | checkpoint='open-mmlab://detectron2/resnet50_caffe')), 18 | neck=None, 19 | rpn_head=dict( 20 | type='RPNHead', 21 | in_channels=1024, 22 | feat_channels=1024, 23 | anchor_generator=dict( 24 | type='AnchorGenerator', 25 | scales=[2, 4, 8, 16, 32], 26 | ratios=[0.5, 1.0, 2.0], 27 | strides=[16]), 28 | bbox_coder=dict( 29 | type='DeltaXYWHBBoxCoder', 30 | target_means=[.0, .0, .0, .0], 31 | target_stds=[1.0, 1.0, 1.0, 1.0]), 32 | loss_cls=dict( 33 | type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0), 34 | loss_bbox=dict(type='L1Loss', loss_weight=1.0)), 35 | # model training and testing settings 36 | train_cfg=dict( 37 | rpn=dict( 38 | assigner=dict( 39 | type='MaxIoUAssigner', 40 | pos_iou_thr=0.7, 41 | neg_iou_thr=0.3, 42 | min_pos_iou=0.3, 43 | ignore_iof_thr=-1), 44 | sampler=dict( 45 | type='RandomSampler', 46 | num=256, 47 | pos_fraction=0.5, 48 | neg_pos_ub=-1, 49 | add_gt_as_proposals=False), 50 | allowed_border=0, 51 | pos_weight=-1, 52 | debug=False)), 53 | test_cfg=dict( 54 | rpn=dict( 55 | nms_pre=12000, 56 | max_per_img=2000, 57 | nms=dict(type='nms', iou_threshold=0.7), 58 | min_bbox_size=0))) 59 | -------------------------------------------------------------------------------- /configs/_base_/models/rpn_r50_fpn.py: -------------------------------------------------------------------------------- 1 | # model settings 2 | model = dict( 3 | type='RPN', 4 | backbone=dict( 5 | type='ResNet', 6 | depth=50, 7 | num_stages=4, 8 | out_indices=(0, 1, 2, 3), 9 | frozen_stages=1, 10 | norm_cfg=dict(type='BN', requires_grad=True), 11 | norm_eval=True, 12 | style='pytorch', 13 | init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')), 14 | neck=dict( 15 | type='FPN', 16 | in_channels=[256, 512, 1024, 2048], 17 | out_channels=256, 18 | num_outs=5), 19 | rpn_head=dict( 20 | type='RPNHead', 21 | in_channels=256, 22 | feat_channels=256, 23 | anchor_generator=dict( 24 | type='AnchorGenerator', 25 | scales=[8], 26 | ratios=[0.5, 1.0, 2.0], 27 | strides=[4, 8, 16, 32, 64]), 28 | bbox_coder=dict( 29 | type='DeltaXYWHBBoxCoder', 30 | target_means=[.0, .0, .0, .0], 31 | target_stds=[1.0, 1.0, 1.0, 1.0]), 32 | loss_cls=dict( 33 | type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0), 34 | loss_bbox=dict(type='L1Loss', loss_weight=1.0)), 35 | # model training and testing settings 36 | train_cfg=dict( 37 | rpn=dict( 38 | assigner=dict( 39 | type='MaxIoUAssigner', 40 | pos_iou_thr=0.7, 41 | neg_iou_thr=0.3, 42 | min_pos_iou=0.3, 43 | ignore_iof_thr=-1), 44 | sampler=dict( 45 | type='RandomSampler', 46 | num=256, 47 | pos_fraction=0.5, 48 | neg_pos_ub=-1, 49 | add_gt_as_proposals=False), 50 | allowed_border=0, 51 | pos_weight=-1, 52 | debug=False)), 53 | test_cfg=dict( 54 | rpn=dict( 55 | nms_pre=2000, 56 | max_per_img=1000, 57 | nms=dict(type='nms', iou_threshold=0.7), 58 | min_bbox_size=0))) 59 | -------------------------------------------------------------------------------- /configs/_base_/models/ssd300.py: -------------------------------------------------------------------------------- 1 | # model settings 2 | input_size = 300 3 | model = dict( 4 | type='SingleStageDetector', 5 | backbone=dict( 6 | type='SSDVGG', 7 | depth=16, 8 | with_last_pool=False, 9 | ceil_mode=True, 10 | out_indices=(3, 4), 11 | out_feature_indices=(22, 34), 12 | init_cfg=dict( 13 | type='Pretrained', checkpoint='open-mmlab://vgg16_caffe')), 14 | neck=dict( 15 | type='SSDNeck', 16 | in_channels=(512, 1024), 17 | out_channels=(512, 1024, 512, 256, 256, 256), 18 | level_strides=(2, 2, 1, 1), 19 | level_paddings=(1, 1, 0, 0), 20 | l2_norm_scale=20), 21 | bbox_head=dict( 22 | type='SSDHead', 23 | in_channels=(512, 1024, 512, 256, 256, 256), 24 | num_classes=80, 25 | anchor_generator=dict( 26 | type='SSDAnchorGenerator', 27 | scale_major=False, 28 | input_size=input_size, 29 | basesize_ratio_range=(0.15, 0.9), 30 | strides=[8, 16, 32, 64, 100, 300], 31 | ratios=[[2], [2, 3], [2, 3], [2, 3], [2], [2]]), 32 | bbox_coder=dict( 33 | type='DeltaXYWHBBoxCoder', 34 | target_means=[.0, .0, .0, .0], 35 | target_stds=[0.1, 0.1, 0.2, 0.2])), 36 | # model training and testing settings 37 | train_cfg=dict( 38 | assigner=dict( 39 | type='MaxIoUAssigner', 40 | pos_iou_thr=0.5, 41 | neg_iou_thr=0.5, 42 | min_pos_iou=0., 43 | ignore_iof_thr=-1, 44 | gt_max_assign_all=False), 45 | smoothl1_beta=1., 46 | allowed_border=-1, 47 | pos_weight=-1, 48 | neg_pos_ratio=3, 49 | debug=False), 50 | test_cfg=dict( 51 | nms_pre=1000, 52 | nms=dict(type='nms', iou_threshold=0.45), 53 | min_bbox_size=0, 54 | score_thr=0.02, 55 | max_per_img=200)) 56 | cudnn_benchmark = True 57 | -------------------------------------------------------------------------------- /configs/_base_/schedules/schedule_1x.py: -------------------------------------------------------------------------------- 1 | # optimizer 2 | optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) 3 | optimizer_config = dict(grad_clip=None) 4 | # learning policy 5 | lr_config = dict( 6 | policy='step', 7 | warmup='linear', 8 | warmup_iters=500, 9 | warmup_ratio=0.001, 10 | step=[8, 11]) 11 | runner = dict(type='EpochBasedRunner', max_epochs=12) 12 | -------------------------------------------------------------------------------- /configs/_base_/schedules/schedule_20e.py: -------------------------------------------------------------------------------- 1 | # optimizer 2 | optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) 3 | optimizer_config = dict(grad_clip=None) 4 | # learning policy 5 | lr_config = dict( 6 | policy='step', 7 | warmup='linear', 8 | warmup_iters=500, 9 | warmup_ratio=0.001, 10 | step=[16, 19]) 11 | runner = dict(type='EpochBasedRunner', max_epochs=20) 12 | -------------------------------------------------------------------------------- /configs/_base_/schedules/schedule_2x.py: -------------------------------------------------------------------------------- 1 | # optimizer 2 | optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) 3 | optimizer_config = dict(grad_clip=None) 4 | # learning policy 5 | lr_config = dict( 6 | policy='step', 7 | warmup='linear', 8 | warmup_iters=500, 9 | warmup_ratio=0.001, 10 | step=[16, 22]) 11 | runner = dict(type='EpochBasedRunner', max_epochs=24) 12 | -------------------------------------------------------------------------------- /demo/demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/demo/demo.jpg -------------------------------------------------------------------------------- /demo/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/demo/demo.mp4 -------------------------------------------------------------------------------- /demo/webcam_demo.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import argparse 3 | 4 | import cv2 5 | import torch 6 | 7 | from mmdet.apis import inference_detector, init_detector 8 | 9 | 10 | def parse_args(): 11 | parser = argparse.ArgumentParser(description='MMDetection webcam demo') 12 | parser.add_argument('config', help='test config file path') 13 | parser.add_argument('checkpoint', help='checkpoint file') 14 | parser.add_argument( 15 | '--device', type=str, default='cuda:0', help='CPU/CUDA device option') 16 | parser.add_argument( 17 | '--camera-id', type=int, default=0, help='camera device id') 18 | parser.add_argument( 19 | '--score-thr', type=float, default=0.5, help='bbox score threshold') 20 | args = parser.parse_args() 21 | return args 22 | 23 | 24 | def main(): 25 | args = parse_args() 26 | 27 | device = torch.device(args.device) 28 | 29 | model = init_detector(args.config, args.checkpoint, device=device) 30 | 31 | camera = cv2.VideoCapture(args.camera_id) 32 | 33 | print('Press "Esc", "q" or "Q" to exit.') 34 | while True: 35 | ret_val, img = camera.read() 36 | result = inference_detector(model, img) 37 | 38 | ch = cv2.waitKey(1) 39 | if ch == 27 or ch == ord('q') or ch == ord('Q'): 40 | break 41 | 42 | model.show_result( 43 | img, result, score_thr=args.score_thr, wait_time=1, show=True) 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PYTORCH="1.6.0" 2 | ARG CUDA="10.1" 3 | ARG CUDNN="7" 4 | 5 | FROM pytorch/pytorch:${PYTORCH}-cuda${CUDA}-cudnn${CUDNN}-devel 6 | 7 | ENV TORCH_CUDA_ARCH_LIST="6.0 6.1 7.0+PTX" 8 | ENV TORCH_NVCC_FLAGS="-Xfatbin -compress-all" 9 | ENV CMAKE_PREFIX_PATH="$(dirname $(which conda))/../" 10 | 11 | # To fix GPG key error when running apt-get update 12 | RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub 13 | RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub 14 | 15 | RUN apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 \ 16 | && apt-get clean \ 17 | && rm -rf /var/lib/apt/lists/* 18 | 19 | # Install MMCV 20 | RUN pip install --no-cache-dir --upgrade pip wheel setuptools 21 | RUN pip install --no-cache-dir mmcv-full==1.3.17 -f https://download.openmmlab.com/mmcv/dist/cu101/torch1.6.0/index.html 22 | 23 | # Install MMDetection 24 | RUN conda clean --all 25 | RUN git clone https://github.com/open-mmlab/mmdetection.git /mmdetection 26 | WORKDIR /mmdetection 27 | ENV FORCE_CUDA="1" 28 | RUN pip install --no-cache-dir -r requirements/build.txt 29 | RUN pip install --no-cache-dir -e . 30 | -------------------------------------------------------------------------------- /docker/serve/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PYTORCH="1.6.0" 2 | ARG CUDA="10.1" 3 | ARG CUDNN="7" 4 | FROM pytorch/pytorch:${PYTORCH}-cuda${CUDA}-cudnn${CUDNN}-devel 5 | 6 | ARG MMCV="1.3.17" 7 | ARG MMDET="2.25.1" 8 | 9 | ENV PYTHONUNBUFFERED TRUE 10 | 11 | RUN apt-get update && \ 12 | DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ 13 | ca-certificates \ 14 | g++ \ 15 | openjdk-11-jre-headless \ 16 | # MMDet Requirements 17 | ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 \ 18 | && rm -rf /var/lib/apt/lists/* 19 | 20 | ENV PATH="/opt/conda/bin:$PATH" 21 | RUN export FORCE_CUDA=1 22 | 23 | # TORCHSEVER 24 | RUN pip install torchserve torch-model-archiver 25 | 26 | # MMLAB 27 | ARG PYTORCH 28 | ARG CUDA 29 | RUN ["/bin/bash", "-c", "pip install mmcv-full==${MMCV} -f https://download.openmmlab.com/mmcv/dist/cu${CUDA//./}/torch${PYTORCH}/index.html"] 30 | RUN pip install mmdet==${MMDET} 31 | 32 | RUN useradd -m model-server \ 33 | && mkdir -p /home/model-server/tmp 34 | 35 | COPY entrypoint.sh /usr/local/bin/entrypoint.sh 36 | 37 | RUN chmod +x /usr/local/bin/entrypoint.sh \ 38 | && chown -R model-server /home/model-server 39 | 40 | COPY config.properties /home/model-server/config.properties 41 | RUN mkdir /home/model-server/model-store && chown -R model-server /home/model-server/model-store 42 | 43 | EXPOSE 8080 8081 8082 44 | 45 | USER model-server 46 | WORKDIR /home/model-server 47 | ENV TEMP=/home/model-server/tmp 48 | ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] 49 | CMD ["serve"] 50 | -------------------------------------------------------------------------------- /docker/serve/config.properties: -------------------------------------------------------------------------------- 1 | inference_address=http://0.0.0.0:8080 2 | management_address=http://0.0.0.0:8081 3 | metrics_address=http://0.0.0.0:8082 4 | model_store=/home/model-server/model-store 5 | load_models=all 6 | -------------------------------------------------------------------------------- /docker/serve/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [[ "$1" = "serve" ]]; then 5 | shift 1 6 | torchserve --start --ts-config /home/model-server/config.properties 7 | else 8 | eval "$@" 9 | fi 10 | 11 | # prevent docker exit 12 | tail -f /dev/null 13 | -------------------------------------------------------------------------------- /docs/en/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/en/_static/css/readthedocs.css: -------------------------------------------------------------------------------- 1 | .header-logo { 2 | background-image: url("../image/mmdet-logo.png"); 3 | background-size: 156px 40px; 4 | height: 40px; 5 | width: 156px; 6 | } 7 | -------------------------------------------------------------------------------- /docs/en/_static/image/mmdet-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/docs/en/_static/image/mmdet-logo.png -------------------------------------------------------------------------------- /docs/en/api.rst: -------------------------------------------------------------------------------- 1 | mmdet.apis 2 | -------------- 3 | .. automodule:: mmdet.apis 4 | :members: 5 | 6 | mmdet.core 7 | -------------- 8 | 9 | anchor 10 | ^^^^^^^^^^ 11 | .. automodule:: mmdet.core.anchor 12 | :members: 13 | 14 | bbox 15 | ^^^^^^^^^^ 16 | .. automodule:: mmdet.core.bbox 17 | :members: 18 | 19 | export 20 | ^^^^^^^^^^ 21 | .. automodule:: mmdet.core.export 22 | :members: 23 | 24 | mask 25 | ^^^^^^^^^^ 26 | .. automodule:: mmdet.core.mask 27 | :members: 28 | 29 | evaluation 30 | ^^^^^^^^^^ 31 | .. automodule:: mmdet.core.evaluation 32 | :members: 33 | 34 | post_processing 35 | ^^^^^^^^^^^^^^^ 36 | .. automodule:: mmdet.core.post_processing 37 | :members: 38 | 39 | utils 40 | ^^^^^^^^^^ 41 | .. automodule:: mmdet.core.utils 42 | :members: 43 | 44 | mmdet.datasets 45 | -------------- 46 | 47 | datasets 48 | ^^^^^^^^^^ 49 | .. automodule:: mmdet.datasets 50 | :members: 51 | 52 | pipelines 53 | ^^^^^^^^^^ 54 | .. automodule:: mmdet.datasets.pipelines 55 | :members: 56 | 57 | samplers 58 | ^^^^^^^^^^ 59 | .. automodule:: mmdet.datasets.samplers 60 | :members: 61 | 62 | api_wrappers 63 | ^^^^^^^^^^^^ 64 | .. automodule:: mmdet.datasets.api_wrappers 65 | :members: 66 | 67 | mmdet.models 68 | -------------- 69 | 70 | detectors 71 | ^^^^^^^^^^ 72 | .. automodule:: mmdet.models.detectors 73 | :members: 74 | 75 | backbones 76 | ^^^^^^^^^^ 77 | .. automodule:: mmdet.models.backbones 78 | :members: 79 | 80 | necks 81 | ^^^^^^^^^^^^ 82 | .. automodule:: mmdet.models.necks 83 | :members: 84 | 85 | dense_heads 86 | ^^^^^^^^^^^^ 87 | .. automodule:: mmdet.models.dense_heads 88 | :members: 89 | 90 | roi_heads 91 | ^^^^^^^^^^ 92 | .. automodule:: mmdet.models.roi_heads 93 | :members: 94 | 95 | losses 96 | ^^^^^^^^^^ 97 | .. automodule:: mmdet.models.losses 98 | :members: 99 | 100 | utils 101 | ^^^^^^^^^^ 102 | .. automodule:: mmdet.models.utils 103 | :members: 104 | 105 | mmdet.utils 106 | -------------- 107 | .. automodule::mmdet.utils 108 | :members: 109 | -------------------------------------------------------------------------------- /docs/en/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to MMDetection's documentation! 2 | ======================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Get Started 7 | 8 | get_started.md 9 | modelzoo_statistics.md 10 | model_zoo.md 11 | 12 | .. toctree:: 13 | :maxdepth: 2 14 | :caption: Quick Run 15 | 16 | 1_exist_data_model.md 17 | 2_new_data_model.md 18 | 3_exist_data_new_model.md 19 | 20 | .. toctree:: 21 | :maxdepth: 2 22 | :caption: Tutorials 23 | 24 | tutorials/index.rst 25 | 26 | .. toctree:: 27 | :maxdepth: 2 28 | :caption: Useful Tools and Scripts 29 | 30 | useful_tools.md 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | :caption: Notes 35 | 36 | conventions.md 37 | compatibility.md 38 | projects.md 39 | changelog.md 40 | faq.md 41 | 42 | .. toctree:: 43 | :caption: Switch Language 44 | 45 | switch_language.md 46 | 47 | .. toctree:: 48 | :maxdepth: 1 49 | :caption: API Reference 50 | 51 | api.rst 52 | 53 | Indices and tables 54 | ================== 55 | 56 | * :ref:`genindex` 57 | * :ref:`search` 58 | -------------------------------------------------------------------------------- /docs/en/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/en/stat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import functools as func 3 | import glob 4 | import os.path as osp 5 | import re 6 | 7 | import numpy as np 8 | 9 | url_prefix = 'https://github.com/open-mmlab/mmdetection/blob/master/configs' 10 | 11 | files = sorted(glob.glob('../../configs/*/README.md')) 12 | 13 | stats = [] 14 | titles = [] 15 | num_ckpts = 0 16 | 17 | for f in files: 18 | url = osp.dirname(f.replace('../../configs', url_prefix)) 19 | 20 | with open(f, 'r') as content_file: 21 | content = content_file.read() 22 | 23 | title = content.split('\n')[0].replace('# ', '').strip() 24 | ckpts = set(x.lower().strip() 25 | for x in re.findall(r'\[model\]\((https?.*)\)', content)) 26 | 27 | if len(ckpts) == 0: 28 | continue 29 | 30 | _papertype = [x for x in re.findall(r'\[([A-Z]+)\]', content)] 31 | assert len(_papertype) > 0 32 | papertype = _papertype[0] 33 | 34 | paper = set([(papertype, title)]) 35 | 36 | titles.append(title) 37 | num_ckpts += len(ckpts) 38 | 39 | statsmsg = f""" 40 | \t* [{papertype}] [{title}]({url}) ({len(ckpts)} ckpts) 41 | """ 42 | stats.append((paper, ckpts, statsmsg)) 43 | 44 | allpapers = func.reduce(lambda a, b: a.union(b), [p for p, _, _ in stats]) 45 | msglist = '\n'.join(x for _, _, x in stats) 46 | 47 | papertypes, papercounts = np.unique([t for t, _ in allpapers], 48 | return_counts=True) 49 | countstr = '\n'.join( 50 | [f' - {t}: {c}' for t, c in zip(papertypes, papercounts)]) 51 | 52 | modelzoo = f""" 53 | # Model Zoo Statistics 54 | 55 | * Number of papers: {len(set(titles))} 56 | {countstr} 57 | 58 | * Number of checkpoints: {num_ckpts} 59 | 60 | {msglist} 61 | """ 62 | 63 | with open('modelzoo_statistics.md', 'w') as f: 64 | f.write(modelzoo) 65 | -------------------------------------------------------------------------------- /docs/en/switch_language.md: -------------------------------------------------------------------------------- 1 | ## English 2 | 3 | ## 简体中文 4 | -------------------------------------------------------------------------------- /docs/en/tutorials/index.rst: -------------------------------------------------------------------------------- 1 | .. toctree:: 2 | :maxdepth: 2 3 | 4 | config.md 5 | customize_dataset.md 6 | data_pipeline.md 7 | customize_models.md 8 | customize_runtime.md 9 | customize_losses.md 10 | finetune.md 11 | robustness_benchmarking.md 12 | pytorch2onnx.md 13 | onnx2tensorrt.md 14 | init_cfg.md 15 | how_to.md 16 | test_results_submission.md 17 | useful_hooks.md 18 | -------------------------------------------------------------------------------- /docs/top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/docs/top.jpg -------------------------------------------------------------------------------- /docs/visualization.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/docs/visualization.jpg -------------------------------------------------------------------------------- /docs/zh_cn/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/zh_cn/_static/css/readthedocs.css: -------------------------------------------------------------------------------- 1 | .header-logo { 2 | background-image: url("../image/mmdet-logo.png"); 3 | background-size: 156px 40px; 4 | height: 40px; 5 | width: 156px; 6 | } 7 | -------------------------------------------------------------------------------- /docs/zh_cn/_static/image/mmdet-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/docs/zh_cn/_static/image/mmdet-logo.png -------------------------------------------------------------------------------- /docs/zh_cn/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to MMDetection's documentation! 2 | ======================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: 开始你的第一步 7 | 8 | get_started.md 9 | model_zoo.md 10 | article.md 11 | 12 | .. toctree:: 13 | :maxdepth: 2 14 | :caption: 快速启动 15 | 16 | 1_exist_data_model.md 17 | 2_new_data_model.md 18 | 19 | .. toctree:: 20 | :maxdepth: 2 21 | :caption: 教程 22 | 23 | tutorials/index.rst 24 | 25 | .. toctree:: 26 | :maxdepth: 2 27 | :caption: 实用工具与脚本 28 | 29 | useful_tools.md 30 | 31 | .. toctree:: 32 | :maxdepth: 2 33 | :caption: 说明 34 | 35 | conventions.md 36 | compatibility.md 37 | faq.md 38 | 39 | .. toctree:: 40 | :caption: 语言切换 41 | 42 | switch_language.md 43 | 44 | .. toctree:: 45 | :maxdepth: 1 46 | :caption: 接口文档(英文) 47 | 48 | api.rst 49 | 50 | 51 | Indices and tables 52 | ================== 53 | 54 | * :ref:`genindex` 55 | * :ref:`search` 56 | -------------------------------------------------------------------------------- /docs/zh_cn/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/zh_cn/stat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import functools as func 3 | import glob 4 | import os.path as osp 5 | import re 6 | 7 | import numpy as np 8 | 9 | url_prefix = 'https://github.com/open-mmlab/mmdetection/blob/master/' 10 | 11 | files = sorted(glob.glob('../configs/*/README.md')) 12 | 13 | stats = [] 14 | titles = [] 15 | num_ckpts = 0 16 | 17 | for f in files: 18 | url = osp.dirname(f.replace('../', url_prefix)) 19 | 20 | with open(f, 'r') as content_file: 21 | content = content_file.read() 22 | 23 | title = content.split('\n')[0].replace('# ', '').strip() 24 | ckpts = set(x.lower().strip() 25 | for x in re.findall(r'\[model\]\((https?.*)\)', content)) 26 | 27 | if len(ckpts) == 0: 28 | continue 29 | 30 | _papertype = [x for x in re.findall(r'\[([A-Z]+)\]', content)] 31 | assert len(_papertype) > 0 32 | papertype = _papertype[0] 33 | 34 | paper = set([(papertype, title)]) 35 | 36 | titles.append(title) 37 | num_ckpts += len(ckpts) 38 | 39 | statsmsg = f""" 40 | \t* [{papertype}] [{title}]({url}) ({len(ckpts)} ckpts) 41 | """ 42 | stats.append((paper, ckpts, statsmsg)) 43 | 44 | allpapers = func.reduce(lambda a, b: a.union(b), [p for p, _, _ in stats]) 45 | msglist = '\n'.join(x for _, _, x in stats) 46 | 47 | papertypes, papercounts = np.unique([t for t, _ in allpapers], 48 | return_counts=True) 49 | countstr = '\n'.join( 50 | [f' - {t}: {c}' for t, c in zip(papertypes, papercounts)]) 51 | 52 | modelzoo = f""" 53 | # Model Zoo Statistics 54 | 55 | * Number of papers: {len(set(titles))} 56 | {countstr} 57 | 58 | * Number of checkpoints: {num_ckpts} 59 | 60 | {msglist} 61 | """ 62 | 63 | with open('modelzoo_statistics.md', 'w') as f: 64 | f.write(modelzoo) 65 | -------------------------------------------------------------------------------- /docs/zh_cn/switch_language.md: -------------------------------------------------------------------------------- 1 | ## English 2 | 3 | ## 简体中文 4 | -------------------------------------------------------------------------------- /docs/zh_cn/tutorials/customize_runtime.md: -------------------------------------------------------------------------------- 1 | # 教程 5: 自定义训练配置 2 | -------------------------------------------------------------------------------- /docs/zh_cn/tutorials/index.rst: -------------------------------------------------------------------------------- 1 | .. toctree:: 2 | :maxdepth: 2 3 | 4 | config.md 5 | customize_dataset.md 6 | data_pipeline.md 7 | customize_models.md 8 | customize_runtime.md 9 | customize_losses.md 10 | finetune.md 11 | pytorch2onnx.md 12 | onnx2tensorrt.md 13 | init_cfg.md 14 | how_to.md 15 | -------------------------------------------------------------------------------- /docs/zh_cn/tutorials/pytorch2onnx.md: -------------------------------------------------------------------------------- 1 | # 教程 8: Pytorch 到 ONNX 的模型转换(实验性支持) 2 | 3 | > ## [尝试使用新的 MMDeploy 來部署你的模型](https://mmdeploy.readthedocs.io/) 4 | -------------------------------------------------------------------------------- /docs/zh_cn/useful_tools.md: -------------------------------------------------------------------------------- 1 | ## 日志分析 2 | -------------------------------------------------------------------------------- /mmdet/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import mmcv 3 | 4 | from .version import __version__, short_version 5 | 6 | 7 | def digit_version(version_str): 8 | digit_version = [] 9 | for x in version_str.split('.'): 10 | if x.isdigit(): 11 | digit_version.append(int(x)) 12 | elif x.find('rc') != -1: 13 | patch_version = x.split('rc') 14 | digit_version.append(int(patch_version[0]) - 1) 15 | digit_version.append(int(patch_version[1])) 16 | return digit_version 17 | 18 | 19 | mmcv_minimum_version = '1.3.17' 20 | mmcv_maximum_version = '1.7.0' 21 | mmcv_version = digit_version(mmcv.__version__) 22 | 23 | 24 | assert (mmcv_version >= digit_version(mmcv_minimum_version) 25 | and mmcv_version <= digit_version(mmcv_maximum_version)), \ 26 | f'MMCV=={mmcv.__version__} is used but incompatible. ' \ 27 | f'Please install mmcv>={mmcv_minimum_version}, <={mmcv_maximum_version}.' 28 | 29 | __all__ = ['__version__', 'short_version'] 30 | -------------------------------------------------------------------------------- /mmdet/apis/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .inference import (async_inference_detector, inference_detector, 3 | init_detector, show_result_pyplot) 4 | from .test import multi_gpu_test, single_gpu_test 5 | from .train import (get_root_logger, init_random_seed, set_random_seed, 6 | train_detector) 7 | 8 | __all__ = [ 9 | 'get_root_logger', 'set_random_seed', 'train_detector', 'init_detector', 10 | 'async_inference_detector', 'inference_detector', 'show_result_pyplot', 11 | 'multi_gpu_test', 'single_gpu_test', 'init_random_seed' 12 | ] 13 | -------------------------------------------------------------------------------- /mmdet/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .anchor import * # noqa: F401, F403 3 | from .bbox import * # noqa: F401, F403 4 | from .data_structures import * # noqa: F401, F403 5 | from .evaluation import * # noqa: F401, F403 6 | from .hook import * # noqa: F401, F403 7 | from .mask import * # noqa: F401, F403 8 | from .optimizers import * # noqa: F401, F403 9 | from .post_processing import * # noqa: F401, F403 10 | from .utils import * # noqa: F401, F403 11 | -------------------------------------------------------------------------------- /mmdet/core/anchor/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .anchor_generator import (AnchorGenerator, LegacyAnchorGenerator, 3 | YOLOAnchorGenerator) 4 | from .builder import (ANCHOR_GENERATORS, PRIOR_GENERATORS, 5 | build_anchor_generator, build_prior_generator) 6 | from .point_generator import MlvlPointGenerator, PointGenerator 7 | from .utils import anchor_inside_flags, calc_region, images_to_levels 8 | 9 | __all__ = [ 10 | 'AnchorGenerator', 'LegacyAnchorGenerator', 'anchor_inside_flags', 11 | 'PointGenerator', 'images_to_levels', 'calc_region', 12 | 'build_anchor_generator', 'ANCHOR_GENERATORS', 'YOLOAnchorGenerator', 13 | 'build_prior_generator', 'PRIOR_GENERATORS', 'MlvlPointGenerator' 14 | ] 15 | -------------------------------------------------------------------------------- /mmdet/core/anchor/builder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import warnings 3 | 4 | from mmcv.utils import Registry, build_from_cfg 5 | 6 | PRIOR_GENERATORS = Registry('Generator for anchors and points') 7 | 8 | ANCHOR_GENERATORS = PRIOR_GENERATORS 9 | 10 | 11 | def build_prior_generator(cfg, default_args=None): 12 | return build_from_cfg(cfg, PRIOR_GENERATORS, default_args) 13 | 14 | 15 | def build_anchor_generator(cfg, default_args=None): 16 | warnings.warn( 17 | '``build_anchor_generator`` would be deprecated soon, please use ' 18 | '``build_prior_generator`` ') 19 | return build_prior_generator(cfg, default_args=default_args) 20 | -------------------------------------------------------------------------------- /mmdet/core/bbox/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .assigners import (AssignResult, BaseAssigner, CenterRegionAssigner, 3 | MaxIoUAssigner, RegionAssigner) 4 | from .builder import build_assigner, build_bbox_coder, build_sampler 5 | from .coder import (BaseBBoxCoder, DeltaXYWHBBoxCoder, DistancePointBBoxCoder, 6 | PseudoBBoxCoder, TBLRBBoxCoder) 7 | from .iou_calculators import BboxOverlaps2D, bbox_overlaps 8 | from .samplers import (BaseSampler, CombinedSampler, 9 | InstanceBalancedPosSampler, IoUBalancedNegSampler, 10 | OHEMSampler, PseudoSampler, RandomSampler, 11 | SamplingResult, ScoreHLRSampler) 12 | from .transforms import (bbox2distance, bbox2result, bbox2roi, 13 | bbox_cxcywh_to_xyxy, bbox_flip, bbox_mapping, 14 | bbox_mapping_back, bbox_rescale, bbox_xyxy_to_cxcywh, 15 | distance2bbox, find_inside_bboxes, roi2bbox) 16 | 17 | __all__ = [ 18 | 'bbox_overlaps', 'BboxOverlaps2D', 'BaseAssigner', 'MaxIoUAssigner', 19 | 'AssignResult', 'BaseSampler', 'PseudoSampler', 'RandomSampler', 20 | 'InstanceBalancedPosSampler', 'IoUBalancedNegSampler', 'CombinedSampler', 21 | 'OHEMSampler', 'SamplingResult', 'ScoreHLRSampler', 'build_assigner', 22 | 'build_sampler', 'bbox_flip', 'bbox_mapping', 'bbox_mapping_back', 23 | 'bbox2roi', 'roi2bbox', 'bbox2result', 'distance2bbox', 'bbox2distance', 24 | 'build_bbox_coder', 'BaseBBoxCoder', 'PseudoBBoxCoder', 25 | 'DeltaXYWHBBoxCoder', 'TBLRBBoxCoder', 'DistancePointBBoxCoder', 26 | 'CenterRegionAssigner', 'bbox_rescale', 'bbox_cxcywh_to_xyxy', 27 | 'bbox_xyxy_to_cxcywh', 'RegionAssigner', 'find_inside_bboxes' 28 | ] 29 | -------------------------------------------------------------------------------- /mmdet/core/bbox/assigners/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .approx_max_iou_assigner import ApproxMaxIoUAssigner 3 | from .assign_result import AssignResult 4 | from .atss_assigner import ATSSAssigner 5 | from .base_assigner import BaseAssigner 6 | from .center_region_assigner import CenterRegionAssigner 7 | from .grid_assigner import GridAssigner 8 | from .hungarian_assigner import HungarianAssigner 9 | from .mask_hungarian_assigner import MaskHungarianAssigner 10 | from .max_iou_assigner import MaxIoUAssigner 11 | from .point_assigner import PointAssigner 12 | from .region_assigner import RegionAssigner 13 | from .sim_ota_assigner import SimOTAAssigner 14 | from .task_aligned_assigner import TaskAlignedAssigner 15 | from .uniform_assigner import UniformAssigner 16 | 17 | __all__ = [ 18 | 'BaseAssigner', 'MaxIoUAssigner', 'ApproxMaxIoUAssigner', 'AssignResult', 19 | 'PointAssigner', 'ATSSAssigner', 'CenterRegionAssigner', 'GridAssigner', 20 | 'HungarianAssigner', 'RegionAssigner', 'UniformAssigner', 'SimOTAAssigner', 21 | 'TaskAlignedAssigner', 'MaskHungarianAssigner' 22 | ] 23 | -------------------------------------------------------------------------------- /mmdet/core/bbox/assigners/base_assigner.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from abc import ABCMeta, abstractmethod 3 | 4 | 5 | class BaseAssigner(metaclass=ABCMeta): 6 | """Base assigner that assigns boxes to ground truth boxes.""" 7 | 8 | @abstractmethod 9 | def assign(self, bboxes, gt_bboxes, gt_bboxes_ignore=None, gt_labels=None): 10 | """Assign boxes to either a ground truth boxes or a negative boxes.""" 11 | -------------------------------------------------------------------------------- /mmdet/core/bbox/builder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmcv.utils import Registry, build_from_cfg 3 | 4 | BBOX_ASSIGNERS = Registry('bbox_assigner') 5 | BBOX_SAMPLERS = Registry('bbox_sampler') 6 | BBOX_CODERS = Registry('bbox_coder') 7 | 8 | 9 | def build_assigner(cfg, **default_args): 10 | """Builder of box assigner.""" 11 | return build_from_cfg(cfg, BBOX_ASSIGNERS, default_args) 12 | 13 | 14 | def build_sampler(cfg, **default_args): 15 | """Builder of box sampler.""" 16 | return build_from_cfg(cfg, BBOX_SAMPLERS, default_args) 17 | 18 | 19 | def build_bbox_coder(cfg, **default_args): 20 | """Builder of box coder.""" 21 | return build_from_cfg(cfg, BBOX_CODERS, default_args) 22 | -------------------------------------------------------------------------------- /mmdet/core/bbox/coder/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .base_bbox_coder import BaseBBoxCoder 3 | from .bucketing_bbox_coder import BucketingBBoxCoder 4 | from .delta_xywh_bbox_coder import DeltaXYWHBBoxCoder 5 | from .distance_point_bbox_coder import DistancePointBBoxCoder 6 | from .legacy_delta_xywh_bbox_coder import LegacyDeltaXYWHBBoxCoder 7 | from .pseudo_bbox_coder import PseudoBBoxCoder 8 | from .tblr_bbox_coder import TBLRBBoxCoder 9 | from .yolo_bbox_coder import YOLOBBoxCoder 10 | 11 | __all__ = [ 12 | 'BaseBBoxCoder', 'PseudoBBoxCoder', 'DeltaXYWHBBoxCoder', 13 | 'LegacyDeltaXYWHBBoxCoder', 'TBLRBBoxCoder', 'YOLOBBoxCoder', 14 | 'BucketingBBoxCoder', 'DistancePointBBoxCoder' 15 | ] 16 | -------------------------------------------------------------------------------- /mmdet/core/bbox/coder/base_bbox_coder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from abc import ABCMeta, abstractmethod 3 | 4 | 5 | class BaseBBoxCoder(metaclass=ABCMeta): 6 | """Base bounding box coder.""" 7 | 8 | def __init__(self, **kwargs): 9 | pass 10 | 11 | @abstractmethod 12 | def encode(self, bboxes, gt_bboxes): 13 | """Encode deltas between bboxes and ground truth boxes.""" 14 | 15 | @abstractmethod 16 | def decode(self, bboxes, bboxes_pred): 17 | """Decode the predicted bboxes according to prediction and base 18 | boxes.""" 19 | -------------------------------------------------------------------------------- /mmdet/core/bbox/coder/pseudo_bbox_coder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import BBOX_CODERS 3 | from .base_bbox_coder import BaseBBoxCoder 4 | 5 | 6 | @BBOX_CODERS.register_module() 7 | class PseudoBBoxCoder(BaseBBoxCoder): 8 | """Pseudo bounding box coder.""" 9 | 10 | def __init__(self, **kwargs): 11 | super(BaseBBoxCoder, self).__init__(**kwargs) 12 | 13 | def encode(self, bboxes, gt_bboxes): 14 | """torch.Tensor: return the given ``bboxes``""" 15 | return gt_bboxes 16 | 17 | def decode(self, bboxes, pred_bboxes): 18 | """torch.Tensor: return the given ``pred_bboxes``""" 19 | return pred_bboxes 20 | -------------------------------------------------------------------------------- /mmdet/core/bbox/demodata.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import numpy as np 3 | import torch 4 | 5 | from mmdet.utils.util_random import ensure_rng 6 | 7 | 8 | def random_boxes(num=1, scale=1, rng=None): 9 | """Simple version of ``kwimage.Boxes.random`` 10 | 11 | Returns: 12 | Tensor: shape (n, 4) in x1, y1, x2, y2 format. 13 | 14 | References: 15 | https://gitlab.kitware.com/computer-vision/kwimage/blob/master/kwimage/structs/boxes.py#L1390 16 | 17 | Example: 18 | >>> num = 3 19 | >>> scale = 512 20 | >>> rng = 0 21 | >>> boxes = random_boxes(num, scale, rng) 22 | >>> print(boxes) 23 | tensor([[280.9925, 278.9802, 308.6148, 366.1769], 24 | [216.9113, 330.6978, 224.0446, 456.5878], 25 | [405.3632, 196.3221, 493.3953, 270.7942]]) 26 | """ 27 | rng = ensure_rng(rng) 28 | 29 | tlbr = rng.rand(num, 4).astype(np.float32) 30 | 31 | tl_x = np.minimum(tlbr[:, 0], tlbr[:, 2]) 32 | tl_y = np.minimum(tlbr[:, 1], tlbr[:, 3]) 33 | br_x = np.maximum(tlbr[:, 0], tlbr[:, 2]) 34 | br_y = np.maximum(tlbr[:, 1], tlbr[:, 3]) 35 | 36 | tlbr[:, 0] = tl_x * scale 37 | tlbr[:, 1] = tl_y * scale 38 | tlbr[:, 2] = br_x * scale 39 | tlbr[:, 3] = br_y * scale 40 | 41 | boxes = torch.from_numpy(tlbr) 42 | return boxes 43 | -------------------------------------------------------------------------------- /mmdet/core/bbox/iou_calculators/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .builder import build_iou_calculator 3 | from .iou2d_calculator import BboxOverlaps2D, bbox_overlaps 4 | 5 | __all__ = ['build_iou_calculator', 'BboxOverlaps2D', 'bbox_overlaps'] 6 | -------------------------------------------------------------------------------- /mmdet/core/bbox/iou_calculators/builder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmcv.utils import Registry, build_from_cfg 3 | 4 | IOU_CALCULATORS = Registry('IoU calculator') 5 | 6 | 7 | def build_iou_calculator(cfg, default_args=None): 8 | """Builder of IoU calculator.""" 9 | return build_from_cfg(cfg, IOU_CALCULATORS, default_args) 10 | -------------------------------------------------------------------------------- /mmdet/core/bbox/match_costs/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .builder import build_match_cost 3 | from .match_cost import (BBoxL1Cost, ClassificationCost, CrossEntropyLossCost, 4 | DiceCost, FocalLossCost, IoUCost) 5 | 6 | __all__ = [ 7 | 'build_match_cost', 'ClassificationCost', 'BBoxL1Cost', 'IoUCost', 8 | 'FocalLossCost', 'DiceCost', 'CrossEntropyLossCost' 9 | ] 10 | -------------------------------------------------------------------------------- /mmdet/core/bbox/match_costs/builder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmcv.utils import Registry, build_from_cfg 3 | 4 | MATCH_COST = Registry('Match Cost') 5 | 6 | 7 | def build_match_cost(cfg, default_args=None): 8 | """Builder of IoU calculator.""" 9 | return build_from_cfg(cfg, MATCH_COST, default_args) 10 | -------------------------------------------------------------------------------- /mmdet/core/bbox/samplers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .base_sampler import BaseSampler 3 | from .combined_sampler import CombinedSampler 4 | from .instance_balanced_pos_sampler import InstanceBalancedPosSampler 5 | from .iou_balanced_neg_sampler import IoUBalancedNegSampler 6 | from .mask_pseudo_sampler import MaskPseudoSampler 7 | from .mask_sampling_result import MaskSamplingResult 8 | from .ohem_sampler import OHEMSampler 9 | from .pseudo_sampler import PseudoSampler 10 | from .random_sampler import RandomSampler 11 | from .sampling_result import SamplingResult 12 | from .score_hlr_sampler import ScoreHLRSampler 13 | 14 | __all__ = [ 15 | 'BaseSampler', 'PseudoSampler', 'RandomSampler', 16 | 'InstanceBalancedPosSampler', 'IoUBalancedNegSampler', 'CombinedSampler', 17 | 'OHEMSampler', 'SamplingResult', 'ScoreHLRSampler', 'MaskPseudoSampler', 18 | 'MaskSamplingResult' 19 | ] 20 | -------------------------------------------------------------------------------- /mmdet/core/bbox/samplers/combined_sampler.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import BBOX_SAMPLERS, build_sampler 3 | from .base_sampler import BaseSampler 4 | 5 | 6 | @BBOX_SAMPLERS.register_module() 7 | class CombinedSampler(BaseSampler): 8 | """A sampler that combines positive sampler and negative sampler.""" 9 | 10 | def __init__(self, pos_sampler, neg_sampler, **kwargs): 11 | super(CombinedSampler, self).__init__(**kwargs) 12 | self.pos_sampler = build_sampler(pos_sampler, **kwargs) 13 | self.neg_sampler = build_sampler(neg_sampler, **kwargs) 14 | 15 | def _sample_pos(self, **kwargs): 16 | """Sample positive samples.""" 17 | raise NotImplementedError 18 | 19 | def _sample_neg(self, **kwargs): 20 | """Sample negative samples.""" 21 | raise NotImplementedError 22 | -------------------------------------------------------------------------------- /mmdet/core/bbox/samplers/mask_pseudo_sampler.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | """copy from 3 | https://github.com/ZwwWayne/K-Net/blob/main/knet/det/mask_pseudo_sampler.py.""" 4 | 5 | import torch 6 | 7 | from mmdet.core.bbox.builder import BBOX_SAMPLERS 8 | from .base_sampler import BaseSampler 9 | from .mask_sampling_result import MaskSamplingResult 10 | 11 | 12 | @BBOX_SAMPLERS.register_module() 13 | class MaskPseudoSampler(BaseSampler): 14 | """A pseudo sampler that does not do sampling actually.""" 15 | 16 | def __init__(self, **kwargs): 17 | pass 18 | 19 | def _sample_pos(self, **kwargs): 20 | """Sample positive samples.""" 21 | raise NotImplementedError 22 | 23 | def _sample_neg(self, **kwargs): 24 | """Sample negative samples.""" 25 | raise NotImplementedError 26 | 27 | def sample(self, assign_result, masks, gt_masks, **kwargs): 28 | """Directly returns the positive and negative indices of samples. 29 | 30 | Args: 31 | assign_result (:obj:`AssignResult`): Assigned results 32 | masks (torch.Tensor): Bounding boxes 33 | gt_masks (torch.Tensor): Ground truth boxes 34 | Returns: 35 | :obj:`SamplingResult`: sampler results 36 | """ 37 | pos_inds = torch.nonzero( 38 | assign_result.gt_inds > 0, as_tuple=False).squeeze(-1).unique() 39 | neg_inds = torch.nonzero( 40 | assign_result.gt_inds == 0, as_tuple=False).squeeze(-1).unique() 41 | gt_flags = masks.new_zeros(masks.shape[0], dtype=torch.uint8) 42 | sampling_result = MaskSamplingResult(pos_inds, neg_inds, masks, 43 | gt_masks, assign_result, gt_flags) 44 | return sampling_result 45 | -------------------------------------------------------------------------------- /mmdet/core/bbox/samplers/pseudo_sampler.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import torch 3 | 4 | from ..builder import BBOX_SAMPLERS 5 | from .base_sampler import BaseSampler 6 | from .sampling_result import SamplingResult 7 | 8 | 9 | @BBOX_SAMPLERS.register_module() 10 | class PseudoSampler(BaseSampler): 11 | """A pseudo sampler that does not do sampling actually.""" 12 | 13 | def __init__(self, **kwargs): 14 | pass 15 | 16 | def _sample_pos(self, **kwargs): 17 | """Sample positive samples.""" 18 | raise NotImplementedError 19 | 20 | def _sample_neg(self, **kwargs): 21 | """Sample negative samples.""" 22 | raise NotImplementedError 23 | 24 | def sample(self, assign_result, bboxes, gt_bboxes, *args, **kwargs): 25 | """Directly returns the positive and negative indices of samples. 26 | 27 | Args: 28 | assign_result (:obj:`AssignResult`): Assigned results 29 | bboxes (torch.Tensor): Bounding boxes 30 | gt_bboxes (torch.Tensor): Ground truth boxes 31 | 32 | Returns: 33 | :obj:`SamplingResult`: sampler results 34 | """ 35 | pos_inds = torch.nonzero( 36 | assign_result.gt_inds > 0, as_tuple=False).squeeze(-1).unique() 37 | neg_inds = torch.nonzero( 38 | assign_result.gt_inds == 0, as_tuple=False).squeeze(-1).unique() 39 | gt_flags = bboxes.new_zeros(bboxes.shape[0], dtype=torch.uint8) 40 | sampling_result = SamplingResult(pos_inds, neg_inds, bboxes, gt_bboxes, 41 | assign_result, gt_flags) 42 | return sampling_result 43 | -------------------------------------------------------------------------------- /mmdet/core/data_structures/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .general_data import GeneralData 3 | from .instance_data import InstanceData 4 | 5 | __all__ = ['GeneralData', 'InstanceData'] 6 | -------------------------------------------------------------------------------- /mmdet/core/evaluation/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .class_names import (cityscapes_classes, coco_classes, dataset_aliases, 3 | get_classes, imagenet_det_classes, 4 | imagenet_vid_classes, oid_challenge_classes, 5 | oid_v6_classes, voc_classes) 6 | from .eval_hooks import DistEvalHook, EvalHook 7 | from .mean_ap import average_precision, eval_map, print_map_summary 8 | from .panoptic_utils import INSTANCE_OFFSET 9 | from .recall import (eval_recalls, plot_iou_recall, plot_num_recall, 10 | print_recall_summary) 11 | 12 | __all__ = [ 13 | 'voc_classes', 'imagenet_det_classes', 'imagenet_vid_classes', 14 | 'coco_classes', 'cityscapes_classes', 'dataset_aliases', 'get_classes', 15 | 'DistEvalHook', 'EvalHook', 'average_precision', 'eval_map', 16 | 'print_map_summary', 'eval_recalls', 'print_recall_summary', 17 | 'plot_num_recall', 'plot_iou_recall', 'oid_v6_classes', 18 | 'oid_challenge_classes', 'INSTANCE_OFFSET' 19 | ] 20 | -------------------------------------------------------------------------------- /mmdet/core/evaluation/panoptic_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | # A custom value to distinguish instance ID and category ID; need to 3 | # be greater than the number of categories. 4 | # For a pixel in the panoptic result map: 5 | # pan_id = ins_id * INSTANCE_OFFSET + cat_id 6 | INSTANCE_OFFSET = 1000 7 | -------------------------------------------------------------------------------- /mmdet/core/export/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .onnx_helper import (add_dummy_nms_for_onnx, dynamic_clip_for_onnx, 3 | get_k_for_topk) 4 | from .pytorch2onnx import (build_model_from_cfg, 5 | generate_inputs_and_wrap_model, 6 | preprocess_example_input) 7 | 8 | __all__ = [ 9 | 'build_model_from_cfg', 'generate_inputs_and_wrap_model', 10 | 'preprocess_example_input', 'get_k_for_topk', 'add_dummy_nms_for_onnx', 11 | 'dynamic_clip_for_onnx' 12 | ] 13 | -------------------------------------------------------------------------------- /mmdet/core/hook/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .checkloss_hook import CheckInvalidLossHook 3 | from .ema import ExpMomentumEMAHook, LinearMomentumEMAHook 4 | from .memory_profiler_hook import MemoryProfilerHook 5 | from .set_epoch_info_hook import SetEpochInfoHook 6 | from .sync_norm_hook import SyncNormHook 7 | from .sync_random_size_hook import SyncRandomSizeHook 8 | from .wandblogger_hook import MMDetWandbHook 9 | from .yolox_lrupdater_hook import YOLOXLrUpdaterHook 10 | from .yolox_mode_switch_hook import YOLOXModeSwitchHook 11 | 12 | __all__ = [ 13 | 'SyncRandomSizeHook', 'YOLOXModeSwitchHook', 'SyncNormHook', 14 | 'ExpMomentumEMAHook', 'LinearMomentumEMAHook', 'YOLOXLrUpdaterHook', 15 | 'CheckInvalidLossHook', 'SetEpochInfoHook', 'MemoryProfilerHook', 16 | 'MMDetWandbHook' 17 | ] 18 | -------------------------------------------------------------------------------- /mmdet/core/hook/checkloss_hook.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import torch 3 | from mmcv.runner.hooks import HOOKS, Hook 4 | 5 | 6 | @HOOKS.register_module() 7 | class CheckInvalidLossHook(Hook): 8 | """Check invalid loss hook. 9 | 10 | This hook will regularly check whether the loss is valid 11 | during training. 12 | 13 | Args: 14 | interval (int): Checking interval (every k iterations). 15 | Default: 50. 16 | """ 17 | 18 | def __init__(self, interval=50): 19 | self.interval = interval 20 | 21 | def after_train_iter(self, runner): 22 | if self.every_n_iters(runner, self.interval): 23 | assert torch.isfinite(runner.outputs['loss']), \ 24 | runner.logger.info('loss become infinite or NaN!') 25 | -------------------------------------------------------------------------------- /mmdet/core/hook/set_epoch_info_hook.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmcv.parallel import is_module_wrapper 3 | from mmcv.runner import HOOKS, Hook 4 | 5 | 6 | @HOOKS.register_module() 7 | class SetEpochInfoHook(Hook): 8 | """Set runner's epoch information to the model.""" 9 | 10 | def before_train_epoch(self, runner): 11 | epoch = runner.epoch 12 | model = runner.model 13 | if is_module_wrapper(model): 14 | model = model.module 15 | model.set_epoch(epoch) 16 | -------------------------------------------------------------------------------- /mmdet/core/hook/sync_norm_hook.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from collections import OrderedDict 3 | 4 | from mmcv.runner import get_dist_info 5 | from mmcv.runner.hooks import HOOKS, Hook 6 | from torch import nn 7 | 8 | from ..utils.dist_utils import all_reduce_dict 9 | 10 | 11 | def get_norm_states(module): 12 | async_norm_states = OrderedDict() 13 | for name, child in module.named_modules(): 14 | if isinstance(child, nn.modules.batchnorm._NormBase): 15 | for k, v in child.state_dict().items(): 16 | async_norm_states['.'.join([name, k])] = v 17 | return async_norm_states 18 | 19 | 20 | @HOOKS.register_module() 21 | class SyncNormHook(Hook): 22 | """Synchronize Norm states after training epoch, currently used in YOLOX. 23 | 24 | Args: 25 | num_last_epochs (int): The number of latter epochs in the end of the 26 | training to switch to synchronizing norm interval. Default: 15. 27 | interval (int): Synchronizing norm interval. Default: 1. 28 | """ 29 | 30 | def __init__(self, num_last_epochs=15, interval=1): 31 | self.interval = interval 32 | self.num_last_epochs = num_last_epochs 33 | 34 | def before_train_epoch(self, runner): 35 | epoch = runner.epoch 36 | if (epoch + 1) == runner.max_epochs - self.num_last_epochs: 37 | # Synchronize norm every epoch. 38 | self.interval = 1 39 | 40 | def after_train_epoch(self, runner): 41 | """Synchronizing norm.""" 42 | epoch = runner.epoch 43 | module = runner.model 44 | if (epoch + 1) % self.interval == 0: 45 | _, world_size = get_dist_info() 46 | if world_size == 1: 47 | return 48 | norm_states = get_norm_states(module) 49 | if len(norm_states) == 0: 50 | return 51 | norm_states = all_reduce_dict(norm_states, op='mean') 52 | module.load_state_dict(norm_states, strict=False) 53 | -------------------------------------------------------------------------------- /mmdet/core/mask/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .mask_target import mask_target 3 | from .structures import BaseInstanceMasks, BitmapMasks, PolygonMasks 4 | from .utils import encode_mask_results, mask2bbox, split_combined_polys 5 | 6 | __all__ = [ 7 | 'split_combined_polys', 'mask_target', 'BaseInstanceMasks', 'BitmapMasks', 8 | 'PolygonMasks', 'encode_mask_results', 'mask2bbox' 9 | ] 10 | -------------------------------------------------------------------------------- /mmdet/core/optimizers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .builder import OPTIMIZER_BUILDERS, build_optimizer 3 | from .layer_decay_optimizer_constructor import \ 4 | LearningRateDecayOptimizerConstructor 5 | 6 | __all__ = [ 7 | 'LearningRateDecayOptimizerConstructor', 'OPTIMIZER_BUILDERS', 8 | 'build_optimizer' 9 | ] 10 | -------------------------------------------------------------------------------- /mmdet/core/optimizers/builder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import copy 3 | 4 | from mmcv.runner.optimizer import OPTIMIZER_BUILDERS as MMCV_OPTIMIZER_BUILDERS 5 | from mmcv.utils import Registry, build_from_cfg 6 | 7 | OPTIMIZER_BUILDERS = Registry( 8 | 'optimizer builder', parent=MMCV_OPTIMIZER_BUILDERS) 9 | 10 | 11 | def build_optimizer_constructor(cfg): 12 | constructor_type = cfg.get('type') 13 | if constructor_type in OPTIMIZER_BUILDERS: 14 | return build_from_cfg(cfg, OPTIMIZER_BUILDERS) 15 | elif constructor_type in MMCV_OPTIMIZER_BUILDERS: 16 | return build_from_cfg(cfg, MMCV_OPTIMIZER_BUILDERS) 17 | else: 18 | raise KeyError(f'{constructor_type} is not registered ' 19 | 'in the optimizer builder registry.') 20 | 21 | 22 | def build_optimizer(model, cfg): 23 | optimizer_cfg = copy.deepcopy(cfg) 24 | constructor_type = optimizer_cfg.pop('constructor', 25 | 'DefaultOptimizerConstructor') 26 | paramwise_cfg = optimizer_cfg.pop('paramwise_cfg', None) 27 | optim_constructor = build_optimizer_constructor( 28 | dict( 29 | type=constructor_type, 30 | optimizer_cfg=optimizer_cfg, 31 | paramwise_cfg=paramwise_cfg)) 32 | optimizer = optim_constructor(model) 33 | return optimizer 34 | -------------------------------------------------------------------------------- /mmdet/core/post_processing/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .bbox_nms import fast_nms, multiclass_nms 3 | from .matrix_nms import mask_matrix_nms 4 | from .merge_augs import (merge_aug_bboxes, merge_aug_masks, 5 | merge_aug_proposals, merge_aug_scores) 6 | 7 | __all__ = [ 8 | 'multiclass_nms', 'merge_aug_proposals', 'merge_aug_bboxes', 9 | 'merge_aug_scores', 'merge_aug_masks', 'mask_matrix_nms', 'fast_nms' 10 | ] 11 | -------------------------------------------------------------------------------- /mmdet/core/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .dist_utils import (DistOptimizerHook, all_reduce_dict, allreduce_grads, 3 | reduce_mean, sync_random_seed) 4 | from .misc import (center_of_mass, filter_scores_and_topk, flip_tensor, 5 | generate_coordinate, mask2ndarray, multi_apply, 6 | select_single_mlvl, unmap) 7 | 8 | __all__ = [ 9 | 'allreduce_grads', 'DistOptimizerHook', 'reduce_mean', 'multi_apply', 10 | 'unmap', 'mask2ndarray', 'flip_tensor', 'all_reduce_dict', 11 | 'center_of_mass', 'generate_coordinate', 'select_single_mlvl', 12 | 'filter_scores_and_topk', 'sync_random_seed' 13 | ] 14 | -------------------------------------------------------------------------------- /mmdet/core/visualization/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .image import (color_val_matplotlib, imshow_det_bboxes, 3 | imshow_gt_det_bboxes) 4 | from .palette import get_palette, palette_val 5 | 6 | __all__ = [ 7 | 'imshow_det_bboxes', 'imshow_gt_det_bboxes', 'color_val_matplotlib', 8 | 'palette_val', 'get_palette' 9 | ] 10 | -------------------------------------------------------------------------------- /mmdet/datasets/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .builder import DATASETS, PIPELINES, build_dataloader, build_dataset 3 | from .cityscapes import CityscapesDataset 4 | from .coco import CocoDataset 5 | from .coco_panoptic import CocoPanopticDataset 6 | from .custom import CustomDataset 7 | from .dataset_wrappers import (ClassBalancedDataset, ConcatDataset, 8 | MultiImageMixDataset, RepeatDataset) 9 | from .deepfashion import DeepFashionDataset 10 | from .lvis import LVISDataset, LVISV1Dataset, LVISV05Dataset 11 | from .openimages import OpenImagesChallengeDataset, OpenImagesDataset 12 | from .samplers import DistributedGroupSampler, DistributedSampler, GroupSampler 13 | from .utils import (NumClassCheckHook, get_loading_pipeline, 14 | replace_ImageToTensor) 15 | from .voc import VOCDataset 16 | from .wider_face import WIDERFaceDataset 17 | from .xml_style import XMLDataset 18 | 19 | __all__ = [ 20 | 'CustomDataset', 'XMLDataset', 'CocoDataset', 'DeepFashionDataset', 21 | 'VOCDataset', 'CityscapesDataset', 'LVISDataset', 'LVISV05Dataset', 22 | 'LVISV1Dataset', 'GroupSampler', 'DistributedGroupSampler', 23 | 'DistributedSampler', 'build_dataloader', 'ConcatDataset', 'RepeatDataset', 24 | 'ClassBalancedDataset', 'WIDERFaceDataset', 'DATASETS', 'PIPELINES', 25 | 'build_dataset', 'replace_ImageToTensor', 'get_loading_pipeline', 26 | 'NumClassCheckHook', 'CocoPanopticDataset', 'MultiImageMixDataset', 27 | 'OpenImagesDataset', 'OpenImagesChallengeDataset' 28 | ] 29 | -------------------------------------------------------------------------------- /mmdet/datasets/api_wrappers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .coco_api import COCO, COCOeval 3 | from .panoptic_evaluation import pq_compute_multi_core, pq_compute_single_core 4 | 5 | __all__ = [ 6 | 'COCO', 'COCOeval', 'pq_compute_multi_core', 'pq_compute_single_core' 7 | ] 8 | -------------------------------------------------------------------------------- /mmdet/datasets/api_wrappers/coco_api.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | # This file add snake case alias for coco api 3 | 4 | import warnings 5 | 6 | import pycocotools 7 | from pycocotools.coco import COCO as _COCO 8 | from pycocotools.cocoeval import COCOeval as _COCOeval 9 | 10 | 11 | class COCO(_COCO): 12 | """This class is almost the same as official pycocotools package. 13 | 14 | It implements some snake case function aliases. So that the COCO class has 15 | the same interface as LVIS class. 16 | """ 17 | 18 | def __init__(self, annotation_file=None): 19 | if getattr(pycocotools, '__version__', '0') >= '12.0.2': 20 | warnings.warn( 21 | 'mmpycocotools is deprecated. Please install official pycocotools by "pip install pycocotools"', # noqa: E501 22 | UserWarning) 23 | super().__init__(annotation_file=annotation_file) 24 | self.img_ann_map = self.imgToAnns 25 | self.cat_img_map = self.catToImgs 26 | 27 | def get_ann_ids(self, img_ids=[], cat_ids=[], area_rng=[], iscrowd=None): 28 | return self.getAnnIds(img_ids, cat_ids, area_rng, iscrowd) 29 | 30 | def get_cat_ids(self, cat_names=[], sup_names=[], cat_ids=[]): 31 | return self.getCatIds(cat_names, sup_names, cat_ids) 32 | 33 | def get_img_ids(self, img_ids=[], cat_ids=[]): 34 | return self.getImgIds(img_ids, cat_ids) 35 | 36 | def load_anns(self, ids): 37 | return self.loadAnns(ids) 38 | 39 | def load_cats(self, ids): 40 | return self.loadCats(ids) 41 | 42 | def load_imgs(self, ids): 43 | return self.loadImgs(ids) 44 | 45 | 46 | # just for the ease of import 47 | COCOeval = _COCOeval 48 | -------------------------------------------------------------------------------- /mmdet/datasets/deepfashion.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .builder import DATASETS 3 | from .coco import CocoDataset 4 | 5 | 6 | @DATASETS.register_module() 7 | class DeepFashionDataset(CocoDataset): 8 | 9 | CLASSES = ('top', 'skirt', 'leggings', 'dress', 'outer', 'pants', 'bag', 10 | 'neckwear', 'headwear', 'eyeglass', 'belt', 'footwear', 'hair', 11 | 'skin', 'face') 12 | 13 | PALETTE = [(0, 192, 64), (0, 64, 96), (128, 192, 192), (0, 64, 64), 14 | (0, 192, 224), (0, 192, 192), (128, 192, 64), (0, 192, 96), 15 | (128, 32, 192), (0, 0, 224), (0, 0, 64), (0, 160, 192), 16 | (128, 0, 96), (128, 0, 192), (0, 32, 192)] 17 | -------------------------------------------------------------------------------- /mmdet/datasets/pipelines/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .auto_augment import (AutoAugment, BrightnessTransform, ColorTransform, 3 | ContrastTransform, EqualizeTransform, Rotate, Shear, 4 | Translate) 5 | from .compose import Compose 6 | from .formatting import (Collect, DefaultFormatBundle, ImageToTensor, 7 | ToDataContainer, ToTensor, Transpose, to_tensor) 8 | from .instaboost import InstaBoost 9 | from .loading import (FilterAnnotations, LoadAnnotations, LoadImageFromFile, 10 | LoadImageFromWebcam, LoadMultiChannelImageFromFiles, 11 | LoadPanopticAnnotations, LoadProposals) 12 | from .test_time_aug import MultiScaleFlipAug 13 | from .transforms import (Albu, CopyPaste, CutOut, Expand, MinIoURandomCrop, 14 | MixUp, Mosaic, Normalize, Pad, PhotoMetricDistortion, 15 | RandomAffine, RandomCenterCropPad, RandomCrop, 16 | RandomFlip, RandomShift, Resize, SegRescale, 17 | YOLOXHSVRandomAug) 18 | 19 | __all__ = [ 20 | 'Compose', 'to_tensor', 'ToTensor', 'ImageToTensor', 'ToDataContainer', 21 | 'Transpose', 'Collect', 'DefaultFormatBundle', 'LoadAnnotations', 22 | 'LoadImageFromFile', 'LoadImageFromWebcam', 'LoadPanopticAnnotations', 23 | 'LoadMultiChannelImageFromFiles', 'LoadProposals', 'FilterAnnotations', 24 | 'MultiScaleFlipAug', 'Resize', 'RandomFlip', 'Pad', 'RandomCrop', 25 | 'Normalize', 'SegRescale', 'MinIoURandomCrop', 'Expand', 26 | 'PhotoMetricDistortion', 'Albu', 'InstaBoost', 'RandomCenterCropPad', 27 | 'AutoAugment', 'CutOut', 'Shear', 'Rotate', 'ColorTransform', 28 | 'EqualizeTransform', 'BrightnessTransform', 'ContrastTransform', 29 | 'Translate', 'RandomShift', 'Mosaic', 'MixUp', 'RandomAffine', 30 | 'YOLOXHSVRandomAug', 'CopyPaste' 31 | ] 32 | -------------------------------------------------------------------------------- /mmdet/datasets/pipelines/compose.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import collections 3 | 4 | from mmcv.utils import build_from_cfg 5 | 6 | from ..builder import PIPELINES 7 | 8 | 9 | @PIPELINES.register_module() 10 | class Compose: 11 | """Compose multiple transforms sequentially. 12 | 13 | Args: 14 | transforms (Sequence[dict | callable]): Sequence of transform object or 15 | config dict to be composed. 16 | """ 17 | 18 | def __init__(self, transforms): 19 | assert isinstance(transforms, collections.abc.Sequence) 20 | self.transforms = [] 21 | for transform in transforms: 22 | if isinstance(transform, dict): 23 | transform = build_from_cfg(transform, PIPELINES) 24 | self.transforms.append(transform) 25 | elif callable(transform): 26 | self.transforms.append(transform) 27 | else: 28 | raise TypeError('transform must be callable or a dict') 29 | 30 | def __call__(self, data): 31 | """Call function to apply transforms sequentially. 32 | 33 | Args: 34 | data (dict): A result dict contains the data to transform. 35 | 36 | Returns: 37 | dict: Transformed data. 38 | """ 39 | 40 | for t in self.transforms: 41 | data = t(data) 42 | if data is None: 43 | return None 44 | return data 45 | 46 | def __repr__(self): 47 | format_string = self.__class__.__name__ + '(' 48 | for t in self.transforms: 49 | str_ = t.__repr__() 50 | if 'Compose(' in str_: 51 | str_ = str_.replace('\n', '\n ') 52 | format_string += '\n' 53 | format_string += f' {str_}' 54 | format_string += '\n)' 55 | return format_string 56 | -------------------------------------------------------------------------------- /mmdet/datasets/pipelines/formating.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | # flake8: noqa 3 | import warnings 4 | 5 | from .formatting import * 6 | 7 | warnings.warn('DeprecationWarning: mmdet.datasets.pipelines.formating will be ' 8 | 'deprecated, please replace it with ' 9 | 'mmdet.datasets.pipelines.formatting.') 10 | -------------------------------------------------------------------------------- /mmdet/datasets/samplers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .class_aware_sampler import ClassAwareSampler 3 | from .distributed_sampler import DistributedSampler 4 | from .group_sampler import DistributedGroupSampler, GroupSampler 5 | from .infinite_sampler import InfiniteBatchSampler, InfiniteGroupBatchSampler 6 | 7 | __all__ = [ 8 | 'DistributedSampler', 'DistributedGroupSampler', 'GroupSampler', 9 | 'InfiniteGroupBatchSampler', 'InfiniteBatchSampler', 'ClassAwareSampler' 10 | ] 11 | -------------------------------------------------------------------------------- /mmdet/datasets/wider_face.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import os.path as osp 3 | import xml.etree.ElementTree as ET 4 | 5 | import mmcv 6 | 7 | from .builder import DATASETS 8 | from .xml_style import XMLDataset 9 | 10 | 11 | @DATASETS.register_module() 12 | class WIDERFaceDataset(XMLDataset): 13 | """Reader for the WIDER Face dataset in PASCAL VOC format. 14 | 15 | Conversion scripts can be found in 16 | https://github.com/sovrasov/wider-face-pascal-voc-annotations 17 | """ 18 | CLASSES = ('face', ) 19 | 20 | PALETTE = [(0, 255, 0)] 21 | 22 | def __init__(self, **kwargs): 23 | super(WIDERFaceDataset, self).__init__(**kwargs) 24 | 25 | def load_annotations(self, ann_file): 26 | """Load annotation from WIDERFace XML style annotation file. 27 | 28 | Args: 29 | ann_file (str): Path of XML file. 30 | 31 | Returns: 32 | list[dict]: Annotation info from XML file. 33 | """ 34 | 35 | data_infos = [] 36 | img_ids = mmcv.list_from_file(ann_file) 37 | for img_id in img_ids: 38 | filename = f'{img_id}.jpg' 39 | xml_path = osp.join(self.img_prefix, 'Annotations', 40 | f'{img_id}.xml') 41 | tree = ET.parse(xml_path) 42 | root = tree.getroot() 43 | size = root.find('size') 44 | width = int(size.find('width').text) 45 | height = int(size.find('height').text) 46 | folder = root.find('folder').text 47 | data_infos.append( 48 | dict( 49 | id=img_id, 50 | filename=osp.join(folder, filename), 51 | width=width, 52 | height=height)) 53 | 54 | return data_infos 55 | -------------------------------------------------------------------------------- /mmdet/models/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .backbones import * # noqa: F401,F403 3 | from .builder import (BACKBONES, DETECTORS, HEADS, LOSSES, NECKS, 4 | ROI_EXTRACTORS, SHARED_HEADS, build_backbone, 5 | build_detector, build_head, build_loss, build_neck, 6 | build_roi_extractor, build_shared_head) 7 | from .dense_heads import * # noqa: F401,F403 8 | from .detectors import * # noqa: F401,F403 9 | from .losses import * # noqa: F401,F403 10 | from .necks import * # noqa: F401,F403 11 | from .plugins import * # noqa: F401,F403 12 | from .roi_heads import * # noqa: F401,F403 13 | from .seg_heads import * # noqa: F401,F403 14 | 15 | __all__ = [ 16 | 'BACKBONES', 'NECKS', 'ROI_EXTRACTORS', 'SHARED_HEADS', 'HEADS', 'LOSSES', 17 | 'DETECTORS', 'build_backbone', 'build_neck', 'build_roi_extractor', 18 | 'build_shared_head', 'build_head', 'build_loss', 'build_detector' 19 | ] 20 | -------------------------------------------------------------------------------- /mmdet/models/backbones/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .csp_darknet import CSPDarknet 3 | from .darknet import Darknet 4 | from .detectors_resnet import DetectoRS_ResNet 5 | from .detectors_resnext import DetectoRS_ResNeXt 6 | from .efficientnet import EfficientNet 7 | from .hourglass import HourglassNet 8 | from .hrnet import HRNet 9 | from .mobilenet_v2 import MobileNetV2 10 | from .pvt import PyramidVisionTransformer, PyramidVisionTransformerV2 11 | from .regnet import RegNet 12 | from .res2net import Res2Net 13 | from .resnest import ResNeSt 14 | from .resnet import ResNet, ResNetV1d 15 | from .resnext import ResNeXt 16 | from .ssd_vgg import SSDVGG 17 | from .swin import SwinTransformer 18 | from .trident_resnet import TridentResNet 19 | from .regnet32gf import RegNet32gf 20 | from .regnet256gf import RegNet256gf 21 | from .regnet10b import RegNet10b 22 | 23 | 24 | __all__ = [ 25 | 'RegNet', 'ResNet', 'ResNetV1d', 'ResNeXt', 'SSDVGG', 'HRNet', 26 | 'MobileNetV2', 'Res2Net', 'HourglassNet', 'DetectoRS_ResNet', 27 | 'DetectoRS_ResNeXt', 'Darknet', 'ResNeSt', 'TridentResNet', 'CSPDarknet', 28 | 'SwinTransformer', 'PyramidVisionTransformer', 29 | 'PyramidVisionTransformerV2', 'EfficientNet', 30 | 'RegNet32gf', 'RegNet256gf', 'RegNet10b' 31 | ] 32 | -------------------------------------------------------------------------------- /mmdet/models/builder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import warnings 3 | 4 | from mmcv.cnn import MODELS as MMCV_MODELS 5 | from mmcv.utils import Registry 6 | 7 | MODELS = Registry('models', parent=MMCV_MODELS) 8 | 9 | BACKBONES = MODELS 10 | NECKS = MODELS 11 | ROI_EXTRACTORS = MODELS 12 | SHARED_HEADS = MODELS 13 | HEADS = MODELS 14 | LOSSES = MODELS 15 | DETECTORS = MODELS 16 | 17 | 18 | def build_backbone(cfg): 19 | """Build backbone.""" 20 | return BACKBONES.build(cfg) 21 | 22 | 23 | def build_neck(cfg): 24 | """Build neck.""" 25 | return NECKS.build(cfg) 26 | 27 | 28 | def build_roi_extractor(cfg): 29 | """Build roi extractor.""" 30 | return ROI_EXTRACTORS.build(cfg) 31 | 32 | 33 | def build_shared_head(cfg): 34 | """Build shared head.""" 35 | return SHARED_HEADS.build(cfg) 36 | 37 | 38 | def build_head(cfg): 39 | """Build head.""" 40 | return HEADS.build(cfg) 41 | 42 | 43 | def build_loss(cfg): 44 | """Build loss.""" 45 | return LOSSES.build(cfg) 46 | 47 | 48 | def build_detector(cfg, train_cfg=None, test_cfg=None): 49 | """Build detector.""" 50 | if train_cfg is not None or test_cfg is not None: 51 | warnings.warn( 52 | 'train_cfg and test_cfg is deprecated, ' 53 | 'please specify them in model', UserWarning) 54 | assert cfg.get('train_cfg') is None or train_cfg is None, \ 55 | 'train_cfg specified in both outer field and model field ' 56 | assert cfg.get('test_cfg') is None or test_cfg is None, \ 57 | 'test_cfg specified in both outer field and model field ' 58 | return DETECTORS.build( 59 | cfg, default_args=dict(train_cfg=train_cfg, test_cfg=test_cfg)) 60 | -------------------------------------------------------------------------------- /mmdet/models/detectors/atss.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class ATSS(SingleStageDetector): 8 | """Implementation of `ATSS `_.""" 9 | 10 | def __init__(self, 11 | backbone, 12 | neck, 13 | bbox_head, 14 | train_cfg=None, 15 | test_cfg=None, 16 | pretrained=None, 17 | init_cfg=None): 18 | super(ATSS, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained, init_cfg) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/autoassign.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class AutoAssign(SingleStageDetector): 8 | """Implementation of `AutoAssign: Differentiable Label Assignment for Dense 9 | Object Detection `_.""" 10 | 11 | def __init__(self, 12 | backbone, 13 | neck, 14 | bbox_head, 15 | train_cfg=None, 16 | test_cfg=None, 17 | pretrained=None): 18 | super(AutoAssign, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/cascade_rcnn.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .two_stage import TwoStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class CascadeRCNN(TwoStageDetector): 8 | r"""Implementation of `Cascade R-CNN: Delving into High Quality Object 9 | Detection `_""" 10 | 11 | def __init__(self, 12 | backbone, 13 | neck=None, 14 | rpn_head=None, 15 | roi_head=None, 16 | train_cfg=None, 17 | test_cfg=None, 18 | pretrained=None, 19 | init_cfg=None): 20 | super(CascadeRCNN, self).__init__( 21 | backbone=backbone, 22 | neck=neck, 23 | rpn_head=rpn_head, 24 | roi_head=roi_head, 25 | train_cfg=train_cfg, 26 | test_cfg=test_cfg, 27 | pretrained=pretrained, 28 | init_cfg=init_cfg) 29 | 30 | def show_result(self, data, result, **kwargs): 31 | """Show prediction results of the detector. 32 | 33 | Args: 34 | data (str or np.ndarray): Image filename or loaded image. 35 | result (Tensor or tuple): The results to draw over `img` 36 | bbox_result or (bbox_result, segm_result). 37 | 38 | Returns: 39 | np.ndarray: The image with bboxes drawn on it. 40 | """ 41 | if self.with_mask: 42 | ms_bbox_result, ms_segm_result = result 43 | if isinstance(ms_bbox_result, dict): 44 | result = (ms_bbox_result['ensemble'], 45 | ms_segm_result['ensemble']) 46 | else: 47 | if isinstance(result, dict): 48 | result = result['ensemble'] 49 | return super(CascadeRCNN, self).show_result(data, result, **kwargs) 50 | -------------------------------------------------------------------------------- /mmdet/models/detectors/ddod.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class DDOD(SingleStageDetector): 8 | """Implementation of `DDOD `_.""" 9 | 10 | def __init__(self, 11 | backbone, 12 | neck, 13 | bbox_head, 14 | train_cfg=None, 15 | test_cfg=None, 16 | pretrained=None, 17 | init_cfg=None): 18 | super(DDOD, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained, init_cfg) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/deformable_detr.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .detr import DETR 4 | 5 | 6 | @DETECTORS.register_module() 7 | class DeformableDETR(DETR): 8 | 9 | def __init__(self, *args, **kwargs): 10 | super(DETR, self).__init__(*args, **kwargs) 11 | -------------------------------------------------------------------------------- /mmdet/models/detectors/faster_rcnn.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .two_stage import TwoStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class FasterRCNN(TwoStageDetector): 8 | """Implementation of `Faster R-CNN `_""" 9 | 10 | def __init__(self, 11 | backbone, 12 | rpn_head, 13 | roi_head, 14 | train_cfg, 15 | test_cfg, 16 | neck=None, 17 | pretrained=None, 18 | init_cfg=None): 19 | super(FasterRCNN, self).__init__( 20 | backbone=backbone, 21 | neck=neck, 22 | rpn_head=rpn_head, 23 | roi_head=roi_head, 24 | train_cfg=train_cfg, 25 | test_cfg=test_cfg, 26 | pretrained=pretrained, 27 | init_cfg=init_cfg) 28 | -------------------------------------------------------------------------------- /mmdet/models/detectors/fcos.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class FCOS(SingleStageDetector): 8 | """Implementation of `FCOS `_""" 9 | 10 | def __init__(self, 11 | backbone, 12 | neck, 13 | bbox_head, 14 | train_cfg=None, 15 | test_cfg=None, 16 | pretrained=None, 17 | init_cfg=None): 18 | super(FCOS, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained, init_cfg) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/fovea.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class FOVEA(SingleStageDetector): 8 | """Implementation of `FoveaBox `_""" 9 | 10 | def __init__(self, 11 | backbone, 12 | neck, 13 | bbox_head, 14 | train_cfg=None, 15 | test_cfg=None, 16 | pretrained=None, 17 | init_cfg=None): 18 | super(FOVEA, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained, init_cfg) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/fsaf.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class FSAF(SingleStageDetector): 8 | """Implementation of `FSAF `_""" 9 | 10 | def __init__(self, 11 | backbone, 12 | neck, 13 | bbox_head, 14 | train_cfg=None, 15 | test_cfg=None, 16 | pretrained=None, 17 | init_cfg=None): 18 | super(FSAF, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained, init_cfg) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/gfl.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class GFL(SingleStageDetector): 8 | 9 | def __init__(self, 10 | backbone, 11 | neck, 12 | bbox_head, 13 | train_cfg=None, 14 | test_cfg=None, 15 | pretrained=None, 16 | init_cfg=None): 17 | super(GFL, self).__init__(backbone, neck, bbox_head, train_cfg, 18 | test_cfg, pretrained, init_cfg) 19 | -------------------------------------------------------------------------------- /mmdet/models/detectors/grid_rcnn.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .two_stage import TwoStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class GridRCNN(TwoStageDetector): 8 | """Grid R-CNN. 9 | 10 | This detector is the implementation of: 11 | - Grid R-CNN (https://arxiv.org/abs/1811.12030) 12 | - Grid R-CNN Plus: Faster and Better (https://arxiv.org/abs/1906.05688) 13 | """ 14 | 15 | def __init__(self, 16 | backbone, 17 | rpn_head, 18 | roi_head, 19 | train_cfg, 20 | test_cfg, 21 | neck=None, 22 | pretrained=None, 23 | init_cfg=None): 24 | super(GridRCNN, self).__init__( 25 | backbone=backbone, 26 | neck=neck, 27 | rpn_head=rpn_head, 28 | roi_head=roi_head, 29 | train_cfg=train_cfg, 30 | test_cfg=test_cfg, 31 | pretrained=pretrained, 32 | init_cfg=init_cfg) 33 | -------------------------------------------------------------------------------- /mmdet/models/detectors/htc.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .cascade_rcnn import CascadeRCNN 4 | 5 | 6 | @DETECTORS.register_module() 7 | class HybridTaskCascade(CascadeRCNN): 8 | """Implementation of `HTC `_""" 9 | 10 | def __init__(self, **kwargs): 11 | super(HybridTaskCascade, self).__init__(**kwargs) 12 | 13 | @property 14 | def with_semantic(self): 15 | """bool: whether the detector has a semantic head""" 16 | return self.roi_head.with_semantic 17 | -------------------------------------------------------------------------------- /mmdet/models/detectors/mask2former.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .maskformer import MaskFormer 4 | 5 | 6 | @DETECTORS.register_module() 7 | class Mask2Former(MaskFormer): 8 | r"""Implementation of `Masked-attention Mask 9 | Transformer for Universal Image Segmentation 10 | `_.""" 11 | 12 | def __init__(self, 13 | backbone, 14 | neck=None, 15 | panoptic_head=None, 16 | panoptic_fusion_head=None, 17 | train_cfg=None, 18 | test_cfg=None, 19 | init_cfg=None): 20 | super().__init__( 21 | backbone, 22 | neck=neck, 23 | panoptic_head=panoptic_head, 24 | panoptic_fusion_head=panoptic_fusion_head, 25 | train_cfg=train_cfg, 26 | test_cfg=test_cfg, 27 | init_cfg=init_cfg) 28 | -------------------------------------------------------------------------------- /mmdet/models/detectors/mask_rcnn.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .two_stage import TwoStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class MaskRCNN(TwoStageDetector): 8 | """Implementation of `Mask R-CNN `_""" 9 | 10 | def __init__(self, 11 | backbone, 12 | rpn_head, 13 | roi_head, 14 | train_cfg, 15 | test_cfg, 16 | neck=None, 17 | pretrained=None, 18 | init_cfg=None): 19 | super(MaskRCNN, self).__init__( 20 | backbone=backbone, 21 | neck=neck, 22 | rpn_head=rpn_head, 23 | roi_head=roi_head, 24 | train_cfg=train_cfg, 25 | test_cfg=test_cfg, 26 | pretrained=pretrained, 27 | init_cfg=init_cfg) 28 | -------------------------------------------------------------------------------- /mmdet/models/detectors/mask_scoring_rcnn.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .two_stage import TwoStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class MaskScoringRCNN(TwoStageDetector): 8 | """Mask Scoring RCNN. 9 | 10 | https://arxiv.org/abs/1903.00241 11 | """ 12 | 13 | def __init__(self, 14 | backbone, 15 | rpn_head, 16 | roi_head, 17 | train_cfg, 18 | test_cfg, 19 | neck=None, 20 | pretrained=None, 21 | init_cfg=None): 22 | super(MaskScoringRCNN, self).__init__( 23 | backbone=backbone, 24 | neck=neck, 25 | rpn_head=rpn_head, 26 | roi_head=roi_head, 27 | train_cfg=train_cfg, 28 | test_cfg=test_cfg, 29 | pretrained=pretrained, 30 | init_cfg=init_cfg) 31 | -------------------------------------------------------------------------------- /mmdet/models/detectors/nasfcos.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class NASFCOS(SingleStageDetector): 8 | """NAS-FCOS: Fast Neural Architecture Search for Object Detection. 9 | 10 | https://arxiv.org/abs/1906.0442 11 | """ 12 | 13 | def __init__(self, 14 | backbone, 15 | neck, 16 | bbox_head, 17 | train_cfg=None, 18 | test_cfg=None, 19 | pretrained=None, 20 | init_cfg=None): 21 | super(NASFCOS, self).__init__(backbone, neck, bbox_head, train_cfg, 22 | test_cfg, pretrained, init_cfg) 23 | -------------------------------------------------------------------------------- /mmdet/models/detectors/paa.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class PAA(SingleStageDetector): 8 | """Implementation of `PAA `_.""" 9 | 10 | def __init__(self, 11 | backbone, 12 | neck, 13 | bbox_head, 14 | train_cfg=None, 15 | test_cfg=None, 16 | pretrained=None, 17 | init_cfg=None): 18 | super(PAA, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained, init_cfg) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/panoptic_fpn.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .panoptic_two_stage_segmentor import TwoStagePanopticSegmentor 4 | 5 | 6 | @DETECTORS.register_module() 7 | class PanopticFPN(TwoStagePanopticSegmentor): 8 | r"""Implementation of `Panoptic feature pyramid 9 | networks `_""" 10 | 11 | def __init__( 12 | self, 13 | backbone, 14 | neck=None, 15 | rpn_head=None, 16 | roi_head=None, 17 | train_cfg=None, 18 | test_cfg=None, 19 | pretrained=None, 20 | init_cfg=None, 21 | # for panoptic segmentation 22 | semantic_head=None, 23 | panoptic_fusion_head=None): 24 | super(PanopticFPN, self).__init__( 25 | backbone=backbone, 26 | neck=neck, 27 | rpn_head=rpn_head, 28 | roi_head=roi_head, 29 | train_cfg=train_cfg, 30 | test_cfg=test_cfg, 31 | pretrained=pretrained, 32 | init_cfg=init_cfg, 33 | semantic_head=semantic_head, 34 | panoptic_fusion_head=panoptic_fusion_head) 35 | -------------------------------------------------------------------------------- /mmdet/models/detectors/point_rend.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .two_stage import TwoStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class PointRend(TwoStageDetector): 8 | """PointRend: Image Segmentation as Rendering 9 | 10 | This detector is the implementation of 11 | `PointRend `_. 12 | 13 | """ 14 | 15 | def __init__(self, 16 | backbone, 17 | rpn_head, 18 | roi_head, 19 | train_cfg, 20 | test_cfg, 21 | neck=None, 22 | pretrained=None, 23 | init_cfg=None): 24 | super(PointRend, self).__init__( 25 | backbone=backbone, 26 | neck=neck, 27 | rpn_head=rpn_head, 28 | roi_head=roi_head, 29 | train_cfg=train_cfg, 30 | test_cfg=test_cfg, 31 | pretrained=pretrained, 32 | init_cfg=init_cfg) 33 | -------------------------------------------------------------------------------- /mmdet/models/detectors/queryinst.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .sparse_rcnn import SparseRCNN 4 | 5 | 6 | @DETECTORS.register_module() 7 | class QueryInst(SparseRCNN): 8 | r"""Implementation of 9 | `Instances as Queries `_""" 10 | 11 | def __init__(self, 12 | backbone, 13 | rpn_head, 14 | roi_head, 15 | train_cfg, 16 | test_cfg, 17 | neck=None, 18 | pretrained=None, 19 | init_cfg=None): 20 | super(QueryInst, self).__init__( 21 | backbone=backbone, 22 | neck=neck, 23 | rpn_head=rpn_head, 24 | roi_head=roi_head, 25 | train_cfg=train_cfg, 26 | test_cfg=test_cfg, 27 | pretrained=pretrained, 28 | init_cfg=init_cfg) 29 | -------------------------------------------------------------------------------- /mmdet/models/detectors/reppoints_detector.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class RepPointsDetector(SingleStageDetector): 8 | """RepPoints: Point Set Representation for Object Detection. 9 | 10 | This detector is the implementation of: 11 | - RepPoints detector (https://arxiv.org/pdf/1904.11490) 12 | """ 13 | 14 | def __init__(self, 15 | backbone, 16 | neck, 17 | bbox_head, 18 | train_cfg=None, 19 | test_cfg=None, 20 | pretrained=None, 21 | init_cfg=None): 22 | super(RepPointsDetector, 23 | self).__init__(backbone, neck, bbox_head, train_cfg, test_cfg, 24 | pretrained, init_cfg) 25 | -------------------------------------------------------------------------------- /mmdet/models/detectors/retinanet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class RetinaNet(SingleStageDetector): 8 | """Implementation of `RetinaNet `_""" 9 | 10 | def __init__(self, 11 | backbone, 12 | neck, 13 | bbox_head, 14 | train_cfg=None, 15 | test_cfg=None, 16 | pretrained=None, 17 | init_cfg=None): 18 | super(RetinaNet, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained, init_cfg) 20 | -------------------------------------------------------------------------------- /mmdet/models/detectors/scnet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .cascade_rcnn import CascadeRCNN 4 | 5 | 6 | @DETECTORS.register_module() 7 | class SCNet(CascadeRCNN): 8 | """Implementation of `SCNet `_""" 9 | 10 | def __init__(self, **kwargs): 11 | super(SCNet, self).__init__(**kwargs) 12 | -------------------------------------------------------------------------------- /mmdet/models/detectors/solo.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage_instance_seg import SingleStageInstanceSegmentor 4 | 5 | 6 | @DETECTORS.register_module() 7 | class SOLO(SingleStageInstanceSegmentor): 8 | """`SOLO: Segmenting Objects by Locations 9 | `_ 10 | 11 | """ 12 | 13 | def __init__(self, 14 | backbone, 15 | neck=None, 16 | bbox_head=None, 17 | mask_head=None, 18 | train_cfg=None, 19 | test_cfg=None, 20 | init_cfg=None, 21 | pretrained=None): 22 | super().__init__( 23 | backbone=backbone, 24 | neck=neck, 25 | bbox_head=bbox_head, 26 | mask_head=mask_head, 27 | train_cfg=train_cfg, 28 | test_cfg=test_cfg, 29 | init_cfg=init_cfg, 30 | pretrained=pretrained) 31 | -------------------------------------------------------------------------------- /mmdet/models/detectors/solov2.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage_instance_seg import SingleStageInstanceSegmentor 4 | 5 | 6 | @DETECTORS.register_module() 7 | class SOLOv2(SingleStageInstanceSegmentor): 8 | """`SOLOv2: Dynamic and Fast Instance Segmentation 9 | `_ 10 | 11 | """ 12 | 13 | def __init__(self, 14 | backbone, 15 | neck=None, 16 | bbox_head=None, 17 | mask_head=None, 18 | train_cfg=None, 19 | test_cfg=None, 20 | init_cfg=None, 21 | pretrained=None): 22 | super().__init__( 23 | backbone=backbone, 24 | neck=neck, 25 | bbox_head=bbox_head, 26 | mask_head=mask_head, 27 | train_cfg=train_cfg, 28 | test_cfg=test_cfg, 29 | init_cfg=init_cfg, 30 | pretrained=pretrained) 31 | -------------------------------------------------------------------------------- /mmdet/models/detectors/tood.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class TOOD(SingleStageDetector): 8 | r"""Implementation of `TOOD: Task-aligned One-stage Object Detection. 9 | `_.""" 10 | 11 | def __init__(self, 12 | backbone, 13 | neck, 14 | bbox_head, 15 | train_cfg=None, 16 | test_cfg=None, 17 | pretrained=None, 18 | init_cfg=None): 19 | super(TOOD, self).__init__(backbone, neck, bbox_head, train_cfg, 20 | test_cfg, pretrained, init_cfg) 21 | 22 | def set_epoch(self, epoch): 23 | self.bbox_head.epoch = epoch 24 | -------------------------------------------------------------------------------- /mmdet/models/detectors/vfnet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class VFNet(SingleStageDetector): 8 | """Implementation of `VarifocalNet 9 | (VFNet).`_""" 10 | 11 | def __init__(self, 12 | backbone, 13 | neck, 14 | bbox_head, 15 | train_cfg=None, 16 | test_cfg=None, 17 | pretrained=None, 18 | init_cfg=None): 19 | super(VFNet, self).__init__(backbone, neck, bbox_head, train_cfg, 20 | test_cfg, pretrained, init_cfg) 21 | -------------------------------------------------------------------------------- /mmdet/models/detectors/yolo.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | # Copyright (c) 2019 Western Digital Corporation or its affiliates. 3 | import torch 4 | 5 | from ..builder import DETECTORS 6 | from .single_stage import SingleStageDetector 7 | 8 | 9 | @DETECTORS.register_module() 10 | class YOLOV3(SingleStageDetector): 11 | 12 | def __init__(self, 13 | backbone, 14 | neck, 15 | bbox_head, 16 | train_cfg=None, 17 | test_cfg=None, 18 | pretrained=None, 19 | init_cfg=None): 20 | super(YOLOV3, self).__init__(backbone, neck, bbox_head, train_cfg, 21 | test_cfg, pretrained, init_cfg) 22 | 23 | def onnx_export(self, img, img_metas): 24 | """Test function for exporting to ONNX, without test time augmentation. 25 | 26 | Args: 27 | img (torch.Tensor): input images. 28 | img_metas (list[dict]): List of image information. 29 | 30 | Returns: 31 | tuple[Tensor, Tensor]: dets of shape [N, num_det, 5] 32 | and class labels of shape [N, num_det]. 33 | """ 34 | x = self.extract_feat(img) 35 | outs = self.bbox_head.forward(x) 36 | # get shape as tensor 37 | img_shape = torch._shape_as_tensor(img)[2:] 38 | img_metas[0]['img_shape_for_onnx'] = img_shape 39 | 40 | det_bboxes, det_labels = self.bbox_head.onnx_export(*outs, img_metas) 41 | 42 | return det_bboxes, det_labels 43 | -------------------------------------------------------------------------------- /mmdet/models/detectors/yolof.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import DETECTORS 3 | from .single_stage import SingleStageDetector 4 | 5 | 6 | @DETECTORS.register_module() 7 | class YOLOF(SingleStageDetector): 8 | r"""Implementation of `You Only Look One-level Feature 9 | `_""" 10 | 11 | def __init__(self, 12 | backbone, 13 | neck, 14 | bbox_head, 15 | train_cfg=None, 16 | test_cfg=None, 17 | pretrained=None): 18 | super(YOLOF, self).__init__(backbone, neck, bbox_head, train_cfg, 19 | test_cfg, pretrained) 20 | -------------------------------------------------------------------------------- /mmdet/models/losses/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .accuracy import Accuracy, accuracy 3 | from .ae_loss import AssociativeEmbeddingLoss 4 | from .balanced_l1_loss import BalancedL1Loss, balanced_l1_loss 5 | from .cross_entropy_loss import (CrossEntropyLoss, binary_cross_entropy, 6 | cross_entropy, mask_cross_entropy) 7 | from .dice_loss import DiceLoss 8 | from .focal_loss import FocalLoss, sigmoid_focal_loss 9 | from .gaussian_focal_loss import GaussianFocalLoss 10 | from .gfocal_loss import DistributionFocalLoss, QualityFocalLoss 11 | from .ghm_loss import GHMC, GHMR 12 | from .iou_loss import (BoundedIoULoss, CIoULoss, DIoULoss, GIoULoss, IoULoss, 13 | bounded_iou_loss, iou_loss) 14 | from .kd_loss import KnowledgeDistillationKLDivLoss 15 | from .mse_loss import MSELoss, mse_loss 16 | from .pisa_loss import carl_loss, isr_p 17 | from .seesaw_loss import SeesawLoss 18 | from .smooth_l1_loss import L1Loss, SmoothL1Loss, l1_loss, smooth_l1_loss 19 | from .utils import reduce_loss, weight_reduce_loss, weighted_loss 20 | from .varifocal_loss import VarifocalLoss 21 | from .hierarchy_loss import HierarchyLoss 22 | 23 | __all__ = [ 24 | 'accuracy', 'Accuracy', 'cross_entropy', 'binary_cross_entropy', 25 | 'mask_cross_entropy', 'CrossEntropyLoss', 'sigmoid_focal_loss', 26 | 'FocalLoss', 'smooth_l1_loss', 'SmoothL1Loss', 'balanced_l1_loss', 27 | 'BalancedL1Loss', 'mse_loss', 'MSELoss', 'iou_loss', 'bounded_iou_loss', 28 | 'IoULoss', 'BoundedIoULoss', 'GIoULoss', 'DIoULoss', 'CIoULoss', 'GHMC', 29 | 'GHMR', 'reduce_loss', 'weight_reduce_loss', 'weighted_loss', 'L1Loss', 30 | 'l1_loss', 'isr_p', 'carl_loss', 'AssociativeEmbeddingLoss', 31 | 'GaussianFocalLoss', 'QualityFocalLoss', 'DistributionFocalLoss', 32 | 'VarifocalLoss', 'KnowledgeDistillationKLDivLoss', 'SeesawLoss', 'DiceLoss', 33 | 'HierarchyLoss' 34 | ] 35 | -------------------------------------------------------------------------------- /mmdet/models/necks/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .bfp import BFP 3 | from .channel_mapper import ChannelMapper 4 | from .ct_resnet_neck import CTResNetNeck 5 | from .dilated_encoder import DilatedEncoder 6 | from .dyhead import DyHead 7 | from .fpg import FPG 8 | from .fpn import FPN 9 | from .fpn_carafe import FPN_CARAFE 10 | from .hrfpn import HRFPN 11 | from .nas_fpn import NASFPN 12 | from .nasfcos_fpn import NASFCOS_FPN 13 | from .pafpn import PAFPN 14 | from .rfp import RFP 15 | from .ssd_neck import SSDNeck 16 | from .yolo_neck import YOLOV3Neck 17 | from .yolox_pafpn import YOLOXPAFPN 18 | from .bifpn import BIFPN 19 | 20 | __all__ = [ 21 | 'FPN', 'BFP', 'ChannelMapper', 'HRFPN', 'NASFPN', 'FPN_CARAFE', 'PAFPN', 22 | 'NASFCOS_FPN', 'RFP', 'YOLOV3Neck', 'FPG', 'DilatedEncoder', 23 | 'CTResNetNeck', 'SSDNeck', 'YOLOXPAFPN', 'DyHead', 'BIFPN' 24 | ] 25 | -------------------------------------------------------------------------------- /mmdet/models/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .dropblock import DropBlock 3 | from .msdeformattn_pixel_decoder import MSDeformAttnPixelDecoder 4 | from .pixel_decoder import PixelDecoder, TransformerEncoderPixelDecoder 5 | 6 | __all__ = [ 7 | 'DropBlock', 'PixelDecoder', 'TransformerEncoderPixelDecoder', 8 | 'MSDeformAttnPixelDecoder' 9 | ] 10 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .base_roi_head import BaseRoIHead 3 | from .bbox_heads import (BBoxHead, ConvFCBBoxHead, DIIHead, 4 | DoubleConvFCBBoxHead, SABLHead, SCNetBBoxHead, 5 | Shared2FCBBoxHead, Shared4Conv1FCBBoxHead) 6 | from .cascade_roi_head import CascadeRoIHead 7 | from .double_roi_head import DoubleHeadRoIHead 8 | from .dynamic_roi_head import DynamicRoIHead 9 | from .grid_roi_head import GridRoIHead 10 | from .htc_roi_head import HybridTaskCascadeRoIHead 11 | from .mask_heads import (CoarseMaskHead, FCNMaskHead, FeatureRelayHead, 12 | FusedSemanticHead, GlobalContextHead, GridHead, 13 | HTCMaskHead, MaskIoUHead, MaskPointHead, 14 | SCNetMaskHead, SCNetSemanticHead) 15 | from .mask_scoring_roi_head import MaskScoringRoIHead 16 | from .pisa_roi_head import PISARoIHead 17 | from .point_rend_roi_head import PointRendRoIHead 18 | from .roi_extractors import (BaseRoIExtractor, GenericRoIExtractor, 19 | SingleRoIExtractor) 20 | from .scnet_roi_head import SCNetRoIHead 21 | from .shared_heads import ResLayer 22 | from .sparse_roi_head import SparseRoIHead 23 | from .standard_roi_head import StandardRoIHead 24 | from .trident_roi_head import TridentRoIHead 25 | 26 | __all__ = [ 27 | 'BaseRoIHead', 'CascadeRoIHead', 'DoubleHeadRoIHead', 'MaskScoringRoIHead', 28 | 'HybridTaskCascadeRoIHead', 'GridRoIHead', 'ResLayer', 'BBoxHead', 29 | 'ConvFCBBoxHead', 'DIIHead', 'SABLHead', 'Shared2FCBBoxHead', 30 | 'StandardRoIHead', 'Shared4Conv1FCBBoxHead', 'DoubleConvFCBBoxHead', 31 | 'FCNMaskHead', 'HTCMaskHead', 'FusedSemanticHead', 'GridHead', 32 | 'MaskIoUHead', 'BaseRoIExtractor', 'GenericRoIExtractor', 33 | 'SingleRoIExtractor', 'PISARoIHead', 'PointRendRoIHead', 'MaskPointHead', 34 | 'CoarseMaskHead', 'DynamicRoIHead', 'SparseRoIHead', 'TridentRoIHead', 35 | 'SCNetRoIHead', 'SCNetMaskHead', 'SCNetSemanticHead', 'SCNetBBoxHead', 36 | 'FeatureRelayHead', 'GlobalContextHead' 37 | ] 38 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/bbox_heads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .bbox_head import BBoxHead 3 | from .convfc_bbox_head import (ConvFCBBoxHead, Shared2FCBBoxHead, 4 | Shared4Conv1FCBBoxHead) 5 | from .dii_head import DIIHead 6 | from .double_bbox_head import DoubleConvFCBBoxHead 7 | from .sabl_head import SABLHead 8 | from .scnet_bbox_head import SCNetBBoxHead 9 | 10 | __all__ = [ 11 | 'BBoxHead', 'ConvFCBBoxHead', 'Shared2FCBBoxHead', 12 | 'Shared4Conv1FCBBoxHead', 'DoubleConvFCBBoxHead', 'SABLHead', 'DIIHead', 13 | 'SCNetBBoxHead' 14 | ] 15 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/double_roi_head.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from ..builder import HEADS 3 | from .standard_roi_head import StandardRoIHead 4 | 5 | 6 | @HEADS.register_module() 7 | class DoubleHeadRoIHead(StandardRoIHead): 8 | """RoI head for Double Head RCNN. 9 | 10 | https://arxiv.org/abs/1904.06493 11 | """ 12 | 13 | def __init__(self, reg_roi_scale_factor, **kwargs): 14 | super(DoubleHeadRoIHead, self).__init__(**kwargs) 15 | self.reg_roi_scale_factor = reg_roi_scale_factor 16 | 17 | def _bbox_forward(self, x, rois): 18 | """Box head forward function used in both training and testing time.""" 19 | bbox_cls_feats = self.bbox_roi_extractor( 20 | x[:self.bbox_roi_extractor.num_inputs], rois) 21 | bbox_reg_feats = self.bbox_roi_extractor( 22 | x[:self.bbox_roi_extractor.num_inputs], 23 | rois, 24 | roi_scale_factor=self.reg_roi_scale_factor) 25 | if self.with_shared_head: 26 | bbox_cls_feats = self.shared_head(bbox_cls_feats) 27 | bbox_reg_feats = self.shared_head(bbox_reg_feats) 28 | cls_score, bbox_pred = self.bbox_head(bbox_cls_feats, bbox_reg_feats) 29 | 30 | bbox_results = dict( 31 | cls_score=cls_score, 32 | bbox_pred=bbox_pred, 33 | bbox_feats=bbox_cls_feats) 34 | return bbox_results 35 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/mask_heads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .coarse_mask_head import CoarseMaskHead 3 | from .dynamic_mask_head import DynamicMaskHead 4 | from .fcn_mask_head import FCNMaskHead 5 | from .feature_relay_head import FeatureRelayHead 6 | from .fused_semantic_head import FusedSemanticHead 7 | from .global_context_head import GlobalContextHead 8 | from .grid_head import GridHead 9 | from .htc_mask_head import HTCMaskHead 10 | from .mask_point_head import MaskPointHead 11 | from .maskiou_head import MaskIoUHead 12 | from .scnet_mask_head import SCNetMaskHead 13 | from .scnet_semantic_head import SCNetSemanticHead 14 | 15 | __all__ = [ 16 | 'FCNMaskHead', 'HTCMaskHead', 'FusedSemanticHead', 'GridHead', 17 | 'MaskIoUHead', 'CoarseMaskHead', 'MaskPointHead', 'SCNetMaskHead', 18 | 'SCNetSemanticHead', 'GlobalContextHead', 'FeatureRelayHead', 19 | 'DynamicMaskHead' 20 | ] 21 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/mask_heads/htc_mask_head.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmcv.cnn import ConvModule 3 | 4 | from mmdet.models.builder import HEADS 5 | from .fcn_mask_head import FCNMaskHead 6 | 7 | 8 | @HEADS.register_module() 9 | class HTCMaskHead(FCNMaskHead): 10 | 11 | def __init__(self, with_conv_res=True, *args, **kwargs): 12 | super(HTCMaskHead, self).__init__(*args, **kwargs) 13 | self.with_conv_res = with_conv_res 14 | if self.with_conv_res: 15 | self.conv_res = ConvModule( 16 | self.conv_out_channels, 17 | self.conv_out_channels, 18 | 1, 19 | conv_cfg=self.conv_cfg, 20 | norm_cfg=self.norm_cfg) 21 | 22 | def forward(self, x, res_feat=None, return_logits=True, return_feat=True): 23 | if res_feat is not None: 24 | assert self.with_conv_res 25 | res_feat = self.conv_res(res_feat) 26 | x = x + res_feat 27 | for conv in self.convs: 28 | x = conv(x) 29 | res_feat = x 30 | outs = [] 31 | if return_logits: 32 | x = self.upsample(x) 33 | if self.upsample_method == 'deconv': 34 | x = self.relu(x) 35 | mask_pred = self.conv_logits(x) 36 | outs.append(mask_pred) 37 | if return_feat: 38 | outs.append(res_feat) 39 | return outs if len(outs) > 1 else outs[0] 40 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/mask_heads/scnet_mask_head.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmdet.models.builder import HEADS 3 | from mmdet.models.utils import ResLayer, SimplifiedBasicBlock 4 | from .fcn_mask_head import FCNMaskHead 5 | 6 | 7 | @HEADS.register_module() 8 | class SCNetMaskHead(FCNMaskHead): 9 | """Mask head for `SCNet `_. 10 | 11 | Args: 12 | conv_to_res (bool, optional): if True, change the conv layers to 13 | ``SimplifiedBasicBlock``. 14 | """ 15 | 16 | def __init__(self, conv_to_res=True, **kwargs): 17 | super(SCNetMaskHead, self).__init__(**kwargs) 18 | self.conv_to_res = conv_to_res 19 | if conv_to_res: 20 | assert self.conv_kernel_size == 3 21 | self.num_res_blocks = self.num_convs // 2 22 | self.convs = ResLayer( 23 | SimplifiedBasicBlock, 24 | self.in_channels, 25 | self.conv_out_channels, 26 | self.num_res_blocks, 27 | conv_cfg=self.conv_cfg, 28 | norm_cfg=self.norm_cfg) 29 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/mask_heads/scnet_semantic_head.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmdet.models.builder import HEADS 3 | from mmdet.models.utils import ResLayer, SimplifiedBasicBlock 4 | from .fused_semantic_head import FusedSemanticHead 5 | 6 | 7 | @HEADS.register_module() 8 | class SCNetSemanticHead(FusedSemanticHead): 9 | """Mask head for `SCNet `_. 10 | 11 | Args: 12 | conv_to_res (bool, optional): if True, change the conv layers to 13 | ``SimplifiedBasicBlock``. 14 | """ 15 | 16 | def __init__(self, conv_to_res=True, **kwargs): 17 | super(SCNetSemanticHead, self).__init__(**kwargs) 18 | self.conv_to_res = conv_to_res 19 | if self.conv_to_res: 20 | num_res_blocks = self.num_convs // 2 21 | self.convs = ResLayer( 22 | SimplifiedBasicBlock, 23 | self.in_channels, 24 | self.conv_out_channels, 25 | num_res_blocks, 26 | conv_cfg=self.conv_cfg, 27 | norm_cfg=self.norm_cfg) 28 | self.num_convs = num_res_blocks 29 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/roi_extractors/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .base_roi_extractor import BaseRoIExtractor 3 | from .generic_roi_extractor import GenericRoIExtractor 4 | from .single_level_roi_extractor import SingleRoIExtractor 5 | 6 | __all__ = ['BaseRoIExtractor', 'SingleRoIExtractor', 'GenericRoIExtractor'] 7 | -------------------------------------------------------------------------------- /mmdet/models/roi_heads/shared_heads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .res_layer import ResLayer 3 | 4 | __all__ = ['ResLayer'] 5 | -------------------------------------------------------------------------------- /mmdet/models/seg_heads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .panoptic_fpn_head import PanopticFPNHead # noqa: F401,F403 3 | from .panoptic_fusion_heads import * # noqa: F401,F403 4 | -------------------------------------------------------------------------------- /mmdet/models/seg_heads/panoptic_fusion_heads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .base_panoptic_fusion_head import \ 3 | BasePanopticFusionHead # noqa: F401,F403 4 | from .heuristic_fusion_head import HeuristicFusionHead # noqa: F401,F403 5 | from .maskformer_fusion_head import MaskFormerFusionHead # noqa: F401,F403 6 | -------------------------------------------------------------------------------- /mmdet/models/seg_heads/panoptic_fusion_heads/base_panoptic_fusion_head.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from abc import ABCMeta, abstractmethod 3 | 4 | from mmcv.runner import BaseModule 5 | 6 | from ...builder import build_loss 7 | 8 | 9 | class BasePanopticFusionHead(BaseModule, metaclass=ABCMeta): 10 | """Base class for panoptic heads.""" 11 | 12 | def __init__(self, 13 | num_things_classes=80, 14 | num_stuff_classes=53, 15 | test_cfg=None, 16 | loss_panoptic=None, 17 | init_cfg=None, 18 | **kwargs): 19 | super(BasePanopticFusionHead, self).__init__(init_cfg) 20 | self.num_things_classes = num_things_classes 21 | self.num_stuff_classes = num_stuff_classes 22 | self.num_classes = num_things_classes + num_stuff_classes 23 | self.test_cfg = test_cfg 24 | 25 | if loss_panoptic: 26 | self.loss_panoptic = build_loss(loss_panoptic) 27 | else: 28 | self.loss_panoptic = None 29 | 30 | @property 31 | def with_loss(self): 32 | """bool: whether the panoptic head contains loss function.""" 33 | return self.loss_panoptic is not None 34 | 35 | @abstractmethod 36 | def forward_train(self, gt_masks=None, gt_semantic_seg=None, **kwargs): 37 | """Forward function during training.""" 38 | 39 | @abstractmethod 40 | def simple_test(self, 41 | img_metas, 42 | det_labels, 43 | mask_preds, 44 | seg_preds, 45 | det_bboxes, 46 | cfg=None, 47 | **kwargs): 48 | """Test without augmentation.""" 49 | -------------------------------------------------------------------------------- /mmdet/models/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .brick_wrappers import AdaptiveAvgPool2d, adaptive_avg_pool2d 3 | from .builder import build_linear_layer, build_transformer 4 | from .ckpt_convert import pvt_convert 5 | from .conv_upsample import ConvUpsample 6 | from .csp_layer import CSPLayer 7 | from .gaussian_target import gaussian_radius, gen_gaussian_target 8 | from .inverted_residual import InvertedResidual 9 | from .make_divisible import make_divisible 10 | from .misc import interpolate_as, sigmoid_geometric_mean 11 | from .normed_predictor import NormedConv2d, NormedLinear 12 | from .panoptic_gt_processing import preprocess_panoptic_gt 13 | from .point_sample import (get_uncertain_point_coords_with_randomness, 14 | get_uncertainty) 15 | from .positional_encoding import (LearnedPositionalEncoding, 16 | SinePositionalEncoding) 17 | from .res_layer import ResLayer, SimplifiedBasicBlock 18 | from .se_layer import DyReLU, SELayer 19 | from .transformer import (DetrTransformerDecoder, DetrTransformerDecoderLayer, 20 | DynamicConv, PatchEmbed, Transformer, nchw_to_nlc, 21 | nlc_to_nchw) 22 | 23 | __all__ = [ 24 | 'ResLayer', 'gaussian_radius', 'gen_gaussian_target', 25 | 'DetrTransformerDecoderLayer', 'DetrTransformerDecoder', 'Transformer', 26 | 'build_transformer', 'build_linear_layer', 'SinePositionalEncoding', 27 | 'LearnedPositionalEncoding', 'DynamicConv', 'SimplifiedBasicBlock', 28 | 'NormedLinear', 'NormedConv2d', 'make_divisible', 'InvertedResidual', 29 | 'SELayer', 'interpolate_as', 'ConvUpsample', 'CSPLayer', 30 | 'adaptive_avg_pool2d', 'AdaptiveAvgPool2d', 'PatchEmbed', 'nchw_to_nlc', 31 | 'nlc_to_nchw', 'pvt_convert', 'sigmoid_geometric_mean', 32 | 'preprocess_panoptic_gt', 'DyReLU', 33 | 'get_uncertain_point_coords_with_randomness', 'get_uncertainty' 34 | ] 35 | -------------------------------------------------------------------------------- /mmdet/models/utils/brick_wrappers.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import torch 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | from mmcv.cnn.bricks.wrappers import NewEmptyTensorOp, obsolete_torch_version 6 | 7 | if torch.__version__ == 'parrots': 8 | TORCH_VERSION = torch.__version__ 9 | else: 10 | # torch.__version__ could be 1.3.1+cu92, we only need the first two 11 | # for comparison 12 | TORCH_VERSION = tuple(int(x) for x in torch.__version__.split('.')[:2]) 13 | 14 | 15 | def adaptive_avg_pool2d(input, output_size): 16 | """Handle empty batch dimension to adaptive_avg_pool2d. 17 | 18 | Args: 19 | input (tensor): 4D tensor. 20 | output_size (int, tuple[int,int]): the target output size. 21 | """ 22 | if input.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 9)): 23 | if isinstance(output_size, int): 24 | output_size = [output_size, output_size] 25 | output_size = [*input.shape[:2], *output_size] 26 | empty = NewEmptyTensorOp.apply(input, output_size) 27 | return empty 28 | else: 29 | return F.adaptive_avg_pool2d(input, output_size) 30 | 31 | 32 | class AdaptiveAvgPool2d(nn.AdaptiveAvgPool2d): 33 | """Handle empty batch dimension to AdaptiveAvgPool2d.""" 34 | 35 | def forward(self, x): 36 | # PyTorch 1.9 does not support empty tensor inference yet 37 | if x.numel() == 0 and obsolete_torch_version(TORCH_VERSION, (1, 9)): 38 | output_size = self.output_size 39 | if isinstance(output_size, int): 40 | output_size = [output_size, output_size] 41 | else: 42 | output_size = [ 43 | v if v is not None else d 44 | for v, d in zip(output_size, 45 | x.size()[-2:]) 46 | ] 47 | output_size = [*x.shape[:2], *output_size] 48 | empty = NewEmptyTensorOp.apply(x, output_size) 49 | return empty 50 | 51 | return super().forward(x) 52 | -------------------------------------------------------------------------------- /mmdet/models/utils/builder.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import torch.nn as nn 3 | from mmcv.utils import Registry, build_from_cfg 4 | 5 | TRANSFORMER = Registry('Transformer') 6 | LINEAR_LAYERS = Registry('linear layers') 7 | 8 | 9 | def build_transformer(cfg, default_args=None): 10 | """Builder for Transformer.""" 11 | return build_from_cfg(cfg, TRANSFORMER, default_args) 12 | 13 | 14 | LINEAR_LAYERS.register_module('Linear', module=nn.Linear) 15 | 16 | 17 | def build_linear_layer(cfg, *args, **kwargs): 18 | """Build linear layer. 19 | Args: 20 | cfg (None or dict): The linear layer config, which should contain: 21 | - type (str): Layer type. 22 | - layer args: Args needed to instantiate an linear layer. 23 | args (argument list): Arguments passed to the `__init__` 24 | method of the corresponding linear layer. 25 | kwargs (keyword arguments): Keyword arguments passed to the `__init__` 26 | method of the corresponding linear layer. 27 | Returns: 28 | nn.Module: Created linear layer. 29 | """ 30 | if cfg is None: 31 | cfg_ = dict(type='Linear') 32 | else: 33 | if not isinstance(cfg, dict): 34 | raise TypeError('cfg must be a dict') 35 | if 'type' not in cfg: 36 | raise KeyError('the cfg dict must contain the key "type"') 37 | cfg_ = cfg.copy() 38 | 39 | layer_type = cfg_.pop('type') 40 | if layer_type not in LINEAR_LAYERS: 41 | raise KeyError(f'Unrecognized linear type {layer_type}') 42 | else: 43 | linear_layer = LINEAR_LAYERS.get(layer_type) 44 | 45 | layer = linear_layer(*args, **kwargs, **cfg_) 46 | 47 | return layer 48 | -------------------------------------------------------------------------------- /mmdet/models/utils/make_divisible.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | def make_divisible(value, divisor, min_value=None, min_ratio=0.9): 3 | """Make divisible function. 4 | 5 | This function rounds the channel number to the nearest value that can be 6 | divisible by the divisor. It is taken from the original tf repo. It ensures 7 | that all layers have a channel number that is divisible by divisor. It can 8 | be seen here: https://github.com/tensorflow/models/blob/master/research/slim/nets/mobilenet/mobilenet.py # noqa 9 | 10 | Args: 11 | value (int): The original channel number. 12 | divisor (int): The divisor to fully divide the channel number. 13 | min_value (int): The minimum value of the output channel. 14 | Default: None, means that the minimum value equal to the divisor. 15 | min_ratio (float): The minimum ratio of the rounded channel number to 16 | the original channel number. Default: 0.9. 17 | 18 | Returns: 19 | int: The modified output channel number. 20 | """ 21 | 22 | if min_value is None: 23 | min_value = divisor 24 | new_value = max(min_value, int(value + divisor / 2) // divisor * divisor) 25 | # Make sure that round down does not go down by more than (1-min_ratio). 26 | if new_value < min_ratio * value: 27 | new_value += divisor 28 | return new_value 29 | -------------------------------------------------------------------------------- /mmdet/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .collect_env import collect_env 3 | from .compat_config import compat_cfg 4 | from .logger import get_caller_name, get_root_logger, log_img_scale 5 | from .memory import AvoidCUDAOOM, AvoidOOM 6 | from .misc import find_latest_checkpoint, update_data_root 7 | from .replace_cfg_vals import replace_cfg_vals 8 | from .setup_env import setup_multi_processes 9 | from .split_batch import split_batch 10 | from .util_distribution import build_ddp, build_dp, get_device 11 | 12 | __all__ = [ 13 | 'get_root_logger', 'collect_env', 'find_latest_checkpoint', 14 | 'update_data_root', 'setup_multi_processes', 'get_caller_name', 15 | 'log_img_scale', 'compat_cfg', 'split_batch', 'build_ddp', 'build_dp', 16 | 'get_device', 'replace_cfg_vals', 'AvoidOOM', 'AvoidCUDAOOM' 17 | ] 18 | -------------------------------------------------------------------------------- /mmdet/utils/collect_env.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmcv.utils import collect_env as collect_base_env 3 | from mmcv.utils import get_git_hash 4 | 5 | import mmdet 6 | 7 | 8 | def collect_env(): 9 | """Collect the information of the running environments.""" 10 | env_info = collect_base_env() 11 | env_info['MMDetection'] = mmdet.__version__ + '+' + get_git_hash()[:7] 12 | return env_info 13 | 14 | 15 | if __name__ == '__main__': 16 | for name, val in collect_env().items(): 17 | print(f'{name}: {val}') 18 | -------------------------------------------------------------------------------- /mmdet/utils/profiling.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import contextlib 3 | import sys 4 | import time 5 | 6 | import torch 7 | 8 | if sys.version_info >= (3, 7): 9 | 10 | @contextlib.contextmanager 11 | def profile_time(trace_name, 12 | name, 13 | enabled=True, 14 | stream=None, 15 | end_stream=None): 16 | """Print time spent by CPU and GPU. 17 | 18 | Useful as a temporary context manager to find sweet spots of code 19 | suitable for async implementation. 20 | """ 21 | if (not enabled) or not torch.cuda.is_available(): 22 | yield 23 | return 24 | stream = stream if stream else torch.cuda.current_stream() 25 | end_stream = end_stream if end_stream else stream 26 | start = torch.cuda.Event(enable_timing=True) 27 | end = torch.cuda.Event(enable_timing=True) 28 | stream.record_event(start) 29 | try: 30 | cpu_start = time.monotonic() 31 | yield 32 | finally: 33 | cpu_end = time.monotonic() 34 | end_stream.record_event(end) 35 | end.synchronize() 36 | cpu_time = (cpu_end - cpu_start) * 1000 37 | gpu_time = start.elapsed_time(end) 38 | msg = f'{trace_name} {name} cpu_time {cpu_time:.2f} ms ' 39 | msg += f'gpu_time {gpu_time:.2f} ms stream {stream}' 40 | print(msg, end_stream) 41 | -------------------------------------------------------------------------------- /mmdet/utils/split_batch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import torch 3 | 4 | 5 | def split_batch(img, img_metas, kwargs): 6 | """Split data_batch by tags. 7 | 8 | Code is modified from 9 | # noqa: E501 10 | 11 | Args: 12 | img (Tensor): of shape (N, C, H, W) encoding input images. 13 | Typically these should be mean centered and std scaled. 14 | img_metas (list[dict]): List of image info dict where each dict 15 | has: 'img_shape', 'scale_factor', 'flip', and may also contain 16 | 'filename', 'ori_shape', 'pad_shape', and 'img_norm_cfg'. 17 | For details on the values of these keys, see 18 | :class:`mmdet.datasets.pipelines.Collect`. 19 | kwargs (dict): Specific to concrete implementation. 20 | 21 | Returns: 22 | data_groups (dict): a dict that data_batch splited by tags, 23 | such as 'sup', 'unsup_teacher', and 'unsup_student'. 24 | """ 25 | 26 | # only stack img in the batch 27 | def fuse_list(obj_list, obj): 28 | return torch.stack(obj_list) if isinstance(obj, 29 | torch.Tensor) else obj_list 30 | 31 | # select data with tag from data_batch 32 | def select_group(data_batch, current_tag): 33 | group_flag = [tag == current_tag for tag in data_batch['tag']] 34 | return { 35 | k: fuse_list([vv for vv, gf in zip(v, group_flag) if gf], v) 36 | for k, v in data_batch.items() 37 | } 38 | 39 | kwargs.update({'img': img, 'img_metas': img_metas}) 40 | kwargs.update({'tag': [meta['tag'] for meta in img_metas]}) 41 | tags = list(set(kwargs['tag'])) 42 | data_groups = {tag: select_group(kwargs, tag) for tag in tags} 43 | for tag, group in data_groups.items(): 44 | group.pop('tag') 45 | return data_groups 46 | -------------------------------------------------------------------------------- /mmdet/utils/util_random.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | """Helpers for random number generators.""" 3 | import numpy as np 4 | 5 | 6 | def ensure_rng(rng=None): 7 | """Coerces input into a random number generator. 8 | 9 | If the input is None, then a global random state is returned. 10 | 11 | If the input is a numeric value, then that is used as a seed to construct a 12 | random state. Otherwise the input is returned as-is. 13 | 14 | Adapted from [1]_. 15 | 16 | Args: 17 | rng (int | numpy.random.RandomState | None): 18 | if None, then defaults to the global rng. Otherwise this can be an 19 | integer or a RandomState class 20 | Returns: 21 | (numpy.random.RandomState) : rng - 22 | a numpy random number generator 23 | 24 | References: 25 | .. [1] https://gitlab.kitware.com/computer-vision/kwarray/blob/master/kwarray/util_random.py#L270 # noqa: E501 26 | """ 27 | 28 | if rng is None: 29 | rng = np.random.mtrand._rand 30 | elif isinstance(rng, int): 31 | rng = np.random.RandomState(rng) 32 | else: 33 | rng = rng 34 | return rng 35 | -------------------------------------------------------------------------------- /mmdet/version.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | 3 | __version__ = '2.25.1' 4 | short_version = __version__ 5 | 6 | 7 | def parse_version_info(version_str): 8 | version_info = [] 9 | for x in version_str.split('.'): 10 | if x.isdigit(): 11 | version_info.append(int(x)) 12 | elif x.find('rc') != -1: 13 | patch_version = x.split('rc') 14 | version_info.append(int(patch_version[0])) 15 | version_info.append(f'rc{patch_version[1]}') 16 | return tuple(version_info) 17 | 18 | 19 | version_info = parse_version_info(__version__) 20 | -------------------------------------------------------------------------------- /openimages2coco-master/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Bethge Lab 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 | -------------------------------------------------------------------------------- /openimages2coco-master/requirements.txt: -------------------------------------------------------------------------------- 1 | tqdm 2 | imagesize 3 | scikit_image 4 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | addopts = --xdoctest --xdoctest-style=auto 3 | norecursedirs = .git ignore build __pycache__ data docker docs .eggs 4 | 5 | filterwarnings= default 6 | ignore:.*No cfgstr given in Cacher constructor or call.*:Warning 7 | ignore:.*Define the __nice__ method for.*:Warning 8 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | -r requirements/build.txt 2 | -r requirements/optional.txt 3 | -r requirements/runtime.txt 4 | -r requirements/tests.txt 5 | -------------------------------------------------------------------------------- /requirements/albu.txt: -------------------------------------------------------------------------------- 1 | albumentations>=0.3.2 --no-binary qudida,albumentations 2 | -------------------------------------------------------------------------------- /requirements/build.txt: -------------------------------------------------------------------------------- 1 | # These must be installed before building mmdetection 2 | cython 3 | numpy 4 | -------------------------------------------------------------------------------- /requirements/docs.txt: -------------------------------------------------------------------------------- 1 | docutils==0.16.0 2 | myst-parser 3 | -e git+https://github.com/open-mmlab/pytorch_sphinx_theme.git#egg=pytorch_sphinx_theme 4 | sphinx==4.0.2 5 | sphinx-copybutton 6 | sphinx_markdown_tables 7 | sphinx_rtd_theme==0.5.2 8 | -------------------------------------------------------------------------------- /requirements/mminstall.txt: -------------------------------------------------------------------------------- 1 | mmcv-full>=1.3.17 2 | -------------------------------------------------------------------------------- /requirements/optional.txt: -------------------------------------------------------------------------------- 1 | cityscapesscripts 2 | imagecorruptions 3 | scipy 4 | sklearn 5 | timm 6 | -------------------------------------------------------------------------------- /requirements/readthedocs.txt: -------------------------------------------------------------------------------- 1 | mmcv 2 | torch 3 | torchvision 4 | -------------------------------------------------------------------------------- /requirements/runtime.txt: -------------------------------------------------------------------------------- 1 | matplotlib 2 | numpy 3 | pycocotools 4 | six 5 | terminaltables 6 | -------------------------------------------------------------------------------- /requirements/tests.txt: -------------------------------------------------------------------------------- 1 | asynctest 2 | codecov 3 | flake8 4 | interrogate 5 | isort==4.3.21 6 | # Note: used for kwarray.group_items, this may be ported to mmcv in the future. 7 | kwarray 8 | -e git+https://github.com/open-mmlab/mmtracking#egg=mmtrack 9 | onnx==1.7.0 10 | onnxruntime>=1.8.0 11 | protobuf<=3.20.1 12 | pytest 13 | ubelt 14 | xdoctest>=0.10.0 15 | yapf 16 | -------------------------------------------------------------------------------- /resources/coco_test_12510.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/resources/coco_test_12510.jpg -------------------------------------------------------------------------------- /resources/corruptions_sev_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/resources/corruptions_sev_3.png -------------------------------------------------------------------------------- /resources/data_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/resources/data_pipeline.png -------------------------------------------------------------------------------- /resources/loss_curve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/resources/loss_curve.png -------------------------------------------------------------------------------- /resources/mmdet-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/resources/mmdet-logo.png -------------------------------------------------------------------------------- /resources/zhihu_qrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/resources/zhihu_qrcode.jpg -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [isort] 2 | line_length = 79 3 | multi_line_output = 0 4 | extra_standard_library = setuptools 5 | known_first_party = mmdet 6 | known_third_party = PIL,asynctest,cityscapesscripts,cv2,gather_models,matplotlib,mmcv,numpy,onnx,onnxruntime,pycocotools,pytest,pytorch_sphinx_theme,requests,scipy,seaborn,six,terminaltables,torch,ts,yaml 7 | no_lines_before = STDLIB,LOCALFOLDER 8 | default_section = THIRDPARTY 9 | 10 | [yapf] 11 | BASED_ON_STYLE = pep8 12 | BLANK_LINE_BEFORE_NESTED_CLASS_OR_DEF = true 13 | SPLIT_BEFORE_EXPRESSION_AFTER_OPENING_PAREN = true 14 | 15 | # ignore-words-list needs to be lowercase format. For example, if we want to 16 | # ignore word "BA", then we need to append "ba" to ignore-words-list rather 17 | # than "BA" 18 | [codespell] 19 | skip = *.ipynb 20 | quiet-level = 3 21 | ignore-words-list = patten,nd,ty,mot,hist,formating,winn,gool,datas,wan,confids,TOOD,tood,ba 22 | -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2007/Annotations/000001.xml: -------------------------------------------------------------------------------- 1 | 2 | VOC2007 3 | 000001.jpg 4 | 5 | The VOC2007 Database 6 | PASCAL VOC2007 7 | flickr 8 | 341012865 9 | 10 | 11 | Fried Camels 12 | Jinky the Fruit Bat 13 | 14 | 15 | 353 16 | 500 17 | 3 18 | 19 | 0 20 | 21 | dog 22 | Left 23 | 1 24 | 0 25 | 26 | 48 27 | 240 28 | 195 29 | 371 30 | 31 | 32 | 33 | person 34 | Left 35 | 1 36 | 0 37 | 38 | 8 39 | 12 40 | 352 41 | 498 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2007/ImageSets/Main/test.txt: -------------------------------------------------------------------------------- 1 | 000001 2 | -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2007/ImageSets/Main/trainval.txt: -------------------------------------------------------------------------------- 1 | 000001 2 | -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2007/JPEGImages/000001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/data/VOCdevkit/VOC2007/JPEGImages/000001.jpg -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2012/Annotations/000001.xml: -------------------------------------------------------------------------------- 1 | 2 | VOC2007 3 | 000002.jpg 4 | 5 | The VOC2007 Database 6 | PASCAL VOC2007 7 | flickr 8 | 329145082 9 | 10 | 11 | hiromori2 12 | Hiroyuki Mori 13 | 14 | 15 | 335 16 | 500 17 | 3 18 | 19 | 0 20 | 21 | train 22 | Unspecified 23 | 0 24 | 0 25 | 26 | 139 27 | 200 28 | 207 29 | 301 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2012/ImageSets/Main/test.txt: -------------------------------------------------------------------------------- 1 | 000001 2 | -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2012/ImageSets/Main/trainval.txt: -------------------------------------------------------------------------------- 1 | 000001 2 | -------------------------------------------------------------------------------- /tests/data/VOCdevkit/VOC2012/JPEGImages/000001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/data/VOCdevkit/VOC2012/JPEGImages/000001.jpg -------------------------------------------------------------------------------- /tests/data/coco_sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "file_name": "fake1.jpg", 5 | "height": 800, 6 | "width": 800, 7 | "id": 0 8 | }, 9 | { 10 | "file_name": "fake2.jpg", 11 | "height": 800, 12 | "width": 800, 13 | "id": 1 14 | }, 15 | { 16 | "file_name": "fake3.jpg", 17 | "height": 800, 18 | "width": 800, 19 | "id": 2 20 | } 21 | ], 22 | "annotations": [ 23 | { 24 | "bbox": [ 25 | 0, 26 | 0, 27 | 20, 28 | 20 29 | ], 30 | "area": 400.00, 31 | "score": 1.0, 32 | "category_id": 1, 33 | "id": 1, 34 | "image_id": 0 35 | }, 36 | { 37 | "bbox": [ 38 | 0, 39 | 0, 40 | 20, 41 | 20 42 | ], 43 | "area": 400.00, 44 | "score": 1.0, 45 | "category_id": 2, 46 | "id": 2, 47 | "image_id": 0 48 | }, 49 | { 50 | "bbox": [ 51 | 0, 52 | 0, 53 | 20, 54 | 20 55 | ], 56 | "area": 400.00, 57 | "score": 1.0, 58 | "category_id": 1, 59 | "id": 3, 60 | "image_id": 1 61 | } 62 | ], 63 | "categories": [ 64 | { 65 | "id": 1, 66 | "name": "bus", 67 | "supercategory": "none" 68 | }, 69 | { 70 | "id": 2, 71 | "name": "car", 72 | "supercategory": "none" 73 | } 74 | ], 75 | "licenses": [], 76 | "info": null 77 | } 78 | -------------------------------------------------------------------------------- /tests/data/color.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/data/color.jpg -------------------------------------------------------------------------------- /tests/data/configs_mmtrack/selsa_faster_rcnn_r101_dc5_1x.py: -------------------------------------------------------------------------------- 1 | _base_ = [ 2 | './faster_rcnn_r50_dc5.py', './mot_challenge.py', 3 | '../../../configs/_base_/default_runtime.py' 4 | ] 5 | model = dict( 6 | type='SELSA', 7 | pretrains=None, 8 | detector=dict( 9 | backbone=dict(depth=18, base_channels=2), 10 | roi_head=dict( 11 | type='SelsaRoIHead', 12 | bbox_head=dict( 13 | type='SelsaBBoxHead', 14 | num_shared_fcs=2, 15 | aggregator=dict( 16 | type='SelsaAggregator', 17 | in_channels=32, 18 | num_attention_blocks=16))))) 19 | 20 | # dataset settings 21 | data = dict( 22 | val=dict( 23 | ref_img_sampler=dict( 24 | _delete_=True, 25 | num_ref_imgs=14, 26 | frame_range=[-7, 7], 27 | method='test_with_adaptive_stride')), 28 | test=dict( 29 | ref_img_sampler=dict( 30 | _delete_=True, 31 | num_ref_imgs=14, 32 | frame_range=[-7, 7], 33 | method='test_with_adaptive_stride'))) 34 | 35 | # optimizer 36 | optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001) 37 | optimizer_config = dict( 38 | _delete_=True, grad_clip=dict(max_norm=35, norm_type=2)) 39 | # learning policy 40 | lr_config = dict( 41 | policy='step', 42 | warmup='linear', 43 | warmup_iters=500, 44 | warmup_ratio=1.0 / 3, 45 | step=[2, 5]) 46 | # runtime settings 47 | total_epochs = 7 48 | evaluation = dict(metric=['bbox'], interval=7) 49 | -------------------------------------------------------------------------------- /tests/data/custom_dataset/images/000001.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/data/custom_dataset/images/000001.jpg -------------------------------------------------------------------------------- /tests/data/custom_dataset/images/000001.xml: -------------------------------------------------------------------------------- 1 | 2 | VOC2007 3 | 000001.jpg 4 | 5 | The VOC2007 Database 6 | PASCAL VOC2007 7 | flickr 8 | 341012865 9 | 10 | 11 | Fried Camels 12 | Jinky the Fruit Bat 13 | 14 | 15 | 353 16 | 500 17 | 3 18 | 19 | 0 20 | 21 | dog 22 | Left 23 | 1 24 | 0 25 | 26 | 48 27 | 240 28 | 195 29 | 371 30 | 31 | 32 | 33 | person 34 | Left 35 | 1 36 | 0 37 | 38 | 8 39 | 12 40 | 352 41 | 498 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /tests/data/custom_dataset/test.txt: -------------------------------------------------------------------------------- 1 | 000001 2 | -------------------------------------------------------------------------------- /tests/data/custom_dataset/trainval.txt: -------------------------------------------------------------------------------- 1 | 000001 2 | -------------------------------------------------------------------------------- /tests/data/gray.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/data/gray.jpg -------------------------------------------------------------------------------- /tests/test_data/test_datasets/test_coco_dataset.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import os.path as osp 3 | import tempfile 4 | 5 | import mmcv 6 | import pytest 7 | 8 | from mmdet.datasets import CocoDataset 9 | 10 | 11 | def _create_ids_error_coco_json(json_name): 12 | image = { 13 | 'id': 0, 14 | 'width': 640, 15 | 'height': 640, 16 | 'file_name': 'fake_name.jpg', 17 | } 18 | 19 | annotation_1 = { 20 | 'id': 1, 21 | 'image_id': 0, 22 | 'category_id': 0, 23 | 'area': 400, 24 | 'bbox': [50, 60, 20, 20], 25 | 'iscrowd': 0, 26 | } 27 | 28 | annotation_2 = { 29 | 'id': 1, 30 | 'image_id': 0, 31 | 'category_id': 0, 32 | 'area': 900, 33 | 'bbox': [100, 120, 30, 30], 34 | 'iscrowd': 0, 35 | } 36 | 37 | categories = [{ 38 | 'id': 0, 39 | 'name': 'car', 40 | 'supercategory': 'car', 41 | }] 42 | 43 | fake_json = { 44 | 'images': [image], 45 | 'annotations': [annotation_1, annotation_2], 46 | 'categories': categories 47 | } 48 | mmcv.dump(fake_json, json_name) 49 | 50 | 51 | def test_coco_annotation_ids_unique(): 52 | tmp_dir = tempfile.TemporaryDirectory() 53 | fake_json_file = osp.join(tmp_dir.name, 'fake_data.json') 54 | _create_ids_error_coco_json(fake_json_file) 55 | 56 | # test annotation ids not unique error 57 | with pytest.raises(AssertionError): 58 | CocoDataset(ann_file=fake_json_file, classes=('car', ), pipeline=[]) 59 | -------------------------------------------------------------------------------- /tests/test_data/test_datasets/test_xml_dataset.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | 4 | from mmdet.datasets import DATASETS 5 | 6 | 7 | def test_xml_dataset(): 8 | dataconfig = { 9 | 'ann_file': 'data/VOCdevkit/VOC2007/ImageSets/Main/test.txt', 10 | 'img_prefix': 'data/VOCdevkit/VOC2007/', 11 | 'pipeline': [{ 12 | 'type': 'LoadImageFromFile' 13 | }] 14 | } 15 | XMLDataset = DATASETS.get('XMLDataset') 16 | 17 | class XMLDatasetSubClass(XMLDataset): 18 | CLASSES = None 19 | 20 | # get_ann_info and _filter_imgs of XMLDataset 21 | # would use self.CLASSES, we added CLASSES not NONE 22 | with pytest.raises(AssertionError): 23 | XMLDatasetSubClass(**dataconfig) 24 | -------------------------------------------------------------------------------- /tests/test_data/test_pipelines/test_formatting.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import os.path as osp 3 | 4 | from mmcv.utils import build_from_cfg 5 | 6 | from mmdet.datasets.builder import PIPELINES 7 | 8 | 9 | def test_default_format_bundle(): 10 | results = dict( 11 | img_prefix=osp.join(osp.dirname(__file__), '../../data'), 12 | img_info=dict(filename='color.jpg')) 13 | load = dict(type='LoadImageFromFile') 14 | load = build_from_cfg(load, PIPELINES) 15 | bundle = dict(type='DefaultFormatBundle') 16 | bundle = build_from_cfg(bundle, PIPELINES) 17 | results = load(results) 18 | assert 'pad_shape' not in results 19 | assert 'scale_factor' not in results 20 | assert 'img_norm_cfg' not in results 21 | results = bundle(results) 22 | assert 'pad_shape' in results 23 | assert 'scale_factor' in results 24 | assert 'img_norm_cfg' in results 25 | -------------------------------------------------------------------------------- /tests/test_data/test_pipelines/test_transform/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .utils import check_result_same, construct_toy_data, create_random_bboxes 3 | 4 | __all__ = ['create_random_bboxes', 'construct_toy_data', 'check_result_same'] 5 | -------------------------------------------------------------------------------- /tests/test_metrics/test_recall.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from mmdet.core.evaluation.recall import eval_recalls 4 | 5 | det_bboxes = np.array([ 6 | [0, 0, 10, 10], 7 | [10, 10, 20, 20], 8 | [32, 32, 38, 42], 9 | ]) 10 | gt_bboxes = np.array([[0, 0, 10, 20], [0, 10, 10, 19], [10, 10, 20, 20]]) 11 | gt_ignore = np.array([[5, 5, 10, 20], [6, 10, 10, 19]]) 12 | 13 | 14 | def test_eval_recalls(): 15 | gts = [gt_bboxes, gt_bboxes, gt_bboxes] 16 | proposals = [det_bboxes, det_bboxes, det_bboxes] 17 | 18 | recall = eval_recalls( 19 | gts, proposals, proposal_nums=2, use_legacy_coordinate=True) 20 | assert recall.shape == (1, 1) 21 | assert 0.66 < recall[0][0] < 0.667 22 | recall = eval_recalls( 23 | gts, proposals, proposal_nums=2, use_legacy_coordinate=False) 24 | assert recall.shape == (1, 1) 25 | assert 0.66 < recall[0][0] < 0.667 26 | 27 | recall = eval_recalls( 28 | gts, proposals, proposal_nums=2, use_legacy_coordinate=True) 29 | assert recall.shape == (1, 1) 30 | assert 0.66 < recall[0][0] < 0.667 31 | recall = eval_recalls( 32 | gts, 33 | proposals, 34 | iou_thrs=[0.1, 0.9], 35 | proposal_nums=2, 36 | use_legacy_coordinate=False) 37 | assert recall.shape == (1, 2) 38 | assert recall[0][1] <= recall[0][0] 39 | recall = eval_recalls( 40 | gts, 41 | proposals, 42 | iou_thrs=[0.1, 0.9], 43 | proposal_nums=2, 44 | use_legacy_coordinate=True) 45 | assert recall.shape == (1, 2) 46 | assert recall[0][1] <= recall[0][0] 47 | -------------------------------------------------------------------------------- /tests/test_models/test_backbones/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .utils import check_norm_state, is_block, is_norm 3 | 4 | __all__ = ['is_block', 'is_norm', 'check_norm_state'] 5 | -------------------------------------------------------------------------------- /tests/test_models/test_backbones/test_detectors_resnet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | 4 | from mmdet.models.backbones import DetectoRS_ResNet 5 | 6 | 7 | def test_detectorrs_resnet_backbone(): 8 | detectorrs_cfg = dict( 9 | depth=50, 10 | num_stages=4, 11 | out_indices=(0, 1, 2, 3), 12 | frozen_stages=1, 13 | norm_cfg=dict(type='BN', requires_grad=True), 14 | norm_eval=True, 15 | style='pytorch', 16 | conv_cfg=dict(type='ConvAWS'), 17 | sac=dict(type='SAC', use_deform=True), 18 | stage_with_sac=(False, True, True, True), 19 | output_img=True) 20 | """Test init_weights config""" 21 | with pytest.raises(AssertionError): 22 | # pretrained and init_cfg cannot be specified at the same time 23 | DetectoRS_ResNet( 24 | **detectorrs_cfg, pretrained='Pretrained', init_cfg='Pretrained') 25 | 26 | with pytest.raises(AssertionError): 27 | # init_cfg must be a dict 28 | DetectoRS_ResNet( 29 | **detectorrs_cfg, pretrained=None, init_cfg=['Pretrained']) 30 | 31 | with pytest.raises(KeyError): 32 | # init_cfg must contain the key `type` 33 | DetectoRS_ResNet( 34 | **detectorrs_cfg, 35 | pretrained=None, 36 | init_cfg=dict(checkpoint='Pretrained')) 37 | 38 | with pytest.raises(AssertionError): 39 | # init_cfg only support initialize pretrained model way 40 | DetectoRS_ResNet( 41 | **detectorrs_cfg, pretrained=None, init_cfg=dict(type='Trained')) 42 | 43 | with pytest.raises(TypeError): 44 | # pretrained mast be a str or None 45 | model = DetectoRS_ResNet( 46 | **detectorrs_cfg, pretrained=['Pretrained'], init_cfg=None) 47 | model.init_weights() 48 | -------------------------------------------------------------------------------- /tests/test_models/test_backbones/test_efficientnet.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import torch 3 | 4 | from mmdet.models.backbones import EfficientNet 5 | 6 | 7 | def test_efficientnet_backbone(): 8 | """Test EfficientNet backbone.""" 9 | with pytest.raises(AssertionError): 10 | # EfficientNet arch should be a key in EfficientNet.arch_settings 11 | EfficientNet(arch='c3') 12 | 13 | model = EfficientNet(arch='b0', out_indices=(0, 1, 2, 3, 4, 5, 6)) 14 | model.train() 15 | 16 | imgs = torch.randn(2, 3, 32, 32) 17 | feat = model(imgs) 18 | assert len(feat) == 7 19 | assert feat[0].shape == torch.Size([2, 32, 16, 16]) 20 | assert feat[1].shape == torch.Size([2, 16, 16, 16]) 21 | assert feat[2].shape == torch.Size([2, 24, 8, 8]) 22 | assert feat[3].shape == torch.Size([2, 40, 4, 4]) 23 | assert feat[4].shape == torch.Size([2, 112, 2, 2]) 24 | assert feat[5].shape == torch.Size([2, 320, 1, 1]) 25 | assert feat[6].shape == torch.Size([2, 1280, 1, 1]) 26 | -------------------------------------------------------------------------------- /tests/test_models/test_backbones/test_hourglass.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | import torch 4 | 5 | from mmdet.models.backbones.hourglass import HourglassNet 6 | 7 | 8 | def test_hourglass_backbone(): 9 | with pytest.raises(AssertionError): 10 | # HourglassNet's num_stacks should larger than 0 11 | HourglassNet(num_stacks=0) 12 | 13 | with pytest.raises(AssertionError): 14 | # len(stage_channels) should equal len(stage_blocks) 15 | HourglassNet( 16 | stage_channels=[256, 256, 384, 384, 384], 17 | stage_blocks=[2, 2, 2, 2, 2, 4]) 18 | 19 | with pytest.raises(AssertionError): 20 | # len(stage_channels) should lagrer than downsample_times 21 | HourglassNet( 22 | downsample_times=5, 23 | stage_channels=[256, 256, 384, 384, 384], 24 | stage_blocks=[2, 2, 2, 2, 2]) 25 | 26 | # Test HourglassNet-52 27 | model = HourglassNet( 28 | num_stacks=1, 29 | stage_channels=(64, 64, 96, 96, 96, 128), 30 | feat_channel=64) 31 | model.train() 32 | 33 | imgs = torch.randn(1, 3, 256, 256) 34 | feat = model(imgs) 35 | assert len(feat) == 1 36 | assert feat[0].shape == torch.Size([1, 64, 64, 64]) 37 | 38 | # Test HourglassNet-104 39 | model = HourglassNet( 40 | num_stacks=2, 41 | stage_channels=(64, 64, 96, 96, 96, 128), 42 | feat_channel=64) 43 | model.train() 44 | 45 | imgs = torch.randn(1, 3, 256, 256) 46 | feat = model(imgs) 47 | assert len(feat) == 2 48 | assert feat[0].shape == torch.Size([1, 64, 64, 64]) 49 | assert feat[1].shape == torch.Size([1, 64, 64, 64]) 50 | -------------------------------------------------------------------------------- /tests/test_models/test_backbones/test_resnest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | import torch 4 | 5 | from mmdet.models.backbones import ResNeSt 6 | from mmdet.models.backbones.resnest import Bottleneck as BottleneckS 7 | 8 | 9 | def test_resnest_bottleneck(): 10 | with pytest.raises(AssertionError): 11 | # Style must be in ['pytorch', 'caffe'] 12 | BottleneckS(64, 64, radix=2, reduction_factor=4, style='tensorflow') 13 | 14 | # Test ResNeSt Bottleneck structure 15 | block = BottleneckS( 16 | 2, 4, radix=2, reduction_factor=4, stride=2, style='pytorch') 17 | assert block.avd_layer.stride == 2 18 | assert block.conv2.channels == 4 19 | 20 | # Test ResNeSt Bottleneck forward 21 | block = BottleneckS(16, 4, radix=2, reduction_factor=4) 22 | x = torch.randn(2, 16, 56, 56) 23 | x_out = block(x) 24 | assert x_out.shape == torch.Size([2, 16, 56, 56]) 25 | 26 | 27 | def test_resnest_backbone(): 28 | with pytest.raises(KeyError): 29 | # ResNeSt depth should be in [50, 101, 152, 200] 30 | ResNeSt(depth=18) 31 | 32 | # Test ResNeSt with radix 2, reduction_factor 4 33 | model = ResNeSt( 34 | depth=50, 35 | base_channels=4, 36 | radix=2, 37 | reduction_factor=4, 38 | out_indices=(0, 1, 2, 3)) 39 | model.train() 40 | 41 | imgs = torch.randn(2, 3, 32, 32) 42 | feat = model(imgs) 43 | assert len(feat) == 4 44 | assert feat[0].shape == torch.Size([2, 16, 8, 8]) 45 | assert feat[1].shape == torch.Size([2, 32, 4, 4]) 46 | assert feat[2].shape == torch.Size([2, 64, 2, 2]) 47 | assert feat[3].shape == torch.Size([2, 128, 1, 1]) 48 | -------------------------------------------------------------------------------- /tests/test_models/test_backbones/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from torch.nn.modules import GroupNorm 3 | from torch.nn.modules.batchnorm import _BatchNorm 4 | 5 | from mmdet.models.backbones.res2net import Bottle2neck 6 | from mmdet.models.backbones.resnet import BasicBlock, Bottleneck 7 | from mmdet.models.backbones.resnext import Bottleneck as BottleneckX 8 | from mmdet.models.utils import SimplifiedBasicBlock 9 | 10 | 11 | def is_block(modules): 12 | """Check if is ResNet building block.""" 13 | if isinstance(modules, (BasicBlock, Bottleneck, BottleneckX, Bottle2neck, 14 | SimplifiedBasicBlock)): 15 | return True 16 | return False 17 | 18 | 19 | def is_norm(modules): 20 | """Check if is one of the norms.""" 21 | if isinstance(modules, (GroupNorm, _BatchNorm)): 22 | return True 23 | return False 24 | 25 | 26 | def check_norm_state(modules, train_state): 27 | """Check if norm layer is in correct train state.""" 28 | for mod in modules: 29 | if isinstance(mod, _BatchNorm): 30 | if mod.training != train_state: 31 | return False 32 | return True 33 | -------------------------------------------------------------------------------- /tests/test_models/test_dense_heads/test_dense_heads_attr.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import warnings 3 | 4 | from terminaltables import AsciiTable 5 | 6 | from mmdet.models import dense_heads 7 | from mmdet.models.dense_heads import * # noqa: F401,F403 8 | 9 | 10 | def test_dense_heads_test_attr(): 11 | """Tests inference methods such as simple_test and aug_test.""" 12 | # make list of dense heads 13 | exceptions = ['FeatureAdaption'] # module used in head 14 | all_dense_heads = [m for m in dense_heads.__all__ if m not in exceptions] 15 | 16 | # search attributes 17 | check_attributes = [ 18 | 'simple_test', 'aug_test', 'simple_test_bboxes', 'simple_test_rpn', 19 | 'aug_test_rpn' 20 | ] 21 | table_header = ['head name'] + check_attributes 22 | table_data = [table_header] 23 | not_found = {k: [] for k in check_attributes} 24 | for target_head_name in all_dense_heads: 25 | target_head = globals()[target_head_name] 26 | target_head_attributes = dir(target_head) 27 | check_results = [target_head_name] 28 | for check_attribute in check_attributes: 29 | found = check_attribute in target_head_attributes 30 | check_results.append(found) 31 | if not found: 32 | not_found[check_attribute].append(target_head_name) 33 | table_data.append(check_results) 34 | table = AsciiTable(table_data) 35 | print() 36 | print(table.table) 37 | 38 | # NOTE: this test just checks attributes. 39 | # simple_test of RPN heads will not work now. 40 | assert len(not_found['simple_test']) == 0, \ 41 | f'simple_test not found in {not_found["simple_test"]}' 42 | if len(not_found['aug_test']) != 0: 43 | warnings.warn(f'aug_test not found in {not_found["aug_test"]}. ' 44 | 'Please implement it or raise NotImplementedError.') 45 | -------------------------------------------------------------------------------- /tests/test_models/test_roi_heads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .utils import _dummy_bbox_sampling 3 | 4 | __all__ = ['_dummy_bbox_sampling'] 5 | -------------------------------------------------------------------------------- /tests/test_models/test_roi_heads/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import torch 3 | 4 | from mmdet.core import build_assigner, build_sampler 5 | 6 | 7 | def _dummy_bbox_sampling(proposal_list, gt_bboxes, gt_labels): 8 | """Create sample results that can be passed to BBoxHead.get_targets.""" 9 | num_imgs = 1 10 | feat = torch.rand(1, 1, 3, 3) 11 | assign_config = dict( 12 | type='MaxIoUAssigner', 13 | pos_iou_thr=0.5, 14 | neg_iou_thr=0.5, 15 | min_pos_iou=0.5, 16 | ignore_iof_thr=-1) 17 | sampler_config = dict( 18 | type='RandomSampler', 19 | num=512, 20 | pos_fraction=0.25, 21 | neg_pos_ub=-1, 22 | add_gt_as_proposals=True) 23 | bbox_assigner = build_assigner(assign_config) 24 | bbox_sampler = build_sampler(sampler_config) 25 | gt_bboxes_ignore = [None for _ in range(num_imgs)] 26 | sampling_results = [] 27 | for i in range(num_imgs): 28 | assign_result = bbox_assigner.assign(proposal_list[i], gt_bboxes[i], 29 | gt_bboxes_ignore[i], gt_labels[i]) 30 | sampling_result = bbox_sampler.sample( 31 | assign_result, 32 | proposal_list[i], 33 | gt_bboxes[i], 34 | gt_labels[i], 35 | feats=feat) 36 | sampling_results.append(sampling_result) 37 | 38 | return sampling_results 39 | -------------------------------------------------------------------------------- /tests/test_models/test_seg_heads/test_maskformer_fusion_head.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import torch 3 | from mmcv import ConfigDict 4 | 5 | from mmdet.models.seg_heads.panoptic_fusion_heads import MaskFormerFusionHead 6 | 7 | 8 | def test_maskformer_fusion_head(): 9 | img_metas = [ 10 | { 11 | 'batch_input_shape': (128, 160), 12 | 'img_shape': (126, 160, 3), 13 | 'ori_shape': (63, 80, 3), 14 | 'pad_shape': (128, 160, 3) 15 | }, 16 | ] 17 | num_things_classes = 80 18 | num_stuff_classes = 53 19 | num_classes = num_things_classes + num_stuff_classes 20 | config = ConfigDict( 21 | type='MaskFormerFusionHead', 22 | num_things_classes=num_things_classes, 23 | num_stuff_classes=num_stuff_classes, 24 | loss_panoptic=None, 25 | test_cfg=dict( 26 | panoptic_on=True, 27 | semantic_on=False, 28 | instance_on=True, 29 | max_per_image=100, 30 | object_mask_thr=0.8, 31 | iou_thr=0.8, 32 | filter_low_score=False), 33 | init_cfg=None) 34 | 35 | self = MaskFormerFusionHead(**config) 36 | 37 | # test forward_train 38 | assert self.forward_train() == dict() 39 | 40 | mask_cls_results = torch.rand((1, 100, num_classes + 1)) 41 | mask_pred_results = torch.rand((1, 100, 128, 160)) 42 | 43 | # test panoptic_postprocess and instance_postprocess 44 | results = self.simple_test(mask_cls_results, mask_pred_results, img_metas) 45 | assert 'ins_results' in results[0] and 'pan_results' in results[0] 46 | 47 | # test semantic_postprocess 48 | config.test_cfg.semantic_on = True 49 | with pytest.raises(AssertionError): 50 | self.simple_test(mask_cls_results, mask_pred_results, img_metas) 51 | 52 | with pytest.raises(NotImplementedError): 53 | self.semantic_postprocess(mask_cls_results, mask_pred_results) 54 | -------------------------------------------------------------------------------- /tests/test_models/test_utils/test_conv_upsample.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | import torch 4 | 5 | from mmdet.models.utils import ConvUpsample 6 | 7 | 8 | @pytest.mark.parametrize('num_layers', [0, 1, 2]) 9 | def test_conv_upsample(num_layers): 10 | num_upsample = num_layers if num_layers > 0 else 0 11 | num_layers = num_layers if num_layers > 0 else 1 12 | layer = ConvUpsample( 13 | 10, 14 | 5, 15 | num_layers=num_layers, 16 | num_upsample=num_upsample, 17 | conv_cfg=None, 18 | norm_cfg=None) 19 | 20 | size = 5 21 | x = torch.randn((1, 10, size, size)) 22 | size = size * pow(2, num_upsample) 23 | x = layer(x) 24 | assert x.shape[-2:] == (size, size) 25 | -------------------------------------------------------------------------------- /tests/test_models/test_utils/test_model_misc.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import numpy as np 3 | import torch 4 | from torch.autograd import gradcheck 5 | 6 | from mmdet.models.utils import interpolate_as, sigmoid_geometric_mean 7 | 8 | 9 | def test_interpolate_as(): 10 | source = torch.rand((1, 5, 4, 4)) 11 | target = torch.rand((1, 1, 16, 16)) 12 | 13 | # Test 4D source and target 14 | result = interpolate_as(source, target) 15 | assert result.shape == torch.Size((1, 5, 16, 16)) 16 | 17 | # Test 3D target 18 | result = interpolate_as(source, target.squeeze(0)) 19 | assert result.shape == torch.Size((1, 5, 16, 16)) 20 | 21 | # Test 3D source 22 | result = interpolate_as(source.squeeze(0), target) 23 | assert result.shape == torch.Size((5, 16, 16)) 24 | 25 | # Test type(target) == np.ndarray 26 | target = np.random.rand(16, 16) 27 | result = interpolate_as(source.squeeze(0), target) 28 | assert result.shape == torch.Size((5, 16, 16)) 29 | 30 | 31 | def test_sigmoid_geometric_mean(): 32 | x = torch.randn(20, 20, dtype=torch.double, requires_grad=True) 33 | y = torch.randn(20, 20, dtype=torch.double, requires_grad=True) 34 | inputs = (x, y) 35 | test = gradcheck(sigmoid_geometric_mean, inputs, eps=1e-6, atol=1e-4) 36 | assert test 37 | -------------------------------------------------------------------------------- /tests/test_models/test_utils/test_position_encoding.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | import torch 4 | 5 | from mmdet.models.utils import (LearnedPositionalEncoding, 6 | SinePositionalEncoding) 7 | 8 | 9 | def test_sine_positional_encoding(num_feats=16, batch_size=2): 10 | # test invalid type of scale 11 | with pytest.raises(AssertionError): 12 | module = SinePositionalEncoding( 13 | num_feats, scale=(3., ), normalize=True) 14 | 15 | module = SinePositionalEncoding(num_feats) 16 | h, w = 10, 6 17 | mask = (torch.rand(batch_size, h, w) > 0.5).to(torch.int) 18 | assert not module.normalize 19 | out = module(mask) 20 | assert out.shape == (batch_size, num_feats * 2, h, w) 21 | 22 | # set normalize 23 | module = SinePositionalEncoding(num_feats, normalize=True) 24 | assert module.normalize 25 | out = module(mask) 26 | assert out.shape == (batch_size, num_feats * 2, h, w) 27 | 28 | 29 | def test_learned_positional_encoding(num_feats=16, 30 | row_num_embed=10, 31 | col_num_embed=10, 32 | batch_size=2): 33 | module = LearnedPositionalEncoding(num_feats, row_num_embed, col_num_embed) 34 | assert module.row_embed.weight.shape == (row_num_embed, num_feats) 35 | assert module.col_embed.weight.shape == (col_num_embed, num_feats) 36 | h, w = 10, 6 37 | mask = torch.rand(batch_size, h, w) > 0.5 38 | out = module(mask) 39 | assert out.shape == (batch_size, num_feats * 2, h, w) 40 | -------------------------------------------------------------------------------- /tests/test_models/test_utils/test_se_layer.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | import torch 4 | import torch.nn.functional as F 5 | from mmcv.cnn import constant_init 6 | 7 | from mmdet.models.utils import DyReLU, SELayer 8 | 9 | 10 | def test_se_layer(): 11 | with pytest.raises(AssertionError): 12 | # act_cfg sequence length must equal to 2 13 | SELayer(channels=32, act_cfg=(dict(type='ReLU'), )) 14 | 15 | with pytest.raises(AssertionError): 16 | # act_cfg sequence must be a tuple of dict 17 | SELayer(channels=32, act_cfg=[dict(type='ReLU'), dict(type='ReLU')]) 18 | 19 | # Test SELayer forward 20 | layer = SELayer(channels=32) 21 | layer.init_weights() 22 | layer.train() 23 | 24 | x = torch.randn((1, 32, 10, 10)) 25 | x_out = layer(x) 26 | assert x_out.shape == torch.Size((1, 32, 10, 10)) 27 | 28 | 29 | def test_dyrelu(): 30 | with pytest.raises(AssertionError): 31 | # act_cfg sequence length must equal to 2 32 | DyReLU(channels=32, act_cfg=(dict(type='ReLU'), )) 33 | 34 | with pytest.raises(AssertionError): 35 | # act_cfg sequence must be a tuple of dict 36 | DyReLU(channels=32, act_cfg=[dict(type='ReLU'), dict(type='ReLU')]) 37 | 38 | # Test DyReLU forward 39 | layer = DyReLU(channels=32) 40 | layer.init_weights() 41 | layer.train() 42 | x = torch.randn((1, 32, 10, 10)) 43 | x_out = layer(x) 44 | assert x_out.shape == torch.Size((1, 32, 10, 10)) 45 | 46 | # DyReLU should act as standard (static) ReLU 47 | # when eliminating the effect of SE-like module 48 | layer = DyReLU(channels=32) 49 | constant_init(layer.conv2.conv, 0) 50 | layer.train() 51 | x = torch.randn((1, 32, 10, 10)) 52 | x_out = layer(x) 53 | relu_out = F.relu(x) 54 | assert torch.equal(x_out, relu_out) 55 | -------------------------------------------------------------------------------- /tests/test_onnx/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from .utils import ort_validate 3 | 4 | __all__ = ['ort_validate'] 5 | -------------------------------------------------------------------------------- /tests/test_onnx/data/fsaf_head_get_bboxes.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/test_onnx/data/fsaf_head_get_bboxes.pkl -------------------------------------------------------------------------------- /tests/test_onnx/data/retina_head_get_bboxes.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/test_onnx/data/retina_head_get_bboxes.pkl -------------------------------------------------------------------------------- /tests/test_onnx/data/ssd_head_get_bboxes.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/test_onnx/data/ssd_head_get_bboxes.pkl -------------------------------------------------------------------------------- /tests/test_onnx/data/yolov3_head_get_bboxes.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/test_onnx/data/yolov3_head_get_bboxes.pkl -------------------------------------------------------------------------------- /tests/test_onnx/data/yolov3_neck.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tests/test_onnx/data/yolov3_neck.pkl -------------------------------------------------------------------------------- /tests/test_runtime/test_apis.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | 4 | import pytest 5 | 6 | from mmdet.apis import init_detector 7 | 8 | 9 | def test_init_detector(): 10 | project_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) 11 | project_dir = os.path.join(project_dir, '..') 12 | 13 | config_file = os.path.join( 14 | project_dir, 'configs/mask_rcnn/mask_rcnn_r50_fpn_1x_coco.py') 15 | 16 | # test init_detector with config_file: str and cfg_options 17 | cfg_options = dict( 18 | model=dict( 19 | backbone=dict( 20 | depth=18, 21 | init_cfg=dict( 22 | type='Pretrained', checkpoint='torchvision://resnet18')))) 23 | model = init_detector(config_file, device='cpu', cfg_options=cfg_options) 24 | 25 | # test init_detector with :obj:`Path` 26 | config_path_object = Path(config_file) 27 | model = init_detector(config_path_object, device='cpu') 28 | 29 | # test init_detector with undesirable type 30 | with pytest.raises(TypeError): 31 | config_list = [config_file] 32 | model = init_detector(config_list) # noqa: F841 33 | -------------------------------------------------------------------------------- /tests/test_utils/test_logger.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import pytest 3 | 4 | from mmdet.utils import get_caller_name, log_img_scale 5 | 6 | 7 | def callee_func(): 8 | caller_name = get_caller_name() 9 | return caller_name 10 | 11 | 12 | class CallerClassForTest: 13 | 14 | def __init__(self): 15 | self.caller_name = callee_func() 16 | 17 | 18 | def test_get_caller_name(): 19 | # test the case that caller is a function 20 | caller_name = callee_func() 21 | assert caller_name == 'test_get_caller_name' 22 | 23 | # test the case that caller is a method in a class 24 | caller_class = CallerClassForTest() 25 | assert caller_class.caller_name == 'CallerClassForTest.__init__' 26 | 27 | 28 | def test_log_img_scale(): 29 | img_scale = (800, 1333) 30 | done_logging = log_img_scale(img_scale) 31 | assert done_logging 32 | 33 | img_scale = (1333, 800) 34 | done_logging = log_img_scale(img_scale, shape_order='wh') 35 | assert done_logging 36 | 37 | with pytest.raises(ValueError): 38 | img_scale = (1333, 800) 39 | done_logging = log_img_scale(img_scale, shape_order='xywh') 40 | 41 | img_scale = (640, 640) 42 | done_logging = log_img_scale(img_scale, skip_square=False) 43 | assert done_logging 44 | 45 | img_scale = (640, 640) 46 | done_logging = log_img_scale(img_scale, skip_square=True) 47 | assert not done_logging 48 | -------------------------------------------------------------------------------- /tests/test_utils/test_version.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | from mmdet import digit_version 3 | 4 | 5 | def test_version_check(): 6 | assert digit_version('1.0.5') > digit_version('1.0.5rc0') 7 | assert digit_version('1.0.5') > digit_version('1.0.4rc0') 8 | assert digit_version('1.0.5') > digit_version('1.0rc0') 9 | assert digit_version('1.0.0') > digit_version('0.6.2') 10 | assert digit_version('1.0.0') > digit_version('0.2.16') 11 | assert digit_version('1.0.5rc0') > digit_version('1.0.0rc0') 12 | assert digit_version('1.0.0rc1') > digit_version('1.0.0rc0') 13 | assert digit_version('1.0.0rc2') > digit_version('1.0.0rc0') 14 | assert digit_version('1.0.0rc2') > digit_version('1.0.0rc1') 15 | assert digit_version('1.0.1rc1') > digit_version('1.0.0rc1') 16 | assert digit_version('1.0.0') > digit_version('1.0.0rc1') 17 | -------------------------------------------------------------------------------- /tools/dist_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CONFIG=$1 4 | CHECKPOINT=$2 5 | GPUS=$3 6 | NNODES=${NNODES:-1} 7 | NODE_RANK=${NODE_RANK:-0} 8 | PORT=${PORT:-29500} 9 | MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"} 10 | 11 | PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ 12 | python -m torch.distributed.launch \ 13 | --nnodes=$NNODES \ 14 | --node_rank=$NODE_RANK \ 15 | --master_addr=$MASTER_ADDR \ 16 | --nproc_per_node=$GPUS \ 17 | --master_port=$PORT \ 18 | $(dirname "$0")/test.py \ 19 | $CONFIG \ 20 | $CHECKPOINT \ 21 | --launcher pytorch \ 22 | ${@:4} 23 | -------------------------------------------------------------------------------- /tools/dist_train.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CONFIG=$1 4 | GPUS=$2 5 | NNODES=${NNODES:-1} 6 | NODE_RANK=${NODE_RANK:-0} 7 | PORT=${PORT:-29500} 8 | MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"} 9 | 10 | PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ 11 | python -m torch.distributed.launch \ 12 | --nnodes=$NNODES \ 13 | --node_rank=$NODE_RANK \ 14 | --master_addr=$MASTER_ADDR \ 15 | --nproc_per_node=$GPUS \ 16 | --master_port=$PORT \ 17 | $(dirname "$0")/train.py \ 18 | $CONFIG \ 19 | --seed 0 \ 20 | --launcher pytorch ${@:3} 21 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/eval.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | INPUT_PREDICTIONS=$1 4 | OUTPUT_FILE=$2 5 | 6 | python tools/eval_tools/oid/oid_eval.py \ 7 | --input_annotations_boxes=./data/oid/annotations/challenge-2019-validation-detection-bbox_expanded.csv \ 8 | --input_annotations_labels=./data/oid/annotations/challenge-2019-validation-detection-human-imagelabels_expanded.csv \ 9 | --input_class_labelmap=tools/eval_tools/oid/oid_object_detection_challenge_500_label_map.pbtxt \ 10 | --input_predictions=$INPUT_PREDICTIONS \ 11 | --output_metrics=$OUTPUT_FILE -------------------------------------------------------------------------------- /tools/eval_tools/oid/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 | Args: 28 | fid: File identifier of an opened file. 29 | metrics: A dictionary with metrics to be written. 30 | """ 31 | metrics_writer = csv.writer(fid, delimiter=',') 32 | for metric_name, metric_value in metrics.items(): 33 | metrics_writer.writerow([metric_name, str(metric_value)]) -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linfeng93/Large-UniDet/a1f54bfa2ece95b4178c882787d5c7aeaf1145ca/tools/eval_tools/oid/protos/__init__.py -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/anchor_generator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | import "object_detection/protos/flexible_grid_anchor_generator.proto"; 6 | import "object_detection/protos/grid_anchor_generator.proto"; 7 | import "object_detection/protos/multiscale_anchor_generator.proto"; 8 | import "object_detection/protos/ssd_anchor_generator.proto"; 9 | 10 | // Configuration proto for the anchor generator to use in the object detection 11 | // pipeline. See core/anchor_generator.py for details. 12 | message AnchorGenerator { 13 | oneof anchor_generator_oneof { 14 | GridAnchorGenerator grid_anchor_generator = 1; 15 | SsdAnchorGenerator ssd_anchor_generator = 2; 16 | MultiscaleAnchorGenerator multiscale_anchor_generator = 3; 17 | FlexibleGridAnchorGenerator flexible_grid_anchor_generator = 4; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/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 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/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 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/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 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/faster_rcnn_box_coder.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for FasterRCNNBoxCoder. See 6 | // box_coders/faster_rcnn_box_coder.py for details. 7 | message FasterRcnnBoxCoder { 8 | // Scale factor for anchor encoded box center. 9 | optional float y_scale = 1 [default = 10.0]; 10 | optional float x_scale = 2 [default = 10.0]; 11 | 12 | // Scale factor for anchor encoded box height. 13 | optional float height_scale = 3 [default = 5.0]; 14 | 15 | // Scale factor for anchor encoded box width. 16 | optional float width_scale = 4 [default = 5.0]; 17 | } 18 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/flexible_grid_anchor_generator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | message FlexibleGridAnchorGenerator { 6 | repeated AnchorGrid anchor_grid = 1; 7 | 8 | // Whether to produce anchors in normalized coordinates. 9 | optional bool normalize_coordinates = 2 [default = true]; 10 | } 11 | 12 | message AnchorGrid { 13 | // The base sizes in pixels for each anchor in this anchor layer. 14 | repeated float base_sizes = 1; 15 | 16 | // The aspect ratios for each anchor in this anchor layer. 17 | repeated float aspect_ratios = 2; 18 | 19 | // The anchor height stride in pixels. 20 | optional uint32 height_stride = 3; 21 | 22 | // The anchor width stride in pixels. 23 | optional uint32 width_stride = 4; 24 | 25 | // The anchor height offset in pixels. 26 | optional uint32 height_offset = 5 [default = 0]; 27 | 28 | // The anchor width offset in pixels. 29 | optional uint32 width_offset = 6 [default = 0]; 30 | } 31 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/graph_rewriter.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Message to configure graph rewriter for the tf graph. 6 | message GraphRewriter { 7 | optional Quantization quantization = 1; 8 | extensions 1000 to max; 9 | } 10 | 11 | // Message for quantization options. See 12 | // tensorflow/contrib/quantize/python/quantize.py for details. 13 | message Quantization { 14 | // Number of steps to delay before quantization takes effect during training. 15 | optional int32 delay = 1 [default = 500000]; 16 | 17 | // Number of bits to use for quantizing weights. 18 | // Only 8 bit is supported for now. 19 | optional int32 weight_bits = 2 [default = 8]; 20 | 21 | // Number of bits to use for quantizing activations. 22 | // Only 8 bit is supported for now. 23 | optional int32 activation_bits = 3 [default = 8]; 24 | 25 | // Whether to use symmetric weight quantization. 26 | optional bool symmetric = 4 [default = false]; 27 | } 28 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/grid_anchor_generator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for GridAnchorGenerator. See 6 | // anchor_generators/grid_anchor_generator.py for details. 7 | message GridAnchorGenerator { 8 | // Anchor height in pixels. 9 | optional int32 height = 1 [default = 256]; 10 | 11 | // Anchor width in pixels. 12 | optional int32 width = 2 [default = 256]; 13 | 14 | // Anchor stride in height dimension in pixels. 15 | optional int32 height_stride = 3 [default = 16]; 16 | 17 | // Anchor stride in width dimension in pixels. 18 | optional int32 width_stride = 4 [default = 16]; 19 | 20 | // Anchor height offset in pixels. 21 | optional int32 height_offset = 5 [default = 0]; 22 | 23 | // Anchor width offset in pixels. 24 | optional int32 width_offset = 6 [default = 0]; 25 | 26 | // At any given location, len(scales) * len(aspect_ratios) anchors are 27 | // generated with all possible combinations of scales and aspect ratios. 28 | 29 | // List of scales for the anchors. 30 | repeated float scales = 7; 31 | 32 | // List of aspect ratios for the anchors. 33 | repeated float aspect_ratios = 8; 34 | } 35 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/keypoint_box_coder.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for KeypointBoxCoder. See 6 | // box_coders/keypoint_box_coder.py for details. 7 | message KeypointBoxCoder { 8 | optional int32 num_keypoints = 1; 9 | 10 | // Scale factor for anchor encoded box center and keypoints. 11 | optional float y_scale = 2 [default = 10.0]; 12 | optional float x_scale = 3 [default = 10.0]; 13 | 14 | // Scale factor for anchor encoded box height. 15 | optional float height_scale = 4 [default = 5.0]; 16 | 17 | // Scale factor for anchor encoded box width. 18 | optional float width_scale = 5 [default = 5.0]; 19 | } 20 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/matcher.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | import "object_detection/protos/argmax_matcher.proto"; 6 | import "object_detection/protos/bipartite_matcher.proto"; 7 | 8 | // Configuration proto for the matcher to be used in the object detection 9 | // pipeline. See core/matcher.py for details. 10 | message Matcher { 11 | oneof matcher_oneof { 12 | ArgMaxMatcher argmax_matcher = 1; 13 | BipartiteMatcher bipartite_matcher = 2; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/mean_stddev_box_coder.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for MeanStddevBoxCoder. See 6 | // box_coders/mean_stddev_box_coder.py for details. 7 | message MeanStddevBoxCoder { 8 | // The standard deviation used to encode and decode boxes. 9 | optional float stddev = 1 [default=0.01]; 10 | } 11 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/model.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | import "object_detection/protos/center_net.proto"; 6 | import "object_detection/protos/faster_rcnn.proto"; 7 | import "object_detection/protos/ssd.proto"; 8 | 9 | // Top level configuration for DetectionModels. 10 | message DetectionModel { 11 | oneof model { 12 | FasterRcnn faster_rcnn = 1; 13 | Ssd ssd = 2; 14 | 15 | // This can be used to define experimental models. To define your own 16 | // experimental meta architecture, populate a key in the 17 | // model_builder.EXPERIMENTAL_META_ARCH_BUILDER_MAP dict and set its 18 | // value to a function that builds your model. 19 | ExperimentalModel experimental_model = 3; 20 | 21 | CenterNet center_net = 4; 22 | } 23 | } 24 | 25 | message ExperimentalModel { 26 | optional string name = 1; 27 | } 28 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/multiscale_anchor_generator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for RetinaNet anchor generator described in 6 | // https://arxiv.org/abs/1708.02002. See 7 | // anchor_generators/multiscale_grid_anchor_generator.py for details. 8 | message MultiscaleAnchorGenerator { 9 | // minimum level in feature pyramid 10 | optional int32 min_level = 1 [default = 3]; 11 | 12 | // maximum level in feature pyramid 13 | optional int32 max_level = 2 [default = 7]; 14 | 15 | // Scale of anchor to feature stride 16 | optional float anchor_scale = 3 [default = 4.0]; 17 | 18 | // Aspect ratios for anchors at each grid point. 19 | repeated float aspect_ratios = 4; 20 | 21 | // Number of intermediate scale each scale octave 22 | optional int32 scales_per_octave = 5 [default = 2]; 23 | 24 | // Whether to produce anchors in normalized coordinates. 25 | optional bool normalize_coordinates = 6 [default = true]; 26 | } 27 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/pipeline.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | import "object_detection/protos/eval.proto"; 6 | import "object_detection/protos/graph_rewriter.proto"; 7 | import "object_detection/protos/input_reader.proto"; 8 | import "object_detection/protos/model.proto"; 9 | import "object_detection/protos/train.proto"; 10 | 11 | // Convenience message for configuring a training and eval pipeline. Allows all 12 | // of the pipeline parameters to be configured from one file. 13 | // Next id: 8 14 | message TrainEvalPipelineConfig { 15 | optional DetectionModel model = 1; 16 | optional TrainConfig train_config = 2; 17 | optional InputReader train_input_reader = 3; 18 | optional EvalConfig eval_config = 4; 19 | repeated InputReader eval_input_reader = 5; 20 | optional GraphRewriter graph_rewriter = 6; 21 | extensions 1000 to max; 22 | } 23 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/region_similarity_calculator.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for region similarity calculators. See 6 | // core/region_similarity_calculator.py for details. 7 | message RegionSimilarityCalculator { 8 | oneof region_similarity { 9 | NegSqDistSimilarity neg_sq_dist_similarity = 1; 10 | IouSimilarity iou_similarity = 2; 11 | IoaSimilarity ioa_similarity = 3; 12 | ThresholdedIouSimilarity thresholded_iou_similarity = 4; 13 | } 14 | } 15 | 16 | // Configuration for negative squared distance similarity calculator. 17 | message NegSqDistSimilarity { 18 | } 19 | 20 | // Configuration for intersection-over-union (IOU) similarity calculator. 21 | message IouSimilarity { 22 | } 23 | 24 | // Configuration for intersection-over-area (IOA) similarity calculator. 25 | message IoaSimilarity { 26 | } 27 | 28 | // Configuration for thresholded-intersection-over-union similarity calculator. 29 | message ThresholdedIouSimilarity { 30 | 31 | // IOU threshold used for filtering scores. 32 | optional float iou_threshold = 1 [default = 0.5]; 33 | } 34 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/square_box_coder.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | // Configuration proto for SquareBoxCoder. See 6 | // box_coders/square_box_coder.py for details. 7 | message SquareBoxCoder { 8 | // Scale factor for anchor encoded box center. 9 | optional float y_scale = 1 [default = 10.0]; 10 | optional float x_scale = 2 [default = 10.0]; 11 | 12 | // Scale factor for anchor encoded box length. 13 | optional float length_scale = 3 [default = 5.0]; 14 | } 15 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/string_int_label_map.proto: -------------------------------------------------------------------------------- 1 | // Message to store the mapping from class label strings to class id. Datasets 2 | // use string labels to represent classes while the object detection framework 3 | // works with class ids. This message maps them so they can be converted back 4 | // and forth as needed. 5 | syntax = "proto2"; 6 | 7 | package object_detection.protos; 8 | 9 | // LVIS frequency: 10 | enum LVISFrequency { 11 | UNSPECIFIED = 0; 12 | FREQUENT = 1; 13 | COMMON = 2; 14 | RARE = 3; 15 | } 16 | 17 | message StringIntLabelMapItem { 18 | // String name. The most common practice is to set this to a MID or synsets 19 | // id. 20 | optional string name = 1; 21 | 22 | // Integer id that maps to the string name above. Label ids should start from 23 | // 1. 24 | optional int32 id = 2; 25 | 26 | // Human readable string label. 27 | optional string display_name = 3; 28 | 29 | // Name of class specific keypoints for each class object and their respective 30 | // keypoint IDs. 31 | message KeypointMap { 32 | // Id for the keypoint. Id must be unique within a given class, however, it 33 | // could be shared across classes. For example "nose" keypoint can occur 34 | // in both "face" and "person" classes. Hence they can be mapped to the same 35 | // id. 36 | // 37 | // Note: It is advised to assign ids in range [1, num_unique_keypoints] to 38 | // encode keypoint targets efficiently. 39 | optional int32 id = 1; 40 | // Label for the keypoint. 41 | optional string label = 2; 42 | } 43 | repeated KeypointMap keypoints = 4; 44 | 45 | // Label ids for the elements that are connected in the hierarchy with the 46 | // current element. Value should correspond to another label id element. 47 | repeated int32 ancestor_ids = 5; 48 | repeated int32 descendant_ids = 6; 49 | 50 | // LVIS specific label map fields 51 | optional LVISFrequency frequency = 7; 52 | optional int32 instance_count = 8; 53 | }; 54 | 55 | message StringIntLabelMap { 56 | repeated StringIntLabelMapItem item = 1; 57 | }; 58 | -------------------------------------------------------------------------------- /tools/eval_tools/oid/protos/target_assigner.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package object_detection.protos; 4 | 5 | import "object_detection/protos/box_coder.proto"; 6 | import "object_detection/protos/matcher.proto"; 7 | import "object_detection/protos/region_similarity_calculator.proto"; 8 | 9 | // Message to configure Target Assigner for object detectors. 10 | message TargetAssigner { 11 | optional Matcher matcher = 1; 12 | optional RegionSimilarityCalculator similarity_calculator = 2; 13 | optional BoxCoder box_coder = 3; 14 | } 15 | -------------------------------------------------------------------------------- /tools/misc/gen_coco_panoptic_test_info.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os.path as osp 3 | 4 | import mmcv 5 | 6 | 7 | def parse_args(): 8 | parser = argparse.ArgumentParser( 9 | description='Generate COCO test image information ' 10 | 'for COCO panoptic segmentation.') 11 | parser.add_argument('data_root', help='Path to COCO annotation directory.') 12 | args = parser.parse_args() 13 | 14 | return args 15 | 16 | 17 | def main(): 18 | args = parse_args() 19 | data_root = args.data_root 20 | val_info = mmcv.load(osp.join(data_root, 'panoptic_val2017.json')) 21 | test_old_info = mmcv.load( 22 | osp.join(data_root, 'image_info_test-dev2017.json')) 23 | 24 | # replace categories from image_info_test-dev2017.json 25 | # with categories from panoptic_val2017.json which 26 | # has attribute `isthing`. 27 | test_info = test_old_info 28 | test_info.update({'categories': val_info['categories']}) 29 | mmcv.dump(test_info, 30 | osp.join(data_root, 'panoptic_image_info_test-dev2017.json')) 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /tools/model_converters/publish_model.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import argparse 3 | import subprocess 4 | 5 | import torch 6 | 7 | 8 | def parse_args(): 9 | parser = argparse.ArgumentParser( 10 | description='Process a checkpoint to be published') 11 | parser.add_argument('in_file', help='input checkpoint filename') 12 | parser.add_argument('out_file', help='output checkpoint filename') 13 | args = parser.parse_args() 14 | return args 15 | 16 | 17 | def process_checkpoint(in_file, out_file): 18 | checkpoint = torch.load(in_file, map_location='cpu') 19 | # remove optimizer for smaller file size 20 | if 'optimizer' in checkpoint: 21 | del checkpoint['optimizer'] 22 | # if it is necessary to remove some sensitive data in checkpoint['meta'], 23 | # add the code here. 24 | if torch.__version__ >= '1.6': 25 | torch.save(checkpoint, out_file, _use_new_zipfile_serialization=False) 26 | else: 27 | torch.save(checkpoint, out_file) 28 | sha = subprocess.check_output(['sha256sum', out_file]).decode() 29 | if out_file.endswith('.pth'): 30 | out_file_name = out_file[:-4] 31 | else: 32 | out_file_name = out_file 33 | final_file = out_file_name + f'-{sha[:8]}.pth' 34 | subprocess.Popen(['mv', out_file, final_file]) 35 | 36 | 37 | def main(): 38 | args = parse_args() 39 | process_checkpoint(args.in_file, args.out_file) 40 | 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /tools/model_converters/selfsup2mmdet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import argparse 3 | from collections import OrderedDict 4 | 5 | import torch 6 | 7 | 8 | def moco_convert(src, dst): 9 | """Convert keys in pycls pretrained moco models to mmdet style.""" 10 | # load caffe model 11 | moco_model = torch.load(src) 12 | blobs = moco_model['state_dict'] 13 | # convert to pytorch style 14 | state_dict = OrderedDict() 15 | for k, v in blobs.items(): 16 | if not k.startswith('module.encoder_q.'): 17 | continue 18 | old_k = k 19 | k = k.replace('module.encoder_q.', '') 20 | state_dict[k] = v 21 | print(old_k, '->', k) 22 | # save checkpoint 23 | checkpoint = dict() 24 | checkpoint['state_dict'] = state_dict 25 | torch.save(checkpoint, dst) 26 | 27 | 28 | def main(): 29 | parser = argparse.ArgumentParser(description='Convert model keys') 30 | parser.add_argument('src', help='src detectron model path') 31 | parser.add_argument('dst', help='save path') 32 | parser.add_argument( 33 | '--selfsup', type=str, choices=['moco', 'swav'], help='save path') 34 | args = parser.parse_args() 35 | if args.selfsup == 'moco': 36 | moco_convert(args.src, args.dst) 37 | elif args.selfsup == 'swav': 38 | print('SWAV does not need to convert the keys') 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /tools/model_converters/upgrade_ssd_version.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) OpenMMLab. All rights reserved. 2 | import argparse 3 | import tempfile 4 | from collections import OrderedDict 5 | 6 | import torch 7 | from mmcv import Config 8 | 9 | 10 | def parse_config(config_strings): 11 | temp_file = tempfile.NamedTemporaryFile() 12 | config_path = f'{temp_file.name}.py' 13 | with open(config_path, 'w') as f: 14 | f.write(config_strings) 15 | 16 | config = Config.fromfile(config_path) 17 | # check whether it is SSD 18 | if config.model.bbox_head.type != 'SSDHead': 19 | raise AssertionError('This is not a SSD model.') 20 | 21 | 22 | def convert(in_file, out_file): 23 | checkpoint = torch.load(in_file) 24 | in_state_dict = checkpoint.pop('state_dict') 25 | out_state_dict = OrderedDict() 26 | meta_info = checkpoint['meta'] 27 | parse_config('#' + meta_info['config']) 28 | for key, value in in_state_dict.items(): 29 | if 'extra' in key: 30 | layer_idx = int(key.split('.')[2]) 31 | new_key = 'neck.extra_layers.{}.{}.conv.'.format( 32 | layer_idx // 2, layer_idx % 2) + key.split('.')[-1] 33 | elif 'l2_norm' in key: 34 | new_key = 'neck.l2_norm.weight' 35 | elif 'bbox_head' in key: 36 | new_key = key[:21] + '.0' + key[21:] 37 | else: 38 | new_key = key 39 | out_state_dict[new_key] = value 40 | checkpoint['state_dict'] = out_state_dict 41 | 42 | if torch.__version__ >= '1.6': 43 | torch.save(checkpoint, out_file, _use_new_zipfile_serialization=False) 44 | else: 45 | torch.save(checkpoint, out_file) 46 | 47 | 48 | def main(): 49 | parser = argparse.ArgumentParser(description='Upgrade SSD version') 50 | parser.add_argument('in_file', help='input checkpoint file') 51 | parser.add_argument('out_file', help='output checkpoint file') 52 | 53 | args = parser.parse_args() 54 | convert(args.in_file, args.out_file) 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /tools/slurm_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | PARTITION=$1 6 | JOB_NAME=$2 7 | CONFIG=$3 8 | CHECKPOINT=$4 9 | GPUS=${GPUS:-8} 10 | GPUS_PER_NODE=${GPUS_PER_NODE:-8} 11 | CPUS_PER_TASK=${CPUS_PER_TASK:-5} 12 | PY_ARGS=${@:5} 13 | SRUN_ARGS=${SRUN_ARGS:-""} 14 | 15 | PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ 16 | srun -p ${PARTITION} \ 17 | --job-name=${JOB_NAME} \ 18 | --gres=gpu:${GPUS_PER_NODE} \ 19 | --ntasks=${GPUS} \ 20 | --ntasks-per-node=${GPUS_PER_NODE} \ 21 | --cpus-per-task=${CPUS_PER_TASK} \ 22 | --kill-on-bad-exit=1 \ 23 | ${SRUN_ARGS} \ 24 | python -u tools/test.py ${CONFIG} ${CHECKPOINT} --launcher="slurm" ${PY_ARGS} 25 | -------------------------------------------------------------------------------- /tools/slurm_train.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | PARTITION=$1 6 | JOB_NAME=$2 7 | CONFIG=$3 8 | WORK_DIR=$4 9 | GPUS=${GPUS:-8} 10 | GPUS_PER_NODE=${GPUS_PER_NODE:-8} 11 | CPUS_PER_TASK=${CPUS_PER_TASK:-5} 12 | SRUN_ARGS=${SRUN_ARGS:-""} 13 | PY_ARGS=${@:5} 14 | 15 | PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ 16 | srun -p ${PARTITION} \ 17 | --job-name=${JOB_NAME} \ 18 | --gres=gpu:${GPUS_PER_NODE} \ 19 | --ntasks=${GPUS} \ 20 | --ntasks-per-node=${GPUS_PER_NODE} \ 21 | --cpus-per-task=${CPUS_PER_TASK} \ 22 | --kill-on-bad-exit=1 \ 23 | ${SRUN_ARGS} \ 24 | python -u tools/train.py ${CONFIG} --work-dir=${WORK_DIR} --launcher="slurm" ${PY_ARGS} 25 | --------------------------------------------------------------------------------