├── .gitignore ├── LICENSE ├── README.md ├── dataset ├── __init__.py ├── base_dataset.py └── coco_dataset.py ├── eval ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DensePoseData │ └── get_eval_data.sh ├── Detectron.egg-info │ ├── PKG-INFO │ ├── SOURCES.txt │ ├── dependency_links.txt │ └── top_level.txt ├── GETTING_STARTED.md ├── INSTALL.md ├── LICENSE ├── Makefile ├── NOTICE ├── PoseTrack │ ├── DensePose-PoseTrack-Visualize.ipynb │ ├── README.md │ ├── configs │ │ └── DensePose_ResNet50_FPN_s1x-e2e.yaml │ └── get_DensePose_PoseTrack.sh ├── README.md ├── challenge │ ├── 2018_COCO_DensePose │ │ ├── data_format.md │ │ ├── evaluation.md │ │ ├── example_results.json │ │ ├── readme.md │ │ ├── results_format.md │ │ └── upload.md │ ├── 2018_PoseTrack_DensePose │ │ ├── data_format.md │ │ ├── evaluation.md │ │ ├── readme.md │ │ ├── results_format.md │ │ └── upload.md │ ├── 2019_COCO_DensePose │ │ ├── data_format.md │ │ ├── densepose_cocoeval.py │ │ ├── evaluation.md │ │ ├── readme.md │ │ ├── results_format.md │ │ └── upload.md │ └── encode_results_for_competition.py ├── cmake │ ├── Summary.cmake │ └── legacy │ │ ├── Cuda.cmake │ │ ├── Dependencies.cmake │ │ ├── Modules │ │ └── FindCuDNN.cmake │ │ ├── Summary.cmake │ │ ├── Utils.cmake │ │ └── legacymake.cmake ├── configs │ ├── DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.yaml │ ├── DensePose_ResNet101_FPN.yaml │ ├── DensePose_ResNet101_FPN_32x8d_s1x-e2e.yaml │ ├── DensePose_ResNet101_FPN_32x8d_s1x.yaml │ ├── DensePose_ResNet101_FPN_s1x-e2e.yaml │ ├── DensePose_ResNet101_FPN_s1x.yaml │ ├── DensePose_ResNet50_FPN.yaml │ ├── DensePose_ResNet50_FPN_s1x-e2e.yaml │ ├── DensePose_ResNet50_FPN_s1x.yaml │ ├── DensePose_ResNet50_FPN_single_GPU.yaml │ ├── rpn_densepose_only_R-50-FPN_1x.yaml │ └── rpn_densepose_only_X-101-32x8d-FPN_1x.yaml ├── detectron │ ├── __init__.py │ ├── core │ │ ├── __init__.py │ │ ├── config.py │ │ ├── rpn_generator.py │ │ ├── test.py │ │ ├── test_engine.py │ │ └── test_retinanet.py │ ├── datasets │ │ ├── VOCdevkit-matlab-wrapper │ │ │ ├── get_voc_opts.m │ │ │ ├── voc_eval.m │ │ │ └── xVOCap.m │ │ ├── __init__.py │ │ ├── cityscapes_json_dataset_evaluator.py │ │ ├── coco_to_cityscapes_id.py │ │ ├── dataset_catalog.py │ │ ├── densepose_cocoeval.py │ │ ├── dummy_datasets.py │ │ ├── json_dataset.py │ │ ├── json_dataset_evaluator.py │ │ ├── roidb.py │ │ ├── task_evaluation.py │ │ ├── voc_dataset_evaluator.py │ │ └── voc_eval.py │ ├── modeling │ │ ├── FPN.py │ │ ├── ResNet.py │ │ ├── VGG16.py │ │ ├── VGG_CNN_M_1024.py │ │ ├── __init__.py │ │ ├── body_uv_rcnn_heads.py │ │ ├── detector.py │ │ ├── fast_rcnn_heads.py │ │ ├── generate_anchors.py │ │ ├── keypoint_rcnn_heads.py │ │ ├── mask_rcnn_heads.py │ │ ├── model_builder.py │ │ ├── name_compat.py │ │ ├── optimizer.py │ │ ├── retinanet_heads.py │ │ ├── rfcn_heads.py │ │ └── rpn_heads.py │ ├── ops │ │ ├── __init__.py │ │ ├── collect_and_distribute_fpn_rpn_proposals.py │ │ ├── generate_proposal_labels.py │ │ ├── generate_proposals.py │ │ ├── pool_points_interp.cc │ │ ├── pool_points_interp.cu │ │ ├── pool_points_interp.h │ │ ├── zero_even_op.cc │ │ ├── zero_even_op.cu │ │ └── zero_even_op.h │ ├── roi_data │ │ ├── __init__.py │ │ ├── body_uv_rcnn.py │ │ ├── data_utils.py │ │ ├── fast_rcnn.py │ │ ├── keypoint_rcnn.py │ │ ├── loader.py │ │ ├── mask_rcnn.py │ │ ├── minibatch.py │ │ ├── retinanet.py │ │ └── rpn.py │ ├── tests │ │ ├── data_loader_benchmark.py │ │ ├── test_batch_permutation_op.py │ │ ├── test_bbox_transform.py │ │ ├── test_cfg.py │ │ ├── test_loader.py │ │ ├── test_restore_checkpoint.py │ │ ├── test_smooth_l1_loss_op.py │ │ ├── test_spatial_narrow_as_op.py │ │ └── test_zero_even_op.py │ └── utils │ │ ├── __init__.py │ │ ├── blob.py │ │ ├── boxes.py │ │ ├── c2.py │ │ ├── collections.py │ │ ├── colormap.py │ │ ├── coordinator.py │ │ ├── cython_bbox.pyx │ │ ├── cython_nms.pyx │ │ ├── densepose_methods.py │ │ ├── env.py │ │ ├── image.py │ │ ├── io.py │ │ ├── keypoints.py │ │ ├── logging.py │ │ ├── lr_policy.py │ │ ├── model_convert_utils.py │ │ ├── net.py │ │ ├── segms.py │ │ ├── subprocess.py │ │ ├── timer.py │ │ ├── train.py │ │ ├── training_stats.py │ │ └── vis.py ├── docker │ └── Dockerfile ├── environment.yml ├── eval_json.py ├── infer.py ├── infer_simple.py ├── notebooks │ ├── .ipynb_checkpoints │ │ ├── DensePose-COCO-Visualize-checkpoint.ipynb │ │ ├── DensePose-COCO-on-SMPL-checkpoint.ipynb │ │ └── DensePose-RCNN-Texture-Transfer-checkpoint.ipynb │ ├── DensePose-COCO-Visualize.ipynb │ ├── DensePose-COCO-on-SMPL.ipynb │ ├── DensePose-RCNN-Texture-Transfer.ipynb │ └── DensePose-RCNN-Visualize-Results.ipynb ├── parse_json.py ├── requirements.txt ├── setup.py └── tools │ ├── infer.py │ ├── infer_simple.py │ ├── test_net.py │ ├── train_net.py │ └── visualize_results.py ├── evaluation.py ├── loss └── dp_loss.py ├── networks ├── __init__.py ├── base_net.py ├── trans_unet │ ├── vit_seg_configs.py │ ├── vit_seg_modeling.py │ └── vit_seg_modeling_resnet_skip.py └── transformer_net.py ├── options ├── __init__.py ├── base_options.py └── train_options.py ├── png ├── fig2.png └── fig4.png ├── train.py ├── train_transformer.sh └── utils ├── misc.py ├── util.py └── visualizer.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.pyc 3 | *.pyd 4 | *.pyx 5 | *.a 6 | *.so 7 | *.o 8 | *.jpg 9 | *.png 10 | *.bmp 11 | *.obj 12 | .idea/ 13 | checkpoints/ 14 | data/ 15 | eval/detectron/utils/cython_nms.c 16 | eval/detectron/utils/cython_bbox.c 17 | 18 | *.result.tmp.pkl -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 jeonsworld 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UltraPose: Synthesizing Dense Pose with 1 Billion Points by Human-body Decoupling 3D Model 2 | Official repository for the **ICCV 2021** paper: 3 | 4 | **UltraPose: Synthesizing Dense Pose with 1 Billion Points by Human-body Decoupling 3D Model** [[PDF](https://openaccess.thecvf.com/content/ICCV2021/papers/Yan_UltraPose_Synthesizing_Dense_Pose_With_1_Billion_Points_by_Human-Body_ICCV_2021_paper.pdf)] 5 | 6 | Haonan Yan, Jiaqi Chen, Xujie Zhang, Shengkai Zhang, Nianhong Jiao, Xiaodan Liang, Tianxiang Zheng 7 | 8 | The dataset is now available at [Baidu net disk](https://pan.baidu.com/s/1lHM_6bxWGp5ZrxFQNcJpTg) (code: bpi2) or [google drive](https://drive.google.com/drive/folders/13SNcjuQBT62JfCGgBlchnLqbX8cv4QxT?usp=sharing). 9 | 10 | 11 | 12 | 13 | ## Introduction 14 | ![teaser](png/fig2.png) 15 | In this work, we introduce a new 3D human-body model with a series of decoupled parameters that could freely control the generation of the body. Furthermore, we build a data generation system based on this decoupling 3D model, and construct an ultra dense synthetic benchmark UltraPose, containing around 1.3 billion corresponding points. 16 | 17 | ## Installation 18 | We recommend creating a clean [conda](https://docs.conda.io/) environment and install all dependencies. 19 | You can do this as follows: 20 | 21 | step1 22 | ``` 23 | conda create -n ultrapose python=3.7 24 | conda activate ultrapose 25 | ``` 26 | step2 27 | ``` 28 | conda install pytorch=1.7.1 torchvision cudatoolkit=10.2 -c pytorch 29 | ``` 30 | step3 31 | ``` 32 | pip install ml-collections opencv-python imgaug visdom pycocotools Cython future h5py 33 | ``` 34 | 35 | You need to build python3 densepose for evaluation. You can do this as follows: 36 | ``` 37 | cd $UltraPoseDir/eval 38 | make 39 | cd $UltraPoseDir/eval/DensePoseData 40 | bash get_eval_data.sh 41 | ``` 42 | 43 | ## Training 44 | 45 | For single GPU training, please use default configurations by running: 46 | 47 | ``` 48 | python train.py --dataroot data/ultrapose 49 | ``` 50 | Besides, you can also use visdom to monitor the training process. 51 | ``` 52 | python -m visdom.server 53 | python train.py --dataroot data/ultrapose --use_visdom 54 | ``` 55 | For multi-GPU training with default configurations, you can modify `train_transformer.sh` accordingly and run: 56 | ``` 57 | sh train_transformer.sh 58 | ``` 59 | 60 | ## Evaluation 61 | ``` 62 | python evaluation.py 63 | ``` 64 | 65 | ## Dataset 66 | ![teaser](png/fig4.png) 67 | The dataset is now available from [Baidu net disk](https://pan.baidu.com/s/1lHM_6bxWGp5ZrxFQNcJpTg) (code: bpi2) or [google drive](https://drive.google.com/drive/folders/13SNcjuQBT62JfCGgBlchnLqbX8cv4QxT?usp=sharing). 68 | 69 | Extract the data and put them under `$UltraPoseDir/data`. 70 | 71 | | Dataset | Persons | Points | #Avg Density | Mask Resolution | No error | 72 | | :----: | :----: | :----: |:----: | :----: | :----: | 73 | | Densepose-COCO | 49K | 5.2M | 106 | 256x256 | | 74 | | UltraPose | 5K | 13M | 2.6K | 512x512 | ✓ | 75 | 76 | ## Acknowledgements 77 | Parts of the code are taken or adapted from the following repos: 78 | - [TransUNet](https://github.com/Beckschen/TransUNet) 79 | - [ViT-pytorch](https://github.com/jeonsworld/ViT-pytorch) 80 | - [vposer](https://github.com/nghorbani/human_body_prior) 81 | - [densepose](https://github.com/facebookresearch/DensePose) 82 | - [densepose_python3](https://github.com/stimong/densepose_python3) 83 | 84 | 85 | ## Citation 86 | If you use this code or Ultrapose for your research, please cite our work: 87 | ``` 88 | @inproceedings{yan2021ultrapose, 89 | title={UltraPose: Synthesizing Dense Pose With 1 Billion Points by Human-Body Decoupling 3D Model}, 90 | author={Yan, Haonan and Chen, Jiaqi and Zhang, Xujie and Zhang, Shengkai and Jiao, Nianhong and Liang, Xiaodan and Zheng, Tianxiang}, 91 | booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision}, 92 | pages={10891--10900}, 93 | year={2021} 94 | } 95 | ``` 96 | -------------------------------------------------------------------------------- /dataset/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | import torch.utils.data 3 | from dataset.base_dataset import BaseDataset 4 | from torch.utils.data.distributed import DistributedSampler 5 | import utils.misc as misc 6 | 7 | def find_dataset_using_name(dataset_name): 8 | dataset_filename = "dataset." + dataset_name + "_dataset" 9 | datasetlib = importlib.import_module(dataset_filename) 10 | 11 | dataset = None 12 | target_dataset_name = dataset_name.replace('_', '') + 'dataloader' 13 | for name, cls in datasetlib.__dict__.items(): 14 | if name.lower() == target_dataset_name.lower() \ 15 | and issubclass(cls, BaseDataset): 16 | dataset = cls 17 | 18 | if dataset is None: 19 | raise NotImplementedError("In %s.py, there should be a subclass of BaseDataset with class name that matches %s in lowercase." % (dataset_filename, target_dataset_name)) 20 | 21 | return dataset 22 | 23 | def get_option_setter(dataset_name): 24 | dataset_class = find_dataset_using_name(dataset_name) 25 | return dataset_class.modify_commandline_options 26 | 27 | def create_dataset(args, is_train): 28 | dataset_class = find_dataset_using_name(args.dataset_name) 29 | dataset = dataset_class(args, is_train) 30 | print("dataset [{}] was created (rank{})".format(type(dataset).__name__, args.rank)) 31 | 32 | if args.distributed: 33 | sampler = DistributedSampler(dataset, shuffle=is_train) 34 | else: 35 | if is_train: 36 | sampler = torch.utils.data.RandomSampler(dataset) 37 | else: 38 | sampler = torch.utils.data.SequentialSampler(dataset) 39 | 40 | batch_sampler_train = torch.utils.data.BatchSampler( 41 | sampler, args.batch_size if is_train else 1, drop_last=True) 42 | 43 | dataloader = torch.utils.data.DataLoader(dataset, 44 | pin_memory=True, 45 | batch_sampler=batch_sampler_train, 46 | num_workers=args.num_threads if is_train else 0) 47 | 48 | return dataloader, dataset 49 | 50 | -------------------------------------------------------------------------------- /eval/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) 2 | 3 | # Find the Caffe2 package. 4 | # Caffe2 exports the required targets, so find_package should work for 5 | # the standard Caffe2 installation. If you encounter problems with finding 6 | # the Caffe2 package, make sure you have run `make install` when installing 7 | # Caffe2 (`make install` populates your share/cmake/Caffe2). 8 | find_package(Caffe2 REQUIRED) 9 | 10 | if (${CAFFE2_VERSION} VERSION_LESS 0.8.2) 11 | # Pre-0.8.2 caffe2 does not have proper interface libraries set up, so we 12 | # will rely on the old path. 13 | message(WARNING 14 | "You are using an older version of Caffe2 (version " ${CAFFE2_VERSION} 15 | "). Please consider moving to a newer version.") 16 | include(cmake/legacy/legacymake.cmake) 17 | return() 18 | endif() 19 | 20 | # Add compiler flags. 21 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") 22 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -fPIC -Wno-narrowing") 23 | 24 | # Print configuration summary. 25 | include(cmake/Summary.cmake) 26 | detectron_print_config_summary() 27 | 28 | # Collect custom ops sources. 29 | file(GLOB CUSTOM_OPS_CPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cc) 30 | file(GLOB CUSTOM_OPS_GPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cu) 31 | 32 | # Install custom CPU ops lib. 33 | add_library( 34 | caffe2_detectron_custom_ops SHARED 35 | ${CUSTOM_OPS_CPU_SRCS}) 36 | 37 | target_link_libraries(caffe2_detectron_custom_ops caffe2_library) 38 | install(TARGETS caffe2_detectron_custom_ops DESTINATION lib) 39 | 40 | # Install custom GPU ops lib, if gpu is present. 41 | if (CAFFE2_USE_CUDA OR CAFFE2_FOUND_CUDA) 42 | # Additional -I prefix is required for CMake versions before commit (< 3.7): 43 | # https://github.com/Kitware/CMake/commit/7ded655f7ba82ea72a82d0555449f2df5ef38594 44 | list(APPEND CUDA_INCLUDE_DIRS -I${CAFFE2_INCLUDE_DIRS}) 45 | CUDA_ADD_LIBRARY( 46 | caffe2_detectron_custom_ops_gpu SHARED 47 | ${CUSTOM_OPS_CPU_SRCS} 48 | ${CUSTOM_OPS_GPU_SRCS}) 49 | 50 | target_link_libraries(caffe2_detectron_custom_ops_gpu caffe2_gpu_library) 51 | install(TARGETS caffe2_detectron_custom_ops_gpu DESTINATION lib) 52 | endif() 53 | -------------------------------------------------------------------------------- /eval/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Facebook has adopted a Code of Conduct that we expect project participants to adhere to. 4 | Please read the [full text](https://code.facebook.com/pages/876921332402685/open-source-code-of-conduct) 5 | so that you can understand what actions will and will not be tolerated. 6 | 7 | -------------------------------------------------------------------------------- /eval/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to DensePose 2 | We want to make contributing to this project as easy and transparent as 3 | possible. 4 | 5 | ## Our Development Process 6 | Minor changes and improvements will be released on an ongoing basis. 7 | 8 | ## Pull Requests 9 | We actively welcome your pull requests. 10 | 11 | 1. Fork the repo and create your branch from `master`. 12 | 2. If you've added code that should be tested, add tests. 13 | 3. If you've changed APIs, update the documentation. 14 | 4. Ensure the test suite passes. 15 | 5. Make sure your code lints. 16 | 6. If you haven't already, complete the Contributor License Agreement ("CLA"). 17 | 18 | ## Contributor License Agreement ("CLA") 19 | In order to accept your pull request, we need you to submit a CLA. You only need 20 | to do this once to work on any of Facebook's open source projects. 21 | 22 | Complete your CLA here: 23 | 24 | ## Issues 25 | We use GitHub issues to track public bugs. Please ensure your description is 26 | clear and has sufficient instructions to be able to reproduce the issue. 27 | 28 | ## Coding Style 29 | * 4 spaces for indentation rather than tabs 30 | * 80 character line length 31 | * PEP8 formatting 32 | 33 | ## License 34 | By contributing to DensePose, you agree that your contributions will be licensed 35 | under the LICENSE file in the root directory of this source tree. 36 | 37 | -------------------------------------------------------------------------------- /eval/DensePoseData/get_eval_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir eval_data 3 | cd eval_data 4 | wget https://dl.fbaipublicfiles.com/densepose/densepose_eval_data.tar.gz 5 | tar xvf densepose_eval_data.tar.gz 6 | rm densepose_eval_data.tar.gz 7 | -------------------------------------------------------------------------------- /eval/Detectron.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 2.1 2 | Name: Detectron 3 | Version: 0.0.0 4 | Summary: UNKNOWN 5 | Home-page: UNKNOWN 6 | License: UNKNOWN 7 | Platform: UNKNOWN 8 | License-File: LICENSE 9 | License-File: NOTICE 10 | 11 | UNKNOWN 12 | 13 | -------------------------------------------------------------------------------- /eval/Detectron.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | LICENSE 2 | NOTICE 3 | README.md 4 | setup.py 5 | Detectron.egg-info/PKG-INFO 6 | Detectron.egg-info/SOURCES.txt 7 | Detectron.egg-info/dependency_links.txt 8 | Detectron.egg-info/top_level.txt 9 | detectron/__init__.py 10 | detectron/utils/cython_bbox.c 11 | detectron/utils/cython_nms.c -------------------------------------------------------------------------------- /eval/Detectron.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /eval/Detectron.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | detectron 2 | -------------------------------------------------------------------------------- /eval/GETTING_STARTED.md: -------------------------------------------------------------------------------- 1 | # Using Detectron 2 | 3 | This document provides brief tutorials covering DensePose for inference and training on the DensePose-COCO dataset. 4 | This document is a modified version of the [`detectron/GETTING_STARTED.md`](https://github.com/facebookresearch/Detectron/blob/master/GETTING_STARTED.md). 5 | 6 | - For general information about DensePose, please see [`README.md`](README.md). 7 | - For installation instructions, please see [`INSTALL.md`](INSTALL.md). 8 | 9 | ## Inference with Pretrained Models 10 | 11 | #### 1. Directory of Image Files 12 | To run inference on a an image (or a directory of image files), you can use the `infer_simple.py` tool. In this example, we're using an end-to-end trained DensePose-RCNN model with a ResNet-101-FPN backbone from the model zoo: 13 | ``` 14 | python2 tools/infer_simple.py \ 15 | --cfg configs/DensePose_ResNet101_FPN_s1x-e2e.yaml \ 16 | --output-dir DensePoseData/infer_out/ \ 17 | --image-ext jpg \ 18 | --wts https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_s1x-e2e.pkl \ 19 | DensePoseData/demo_data/demo_im.jpg 20 | ``` 21 | 22 | DensePose should automatically download the model from the URL specified by the `--wts` argument. This tool will output visualizations of the detections in PDF format in the directory specified by `--output-dir`. Also, it will output two images `*_IUV.png` and `*_INDS.png` which consists of I,U, V channels and segmented instance indices respectively. Please see [`notebooks/DensePose-RCNN-Visualize-Results.ipynb`](notebooks/DensePose-RCNN-Visualize-Results.ipynb) for the visualizations of these outputs. 23 | 24 | 25 | ## Testing with Pretrained Models 26 | 27 | Make sure that you have downloaded the DensePose evaluation files as instructed in [`INSTALL.md`](INSTALL.md). 28 | This example shows how to run an end-to-end trained DensePose-RCNN model from the model zoo using a single GPU for inference. As configured, this will run inference on all images in `coco_2014_minival` (which must be properly installed). 29 | 30 | ``` 31 | python2 tools/test_net.py \ 32 | --cfg configs/DensePose_ResNet101_FPN_s1x-e2e.yaml \ 33 | TEST.WEIGHTS https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_s1x-e2e.pkl \ 34 | NUM_GPUS 1 35 | ``` 36 | 37 | ## Training a Model 38 | 39 | This example shows how to train a model using the DensePose-COCO dataset. The model will be an end-to-end trained DensePose-RCNN using a ResNet-50-FPN backbone. 40 | 41 | ``` 42 | python2 tools/train_net.py \ 43 | --cfg configs/DensePose_ResNet50_FPN_single_GPU.yaml \ 44 | OUTPUT_DIR /tmp/detectron-output 45 | ``` 46 | The models we have provided in the model zoo are trained using 8 gpus. As in any Detectron configs, we use linear scaling rule to adjust learning schedules. Please refer to the following paper: [Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour](https://arxiv.org/abs/1706.02677). We also provide learning rate and number of iterations for varying number of GPUs. 47 | 48 | -------------------------------------------------------------------------------- /eval/Makefile: -------------------------------------------------------------------------------- 1 | # Don't use the --user flag for setup.py develop mode with virtualenv. 2 | DEV_USER_FLAG=$(shell python -c "import sys; print('' if hasattr(sys, 'real_prefix') else '--user')") 3 | 4 | .PHONY: default 5 | default: dev 6 | 7 | .PHONY: install 8 | install: 9 | python setup.py install 10 | 11 | .PHONY: ops 12 | ops: 13 | mkdir -p build && cd build && cmake .. && make -j$(shell nproc) 14 | 15 | .PHONY: dev 16 | dev: 17 | python setup.py develop $(DEV_USER_FLAG) 18 | 19 | .PHONY: clean 20 | clean: 21 | python setup.py develop --uninstall $(DEV_USER_FLAG) 22 | rm -rf build 23 | -------------------------------------------------------------------------------- /eval/NOTICE: -------------------------------------------------------------------------------- 1 | Portions of this software are derived from py-faster-rcnn. 2 | 3 | ============================================================================== 4 | py-faster-rcnn licence 5 | ============================================================================== 6 | 7 | Faster R-CNN 8 | 9 | The MIT License (MIT) 10 | 11 | Copyright (c) 2015 Microsoft Corporation 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in 21 | all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | THE SOFTWARE. 30 | -------------------------------------------------------------------------------- /eval/PoseTrack/README.md: -------------------------------------------------------------------------------- 1 | # DensePose-PoseTrack 2 | We introduce the DensePose-Posetrack dataset, which consists of videos of multiple persons containing rapid motions, occlusions and scale variations which leads to a very challenging correspondence task. DensePose-PoseTrack will be a part of the [ECCV 2018 - POSETRACK CHALLENGE](https://posetrack.net/workshops/eccv2018/). 3 | 4 |
5 | 6 |
7 | 8 | Please first follow the [INSTALL.md](https://github.com/facebookresearch/DensePose/blob/master/INSTALL.md) and [GETTING_STARTED.md](https://github.com/facebookresearch/DensePose/blob/master/GETTING_STARTED.md), to install and run the DensePose inference and training. Herein, we provide instructions to download and evaluate on the DensePose-PoseTrack dataset. 9 | 10 | ### Fetch DensePose-PoseTrack dataset 11 | 12 | To download the images of the original PoseTrack dataset, please refer to the posetrack webpage: https://posetrack.net. Note that we have used the keypoints provided in the PoseTrack dataset to form the DensePose-PoseTrack dataset. Our dense correspondence annotations are distributed under [NonCommercial Creative Commons](https://creativecommons.org/licenses/by-nc/2.0/) license. 13 | 14 | To downoad, run: 15 | ``` 16 | cd $DENSEPOSE/PoseTrack 17 | bash get_DensePose_PoseTrack.sh 18 | ``` 19 | This script downloads *.json files that contains all annotations along with files that only contains annotations for images with densepose annotations. The latter is used during evaluation. 20 | 21 | Visualization of the DensePose-PoseTrack annotations are demonstrated in the [DensePose-PoseTrack-Visualize.ipynb](https://github.com/facebookresearch/DensePose/blob/master/PoseTrack/DensePose-PoseTrack-Visualize.ipynb): 22 | 23 |
24 | 25 |
26 | 27 | 28 | ## Setting-up the PoseTrack dataset. 29 | 30 | Create a symlink for the PoseTrack dataset in your `datasets/data` folder. 31 | ``` 32 | ln -s /path/to/posetrack $DENSEPOSE/detectron/datasets/data/posetrack 33 | ``` 34 | Create symlinks for the DensePose-PoseTrack annotations 35 | 36 | ``` 37 | ln -s $DENSEPOSE/PoseTrack/DensePose_PoseTrack/densepose_only_posetrack_train2017.json $DENSEPOSE/detectron/datasets/data/posetrack/ 38 | ln -s $DENSEPOSE/PoseTrack/DensePose_PoseTrack/densepose_only_posetrack_val2017.json $DENSEPOSE/detectron/datasets/data/posetrack/ 39 | ln -s $DENSEPOSE/PoseTrack/DensePose_PoseTrack/densepose_posetrack_test2017.json $DENSEPOSE/detectron/datasets/data/posetrack/ 40 | ``` 41 | Your local PoseTrack dataset copy at `/path/to/posetrack` should have the following directory structure: 42 | 43 | ``` 44 | posetrack 45 | |_ images 46 | | |_ 47 | | |_ ... 48 | | |_ . 49 | |_ densepose_only_posetrack_train2017.json 50 | |_ densepose_only_posetrack_val2017.json 51 | |_ densepose_posetrack_test2017.json 52 | ``` 53 | 54 | ### Evaluation on DensePose-PoseTrack dataset 55 | 56 | To demonstrate the evaluation, we use a DensePose-RCNN with a ResNet-50 trunk that is trained on the DensePose-COCO dataset. 57 | ``` 58 | cd $DENSEPOSE 59 | python2 tools/test_net.py \ 60 | --cfg PoseTrack/configs/DensePose_ResNet50_FPN_s1x-e2e.yaml \ 61 | TEST.WEIGHTS https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet50_FPN_s1x-e2e.pkl \ 62 | NUM_GPUS 1 63 | ``` 64 | The evaluation of this baseline network should yield `Bounding Box AP: 0.4438` and `DensePose AP: 0.2698`. 65 | -------------------------------------------------------------------------------- /eval/PoseTrack/configs/DensePose_ResNet50_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | FAST_RCNN: 36 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 37 | ROI_XFORM_METHOD: RoIAlign 38 | ROI_XFORM_RESOLUTION: 7 39 | ROI_XFORM_SAMPLING_RATIO: 2 40 | BODY_UV_RCNN: 41 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 42 | NUM_STACKED_CONVS: 8 43 | NUM_PATCHES: 24 44 | USE_DECONV_OUTPUT: True 45 | CONV_INIT: MSRAFill 46 | CONV_HEAD_DIM: 512 47 | UP_SCALE: 2 48 | HEATMAP_SIZE: 56 49 | ROI_XFORM_METHOD: RoIAlign 50 | ROI_XFORM_RESOLUTION: 14 51 | ROI_XFORM_SAMPLING_RATIO: 2 52 | ## 53 | # Loss weights for annotation masks.(14 Parts) 54 | INDEX_WEIGHTS : 2.0 55 | # Loss weights for surface parts. (24 Parts) 56 | PART_WEIGHTS : 0.3 57 | # Loss weights for UV regression. 58 | POINT_REGRESSION_WEIGHTS : 0.1 59 | ## 60 | BODY_UV_IMS: True 61 | TRAIN: 62 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 63 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 70 | TEST: 71 | DATASETS: ('dense_posetrack_2017_val',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 79 | RPN_POST_NMS_TOP_N: 1000 80 | OUTPUT_DIR: '' 81 | -------------------------------------------------------------------------------- /eval/PoseTrack/get_DensePose_PoseTrack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir DensePose_PoseTrack 3 | cd DensePose_PoseTrack 4 | wget -O densepose_only_posetrack_train2017.json https://www.dropbox.com/s/tpbaemzvlojo2iz/densepose_only_posetrack_train2017.json?dl=1 5 | wget -O densepose_only_posetrack_val2017.json https://www.dropbox.com/s/43h43s0t3hkuogr/densepose_only_posetrack_val2017.json?dl=1 6 | wget -O densepose_posetrack_test2017.json https://www.dropbox.com/s/48tkd4pr8aa3rex/densepose_posetrack_test2017.json?dl=1 7 | wget -O densepose_posetrack_train2017.json https://www.dropbox.com/s/awbdp3v0dz4jcau/densepose_posetrack_train2017.json?dl=1 8 | wget -O densepose_posetrack_val2017.json https://www.dropbox.com/s/6tdmqx0h6a04vzz/densepose_posetrack_val2017.json?dl=1 9 | -------------------------------------------------------------------------------- /eval/README.md: -------------------------------------------------------------------------------- 1 | # DensePose: 2 | **Dense Human Pose Estimation In The Wild** 3 | 4 | _Rıza Alp Güler, Natalia Neverova, Iasonas Kokkinos_ 5 | 6 | [[`densepose.org`](https://densepose.org)] [[`arXiv`](https://arxiv.org/abs/1802.00434)] [[`BibTeX`](#CitingDensePose)] 7 | 8 | Dense human pose estimation aims at mapping all human pixels of an RGB image to the 3D surface of the human body. 9 | DensePose-RCNN is implemented in the [Detectron](https://github.com/facebookresearch/Detectron) framework and is powered by [Caffe2](https://github.com/caffe2/caffe2). 10 | 11 |
12 | 13 |
14 | 15 | 16 | In this repository, we provide the code to train and evaluate DensePose-RCNN. We also provide notebooks to visualize the collected DensePose-COCO dataset and show the correspondences to the SMPL model. 17 | 18 | ## Installation 19 | 20 | Please find installation instructions for Caffe2 and DensePose in [`INSTALL.md`](INSTALL.md), a document based on the [Detectron](https://github.com/facebookresearch/Detectron) installation instructions. 21 | 22 | ## Inference-Training-Testing 23 | 24 | After installation, please see [`GETTING_STARTED.md`](GETTING_STARTED.md) for examples of inference and training and testing. 25 | 26 | ## Notebooks 27 | 28 | ### Visualization of DensePose-COCO annotations: 29 | 30 | See [`notebooks/DensePose-COCO-Visualize.ipynb`](notebooks/DensePose-COCO-Visualize.ipynb) to visualize the DensePose-COCO annotations on the images: 31 | 32 |
33 | 34 |
35 | 36 | --- 37 | 38 | ### DensePose-COCO in 3D: 39 | 40 | See [`notebooks/DensePose-COCO-on-SMPL.ipynb`](notebooks/DensePose-COCO-on-SMPL.ipynb) to localize the DensePose-COCO annotations on the 3D template ([`SMPL`](http://smpl.is.tue.mpg.de)) model: 41 | 42 |
43 | 44 |
45 | 46 | --- 47 | ### Visualize DensePose-RCNN Results: 48 | 49 | See [`notebooks/DensePose-RCNN-Visualize-Results.ipynb`](notebooks/DensePose-RCNN-Visualize-Results.ipynb) to visualize the inferred DensePose-RCNN Results. 50 | 51 |
52 | 53 |
54 | 55 | --- 56 | ### DensePose-RCNN Texture Transfer: 57 | 58 | See [`notebooks/DensePose-RCNN-Texture-Transfer.ipynb`](notebooks/DensePose-RCNN-Texture-Transfer.ipynb) to localize the DensePose-COCO annotations on the 3D template ([`SMPL`](http://smpl.is.tue.mpg.de)) model: 59 | 60 |
61 | 62 |
63 | 64 | ## License 65 | 66 | This source code is licensed under the license found in the [`LICENSE`](LICENSE) file in the root directory of this source tree. 67 | 68 | ## Citing DensePose 69 | 70 | If you use Densepose, please use the following BibTeX entry. 71 | 72 | ``` 73 | @InProceedings{Guler2018DensePose, 74 | title={DensePose: Dense Human Pose Estimation In The Wild}, 75 | author={R\{i}za Alp G\"uler, Natalia Neverova, Iasonas Kokkinos}, 76 | journal={The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, 77 | year={2018} 78 | } 79 | ``` 80 | 81 | 82 | -------------------------------------------------------------------------------- /eval/challenge/2018_COCO_DensePose/data_format.md: -------------------------------------------------------------------------------- 1 | # Data Format 2 | 3 | The annotations are stored in [JSON](http://json.org/). Please note that 4 | [COCO API](https://github.com/cocodataset/cocoapi) described on the 5 | [download](http://cocodataset.org/#download) page can be used to access 6 | and manipulate all annotations. 7 | 8 | The annotations file structure is outlined below: 9 | ``` 10 | { 11 | "images" : [image], 12 | "annotations" : [annotation], 13 | "categories" : [category] 14 | } 15 | 16 | image { 17 | "coco_url" : str, 18 | "date_captured" : datetime, 19 | "file_name" : str, 20 | "flickr_url" : str, 21 | "id" : int, 22 | "width" : int, 23 | "height" : int, 24 | "license" : int 25 | } 26 | 27 | annotation { 28 | "area": float, 29 | "bbox": [x, y, width, height], 30 | "category_id": int, 31 | "dp_I": [float], 32 | "dp_U": [float], 33 | "dp_V": [float], 34 | "dp_masks": [dp_mask], 35 | "dp_x": [float], 36 | "dp_y": [float], 37 | "id": int, 38 | "image_id": int, 39 | "iscrowd": 0 or 1, 40 | "keypoints": [float], 41 | "segmentation": RLE or [polygon] 42 | } 43 | 44 | category { 45 | "id" : int, 46 | "name" : str, 47 | "supercategory" : str, 48 | "keypoints": [str], 49 | "skeleton": [edge] 50 | } 51 | 52 | dp_mask { 53 | "counts": str, 54 | "size": [int, int] 55 | } 56 | ``` 57 | 58 | Each dense pose annotation contains a series of fields, including the category 59 | id and segmentation mask of the person. The segmentation format depends on 60 | whether the instance represents a single object (`iscrowd=0` in which case 61 | polygons are used) or a collection of objects (`iscrowd=1` in which case RLE 62 | is used). Note that a single object (`iscrowd=0`) may require multiple polygons, 63 | for example if occluded. Crowd annotations (`iscrowd=1`) are used to label large 64 | groups of objects (e.g. a crowd of people). In addition, an enclosing bounding 65 | box is provided for each person (box coordinates are measured from the top left 66 | image corner and are 0-indexed). 67 | 68 | The categories field of the annotation structure stores the mapping of category 69 | id to category and supercategory names. It also has two fields: "keypoints", 70 | which is a length `k` array of keypoint names, and "skeleton", which defines 71 | connectivity via a list of keypoint edge pairs and is used for visualization. 72 | 73 | DensePose annotations are stored in `dp_*` fields: 74 | 75 | *Annotated masks*: 76 | 77 | * `dp_masks`: RLE encoded dense masks. All part masks are of size 256x256. 78 | They correspond to 14 semantically meaningful parts of the body: `Torso`, 79 | `Right Hand`, `Left Hand`, `Left Foot`, `Right Foot`, `Upper Leg Right`, 80 | `Upper Leg Left`, `Lower Leg Right`, `Lower Leg Left`, `Upper Arm Left`, 81 | `Upper Arm Right`, `Lower Arm Left`, `Lower Arm Right`, `Head`; 82 | 83 | *Annotated points*: 84 | 85 | * `dp_x`, `dp_y`: spatial coordinates of collected points on the image. 86 | The coordinates are scaled such that the bounding box size is 256x256; 87 | * `dp_I`: The patch index that indicates which of the 24 surface patches the 88 | point is on. Patches correspond to the body parts described above. Some 89 | body parts are split into 2 patches: `1, 2 = Torso`, `3 = Right Hand`, 90 | `4 = Left Hand`, `5 = Left Foot`, `6 = Right Foot`, `7, 9 = Upper Leg Right`, 91 | `8, 10 = Upper Leg Left`, `11, 13 = Lower Leg Right`, `12, 14 = Lower Leg Left`, 92 | `15, 17 = Upper Arm Left`, `16, 18 = Upper Arm Right`, `19, 21 = Lower Arm Left`, 93 | `20, 22 = Lower Arm Right`, `23, 24 = Head`; 94 | * `dp_U`, `dp_V`: Coordinates in the UV space. Each surface patch has a 95 | separate 2D parameterization. 96 | 97 | -------------------------------------------------------------------------------- /eval/challenge/2018_COCO_DensePose/readme.md: -------------------------------------------------------------------------------- 1 | # COCO 2018 DensePose Task 2 | 3 | ![DensePose Splash Image](http://cocodataset.org/images/densepose-splash.png) 4 | 5 | ## Overview 6 | 7 | The COCO DensePose Task requires dense estimation of human pose in challenging, 8 | uncontrolled conditions. The DensePose task involves simultaneously detecting 9 | people, segmenting their bodies and mapping all image pixels that belong to a 10 | human body to the 3D surface of the body. For full details of this task please 11 | see the [DensePose evaluation](evaluation.md) page. 12 | 13 | This task is part of the 14 | [Joint COCO and Mapillary Recognition Challenge Workshop](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html) 15 | at ECCV 2018. For further details about the joint workshop please 16 | visit the workshop page. Please also see the related COCO 17 | [detection](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html#coco-detection), 18 | [panoptic](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html#coco-panoptic), 19 | [keypoints](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html#coco-keypoints) 20 | and [stuff](http://cocodataset.org/#stuff-2018) tasks. 21 | 22 | The COCO train, validation, and test sets, containing more than 39,000 images 23 | and 56,000 person instances labeled with DensePose annotations are available 24 | for [download](http://cocodataset.org/#download). 25 | Annotations on train ( 26 | [train 1](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_train.json), 27 | [train 2](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_valminusminival.json) 28 | ) and [val](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_minival.json) 29 | with over 48,000 people are publicly available. 30 | [Test set](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_test.json) 31 | with the list of images is also available for download. 32 | 33 | Evaluation server for the 2018 task is 34 | [open](https://competitions.codalab.org/competitions/19636). 35 | 36 | ## Dates 37 | 38 | []() | []() 39 | ---- | ----- 40 | **August 17, 2018** | Submission deadline (23:59 PST) 41 | August 26, 2018 | Challenge winners notified 42 | September 9, 2018 | Winners present at ECCV 2018 Workshop 43 | 44 | ## Organizers 45 | 46 | Riza Alp Güler (INRIA, CentraleSupélec) 47 | 48 | Natalia Neverova (Facebook AI Research) 49 | 50 | Iasonas Kokkinos (Facebook AI Research) 51 | 52 | ## Task Guidelines 53 | 54 | Participants are recommended but not restricted to train 55 | their algorithms on COCO DensePose train and val sets. 56 | The [download](http://cocodataset.org/#download) page has 57 | links to all COCO data. When participating in this task, 58 | please specify any and all external data used for training 59 | in the "method description" when uploading results to the 60 | evaluation server. A more thorough explanation of all these 61 | details is available on the 62 | [guidelines](http://cocodataset.org/#guidelines) page, 63 | please be sure to review it carefully prior to participating. 64 | Results in the [correct format](results_format.md) must be 65 | [uploaded](upload.md) to the 66 | [evaluation server](https://competitions.codalab.org/competitions/19636). 67 | The [evaluation](evaluation.md) page lists detailed information 68 | regarding how results will be evaluated. Challenge participants 69 | with the most successful and innovative methods will be invited 70 | to present at the workshop. 71 | 72 | ## Tools and Instructions 73 | 74 | We provide extensive API support for the COCO images, 75 | annotations, and evaluation code. To download the COCO DensePose API, 76 | please visit our 77 | [GitHub repository](https://github.com/facebookresearch/DensePose/). 78 | Due to the large size of COCO and the complexity of this task, 79 | the process of participating may not seem simple. To help, we provide 80 | explanations and instructions for each step of the process: 81 | [download](http://cocodataset.org/#download), 82 | [data format](data_format.md), 83 | [results format](results_format.md), 84 | [upload](upload.md) and [evaluation](evaluation.md) pages. 85 | For additional questions, please contact info@cocodataset.org. 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /eval/challenge/2018_COCO_DensePose/results_format.md: -------------------------------------------------------------------------------- 1 | # Results Format 2 | 3 | This page describes the results format used by COCO DensePose evaluation 4 | procedure. The results format mimics the annotation format detailed on 5 | the [data format](data_format.md) page. Please review the annotation 6 | format before proceeding. 7 | 8 | Each algorithmically generated result is stored separately in its own 9 | result struct. This singleton result struct must contain the id of the 10 | image from which the result was generated (a single image will typically 11 | have multiple associated results). Results for the whole dataset are 12 | aggregated in a single array. Finally, this entire result struct array 13 | is stored to disk as a single JSON file (saved via 14 | [gason](https://github.com/cocodataset/cocoapi/blob/master/MatlabAPI/gason.m) 15 | in Matlab or [json.dump](https://docs.python.org/2/library/json.html) in Python). 16 | 17 | Example result JSON files are available in 18 | [example results](example_results.json). 19 | 20 | The data struct for each of the result types is described below. The format 21 | of the individual fields below (`category_id`, `bbox`, etc.) is the same as 22 | for the annotation (for details see the [data format](data_format.md) page). 23 | Bounding box coordinates `bbox` are floats measured from the top left image 24 | corner (and are 0-indexed). We recommend rounding coordinates to the nearest 25 | tenth of a pixel to reduce the resulting JSON file size. The dense estimates 26 | of patch indices and coordinates in the UV space for the specified bounding 27 | box are stored in `uv_shape` and `uv_data` fields. 28 | `uv_shape` contains the shape of `uv_data` array, it should be of size 29 | `(3, height, width)`, where `height` and `width` should match the bounding box 30 | size. `uv_data` should contain PNG-compressed patch indices and U and V 31 | coordinates scaled to the range `0-255`. 32 | 33 | An example of code that generates results in the form of a `pkl` file can 34 | be found in 35 | [json_dataset_evaluator.py](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/json_dataset_evaluator.py). 36 | We also provide an [example script](../encode_results_for_competition.py) to convert 37 | dense pose estimation results stored in a `pkl` file into a PNG-compressed 38 | JSON file. 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /eval/challenge/2018_COCO_DensePose/upload.md: -------------------------------------------------------------------------------- 1 | # Upload Results to Evaluation Server 2 | 3 | This page describes the upload instructions for submitting results to the 4 | evaluation servers for the COCO DensePose challenge. Submitting results allows 5 | you to participate in the challenges and compare results to the 6 | state-of-the-art on the public leaderboards. Note that you can obtain results 7 | on val by running the 8 | [evaluation code](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/densepose_cocoeval.py) 9 | locally. One can also take advantage of the 10 | [vkhalidov/densepose-codalab](https://hub.docker.com/r/vkhalidov/densepose-codalab/) 11 | docker image which was tailored specifically for evaluation. 12 | Submitting to the evaluation server provides results on the val and 13 | test sets. We now give detailed instructions for submitting to the evaluation 14 | server: 15 | 16 | 1. Create an account on CodaLab. This will allow you to participate in all COCO challenges. 17 | 18 | 2. Carefully review the [guidelines](http://cocodataset.org/#guidelines) for 19 | entering the COCO challenges and using the test sets. 20 | 21 | 3. Prepare a JSON file containing your results in the correct 22 | [results format](results_format.md) for the challenge you wish to enter. 23 | 24 | 4. File naming: the JSON file should be named `densepose_[subset]_[alg]_results.json`. 25 | Replace `[subset]` with the subset you are using (`val` or `test`), 26 | and `[alg]` with your algorithm name. Finally, place the JSON 27 | file into a zip file named `densepose_[subset]_[alg]_results.zip`. 28 | 29 | 5. To submit your zipped result file to the COCO DensePose Challenge, click on 30 | the “Participate” tab on the 31 | [CodaLab evaluation server](https://competitions.codalab.org/competitions/19636) page. 32 | When you select “Submit / View Results” on the left panel, you will be able to choose 33 | the subset. Please fill in the required fields and click “Submit”. A pop-up will 34 | prompt you to select the results zip file for upload. After the file is uploaded 35 | the evaluation server will begin processing. To view the status of your submission 36 | please select “Refresh Status”. Please be patient, the evaluation may take quite 37 | some time to complete (from ~20m to a few hours). If the status of your submission 38 | is “Failed” please check your file is named correctly and has the right format. 39 | 40 | 6. Please enter submission information into Codalab. The most important fields 41 | are "Team name", "Method description", and "Publication URL", which are used 42 | to populate the COCO leaderboard. Additionally, under "user setting" in the 43 | upper right, please add "Team members". There have been issues with the 44 | "Method Description", we may collect these via email if necessary. These 45 | settings are not intuitive, but we have no control of the Codalab website. 46 | For the "Method description", especially for COCO DensePose challenge entries, 47 | we encourage participants to give detailed method information that will help 48 | the award committee invite participants with the most innovative methods. 49 | Listing external data used is mandatory. You may also consider giving some 50 | basic performance breakdowns on test subset (e.g., single model versus 51 | ensemble results), runtime, or any other information you think may be pertinent 52 | to highlight the novelty or efficacy of your method. 53 | 54 | 7. After you submit your results to the test-dev eval server, you can control 55 | whether your results are publicly posted to the CodaLab leaderboard. To toggle 56 | the public visibility of your results please select either “post to leaderboard” 57 | or “remove from leaderboard”. Only one result can be published to the leaderboard 58 | at any time. 59 | 60 | 8. After evaluation is complete and the server shows a status of “Finished”, 61 | you will have the option to download your evaluation results by selecting 62 | “Download evaluation output from scoring step.” The zip file will contain the 63 | score file `scores.txt`. 64 | 65 | -------------------------------------------------------------------------------- /eval/challenge/2018_PoseTrack_DensePose/readme.md: -------------------------------------------------------------------------------- 1 | # ECCV 2018 PoseTrack DensePose Task 2 | 3 | ![PoseTrack DensePose Splash Image](https://posetrack.net/workshops/eccv2018/assets/images/densepose-posetrack_examples.jpg) 4 | 5 | ## Overview 6 | 7 | The PoseTrack DensePose Task requires dense estimation of human pose through time 8 | in challenging, uncontrolled conditions. The task involves processing video frames 9 | to simultaneously detect people, segment their bodies and map all image pixels 10 | that belong to a human body to the 3D surface of the body. For full details on 11 | this task please see the [evaluation](evaluation.md) page. 12 | 13 | This task is part of the 14 | [PoseTrack Challenge Workshop](https://posetrack.net/workshops/eccv2018/) 15 | at ECCV 2018. For further details about the workshop please 16 | visit the workshop page. Please also see the related PoseTrack 17 | [Articulated Human Pose Estimation and Tracking](https://posetrack.net/workshops/eccv2018/#challenges) 18 | and 19 | [3D Human Pose Estimation](https://posetrack.net/workshops/eccv2018/#challenges) 20 | tasks. 21 | 22 | The PoseTrack DensePose train, validation, and test sets, containing more 23 | than 5,000 images 24 | and 27,000 person instances labeled with DensePose annotations are available 25 | for [download](https://posetrack.net/users/download.php). 26 | Annotations on 27 | [train](https://www.dropbox.com/s/tpbaemzvlojo2iz/densepose_only_posetrack_train2017.json?dl=1) 28 | and 29 | [val](https://www.dropbox.com/s/43h43s0t3hkuogr/densepose_only_posetrack_val2017.json?dl=1) 30 | with over 13,000 people are publicly available. 31 | 32 | Evaluation server for the 2018 task is 33 | [open](https://competitions.codalab.org/competitions/19650). 34 | 35 | ## Dates 36 | 37 | []() | []() 38 | ---- | ----- 39 | **August 18, 2018** | Submission deadline (23:59 PST) 40 | September 2, 2018 | Challenge winners notified 41 | September 8, 2018 | Winners present at ECCV 2018 Workshop 42 | 43 | ## Organizers 44 | 45 | Riza Alp Güler (INRIA, CentraleSupélec) 46 | 47 | Natalia Neverova (Facebook AI Research) 48 | 49 | Iasonas Kokkinos (Facebook AI Research) 50 | 51 | ## Task Guidelines 52 | 53 | Participants are recommended but not restricted to train 54 | their algorithms on PoseTrack DensePose train and val sets. 55 | The [download](https://posetrack.net/users/download.php) page has 56 | links to the image data. When participating in this task, 57 | please specify any and all external data used for training 58 | in the "method description" when uploading results to the 59 | evaluation server. **Listing external data used is mandatory.** 60 | We emphasize that any form of **annotation or use of the test sets 61 | for supervised or unsupervised training is strictly forbidden**. 62 | A more thorough explanation of all these 63 | details is available on the 64 | [upload](upload.md) page, 65 | please be sure to review it carefully prior to participating. 66 | Results in the [correct format](results_format.md) must be 67 | [uploaded](upload.md) to the 68 | [evaluation server](https://competitions.codalab.org/competitions/19650). 69 | The [evaluation](evaluation.md) page lists detailed information 70 | regarding how results will be evaluated. Challenge participants 71 | with the most successful and innovative methods will be invited 72 | to present at the workshop. 73 | 74 | ## Tools and Instructions 75 | 76 | We provide extensive API support for the images, annotations, 77 | and evaluation code. To download the COCO DensePose API, 78 | please visit our 79 | [GitHub repository](https://github.com/facebookresearch/DensePose/). 80 | Due to the complexity of this task, the process of participating 81 | may not seem simple. To help, we provide explanations and 82 | instructions for each step of the process: 83 | [download](https://posetrack.net/users/download.php), 84 | [data format](data_format.md), 85 | [results format](results_format.md), 86 | [upload](upload.md) and [evaluation](evaluation.md) pages. 87 | 88 | -------------------------------------------------------------------------------- /eval/challenge/2018_PoseTrack_DensePose/results_format.md: -------------------------------------------------------------------------------- 1 | # Results Format 2 | 3 | This page describes the results format used by PoseTrack DensePose evaluation 4 | procedure. The results format mimics the annotation format detailed on 5 | the [data format](data_format.md) page. Please review the annotation 6 | format before proceeding. 7 | 8 | Each algorithmically generated result is stored separately in its own 9 | result struct. This singleton result struct must contain the id of the 10 | image from which the result was generated (a single image will typically 11 | have multiple associated results). Results for the whole dataset are 12 | aggregated in a single array. Finally, this entire result struct array 13 | is stored to disk as a single JSON file (saved via 14 | [gason](https://github.com/cocodataset/cocoapi/blob/master/MatlabAPI/gason.m) 15 | in Matlab or [json.dump](https://docs.python.org/2/library/json.html) in Python). 16 | 17 | Example result JSON files are available in 18 | [example results](example_results.json). 19 | 20 | The data struct for each of the result types is described below. The format 21 | of the individual fields below (`category_id`, `bbox`, etc.) is the same as 22 | for the annotation (for details see the [data format](data_format.md) page). 23 | Bounding box coordinates `bbox` are floats measured from the top left image 24 | corner (and are 0-indexed). We recommend rounding coordinates to the nearest 25 | tenth of a pixel to reduce the resulting JSON file size. The dense estimates 26 | of patch indices and coordinates in the UV space for the specified bounding 27 | box are stored in `uv_shape` and `uv_data` fields. 28 | `uv_shape` contains the shape of `uv_data` array, it should be of size 29 | `(3, height, width)`, where `height` and `width` should match the bounding box 30 | size. `uv_data` should contain PNG-compressed patch indices and U and V 31 | coordinates scaled to the range `0-255`. 32 | 33 | An example of code that generates results in the form of a `pkl` file can 34 | be found in 35 | [json_dataset_evaluator.py](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/json_dataset_evaluator.py). 36 | We also provide an [example script](../encode_results_for_competition.py) to convert 37 | DensePose estimation results stored in a `pkl` file into a PNG-compressed 38 | JSON file. 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /eval/challenge/2018_PoseTrack_DensePose/upload.md: -------------------------------------------------------------------------------- 1 | # Upload Results to Evaluation Server 2 | 3 | This page describes the upload instructions for submitting results to the 4 | evaluation servers for the PoseTrack DensePose challenge. Submitting results allows 5 | you to participate in the challenges and compare results to the 6 | state-of-the-art on the public leaderboards. Note that you can obtain results 7 | on val by running the 8 | [evaluation code](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/densepose_cocoeval.py) 9 | locally. One can also take advantage of the 10 | [vkhalidov/densepose-codalab](https://hub.docker.com/r/vkhalidov/densepose-codalab/) 11 | docker image which was tailored specifically for evaluation. 12 | Submitting to the evaluation server provides results on the val and 13 | test sets. We now give detailed instructions for submitting to the evaluation 14 | server: 15 | 16 | 1. Create an account on CodaLab. This will allow you to participate in 17 | PoseTrack DensePose challenge. 18 | 19 | 2. Carefully review the [guidelines](readme.md) for 20 | entering the PoseTrack DensePose challenge and using the test sets. 21 | We emphasize that any form of **annotation or use of the test sets 22 | for supervised or unsupervised training is strictly forbidden**. 23 | 24 | 3. Prepare a JSON file containing your results in the correct 25 | [results format](results_format.md). 26 | 27 | 4. File naming: the JSON file should be named `posetrack_[subset]_[alg]_results.json`. 28 | Replace `[subset]` with the subset you are using (`val` or `test`), 29 | and `[alg]` with your algorithm name. Finally, place the JSON 30 | file into a zip file named `posetrack_[subset]_[alg]_results.zip`. 31 | 32 | 5. To submit your zipped result file to the PoseTrack DensePose Challenge, click on 33 | the “Participate” tab on the 34 | [CodaLab evaluation server](https://competitions.codalab.org/competitions/19650) page. 35 | When you select “Submit / View Results” on the left panel, you will be able to choose 36 | the subset. Please fill in the required fields and click “Submit”. A pop-up will 37 | prompt you to select the results zip file for upload. After the file is uploaded 38 | the evaluation server will begin processing. To view the status of your submission 39 | please select “Refresh Status”. Please be patient, the evaluation may take quite 40 | some time to complete (from ~20m to a few hours). If the status of your submission 41 | is “Failed” please check your file is named correctly and has the right format. 42 | 43 | 6. Please enter submission information into Codalab. The most important fields 44 | are "Team name", "Method description", and "Publication URL", which are used 45 | to populate the leaderboard. Additionally, under "user setting" in the 46 | upper right, please add "Team members". There have been issues with the 47 | "Method Description", we may collect these via email if necessary. These 48 | settings are not intuitive, but we have no control of the Codalab website. 49 | For the "Method description" we encourage participants to give detailed 50 | method information that will help 51 | the award committee invite participants with the most innovative methods. 52 | **Listing external data used is mandatory.** You may also consider giving some 53 | basic performance breakdowns on test subset (e.g., single model versus 54 | ensemble results), runtime, or any other information you think may be pertinent 55 | to highlight the novelty or efficacy of your method. 56 | 57 | 7. After you submit your results to the test eval server, you can control 58 | whether your results are publicly posted to the CodaLab leaderboard. To toggle 59 | the public visibility of your results please select either “post to leaderboard” 60 | or “remove from leaderboard”. Only one result can be published to the leaderboard 61 | at any time. 62 | 63 | 8. After evaluation is complete and the server shows a status of “Finished”, 64 | you will have the option to download your evaluation results by selecting 65 | “Download evaluation output from scoring step.” The zip file will contain the 66 | score file `scores.txt`. 67 | 68 | -------------------------------------------------------------------------------- /eval/challenge/2019_COCO_DensePose/data_format.md: -------------------------------------------------------------------------------- 1 | # Data Format 2 | 3 | The annotations are stored in [JSON](http://json.org/). Please note that 4 | [COCO API](https://github.com/cocodataset/cocoapi) described on the 5 | [download](http://cocodataset.org/#download) page can be used to access 6 | and manipulate all annotations. 7 | 8 | The annotations file structure is outlined below: 9 | ``` 10 | { 11 | "images" : [image], 12 | "annotations" : [annotation], 13 | "categories" : [category] 14 | } 15 | 16 | image { 17 | "coco_url" : str, 18 | "date_captured" : datetime, 19 | "file_name" : str, 20 | "flickr_url" : str, 21 | "id" : int, 22 | "width" : int, 23 | "height" : int, 24 | "license" : int 25 | } 26 | 27 | annotation { 28 | "area": float, 29 | "bbox": [x, y, width, height], 30 | "category_id": int, 31 | "dp_I": [float], 32 | "dp_U": [float], 33 | "dp_V": [float], 34 | "dp_masks": [dp_mask], 35 | "dp_x": [float], 36 | "dp_y": [float], 37 | "id": int, 38 | "image_id": int, 39 | "iscrowd": 0 or 1, 40 | "keypoints": [float], 41 | "segmentation": RLE or [polygon] 42 | } 43 | 44 | category { 45 | "id" : int, 46 | "name" : str, 47 | "supercategory" : str, 48 | "keypoints": [str], 49 | "skeleton": [edge] 50 | } 51 | 52 | dp_mask { 53 | "counts": str, 54 | "size": [int, int] 55 | } 56 | ``` 57 | 58 | Each dense pose annotation contains a series of fields, including the category 59 | id and segmentation mask of the person. The segmentation format depends on 60 | whether the instance represents a single object (`iscrowd=0` in which case 61 | polygons are used) or a collection of objects (`iscrowd=1` in which case RLE 62 | is used). Note that a single object (`iscrowd=0`) may require multiple polygons, 63 | for example if occluded. Crowd annotations (`iscrowd=1`) are used to label large 64 | groups of objects (e.g. a crowd of people). In addition, an enclosing bounding 65 | box is provided for each person (box coordinates are measured from the top left 66 | image corner and are 0-indexed). 67 | 68 | The categories field of the annotation structure stores the mapping of category 69 | id to category and supercategory names. It also has two fields: "keypoints", 70 | which is a length `k` array of keypoint names, and "skeleton", which defines 71 | connectivity via a list of keypoint edge pairs and is used for visualization. 72 | 73 | DensePose annotations are stored in `dp_*` fields: 74 | 75 | *Annotated masks*: 76 | 77 | * `dp_masks`: RLE encoded dense masks. All part masks are of size 256x256. 78 | They correspond to 14 semantically meaningful parts of the body: `Torso`, 79 | `Right Hand`, `Left Hand`, `Left Foot`, `Right Foot`, `Upper Leg Right`, 80 | `Upper Leg Left`, `Lower Leg Right`, `Lower Leg Left`, `Upper Arm Left`, 81 | `Upper Arm Right`, `Lower Arm Left`, `Lower Arm Right`, `Head`; 82 | 83 | *Annotated points*: 84 | 85 | * `dp_x`, `dp_y`: spatial coordinates of collected points on the image. 86 | The coordinates are scaled such that the bounding box size is 256x256; 87 | * `dp_I`: The patch index that indicates which of the 24 surface patches the 88 | point is on. Patches correspond to the body parts described above. Some 89 | body parts are split into 2 patches: `1, 2 = Torso`, `3 = Right Hand`, 90 | `4 = Left Hand`, `5 = Left Foot`, `6 = Right Foot`, `7, 9 = Upper Leg Right`, 91 | `8, 10 = Upper Leg Left`, `11, 13 = Lower Leg Right`, `12, 14 = Lower Leg Left`, 92 | `15, 17 = Upper Arm Left`, `16, 18 = Upper Arm Right`, `19, 21 = Lower Arm Left`, 93 | `20, 22 = Lower Arm Right`, `23, 24 = Head`; 94 | * `dp_U`, `dp_V`: Coordinates in the UV space. Each surface patch has a 95 | separate 2D parameterization. 96 | 97 | -------------------------------------------------------------------------------- /eval/challenge/2019_COCO_DensePose/readme.md: -------------------------------------------------------------------------------- 1 | # COCO 2019 DensePose Task 2 | 3 | ![DensePose Splash Image](http://cocodataset.org/images/densepose-splash.png) 4 | 5 | ## Overview 6 | 7 | The COCO DensePose Task requires dense estimation of human pose in challenging, 8 | uncontrolled conditions. The DensePose task involves simultaneously detecting 9 | people, segmenting their bodies and mapping all image pixels that belong to a 10 | human body to the 3D surface of the body. For full details of this task please 11 | see the [DensePose evaluation](evaluation.md) page. 12 | 13 | This task is part of the 14 | [COCO+Mapillary Joint Recognition Challenge Workshop](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html) 15 | at ICCV 2019. For further details about the joint workshop, as well as **new rules regarding technical reports and awards**, please 16 | visit the workshop page. 17 | Please also see the related COCO 18 | [detection](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html#coco-detection), 19 | [panoptic](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html#coco-panoptic) 20 | and 21 | [keypoints](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html#coco-keypoints) 22 | tasks. 23 | 24 | The COCO train, validation, and test sets, containing more than 39,000 images 25 | and 56,000 person instances labeled with DensePose annotations are available 26 | for [download](http://cocodataset.org/#download). 27 | Annotations on train ( 28 | [train 1](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_train.json), 29 | [train 2](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_valminusminival.json) 30 | ) and [val](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_minival.json) 31 | with over 48,000 people are publicly available. 32 | [Test set](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_test.json) 33 | with the list of images is also available for download. 34 | 35 | Evaluation server for the 2019 task is 36 | [open](https://competitions.codalab.org/competitions/20660). 37 | 38 | ## Dates 39 | 40 | []() | []() 41 | ---- | ----- 42 | **October 4, 2019** | Submission deadline (23:59 PST) 43 | October 11, 2019 | Technical report submission deadline 44 | October 18, 2019 | Challenge winners notified 45 | October 27, 2019 | Winners present at ICCV 2019 Workshop 46 | 47 | ## Organizers 48 | 49 | Vasil Khalidov (Facebook AI Research) 50 | 51 | Natalia Neverova (Facebook AI Research) 52 | 53 | Riza Alp Güler (Imperial College London / Ariel AI) 54 | 55 | Iasonas Kokkinos (UCL / Ariel AI) 56 | 57 | ## Task Guidelines 58 | 59 | Participants are recommended but not restricted to train 60 | their algorithms on COCO DensePose train and val sets. 61 | The [download](http://cocodataset.org/#download) page has 62 | links to all COCO data. When participating in this task, 63 | please specify any and all external data used for training 64 | in the "method description" when uploading results to the 65 | evaluation server. A more thorough explanation of all these 66 | details is available on the 67 | [guidelines](http://cocodataset.org/#guidelines) page, 68 | please be sure to review it carefully prior to participating. 69 | Results in the [correct format](results_format.md) must be 70 | [uploaded](upload.md) to the 71 | [evaluation server](https://competitions.codalab.org/competitions/20660). 72 | The [evaluation](evaluation.md) page lists detailed information 73 | regarding how results will be evaluated. Challenge participants 74 | with the most successful and innovative methods will be invited 75 | to present at the workshop. 76 | 77 | ## Tools and Instructions 78 | 79 | We provide extensive API support for the COCO images, 80 | annotations, and evaluation code. To download the COCO DensePose API, 81 | please visit our 82 | [GitHub repository](https://github.com/facebookresearch/DensePose/). 83 | Due to the large size of COCO and the complexity of this task, 84 | the process of participating may not seem simple. To help, we provide 85 | explanations and instructions for each step of the process: 86 | [download](http://cocodataset.org/#download), 87 | [data format](data_format.md), 88 | [results format](results_format.md), 89 | [upload](upload.md) and [evaluation](evaluation.md) pages. 90 | For additional questions, please contact vkhalidov@fb.com and nneverova@fb.com. 91 | 92 | -------------------------------------------------------------------------------- /eval/challenge/2019_COCO_DensePose/results_format.md: -------------------------------------------------------------------------------- 1 | # Results Format 2 | 3 | This page describes the results format used by COCO DensePose evaluation 4 | procedure. The results format mimics the annotation format detailed on 5 | the [data format](data_format.md) page. Please review the annotation 6 | format before proceeding. 7 | 8 | Each algorithmically generated result is stored separately in its own 9 | result struct. This singleton result struct must contain the id of the 10 | image from which the result was generated (a single image will typically 11 | have multiple associated results). Results for the whole dataset are 12 | aggregated in a single array. Finally, this entire result struct array 13 | is stored to disk as a single JSON file (saved via 14 | [gason](https://github.com/cocodataset/cocoapi/blob/master/MatlabAPI/gason.m) 15 | in Matlab or [json.dump](https://docs.python.org/2/library/json.html) in Python). 16 | 17 | Example result JSON files are available in 18 | [example results](example_results.json). 19 | 20 | The data struct for each of the result types is described below. The format 21 | of the individual fields below (`category_id`, `bbox`, etc.) is the same as 22 | for the annotation (for details see the [data format](data_format.md) page). 23 | Bounding box coordinates `bbox` are floats measured from the top left image 24 | corner (and are 0-indexed). We recommend rounding coordinates to the nearest 25 | tenth of a pixel to reduce the resulting JSON file size. The dense estimates 26 | of patch indices and coordinates in the UV space for the specified bounding 27 | box are stored in `uv_shape` and `uv_data` fields. 28 | `uv_shape` contains the shape of `uv_data` array, it should be of size 29 | `(3, height, width)`, where `height` and `width` should match the bounding box 30 | size. `uv_data` should contain PNG-compressed patch indices and U and V 31 | coordinates scaled to the range `0-255`. 32 | 33 | An example of code that generates results in the form of a `pkl` file can 34 | be found in 35 | [json_dataset_evaluator.py](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/json_dataset_evaluator.py). 36 | We also provide an [example script](../encode_results_for_competition.py) to convert 37 | dense pose estimation results stored in a `pkl` file into a PNG-compressed 38 | JSON file. 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /eval/challenge/2019_COCO_DensePose/upload.md: -------------------------------------------------------------------------------- 1 | # Upload Results to Evaluation Server 2 | 3 | This page describes the upload instructions for submitting results to the 4 | evaluation servers for the COCO DensePose challenge. Submitting results allows 5 | you to participate in the challenges and compare results to the 6 | state-of-the-art on the public leaderboards. Note that you can obtain results 7 | on val by running the 8 | [evaluation code](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/densepose_cocoeval.py) 9 | locally. One can also take advantage of the 10 | [vkhalidov/densepose-codalab](https://hub.docker.com/r/vkhalidov/densepose-codalab/) 11 | docker image which was tailored specifically for evaluation. 12 | Submitting to the evaluation server provides results on the val and 13 | test sets. We now give detailed instructions for submitting to the evaluation 14 | server: 15 | 16 | 1. Create an account on CodaLab. This will allow you to participate in all COCO challenges. 17 | 18 | 2. Carefully review the [guidelines](http://cocodataset.org/#guidelines) for 19 | entering the COCO challenges and using the test sets. 20 | 21 | 3. Prepare a JSON file containing your results in the correct 22 | [results format](results_format.md) for the challenge you wish to enter. 23 | 24 | 4. File naming: the JSON file should be named `densepose_[subset]_[alg]_results.json`. 25 | Replace `[subset]` with the subset you are using (`val` or `test`), 26 | and `[alg]` with your algorithm name. Finally, place the JSON 27 | file into a zip file named `densepose_[subset]_[alg]_results.zip`. 28 | 29 | 5. To submit your zipped result file to the COCO DensePose Challenge, click on 30 | the “Participate” tab on the 31 | [CodaLab evaluation server](https://competitions.codalab.org/competitions/20660) page. 32 | When you select “Submit / View Results” on the left panel, you will be able to choose 33 | the subset. Please fill in the required fields and click “Submit”. A pop-up will 34 | prompt you to select the results zip file for upload. After the file is uploaded 35 | the evaluation server will begin processing. To view the status of your submission 36 | please select “Refresh Status”. Please be patient, the evaluation may take quite 37 | some time to complete (from ~20m to a few hours). If the status of your submission 38 | is “Failed” please check your file is named correctly and has the right format. 39 | 40 | 6. Please enter submission information into Codalab. The most important fields 41 | are "Team name", "Method description", and "Publication URL", which are used 42 | to populate the COCO leaderboard. Additionally, under "user setting" in the 43 | upper right, please add "Team members". There have been issues with the 44 | "Method Description", we may collect these via email if necessary. These 45 | settings are not intuitive, but we have no control of the Codalab website. 46 | For the "Method description", especially for COCO DensePose challenge entries, 47 | we encourage participants to give detailed method information that will help 48 | the award committee invite participants with the most innovative methods. 49 | Listing external data used is mandatory. You may also consider giving some 50 | basic performance breakdowns on test subset (e.g., single model versus 51 | ensemble results), runtime, or any other information you think may be pertinent 52 | to highlight the novelty or efficacy of your method. 53 | 54 | 7. After you submit your results to the test-dev eval server, you can control 55 | whether your results are publicly posted to the CodaLab leaderboard. To toggle 56 | the public visibility of your results please select either “post to leaderboard” 57 | or “remove from leaderboard”. Only one result can be published to the leaderboard 58 | at any time. 59 | 60 | 8. After evaluation is complete and the server shows a status of “Finished”, 61 | you will have the option to download your evaluation results by selecting 62 | “Download evaluation output from scoring step.” The zip file will contain the 63 | score file `scores.txt`. 64 | 65 | -------------------------------------------------------------------------------- /eval/challenge/encode_results_for_competition.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | """encode_results.py: script to encode dense human pose estimation results 4 | in DensePose format into a packed representation using PNG compression. 5 | """ 6 | 7 | __author__ = "Vasil Khalidov" 8 | __copyright__ = "Copyright (c) 2018-present, Facebook, Inc." 9 | 10 | import os 11 | import sys 12 | import pickle 13 | import copy 14 | import json 15 | import time 16 | import argparse 17 | import numpy as np 18 | 19 | kPositiveAnswers = ['y', 'Y'] 20 | kNegativeAnswers = ['n', 'N'] 21 | kAnswers = kPositiveAnswers + kNegativeAnswers 22 | 23 | def _parseArguments(): 24 | parser = argparse.ArgumentParser() 25 | parser.add_argument('inPklResultsFile', help='Input pickle file with' 26 | ' dense human pose estimation results') 27 | parser.add_argument('outJsonPackedFile', help='Output JSON file with' 28 | ' packed dense human pose estimation results, which can be' 29 | ' used for submission') 30 | args = parser.parse_args() 31 | return args 32 | 33 | def _encodePngData(arr): 34 | """ 35 | Encode array data as a PNG image using the highest compression rate 36 | @param arr [in] Data stored in an array of size (3, M, N) of type uint8 37 | @return Base64-encoded string containing PNG-compressed data 38 | """ 39 | from PIL import Image 40 | import StringIO 41 | assert len(arr.shape) == 3, "Expected a 3D array as an input," \ 42 | " got a {0}D array".format(len(arr.shape)) 43 | assert arr.shape[0] == 3, "Expected first array dimension of size 3," \ 44 | " got {0}".format(arr.shape[0]) 45 | assert arr.dtype == np.uint8, "Expected an array of type np.uint8, " \ 46 | " got {0}".format(arr.dtype) 47 | data = np.moveaxis(arr, 0, -1) 48 | im = Image.fromarray(data) 49 | fStream = StringIO.StringIO() 50 | im.save(fStream, format='png', optimize=True) 51 | s = fStream.getvalue() 52 | return s.encode('base64') 53 | 54 | def _statusStr(i, dataLen): 55 | kProgressWidth = 20 56 | kProgressTemplate = '[{0}] {1: 4d}%' 57 | progressVisNDone = min(max(0, i * kProgressWidth // dataLen), 58 | kProgressWidth) 59 | progressVisNTodo = kProgressWidth - progressVisNDone 60 | progressVis = '*' * progressVisNDone + ' ' * progressVisNTodo 61 | progressNum = i * 100 // dataLen 62 | progressStr = kProgressTemplate.format(progressVis, progressNum) 63 | return progressStr 64 | 65 | def _savePngJson(hInPklResultsFile, hOutJsonPackedFile): 66 | from PIL import Image 67 | import StringIO 68 | dataFPickle = pickle.load(hInPklResultsFile) 69 | statusStr = '' 70 | dataLen = len(dataFPickle) 71 | for i, x in enumerate(dataFPickle): 72 | x['uv_shape'] = x['uv'].shape 73 | x['uv_data'] = _encodePngData(x['uv']) 74 | del x['uv'] 75 | sys.stdout.write('\b' * len(statusStr)) 76 | statusStr = _statusStr(i, dataLen) 77 | sys.stdout.write(statusStr) 78 | sys.stdout.write('\n') 79 | json.dump(dataFPickle, hOutJsonPackedFile, ensure_ascii=False, 80 | sort_keys=True, indent=4) 81 | 82 | def main(): 83 | args = _parseArguments() 84 | if os.path.exists(args.outJsonPackedFile): 85 | answer = '' 86 | while not answer in kAnswers: 87 | answer = raw_input('File "{0}" already exists, overwrite? [y/n] ' 88 | .format(args.outJsonPackedFile)) 89 | if answer in kNegativeAnswers: 90 | sys.exit(1) 91 | 92 | with open(args.inPklResultsFile, 'rb') as hIn, \ 93 | open(args.outJsonPackedFile, 'w') as hOut: 94 | print('Encoding png: {0}'.format(args.outJsonPackedFile)) 95 | start = time.clock() 96 | _savePngJson(hIn, hOut) 97 | end = time.clock() 98 | print('Finished encoding png, time {0}s'.format(end - start)) 99 | 100 | if __name__ == "__main__": 101 | main() 102 | -------------------------------------------------------------------------------- /eval/cmake/Summary.cmake: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/caffe2/caffe2/blob/master/cmake/Summary.cmake 2 | 3 | # Prints configuration summary. 4 | function (detectron_print_config_summary) 5 | message(STATUS "Summary:") 6 | message(STATUS " CMake version : ${CMAKE_VERSION}") 7 | message(STATUS " CMake command : ${CMAKE_COMMAND}") 8 | message(STATUS " System name : ${CMAKE_SYSTEM_NAME}") 9 | message(STATUS " C++ compiler : ${CMAKE_CXX_COMPILER}") 10 | message(STATUS " C++ compiler version : ${CMAKE_CXX_COMPILER_VERSION}") 11 | message(STATUS " CXX flags : ${CMAKE_CXX_FLAGS}") 12 | message(STATUS " Caffe2 version : ${CAFFE2_VERSION}") 13 | message(STATUS " Caffe2 include path : ${CAFFE2_INCLUDE_DIRS}") 14 | if (CAFFE2_USE_CUDA OR CAFFE2_FOUND_CUDA) 15 | message(STATUS " Caffe2 found CUDA : True") 16 | message(STATUS " CUDA version : ${CUDA_VERSION}") 17 | message(STATUS " CuDNN version : ${CUDNN_VERSION}") 18 | else() 19 | message(STATUS " Caffe2 found CUDA : False") 20 | endif() 21 | endfunction() 22 | -------------------------------------------------------------------------------- /eval/cmake/legacy/Dependencies.cmake: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/caffe2/caffe2/blob/master/cmake/Dependencies.cmake 2 | 3 | # Find CUDA. 4 | include(cmake/legacy/Cuda.cmake) 5 | if (HAVE_CUDA) 6 | # CUDA 9.x requires GCC version <= 6 7 | if ((CUDA_VERSION VERSION_EQUAL 9.0) OR 8 | (CUDA_VERSION VERSION_GREATER 9.0 AND CUDA_VERSION VERSION_LESS 10.0)) 9 | if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND 10 | NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0 AND 11 | CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER) 12 | message(FATAL_ERROR 13 | "CUDA ${CUDA_VERSION} is not compatible with GCC version >= 7. " 14 | "Use the following option to use another version (for example): \n" 15 | " -DCUDA_HOST_COMPILER=/usr/bin/gcc-6\n") 16 | endif() 17 | # CUDA 8.0 requires GCC version <= 5 18 | elseif (CUDA_VERSION VERSION_EQUAL 8.0) 19 | if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND 20 | NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0 AND 21 | CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER) 22 | message(FATAL_ERROR 23 | "CUDA 8.0 is not compatible with GCC version >= 6. " 24 | "Use the following option to use another version (for example): \n" 25 | " -DCUDA_HOST_COMPILER=/usr/bin/gcc-5\n") 26 | endif() 27 | endif() 28 | endif() 29 | 30 | # Find CUDNN. 31 | if (HAVE_CUDA) 32 | find_package(CuDNN REQUIRED) 33 | if (CUDNN_FOUND) 34 | caffe2_include_directories(${CUDNN_INCLUDE_DIRS}) 35 | endif() 36 | endif() 37 | -------------------------------------------------------------------------------- /eval/cmake/legacy/Modules/FindCuDNN.cmake: -------------------------------------------------------------------------------- 1 | # Copied from https://github.com/caffe2/caffe2/blob/master/cmake/Modules/FindCuDNN.cmake 2 | 3 | # - Try to find cuDNN 4 | # 5 | # The following variables are optionally searched for defaults 6 | # CUDNN_ROOT_DIR: Base directory where all cuDNN components are found 7 | # 8 | # The following are set after configuration is done: 9 | # CUDNN_FOUND 10 | # CUDNN_INCLUDE_DIRS 11 | # CUDNN_LIBRARIES 12 | # CUDNN_LIBRARY_DIRS 13 | 14 | include(FindPackageHandleStandardArgs) 15 | 16 | set(CUDNN_ROOT_DIR "" CACHE PATH "Folder contains NVIDIA cuDNN") 17 | 18 | find_path(CUDNN_INCLUDE_DIR cudnn.h 19 | HINTS ${CUDNN_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR} 20 | PATH_SUFFIXES cuda/include include) 21 | 22 | find_library(CUDNN_LIBRARY cudnn 23 | HINTS ${CUDNN_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR} 24 | PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64) 25 | 26 | find_package_handle_standard_args( 27 | CUDNN DEFAULT_MSG CUDNN_INCLUDE_DIR CUDNN_LIBRARY) 28 | 29 | if(CUDNN_FOUND) 30 | # get cuDNN version 31 | file(READ ${CUDNN_INCLUDE_DIR}/cudnn.h CUDNN_HEADER_CONTENTS) 32 | string(REGEX MATCH "define CUDNN_MAJOR * +([0-9]+)" 33 | CUDNN_VERSION_MAJOR "${CUDNN_HEADER_CONTENTS}") 34 | string(REGEX REPLACE "define CUDNN_MAJOR * +([0-9]+)" "\\1" 35 | CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR}") 36 | string(REGEX MATCH "define CUDNN_MINOR * +([0-9]+)" 37 | CUDNN_VERSION_MINOR "${CUDNN_HEADER_CONTENTS}") 38 | string(REGEX REPLACE "define CUDNN_MINOR * +([0-9]+)" "\\1" 39 | CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR}") 40 | string(REGEX MATCH "define CUDNN_PATCHLEVEL * +([0-9]+)" 41 | CUDNN_VERSION_PATCH "${CUDNN_HEADER_CONTENTS}") 42 | string(REGEX REPLACE "define CUDNN_PATCHLEVEL * +([0-9]+)" "\\1" 43 | CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH}") 44 | # Assemble cuDNN version 45 | if(NOT CUDNN_VERSION_MAJOR) 46 | set(CUDNN_VERSION "?") 47 | else() 48 | set(CUDNN_VERSION "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}") 49 | endif() 50 | 51 | set(CUDNN_INCLUDE_DIRS ${CUDNN_INCLUDE_DIR}) 52 | set(CUDNN_LIBRARIES ${CUDNN_LIBRARY}) 53 | message(STATUS "Found cuDNN: v${CUDNN_VERSION} (include: ${CUDNN_INCLUDE_DIR}, library: ${CUDNN_LIBRARY})") 54 | mark_as_advanced(CUDNN_ROOT_DIR CUDNN_LIBRARY CUDNN_INCLUDE_DIR) 55 | endif() 56 | -------------------------------------------------------------------------------- /eval/cmake/legacy/Summary.cmake: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/caffe2/caffe2/blob/master/cmake/Summary.cmake 2 | 3 | # Prints configuration summary. 4 | function (detectron_print_config_summary) 5 | message(STATUS "Summary:") 6 | message(STATUS " CMake version : ${CMAKE_VERSION}") 7 | message(STATUS " CMake command : ${CMAKE_COMMAND}") 8 | message(STATUS " System name : ${CMAKE_SYSTEM_NAME}") 9 | message(STATUS " C++ compiler : ${CMAKE_CXX_COMPILER}") 10 | message(STATUS " C++ compiler version : ${CMAKE_CXX_COMPILER_VERSION}") 11 | message(STATUS " CXX flags : ${CMAKE_CXX_FLAGS}") 12 | message(STATUS " Caffe2 version : ${CAFFE2_VERSION}") 13 | message(STATUS " Caffe2 include path : ${CAFFE2_INCLUDE_DIRS}") 14 | message(STATUS " Have CUDA : ${HAVE_CUDA}") 15 | if (${HAVE_CUDA}) 16 | message(STATUS " CUDA version : ${CUDA_VERSION}") 17 | message(STATUS " CuDNN version : ${CUDNN_VERSION}") 18 | endif() 19 | endfunction() 20 | -------------------------------------------------------------------------------- /eval/cmake/legacy/legacymake.cmake: -------------------------------------------------------------------------------- 1 | # This file contains legacy cmake scripts that is going to be removed 2 | # in a future release. 3 | 4 | # Add CMake modules. 5 | list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/legacy/Modules) 6 | 7 | # Add compiler flags. 8 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -fPIC -Wno-narrowing") 10 | 11 | # Include Caffe2 CMake utils. 12 | include(cmake/legacy/Utils.cmake) 13 | 14 | # Find dependencies. 15 | include(cmake/legacy/Dependencies.cmake) 16 | 17 | # Print configuration summary. 18 | include(cmake/legacy/Summary.cmake) 19 | detectron_print_config_summary() 20 | 21 | # Collect custom ops sources. 22 | file(GLOB CUSTOM_OPS_CPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cc) 23 | file(GLOB CUSTOM_OPS_GPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cu) 24 | 25 | # Install custom CPU ops lib. 26 | add_library( 27 | caffe2_detectron_custom_ops SHARED 28 | ${CUSTOM_OPS_CPU_SRCS}) 29 | 30 | target_include_directories( 31 | caffe2_detectron_custom_ops PRIVATE 32 | ${CAFFE2_INCLUDE_DIRS}) 33 | target_link_libraries(caffe2_detectron_custom_ops caffe2) 34 | install(TARGETS caffe2_detectron_custom_ops DESTINATION lib) 35 | 36 | # Install custom GPU ops lib. 37 | if (${HAVE_CUDA}) 38 | # Additional -I prefix is required for CMake versions before commit (< 3.7): 39 | # https://github.com/Kitware/CMake/commit/7ded655f7ba82ea72a82d0555449f2df5ef38594 40 | list(APPEND CUDA_INCLUDE_DIRS -I${CAFFE2_INCLUDE_DIRS}) 41 | CUDA_ADD_LIBRARY( 42 | caffe2_detectron_custom_ops_gpu SHARED 43 | ${CUSTOM_OPS_CPU_SRCS} 44 | ${CUSTOM_OPS_GPU_SRCS}) 45 | 46 | target_link_libraries(caffe2_detectron_custom_ops_gpu caffe2_gpu) 47 | install(TARGETS caffe2_detectron_custom_ops_gpu DESTINATION lib) 48 | endif() 49 | -------------------------------------------------------------------------------- /eval/configs/DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | MASK_ON: True 8 | KEYPOINTS_ON: True 9 | NUM_GPUS: 8 10 | SOLVER: 11 | WEIGHT_DECAY: 0.0001 12 | LR_POLICY: steps_with_decay 13 | GAMMA: 0.1 14 | WARM_UP_ITERS: 3000 15 | WARM_UP_FACTOR: 0.0000001 16 | # Linear scaling rule: 17 | # 1 GPU: 18 | # BASE_LR: 0.00025 19 | # MAX_ITER: 720000 20 | # STEPS: [0, 480000, 640000] 21 | # 2 GPUs: 22 | # BASE_LR: 0.0005 23 | # MAX_ITER: 360000 24 | # STEPS: [0, 240000, 320000] 25 | # 4 GPUs: 26 | # BASE_LR: 0.001 27 | # MAX_ITER: 180000 28 | # STEPS: [0, 120000, 160000] 29 | #8 GPUs: 30 | BASE_LR: 0.002 31 | MAX_ITER: 230000 32 | STEPS: [0, 150000, 200000] 33 | FPN: 34 | FPN_ON: True 35 | MULTILEVEL_ROIS: True 36 | MULTILEVEL_RPN: True 37 | FAST_RCNN: 38 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 39 | ROI_XFORM_METHOD: RoIAlign 40 | ROI_XFORM_RESOLUTION: 14 41 | ROI_XFORM_SAMPLING_RATIO: 2 42 | BODY_UV_RCNN: 43 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 44 | NUM_STACKED_CONVS: 8 45 | NUM_PATCHES: 24 46 | USE_DECONV_OUTPUT: True 47 | CONV_INIT: MSRAFill 48 | CONV_HEAD_DIM: 512 49 | UP_SCALE: 2 50 | HEATMAP_SIZE: 56 51 | ROI_XFORM_METHOD: RoIAlign 52 | ROI_XFORM_RESOLUTION: 14 53 | ROI_XFORM_SAMPLING_RATIO: 2 54 | ## 55 | # Loss weights for annotation masks.(14 Parts) 56 | INDEX_WEIGHTS : 2.0 57 | # Loss weights for surface parts. (24 Parts) 58 | PART_WEIGHTS : 0.3 59 | # Loss weights for UV regression. 60 | POINT_REGRESSION_WEIGHTS : 0.1 61 | ## 62 | BODY_UV_IMS: True 63 | MRCNN: 64 | ROI_MASK_HEAD: mask_rcnn_heads.mask_rcnn_fcn_head_v1up4convs 65 | RESOLUTION: 28 66 | ROI_XFORM_METHOD: RoIAlign 67 | ROI_XFORM_RESOLUTION: 14 68 | ROI_XFORM_SAMPLING_RATIO: 2 # default 0 69 | DILATION: 1 # default 2 70 | CONV_INIT: MSRAFill # default: GaussianFill 71 | KRCNN: 72 | ROI_KEYPOINTS_HEAD: keypoint_rcnn_heads.add_roi_pose_head_v1convX 73 | NUM_STACKED_CONVS: 8 74 | NUM_KEYPOINTS: 17 75 | USE_DECONV_OUTPUT: True 76 | CONV_INIT: MSRAFill 77 | CONV_HEAD_DIM: 512 78 | UP_SCALE: 2 79 | HEATMAP_SIZE: 56 # ROI_XFORM_RESOLUTION (14) * UP_SCALE (2) * USE_DECONV_OUTPUT (2) 80 | ROI_XFORM_METHOD: RoIAlign 81 | ROI_XFORM_RESOLUTION: 14 82 | ROI_XFORM_SAMPLING_RATIO: 2 83 | KEYPOINT_CONFIDENCE: bbox 84 | TRAIN: 85 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 86 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 87 | SCALES: (640, 672, 704, 736, 768, 800) 88 | MAX_SIZE: 1333 89 | IMS_PER_BATCH: 1 90 | BATCH_SIZE_PER_IM: 512 91 | USE_FLIPPED: True 92 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 93 | TEST: 94 | DATASETS: ('dense_coco_2014_minival',) 95 | PROPOSAL_LIMIT: 1000 96 | SCALE: 800 97 | MAX_SIZE: 1333 98 | NMS: 0.5 99 | FORCE_JSON_DATASET_EVAL: True 100 | DETECTIONS_PER_IM: 20 101 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 102 | RPN_POST_NMS_TOP_N: 1000 103 | OUTPUT_DIR: '' 104 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet101_FPN.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 90000 29 | STEPS: [0, 60000, 80000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('dense_coco_2014_train.pkl','dense_coco_2014_valminusminival.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('dense_coco_2014_minival.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet101_FPN_32x8d_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | 36 | RESNETS: 37 | STRIDE_1X1: False # default True for MSRA; False for C2 or Torch models 38 | TRANS_FUNC: bottleneck_transformation 39 | NUM_GROUPS: 32 40 | WIDTH_PER_GROUP: 8 41 | 42 | FAST_RCNN: 43 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 44 | ROI_XFORM_METHOD: RoIAlign 45 | ROI_XFORM_RESOLUTION: 7 46 | ROI_XFORM_SAMPLING_RATIO: 2 47 | BODY_UV_RCNN: 48 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 49 | NUM_STACKED_CONVS: 8 50 | NUM_PATCHES: 24 51 | USE_DECONV_OUTPUT: True 52 | CONV_INIT: MSRAFill 53 | CONV_HEAD_DIM: 512 54 | UP_SCALE: 2 55 | HEATMAP_SIZE: 56 56 | ROI_XFORM_METHOD: RoIAlign 57 | ROI_XFORM_RESOLUTION: 14 58 | ROI_XFORM_SAMPLING_RATIO: 2 59 | ## 60 | # Loss weights for annotation masks.(14 Parts) 61 | INDEX_WEIGHTS : 2.0 62 | # Loss weights for surface parts. (24 Parts) 63 | PART_WEIGHTS : 0.3 64 | # Loss weights for UV regression. 65 | POINT_REGRESSION_WEIGHTS : 0.1 66 | ## 67 | BODY_UV_IMS: True 68 | TRAIN: 69 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/20171220/X-101-32x8d.pkl 70 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 71 | SCALES: (640, 672, 704, 736, 768, 800) 72 | MAX_SIZE: 1333 73 | IMS_PER_BATCH: 3 74 | BATCH_SIZE_PER_IM: 512 75 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 76 | USE_FLIPPED: True 77 | TEST: 78 | DATASETS: ('dense_coco_2014_minival',) 79 | PROPOSAL_LIMIT: 1000 80 | SCALE: 800 81 | MAX_SIZE: 1333 82 | NMS: 0.5 83 | FORCE_JSON_DATASET_EVAL: True 84 | DETECTIONS_PER_IM: 20 85 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 86 | RPN_POST_NMS_TOP_N: 1000 87 | OUTPUT_DIR: '' 88 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet101_FPN_32x8d_s1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 130000 29 | STEPS: [0, 100000, 120000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | 35 | RESNETS: 36 | STRIDE_1X1: False # default True for MSRA; False for C2 or Torch models 37 | TRANS_FUNC: bottleneck_transformation 38 | NUM_GROUPS: 32 39 | WIDTH_PER_GROUP: 8 40 | 41 | FAST_RCNN: 42 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 43 | ROI_XFORM_METHOD: RoIAlign 44 | ROI_XFORM_RESOLUTION: 7 45 | ROI_XFORM_SAMPLING_RATIO: 2 46 | BODY_UV_RCNN: 47 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 48 | NUM_STACKED_CONVS: 8 49 | NUM_PATCHES: 24 50 | USE_DECONV_OUTPUT: True 51 | CONV_INIT: MSRAFill 52 | CONV_HEAD_DIM: 512 53 | UP_SCALE: 2 54 | HEATMAP_SIZE: 56 55 | ROI_XFORM_METHOD: RoIAlign 56 | ROI_XFORM_RESOLUTION: 14 57 | ROI_XFORM_SAMPLING_RATIO: 2 58 | ## 59 | # Loss weights for annotation masks.(14 Parts) 60 | INDEX_WEIGHTS : 2.0 61 | # Loss weights for surface parts. (24 Parts) 62 | PART_WEIGHTS : 0.3 63 | # Loss weights for UV regression. 64 | POINT_REGRESSION_WEIGHTS : 0.1 65 | ## 66 | BODY_UV_IMS: True 67 | TRAIN: 68 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/20171220/X-101-32x8d.pkl 69 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 70 | PROPOSAL_FILES: ('dense_coco_2014_train.pkl','dense_coco_2014_valminusminival.pkl') 71 | SCALES: (640, 672, 704, 736, 768, 800) 72 | MAX_SIZE: 1333 73 | IMS_PER_BATCH: 3 74 | BATCH_SIZE_PER_IM: 512 75 | USE_FLIPPED: True 76 | TEST: 77 | DATASETS: ('dense_coco_2014_minival',) 78 | PROPOSAL_FILES: ('dense_coco_2014_minival.pkl',) 79 | PROPOSAL_LIMIT: 1000 80 | SCALE: 800 81 | MAX_SIZE: 1333 82 | NMS: 0.5 83 | FORCE_JSON_DATASET_EVAL: True 84 | DETECTIONS_PER_IM: 20 85 | OUTPUT_DIR: '' 86 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet101_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | FAST_RCNN: 36 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 37 | ROI_XFORM_METHOD: RoIAlign 38 | ROI_XFORM_RESOLUTION: 7 39 | ROI_XFORM_SAMPLING_RATIO: 2 40 | BODY_UV_RCNN: 41 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 42 | NUM_STACKED_CONVS: 8 43 | NUM_PATCHES: 24 44 | USE_DECONV_OUTPUT: True 45 | CONV_INIT: MSRAFill 46 | CONV_HEAD_DIM: 512 47 | UP_SCALE: 2 48 | HEATMAP_SIZE: 56 49 | ROI_XFORM_METHOD: RoIAlign 50 | ROI_XFORM_RESOLUTION: 14 51 | ROI_XFORM_SAMPLING_RATIO: 2 52 | ## 53 | # Loss weights for annotation masks.(14 Parts) 54 | INDEX_WEIGHTS : 2.0 55 | # Loss weights for surface parts. (24 Parts) 56 | PART_WEIGHTS : 0.3 57 | # Loss weights for UV regression. 58 | POINT_REGRESSION_WEIGHTS : 0.1 59 | ## 60 | BODY_UV_IMS: True 61 | TRAIN: 62 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-101.pkl 63 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 69 | USE_FLIPPED: True 70 | TEST: 71 | DATASETS: ('dense_coco_2014_minival',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 79 | RPN_POST_NMS_TOP_N: 1000 80 | OUTPUT_DIR: '' 81 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet101_FPN_s1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 130000 29 | STEPS: [0, 100000, 120000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-101.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_fpn_resnet50.pkl','https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_fpn_resnet50.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_fpn_resnet50.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet50_FPN.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 90000 29 | STEPS: [0, 60000, 80000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('dense_coco_2014_train.pkl','dense_coco_2014_valminusminival.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('dense_coco_2014_minival.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet50_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | FAST_RCNN: 36 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 37 | ROI_XFORM_METHOD: RoIAlign 38 | ROI_XFORM_RESOLUTION: 7 39 | ROI_XFORM_SAMPLING_RATIO: 2 40 | BODY_UV_RCNN: 41 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 42 | NUM_STACKED_CONVS: 8 43 | NUM_PATCHES: 24 44 | USE_DECONV_OUTPUT: True 45 | CONV_INIT: MSRAFill 46 | CONV_HEAD_DIM: 512 47 | UP_SCALE: 2 48 | HEATMAP_SIZE: 56 49 | ROI_XFORM_METHOD: RoIAlign 50 | ROI_XFORM_RESOLUTION: 14 51 | ROI_XFORM_SAMPLING_RATIO: 2 52 | ## 53 | # Loss weights for annotation masks.(14 Parts) 54 | INDEX_WEIGHTS : 2.0 55 | # Loss weights for surface parts. (24 Parts) 56 | PART_WEIGHTS : 0.3 57 | # Loss weights for UV regression. 58 | POINT_REGRESSION_WEIGHTS : 0.1 59 | ## 60 | BODY_UV_IMS: True 61 | TRAIN: 62 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 63 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 70 | TEST: 71 | DATASETS: ('dense_coco_2014_minival',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 79 | RPN_POST_NMS_TOP_N: 1000 80 | OUTPUT_DIR: '' 81 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet50_FPN_s1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 130000 29 | STEPS: [0, 100000, 120000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_fpn_resnet50.pkl','https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_fpn_resnet50.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_fpn_resnet50.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /eval/configs/DensePose_ResNet50_FPN_single_GPU.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 1 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | BASE_LR: 0.00025 16 | MAX_ITER: 720000 17 | STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | # BASE_LR: 0.002 28 | # MAX_ITER: 90000 29 | # STEPS: [0, 60000, 80000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_fpn_resnet50.pkl','https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_fpn_resnet50.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_fpn_resnet50.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /eval/configs/rpn_densepose_only_R-50-FPN_1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | RPN_ONLY: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | BASE_LR: 0.02 11 | GAMMA: 0.1 12 | MAX_ITER: 90000 13 | STEPS: [0, 60000, 80000] 14 | FPN: 15 | FPN_ON: True 16 | MULTILEVEL_RPN: True 17 | RPN_MAX_LEVEL: 6 18 | RPN_MIN_LEVEL: 2 19 | RPN_ANCHOR_START_SIZE: 32 20 | RPN_ASPECT_RATIOS: (0.5, 1, 2) 21 | TRAIN: 22 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 23 | DATASETS: ('keypoints_coco_2014_train', 'keypoints_coco_2014_valminusminival') 24 | SCALES: (800,) 25 | MAX_SIZE: 1333 26 | TEST: 27 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/35998996/12_2017_baselines/rpn_person_only_R-50-FPN_1x.yaml.08_10_08.0ZWmJm6F/output/train/keypoints_coco_2014_train%3Akeypoints_coco_2014_valminusminival/generalized_rcnn/model_final.pkl 28 | DATASETS: ('dense_coco_2014_minival', 'dense_coco_2014_train', 'dense_coco_2014_valminusminival') 29 | SCALE: 800 30 | MAX_SIZE: 1333 31 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 32 | RPN_POST_NMS_TOP_N: 2000 33 | OUTPUT_DIR: . 34 | -------------------------------------------------------------------------------- /eval/configs/rpn_densepose_only_X-101-32x8d-FPN_1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | RPN_ONLY: True 6 | NUM_GPUS: 1 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | BASE_LR: 0.02 11 | GAMMA: 0.1 12 | MAX_ITER: 90000 13 | STEPS: [0, 60000, 80000] 14 | FPN: 15 | FPN_ON: True 16 | MULTILEVEL_RPN: True 17 | RPN_MAX_LEVEL: 6 18 | RPN_MIN_LEVEL: 2 19 | RPN_ANCHOR_START_SIZE: 32 20 | RPN_ASPECT_RATIOS: (0.5, 1, 2) 21 | RESNETS: 22 | STRIDE_1X1: False # default True for MSRA; False for C2 or Torch models 23 | TRANS_FUNC: bottleneck_transformation 24 | NUM_GROUPS: 32 25 | WIDTH_PER_GROUP: 8 26 | TRAIN: 27 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/20171220/X-101-32x8d.pkl 28 | DATASETS: ('keypoints_coco_2014_train', 'keypoints_coco_2014_valminusminival') 29 | SCALES: (800,) 30 | MAX_SIZE: 1333 31 | TEST: 32 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/36760438/12_2017_baselines/rpn_person_only_X-101-32x8d-FPN_1x.yaml.06_04_23.M2oJlDPW/output/train/keypoints_coco_2014_train%3Akeypoints_coco_2014_valminusminival/generalized_rcnn/model_final.pkl 33 | DATASETS: ( 'dense_coco_2014_minival', 'dense_coco_2014_valminusminival') 34 | SCALE: 800 35 | MAX_SIZE: 1333 36 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 37 | RPN_POST_NMS_TOP_N: 2000 38 | OUTPUT_DIR: /home/goku/DensePose/CleanJSONs/ 39 | -------------------------------------------------------------------------------- /eval/detectron/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/eval/detectron/__init__.py -------------------------------------------------------------------------------- /eval/detectron/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/eval/detectron/core/__init__.py -------------------------------------------------------------------------------- /eval/detectron/datasets/VOCdevkit-matlab-wrapper/get_voc_opts.m: -------------------------------------------------------------------------------- 1 | function VOCopts = get_voc_opts(path) 2 | 3 | tmp = pwd; 4 | cd(path); 5 | try 6 | addpath('VOCcode'); 7 | VOCinit; 8 | catch 9 | rmpath('VOCcode'); 10 | cd(tmp); 11 | error(sprintf('VOCcode directory not found under %s', path)); 12 | end 13 | rmpath('VOCcode'); 14 | cd(tmp); 15 | -------------------------------------------------------------------------------- /eval/detectron/datasets/VOCdevkit-matlab-wrapper/voc_eval.m: -------------------------------------------------------------------------------- 1 | function res = voc_eval(path, comp_id, test_set, output_dir) 2 | 3 | VOCopts = get_voc_opts(path); 4 | VOCopts.testset = test_set; 5 | 6 | for i = 1:length(VOCopts.classes) 7 | cls = VOCopts.classes{i}; 8 | res(i) = voc_eval_cls(cls, VOCopts, comp_id, output_dir); 9 | end 10 | 11 | fprintf('\n~~~~~~~~~~~~~~~~~~~~\n'); 12 | fprintf('Results:\n'); 13 | aps = [res(:).ap]'; 14 | fprintf('%.1f\n', aps * 100); 15 | fprintf('%.1f\n', mean(aps) * 100); 16 | fprintf('~~~~~~~~~~~~~~~~~~~~\n'); 17 | 18 | function res = voc_eval_cls(cls, VOCopts, comp_id, output_dir) 19 | 20 | test_set = VOCopts.testset; 21 | year = VOCopts.dataset(4:end); 22 | 23 | addpath(fullfile(VOCopts.datadir, 'VOCcode')); 24 | 25 | res_fn = sprintf(VOCopts.detrespath, comp_id, cls); 26 | 27 | recall = []; 28 | prec = []; 29 | ap = 0; 30 | ap_auc = 0; 31 | 32 | do_eval = (str2num(year) <= 2007) | ~strcmp(test_set, 'test'); 33 | if do_eval 34 | % Bug in VOCevaldet requires that tic has been called first 35 | tic; 36 | [recall, prec, ap] = VOCevaldet(VOCopts, comp_id, cls, true); 37 | ap_auc = xVOCap(recall, prec); 38 | 39 | % force plot limits 40 | ylim([0 1]); 41 | xlim([0 1]); 42 | 43 | print(gcf, '-djpeg', '-r0', ... 44 | [output_dir '/' cls '_pr.jpg']); 45 | end 46 | fprintf('!!! %s : %.4f %.4f\n', cls, ap, ap_auc); 47 | 48 | res.recall = recall; 49 | res.prec = prec; 50 | res.ap = ap; 51 | res.ap_auc = ap_auc; 52 | 53 | save([output_dir '/' cls '_pr.mat'], ... 54 | 'res', 'recall', 'prec', 'ap', 'ap_auc'); 55 | 56 | rmpath(fullfile(VOCopts.datadir, 'VOCcode')); 57 | -------------------------------------------------------------------------------- /eval/detectron/datasets/VOCdevkit-matlab-wrapper/xVOCap.m: -------------------------------------------------------------------------------- 1 | function ap = xVOCap(rec,prec) 2 | % From the PASCAL VOC 2011 devkit 3 | 4 | mrec=[0 ; rec ; 1]; 5 | mpre=[0 ; prec ; 0]; 6 | for i=numel(mpre)-1:-1:1 7 | mpre(i)=max(mpre(i),mpre(i+1)); 8 | end 9 | i=find(mrec(2:end)~=mrec(1:end-1))+1; 10 | ap=sum((mrec(i)-mrec(i-1)).*mpre(i)); 11 | -------------------------------------------------------------------------------- /eval/detectron/datasets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/eval/detectron/datasets/__init__.py -------------------------------------------------------------------------------- /eval/detectron/datasets/cityscapes_json_dataset_evaluator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Functions for evaluating results on Cityscapes.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import cv2 16 | import logging 17 | import os 18 | import uuid 19 | 20 | import pycocotools.mask as mask_util 21 | 22 | from detectron.core.config import cfg 23 | from detectron.datasets.dataset_catalog import get_raw_dir 24 | 25 | logger = logging.getLogger(__name__) 26 | 27 | 28 | def evaluate_masks( 29 | json_dataset, 30 | all_boxes, 31 | all_segms, 32 | output_dir, 33 | use_salt=True, 34 | cleanup=False 35 | ): 36 | if cfg.CLUSTER.ON_CLUSTER: 37 | # On the cluster avoid saving these files in the job directory 38 | output_dir = '/tmp' 39 | res_file = os.path.join( 40 | output_dir, 'segmentations_' + json_dataset.name + '_results') 41 | if use_salt: 42 | res_file += '_{}'.format(str(uuid.uuid4())) 43 | res_file += '.json' 44 | 45 | results_dir = os.path.join(output_dir, 'results') 46 | if not os.path.exists(results_dir): 47 | os.mkdir(results_dir) 48 | 49 | os.environ['CITYSCAPES_DATASET'] = get_raw_dir(json_dataset.name) 50 | os.environ['CITYSCAPES_RESULTS'] = output_dir 51 | 52 | # Load the Cityscapes eval script *after* setting the required env vars, 53 | # since the script reads their values into global variables (at load time). 54 | import cityscapesscripts.evaluation.evalInstanceLevelSemanticLabeling \ 55 | as cityscapes_eval 56 | 57 | roidb = json_dataset.get_roidb() 58 | for i, entry in enumerate(roidb): 59 | im_name = entry['image'] 60 | 61 | basename = os.path.splitext(os.path.basename(im_name))[0] 62 | txtname = os.path.join(output_dir, basename + 'pred.txt') 63 | with open(txtname, 'w') as fid_txt: 64 | if i % 10 == 0: 65 | logger.info('i: {}: {}'.format(i, basename)) 66 | for j in range(1, len(all_segms)): 67 | clss = json_dataset.classes[j] 68 | clss_id = cityscapes_eval.name2label[clss].id 69 | segms = all_segms[j][i] 70 | boxes = all_boxes[j][i] 71 | if segms == []: 72 | continue 73 | masks = mask_util.decode(segms) 74 | 75 | for k in range(boxes.shape[0]): 76 | score = boxes[k, -1] 77 | mask = masks[:, :, k] 78 | pngname = os.path.join( 79 | 'results', 80 | basename + '_' + clss + '_{}.png'.format(k)) 81 | # write txt 82 | fid_txt.write('{} {} {}\n'.format(pngname, clss_id, score)) 83 | # save mask 84 | cv2.imwrite(os.path.join(output_dir, pngname), mask * 255) 85 | logger.info('Evaluating...') 86 | cityscapes_eval.main([]) 87 | return None 88 | -------------------------------------------------------------------------------- /eval/detectron/datasets/coco_to_cityscapes_id.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | # mapping coco categories to cityscapes (our converted json) id 9 | # cityscapes 10 | # INFO roidb.py: 220: 1 bicycle: 7286 11 | # INFO roidb.py: 220: 2 car: 53684 12 | # INFO roidb.py: 220: 3 person: 35704 13 | # INFO roidb.py: 220: 4 train: 336 14 | # INFO roidb.py: 220: 5 truck: 964 15 | # INFO roidb.py: 220: 6 motorcycle: 1468 16 | # INFO roidb.py: 220: 7 bus: 758 17 | # INFO roidb.py: 220: 8 rider: 3504 18 | 19 | # coco (val5k) 20 | # INFO roidb.py: 220: 1 person: 21296 21 | # INFO roidb.py: 220: 2 bicycle: 628 22 | # INFO roidb.py: 220: 3 car: 3818 23 | # INFO roidb.py: 220: 4 motorcycle: 732 24 | # INFO roidb.py: 220: 5 airplane: 286 <------ irrelevant 25 | # INFO roidb.py: 220: 6 bus: 564 26 | # INFO roidb.py: 220: 7 train: 380 27 | # INFO roidb.py: 220: 8 truck: 828 28 | 29 | 30 | def cityscapes_to_coco(cityscapes_id): 31 | lookup = { 32 | 0: 0, # ... background 33 | 1: 2, # bicycle 34 | 2: 3, # car 35 | 3: 1, # person 36 | 4: 7, # train 37 | 5: 8, # truck 38 | 6: 4, # motorcycle 39 | 7: 6, # bus 40 | 8: -1, # rider (-1 means rand init) 41 | } 42 | return lookup[cityscapes_id] 43 | 44 | 45 | def cityscapes_to_coco_with_rider(cityscapes_id): 46 | lookup = { 47 | 0: 0, # ... background 48 | 1: 2, # bicycle 49 | 2: 3, # car 50 | 3: 1, # person 51 | 4: 7, # train 52 | 5: 8, # truck 53 | 6: 4, # motorcycle 54 | 7: 6, # bus 55 | 8: 1, # rider ("person", *rider has human right!*) 56 | } 57 | return lookup[cityscapes_id] 58 | 59 | 60 | def cityscapes_to_coco_without_person_rider(cityscapes_id): 61 | lookup = { 62 | 0: 0, # ... background 63 | 1: 2, # bicycle 64 | 2: 3, # car 65 | 3: -1, # person (ignore) 66 | 4: 7, # train 67 | 5: 8, # truck 68 | 6: 4, # motorcycle 69 | 7: 6, # bus 70 | 8: -1, # rider (ignore) 71 | } 72 | return lookup[cityscapes_id] 73 | 74 | 75 | def cityscapes_to_coco_all_random(cityscapes_id): 76 | lookup = { 77 | 0: -1, # ... background 78 | 1: -1, # bicycle 79 | 2: -1, # car 80 | 3: -1, # person (ignore) 81 | 4: -1, # train 82 | 5: -1, # truck 83 | 6: -1, # motorcycle 84 | 7: -1, # bus 85 | 8: -1, # rider (ignore) 86 | } 87 | return lookup[cityscapes_id] 88 | -------------------------------------------------------------------------------- /eval/detectron/datasets/dummy_datasets.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | """Provide stub objects that can act as stand-in "dummy" datasets for simple use 8 | cases, like getting all classes in a dataset. This exists so that demos can be 9 | run without requiring users to download/install datasets first. 10 | """ 11 | 12 | from __future__ import absolute_import 13 | from __future__ import division 14 | from __future__ import print_function 15 | from __future__ import unicode_literals 16 | 17 | from detectron.utils.collections import AttrDict 18 | 19 | 20 | def get_coco_dataset(): 21 | """A dummy COCO dataset that includes only the 'classes' field.""" 22 | ds = AttrDict() 23 | classes = [ 24 | '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 25 | 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 26 | 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 27 | 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 28 | 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 29 | 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 30 | 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 31 | 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 32 | 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 33 | 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 34 | 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 35 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 36 | 'scissors', 'teddy bear', 'hair drier', 'toothbrush' 37 | ] 38 | ds.classes = {i: name for i, name in enumerate(classes)} 39 | return ds 40 | -------------------------------------------------------------------------------- /eval/detectron/modeling/VGG16.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """VGG16 from https://arxiv.org/abs/1409.1556.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | from detectron.core.config import cfg 16 | 17 | 18 | def add_VGG16_conv5_body(model): 19 | model.Conv('data', 'conv1_1', 3, 64, 3, pad=1, stride=1) 20 | model.Relu('conv1_1', 'conv1_1') 21 | model.Conv('conv1_1', 'conv1_2', 64, 64, 3, pad=1, stride=1) 22 | model.Relu('conv1_2', 'conv1_2') 23 | model.MaxPool('conv1_2', 'pool1', kernel=2, pad=0, stride=2) 24 | model.Conv('pool1', 'conv2_1', 64, 128, 3, pad=1, stride=1) 25 | model.Relu('conv2_1', 'conv2_1') 26 | model.Conv('conv2_1', 'conv2_2', 128, 128, 3, pad=1, stride=1) 27 | model.Relu('conv2_2', 'conv2_2') 28 | model.MaxPool('conv2_2', 'pool2', kernel=2, pad=0, stride=2) 29 | model.StopGradient('pool2', 'pool2') 30 | model.Conv('pool2', 'conv3_1', 128, 256, 3, pad=1, stride=1) 31 | model.Relu('conv3_1', 'conv3_1') 32 | model.Conv('conv3_1', 'conv3_2', 256, 256, 3, pad=1, stride=1) 33 | model.Relu('conv3_2', 'conv3_2') 34 | model.Conv('conv3_2', 'conv3_3', 256, 256, 3, pad=1, stride=1) 35 | model.Relu('conv3_3', 'conv3_3') 36 | model.MaxPool('conv3_3', 'pool3', kernel=2, pad=0, stride=2) 37 | model.Conv('pool3', 'conv4_1', 256, 512, 3, pad=1, stride=1) 38 | model.Relu('conv4_1', 'conv4_1') 39 | model.Conv('conv4_1', 'conv4_2', 512, 512, 3, pad=1, stride=1) 40 | model.Relu('conv4_2', 'conv4_2') 41 | model.Conv('conv4_2', 'conv4_3', 512, 512, 3, pad=1, stride=1) 42 | model.Relu('conv4_3', 'conv4_3') 43 | model.MaxPool('conv4_3', 'pool4', kernel=2, pad=0, stride=2) 44 | model.Conv('pool4', 'conv5_1', 512, 512, 3, pad=1, stride=1) 45 | model.Relu('conv5_1', 'conv5_1') 46 | model.Conv('conv5_1', 'conv5_2', 512, 512, 3, pad=1, stride=1) 47 | model.Relu('conv5_2', 'conv5_2') 48 | model.Conv('conv5_2', 'conv5_3', 512, 512, 3, pad=1, stride=1) 49 | blob_out = model.Relu('conv5_3', 'conv5_3') 50 | return blob_out, 512, 1. / 16. 51 | 52 | 53 | def add_VGG16_roi_fc_head(model, blob_in, dim_in, spatial_scale): 54 | model.RoIFeatureTransform( 55 | blob_in, 56 | 'pool5', 57 | blob_rois='rois', 58 | method=cfg.FAST_RCNN.ROI_XFORM_METHOD, 59 | resolution=7, 60 | sampling_ratio=cfg.FAST_RCNN.ROI_XFORM_SAMPLING_RATIO, 61 | spatial_scale=spatial_scale 62 | ) 63 | model.FC('pool5', 'fc6', dim_in * 7 * 7, 4096) 64 | model.Relu('fc6', 'fc6') 65 | model.FC('fc6', 'fc7', 4096, 4096) 66 | blob_out = model.Relu('fc7', 'fc7') 67 | return blob_out, 4096 68 | -------------------------------------------------------------------------------- /eval/detectron/modeling/VGG_CNN_M_1024.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """VGG_CNN_M_1024 from https://arxiv.org/abs/1405.3531.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | from detectron.core.config import cfg 16 | 17 | 18 | def add_VGG_CNN_M_1024_conv5_body(model): 19 | model.Conv('data', 'conv1', 3, 96, 7, pad=0, stride=2) 20 | model.Relu('conv1', 'conv1') 21 | model.LRN('conv1', 'norm1', size=5, alpha=0.0005, beta=0.75, bias=2.) 22 | model.MaxPool('norm1', 'pool1', kernel=3, pad=0, stride=2) 23 | model.StopGradient('pool1', 'pool1') 24 | # No updates at conv1 and below (norm1 and pool1 have no params, 25 | # so we can stop gradients before them, too) 26 | model.Conv('pool1', 'conv2', 96, 256, 5, pad=0, stride=2) 27 | model.Relu('conv2', 'conv2') 28 | model.LRN('conv2', 'norm2', size=5, alpha=0.0005, beta=0.75, bias=2.) 29 | model.MaxPool('norm2', 'pool2', kernel=3, pad=0, stride=2) 30 | model.Conv('pool2', 'conv3', 256, 512, 3, pad=1, stride=1) 31 | model.Relu('conv3', 'conv3') 32 | model.Conv('conv3', 'conv4', 512, 512, 3, pad=1, stride=1) 33 | model.Relu('conv4', 'conv4') 34 | model.Conv('conv4', 'conv5', 512, 512, 3, pad=1, stride=1) 35 | blob_out = model.Relu('conv5', 'conv5') 36 | return blob_out, 512, 1. / 16. 37 | 38 | 39 | def add_VGG_CNN_M_1024_roi_fc_head(model, blob_in, dim_in, spatial_scale): 40 | model.RoIFeatureTransform( 41 | blob_in, 42 | 'pool5', 43 | blob_rois='rois', 44 | method=cfg.FAST_RCNN.ROI_XFORM_METHOD, 45 | resolution=6, 46 | sampling_ratio=cfg.FAST_RCNN.ROI_XFORM_SAMPLING_RATIO, 47 | spatial_scale=spatial_scale 48 | ) 49 | model.FC('pool5', 'fc6', dim_in * 6 * 6, 4096) 50 | model.Relu('fc6', 'fc6') 51 | model.FC('fc6', 'fc7', 4096, 1024) 52 | blob_out = model.Relu('fc7', 'fc7') 53 | return blob_out, 1024 54 | -------------------------------------------------------------------------------- /eval/detectron/modeling/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /eval/detectron/modeling/generate_anchors.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | # 8 | # Based on: 9 | # -------------------------------------------------------- 10 | # Faster R-CNN 11 | # Copyright (c) 2015 Microsoft 12 | # Licensed under The MIT License [see LICENSE for details] 13 | # Written by Ross Girshick and Sean Bell 14 | # -------------------------------------------------------- 15 | 16 | import numpy as np 17 | 18 | # Verify that we compute the same anchors as Shaoqing's matlab implementation: 19 | # 20 | # >> load output/rpn_cachedir/faster_rcnn_VOC2007_ZF_stage1_rpn/anchors.mat 21 | # >> anchors 22 | # 23 | # anchors = 24 | # 25 | # -83 -39 100 56 26 | # -175 -87 192 104 27 | # -359 -183 376 200 28 | # -55 -55 72 72 29 | # -119 -119 136 136 30 | # -247 -247 264 264 31 | # -35 -79 52 96 32 | # -79 -167 96 184 33 | # -167 -343 184 360 34 | 35 | # array([[ -83., -39., 100., 56.], 36 | # [-175., -87., 192., 104.], 37 | # [-359., -183., 376., 200.], 38 | # [ -55., -55., 72., 72.], 39 | # [-119., -119., 136., 136.], 40 | # [-247., -247., 264., 264.], 41 | # [ -35., -79., 52., 96.], 42 | # [ -79., -167., 96., 184.], 43 | # [-167., -343., 184., 360.]]) 44 | 45 | 46 | def generate_anchors( 47 | stride=16, sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.5, 1, 2) 48 | ): 49 | """Generates a matrix of anchor boxes in (x1, y1, x2, y2) format. Anchors 50 | are centered on stride / 2, have (approximate) sqrt areas of the specified 51 | sizes, and aspect ratios as given. 52 | """ 53 | return _generate_anchors( 54 | stride, 55 | np.array(sizes, dtype=np.float) / stride, 56 | np.array(aspect_ratios, dtype=np.float) 57 | ) 58 | 59 | 60 | def _generate_anchors(base_size, scales, aspect_ratios): 61 | """Generate anchor (reference) windows by enumerating aspect ratios X 62 | scales wrt a reference (0, 0, base_size - 1, base_size - 1) window. 63 | """ 64 | anchor = np.array([1, 1, base_size, base_size], dtype=np.float) - 1 65 | anchors = _ratio_enum(anchor, aspect_ratios) 66 | anchors = np.vstack( 67 | [_scale_enum(anchors[i, :], scales) for i in range(anchors.shape[0])] 68 | ) 69 | return anchors 70 | 71 | 72 | def _whctrs(anchor): 73 | """Return width, height, x center, and y center for an anchor (window).""" 74 | w = anchor[2] - anchor[0] + 1 75 | h = anchor[3] - anchor[1] + 1 76 | x_ctr = anchor[0] + 0.5 * (w - 1) 77 | y_ctr = anchor[1] + 0.5 * (h - 1) 78 | return w, h, x_ctr, y_ctr 79 | 80 | 81 | def _mkanchors(ws, hs, x_ctr, y_ctr): 82 | """Given a vector of widths (ws) and heights (hs) around a center 83 | (x_ctr, y_ctr), output a set of anchors (windows). 84 | """ 85 | ws = ws[:, np.newaxis] 86 | hs = hs[:, np.newaxis] 87 | anchors = np.hstack( 88 | ( 89 | x_ctr - 0.5 * (ws - 1), 90 | y_ctr - 0.5 * (hs - 1), 91 | x_ctr + 0.5 * (ws - 1), 92 | y_ctr + 0.5 * (hs - 1) 93 | ) 94 | ) 95 | return anchors 96 | 97 | 98 | def _ratio_enum(anchor, ratios): 99 | """Enumerate a set of anchors for each aspect ratio wrt an anchor.""" 100 | w, h, x_ctr, y_ctr = _whctrs(anchor) 101 | size = w * h 102 | size_ratios = size / ratios 103 | ws = np.round(np.sqrt(size_ratios)) 104 | hs = np.round(ws * ratios) 105 | anchors = _mkanchors(ws, hs, x_ctr, y_ctr) 106 | return anchors 107 | 108 | 109 | def _scale_enum(anchor, scales): 110 | """Enumerate a set of anchors for each scale wrt an anchor.""" 111 | w, h, x_ctr, y_ctr = _whctrs(anchor) 112 | ws = w * scales 113 | hs = h * scales 114 | anchors = _mkanchors(ws, hs, x_ctr, y_ctr) 115 | return anchors 116 | -------------------------------------------------------------------------------- /eval/detectron/modeling/name_compat.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Handle mapping from old network building function names to new names. 9 | 10 | Flexible network configuration is achieved by specifying the function name that 11 | builds a network module (e.g., the name of the conv backbone or the mask roi 12 | head). However we may wish to change names over time without breaking previous 13 | config files. This module provides backwards naming compatibility by providing 14 | a mapping from the old name to the new name. 15 | 16 | When renaming functions, it's generally a good idea to codemod existing yaml 17 | config files. An easy way to batch edit, by example, is a shell command like 18 | 19 | $ find . -name "*.yaml" -exec sed -i -e \ 20 | 's/head_builder\.add_roi_2mlp_head/fast_rcnn_heads.add_roi_2mlp_head/g' {} \; 21 | 22 | to perform the renaming: 23 | head_builder.add_roi_2mlp_head => fast_rcnn_heads.add_roi_2mlp_head 24 | """ 25 | 26 | from __future__ import absolute_import 27 | from __future__ import division 28 | from __future__ import print_function 29 | from __future__ import unicode_literals 30 | 31 | 32 | _RENAME = { 33 | # Removed "ResNet_" from the name because it wasn't relevent 34 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v1up4convs': 35 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v1up4convs', 36 | # Removed "ResNet_" from the name because it wasn't relevent 37 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v1up': 38 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v1up', 39 | # Removed "ResNet_" from the name because it wasn't relevent 40 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v0upshare': 41 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v0upshare', 42 | # Removed "ResNet_" from the name because it wasn't relevent 43 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v0up': 44 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v0up', 45 | # Removed head_builder module in favor of the more specific fast_rcnn name 46 | 'head_builder.add_roi_2mlp_head': 47 | 'fast_rcnn_heads.add_roi_2mlp_head', 48 | } 49 | 50 | 51 | def get_new_name(func_name): 52 | if func_name in _RENAME: 53 | func_name = _RENAME[func_name] 54 | return func_name 55 | -------------------------------------------------------------------------------- /eval/detectron/modeling/rfcn_heads.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | from detectron.core.config import cfg 14 | from detectron.utils.c2 import const_fill 15 | from detectron.utils.c2 import gauss_fill 16 | 17 | 18 | # ---------------------------------------------------------------------------- # 19 | # R-FCN outputs and losses 20 | # ---------------------------------------------------------------------------- # 21 | 22 | def add_rfcn_outputs(model, blob_in, dim_in, dim_reduce, spatial_scale): 23 | if dim_reduce is not None: 24 | # Optional dim reduction 25 | blob_in = model.Conv( 26 | blob_in, 27 | 'conv_dim_reduce', 28 | dim_in, 29 | dim_reduce, 30 | kernel=1, 31 | pad=0, 32 | stride=1, 33 | weight_init=gauss_fill(0.01), 34 | bias_init=const_fill(0.0) 35 | ) 36 | blob_in = model.Relu(blob_in, blob_in) 37 | dim_in = dim_reduce 38 | # Classification conv 39 | model.Conv( 40 | blob_in, 41 | 'conv_cls', 42 | dim_in, 43 | model.num_classes * cfg.RFCN.PS_GRID_SIZE**2, 44 | kernel=1, 45 | pad=0, 46 | stride=1, 47 | weight_init=gauss_fill(0.01), 48 | bias_init=const_fill(0.0) 49 | ) 50 | # Bounding-box regression conv 51 | num_bbox_reg_classes = ( 52 | 2 if cfg.MODEL.CLS_AGNOSTIC_BBOX_REG else model.num_classes 53 | ) 54 | model.Conv( 55 | blob_in, 56 | 'conv_bbox_pred', 57 | dim_in, 58 | 4 * num_bbox_reg_classes * cfg.RFCN.PS_GRID_SIZE**2, 59 | kernel=1, 60 | pad=0, 61 | stride=1, 62 | weight_init=gauss_fill(0.01), 63 | bias_init=const_fill(0.0) 64 | ) 65 | # Classification PS RoI pooling 66 | model.net.PSRoIPool( 67 | ['conv_cls', 'rois'], ['psroipooled_cls', '_mapping_channel_cls'], 68 | group_size=cfg.RFCN.PS_GRID_SIZE, 69 | output_dim=model.num_classes, 70 | spatial_scale=spatial_scale 71 | ) 72 | model.AveragePool( 73 | 'psroipooled_cls', 'cls_score_4d', kernel=cfg.RFCN.PS_GRID_SIZE 74 | ) 75 | model.net.Reshape( 76 | 'cls_score_4d', ['cls_score', '_cls_scores_shape'], 77 | shape=(-1, cfg.MODEL.NUM_CLASSES) 78 | ) 79 | if not model.train: 80 | model.Softmax('cls_score', 'cls_prob', engine='CUDNN') 81 | # Bbox regression PS RoI pooling 82 | model.net.PSRoIPool( 83 | ['conv_bbox_pred', 'rois'], 84 | ['psroipooled_bbox', '_mapping_channel_bbox'], 85 | group_size=cfg.RFCN.PS_GRID_SIZE, 86 | output_dim=4 * num_bbox_reg_classes, 87 | spatial_scale=spatial_scale 88 | ) 89 | model.AveragePool( 90 | 'psroipooled_bbox', 'bbox_pred', kernel=cfg.RFCN.PS_GRID_SIZE 91 | ) 92 | -------------------------------------------------------------------------------- /eval/detectron/ops/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/eval/detectron/ops/__init__.py -------------------------------------------------------------------------------- /eval/detectron/ops/generate_proposal_labels.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import logging 14 | 15 | from detectron.datasets import json_dataset 16 | from detectron.datasets import roidb as roidb_utils 17 | from detectron.utils import blob as blob_utils 18 | import detectron.roi_data.fast_rcnn as fast_rcnn_roi_data 19 | 20 | logger = logging.getLogger(__name__) 21 | 22 | 23 | class GenerateProposalLabelsOp(object): 24 | 25 | def forward(self, inputs, outputs): 26 | """See modeling.detector.GenerateProposalLabels for inputs/outputs 27 | documentation. 28 | """ 29 | # During training we reuse the data loader code. We populate roidb 30 | # entries on the fly using the rois generated by RPN. 31 | # im_info: [[im_height, im_width, im_scale], ...] 32 | rois = inputs[0].data 33 | roidb = blob_utils.deserialize(inputs[1].data) 34 | im_info = inputs[2].data 35 | im_scales = im_info[:, 2] 36 | output_blob_names = fast_rcnn_roi_data.get_fast_rcnn_blob_names() 37 | # For historical consistency with the original Faster R-CNN 38 | # implementation we are *not* filtering crowd proposals. 39 | # This choice should be investigated in the future (it likely does 40 | # not matter). 41 | json_dataset.add_proposals(roidb, rois, im_scales, crowd_thresh=0) 42 | roidb_utils.add_bbox_regression_targets(roidb) 43 | blobs = {k: [] for k in output_blob_names} 44 | fast_rcnn_roi_data.add_fast_rcnn_blobs(blobs, im_scales, roidb) 45 | for i, k in enumerate(output_blob_names): 46 | blob_utils.py_op_copy_blob(blobs[k], outputs[i]) 47 | -------------------------------------------------------------------------------- /eval/detectron/ops/pool_points_interp.cc: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | 10 | #include "pool_points_interp.h" 11 | 12 | namespace caffe2 { 13 | //namespace { 14 | 15 | REGISTER_CPU_OPERATOR(PoolPointsInterp, 16 | PoolPointsInterpOp); 17 | REGISTER_CPU_OPERATOR(PoolPointsInterpGradient, 18 | PoolPointsInterpGradientOp); 19 | 20 | // Input: X, points; Output: Y 21 | OPERATOR_SCHEMA(PoolPointsInterp).NumInputs(2).NumOutputs(1); 22 | // Input: X, points, dY (aka "gradOutput"); 23 | // Output: dX (aka "gradInput") 24 | OPERATOR_SCHEMA(PoolPointsInterpGradient).NumInputs(3).NumOutputs(1); 25 | 26 | class GetPoolPointsInterpGradient : public GradientMakerBase { 27 | using GradientMakerBase::GradientMakerBase; 28 | vector GetGradientDefs() override { 29 | return SingleGradientDef( 30 | "PoolPointsInterpGradient", "", 31 | vector{I(0), I(1), GO(0)}, 32 | vector{GI(0)}); 33 | } 34 | }; 35 | 36 | REGISTER_GRADIENT(PoolPointsInterp, GetPoolPointsInterpGradient); 37 | 38 | //} // namespace 39 | } // namespace caffe2 40 | -------------------------------------------------------------------------------- /eval/detectron/ops/pool_points_interp.h: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | 10 | #ifndef POOL_POINTS_INTERP_OP_H_ 11 | #define POOL_POINTS_INTERP_OP_H_ 12 | 13 | #include "caffe2/core/context.h" 14 | #include "caffe2/core/logging.h" 15 | #include "caffe2/core/operator.h" 16 | 17 | namespace caffe2 { 18 | 19 | template 20 | class PoolPointsInterpOp final : public Operator { 21 | public: 22 | PoolPointsInterpOp(const OperatorDef& operator_def, Workspace* ws) 23 | : Operator(operator_def, ws), 24 | spatial_scale_(OperatorBase::GetSingleArgument( 25 | "spatial_scale", 1.)) { 26 | DCHECK_GT(spatial_scale_, 0); 27 | } 28 | USE_OPERATOR_CONTEXT_FUNCTIONS; 29 | 30 | bool RunOnDevice() override { 31 | CAFFE_NOT_IMPLEMENTED; 32 | } 33 | 34 | protected: 35 | float spatial_scale_; 36 | }; 37 | 38 | template 39 | class PoolPointsInterpGradientOp final : public Operator { 40 | public: 41 | PoolPointsInterpGradientOp(const OperatorDef& def, Workspace* ws) 42 | : Operator(def, ws), 43 | spatial_scale_(OperatorBase::GetSingleArgument( 44 | "spatial_scale", 1.)){ 45 | DCHECK_GT(spatial_scale_, 0); 46 | } 47 | USE_OPERATOR_CONTEXT_FUNCTIONS; 48 | 49 | bool RunOnDevice() override { 50 | CAFFE_NOT_IMPLEMENTED; 51 | } 52 | 53 | protected: 54 | float spatial_scale_; 55 | }; 56 | 57 | } // namespace caffe2 58 | 59 | #endif // PoolPointsInterpOp 60 | -------------------------------------------------------------------------------- /eval/detectron/ops/zero_even_op.cc: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | #include "zero_even_op.h" 10 | 11 | namespace caffe2 { 12 | 13 | template <> 14 | bool ZeroEvenOp::RunOnDevice() { 15 | // Retrieve the input tensor. 16 | const auto& X = Input(0); 17 | CAFFE_ENFORCE(X.ndim() == 1); 18 | 19 | // Initialize the output tensor to a copy of the input tensor. 20 | auto* Y = Output(0); 21 | Y->CopyFrom(X); 22 | 23 | // Set output elements at even indices to zero. 24 | auto* Y_data = Y->mutable_data(); 25 | for (auto i = 0; i < Y->size(); i += 2) { 26 | Y_data[i] = 0.0f; 27 | } 28 | 29 | return true; 30 | } 31 | 32 | REGISTER_CPU_OPERATOR(ZeroEven, ZeroEvenOp); 33 | 34 | OPERATOR_SCHEMA(ZeroEven) 35 | .NumInputs(1) 36 | .NumOutputs(1) 37 | .Input( 38 | 0, 39 | "X", 40 | "1D input tensor") 41 | .Output( 42 | 0, 43 | "Y", 44 | "1D output tensor"); 45 | 46 | } // namespace caffe2 47 | -------------------------------------------------------------------------------- /eval/detectron/ops/zero_even_op.cu: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | #include "caffe2/core/context_gpu.h" 10 | 11 | #include "zero_even_op.h" 12 | 13 | namespace caffe2 { 14 | 15 | namespace { 16 | 17 | template 18 | __global__ void SetEvenIndsToVal(size_t num_even_inds, T val, T* data) { 19 | CUDA_1D_KERNEL_LOOP(i, num_even_inds) { 20 | data[i << 1] = val; 21 | } 22 | } 23 | 24 | } // namespace 25 | 26 | template <> 27 | bool ZeroEvenOp::RunOnDevice() { 28 | // Retrieve the input tensor. 29 | const auto& X = Input(0); 30 | CAFFE_ENFORCE(X.ndim() == 1); 31 | 32 | // Initialize the output tensor to a copy of the input tensor. 33 | auto* Y = Output(0); 34 | Y->CopyFrom(X); 35 | 36 | // Set output elements at even indices to zero. 37 | auto output_size = Y->size(); 38 | 39 | if (output_size > 0) { 40 | size_t num_even_inds = output_size / 2 + output_size % 2; 41 | SetEvenIndsToVal 42 | <<>>( 46 | num_even_inds, 47 | 0.0f, 48 | Y->mutable_data()); 49 | } 50 | 51 | return true; 52 | } 53 | 54 | REGISTER_CUDA_OPERATOR(ZeroEven, ZeroEvenOp); 55 | 56 | } // namespace caffe2 57 | -------------------------------------------------------------------------------- /eval/detectron/ops/zero_even_op.h: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | #ifndef ZERO_EVEN_OP_H_ 10 | #define ZERO_EVEN_OP_H_ 11 | 12 | #include "caffe2/core/context.h" 13 | #include "caffe2/core/operator.h" 14 | //#include "caffe2/utils/math.h" 15 | 16 | namespace caffe2 { 17 | 18 | /** 19 | * ZeroEven operator. Zeros elements at even indices of an 1D array. 20 | * Elements at odd indices are preserved. 21 | * 22 | * This toy operator is an example of a custom operator and may be a useful 23 | * reference for adding new custom operators to the Detectron codebase. 24 | */ 25 | template 26 | class ZeroEvenOp final : public Operator { 27 | public: 28 | // Introduce Operator helper members. 29 | USE_OPERATOR_CONTEXT_FUNCTIONS; 30 | 31 | ZeroEvenOp(const OperatorDef& operator_def, Workspace* ws) 32 | : Operator(operator_def, ws) {} 33 | 34 | bool RunOnDevice() override; 35 | }; 36 | 37 | } // namespace caffe2 38 | 39 | #endif // ZERO_EVEN_OP_H_ 40 | -------------------------------------------------------------------------------- /eval/detectron/roi_data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/eval/detectron/roi_data/__init__.py -------------------------------------------------------------------------------- /eval/detectron/roi_data/data_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Common utility functions for RPN and RetinaNet minibtach blobs preparation. 9 | """ 10 | 11 | from __future__ import absolute_import 12 | from __future__ import division 13 | from __future__ import print_function 14 | from __future__ import unicode_literals 15 | 16 | from collections import namedtuple 17 | import logging 18 | import numpy as np 19 | import threading 20 | 21 | from detectron.core.config import cfg 22 | from detectron.modeling.generate_anchors import generate_anchors 23 | import detectron.utils.boxes as box_utils 24 | 25 | logger = logging.getLogger(__name__) 26 | 27 | 28 | # octave and aspect fields are only used on RetinaNet. Octave corresponds to the 29 | # scale of the anchor and aspect denotes which aspect ratio is used in the range 30 | # of aspect ratios 31 | FieldOfAnchors = namedtuple( 32 | 'FieldOfAnchors', [ 33 | 'field_of_anchors', 'num_cell_anchors', 'stride', 'field_size', 34 | 'octave', 'aspect' 35 | ] 36 | ) 37 | 38 | # Cache for memoizing _get_field_of_anchors 39 | _threadlocal_foa = threading.local() 40 | 41 | 42 | def get_field_of_anchors( 43 | stride, anchor_sizes, anchor_aspect_ratios, octave=None, aspect=None 44 | ): 45 | global _threadlocal_foa 46 | if not hasattr(_threadlocal_foa, 'cache'): 47 | _threadlocal_foa.cache = {} 48 | 49 | cache_key = str(stride) + str(anchor_sizes) + str(anchor_aspect_ratios) 50 | if cache_key in _threadlocal_foa.cache: 51 | return _threadlocal_foa.cache[cache_key] 52 | 53 | # Anchors at a single feature cell 54 | cell_anchors = generate_anchors( 55 | stride=stride, sizes=anchor_sizes, aspect_ratios=anchor_aspect_ratios 56 | ) 57 | num_cell_anchors = cell_anchors.shape[0] 58 | 59 | # Generate canonical proposals from shifted anchors 60 | # Enumerate all shifted positions on the (H, W) grid 61 | fpn_max_size = cfg.FPN.COARSEST_STRIDE * np.ceil( 62 | cfg.TRAIN.MAX_SIZE / float(cfg.FPN.COARSEST_STRIDE) 63 | ) 64 | field_size = int(np.ceil(fpn_max_size / float(stride))) 65 | shifts = np.arange(0, field_size) * stride 66 | shift_x, shift_y = np.meshgrid(shifts, shifts) 67 | shift_x = shift_x.ravel() 68 | shift_y = shift_y.ravel() 69 | shifts = np.vstack((shift_x, shift_y, shift_x, shift_y)).transpose() 70 | 71 | # Broacast anchors over shifts to enumerate all anchors at all positions 72 | # in the (H, W) grid: 73 | # - add A cell anchors of shape (1, A, 4) to 74 | # - K shifts of shape (K, 1, 4) to get 75 | # - all shifted anchors of shape (K, A, 4) 76 | # - reshape to (K*A, 4) shifted anchors 77 | A = num_cell_anchors 78 | K = shifts.shape[0] 79 | field_of_anchors = ( 80 | cell_anchors.reshape((1, A, 4)) + 81 | shifts.reshape((1, K, 4)).transpose((1, 0, 2)) 82 | ) 83 | field_of_anchors = field_of_anchors.reshape((K * A, 4)) 84 | foa = FieldOfAnchors( 85 | field_of_anchors=field_of_anchors.astype(np.float32), 86 | num_cell_anchors=num_cell_anchors, 87 | stride=stride, 88 | field_size=field_size, 89 | octave=octave, 90 | aspect=aspect 91 | ) 92 | _threadlocal_foa.cache[cache_key] = foa 93 | return foa 94 | 95 | 96 | def unmap(data, count, inds, fill=0): 97 | """Unmap a subset of item (data) back to the original set of items (of 98 | size count)""" 99 | if count == len(inds): 100 | return data 101 | 102 | if len(data.shape) == 1: 103 | ret = np.empty((count, ), dtype=data.dtype) 104 | ret.fill(fill) 105 | ret[inds] = data 106 | else: 107 | ret = np.empty((count, ) + data.shape[1:], dtype=data.dtype) 108 | ret.fill(fill) 109 | ret[inds, :] = data 110 | return ret 111 | 112 | 113 | def compute_targets(ex_rois, gt_rois, weights=(1.0, 1.0, 1.0, 1.0)): 114 | """Compute bounding-box regression targets for an image.""" 115 | return box_utils.bbox_transform_inv(ex_rois, gt_rois, weights).astype( 116 | np.float32, copy=False 117 | ) 118 | -------------------------------------------------------------------------------- /eval/detectron/tests/test_batch_permutation_op.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from caffe2.proto import caffe2_pb2 17 | from caffe2.python import core 18 | from caffe2.python import gradient_checker 19 | from caffe2.python import workspace 20 | 21 | import detectron.utils.logging as logging_utils 22 | import detectron.utils.c2 as c2_utils 23 | 24 | 25 | class BatchPermutationOpTest(unittest.TestCase): 26 | def _run_op_test(self, X, I, check_grad=False): 27 | with core.DeviceScope(core.DeviceOption(caffe2_pb2.CUDA, 0)): 28 | op = core.CreateOperator('BatchPermutation', ['X', 'I'], ['Y']) 29 | workspace.FeedBlob('X', X) 30 | workspace.FeedBlob('I', I) 31 | workspace.RunOperatorOnce(op) 32 | Y = workspace.FetchBlob('Y') 33 | 34 | if check_grad: 35 | gc = gradient_checker.GradientChecker( 36 | stepsize=0.1, 37 | threshold=0.001, 38 | device_option=core.DeviceOption(caffe2_pb2.CUDA, 0) 39 | ) 40 | 41 | res, grad, grad_estimated = gc.CheckSimple(op, [X, I], 0, [0]) 42 | self.assertTrue(res, 'Grad check failed') 43 | 44 | Y_ref = X[I] 45 | np.testing.assert_allclose(Y, Y_ref, rtol=1e-5, atol=1e-08) 46 | 47 | def _run_speed_test(self, iters=5, N=1024): 48 | """This function provides an example of how to benchmark custom 49 | operators using the Caffe2 'prof_dag' network execution type. Please 50 | note that for 'prof_dag' to work, Caffe2 must be compiled with profiling 51 | support using the `-DUSE_PROF=ON` option passed to `cmake` when building 52 | Caffe2. 53 | """ 54 | net = core.Net('test') 55 | net.Proto().type = 'prof_dag' 56 | net.Proto().num_workers = 2 57 | Y = net.BatchPermutation(['X', 'I'], 'Y') 58 | Y_flat = net.FlattenToVec([Y], 'Y_flat') 59 | loss = net.AveragedLoss([Y_flat], 'loss') 60 | net.AddGradientOperators([loss]) 61 | workspace.CreateNet(net) 62 | 63 | X = np.random.randn(N, 256, 14, 14) 64 | for _i in range(iters): 65 | I = np.random.permutation(N) 66 | workspace.FeedBlob('X', X.astype(np.float32)) 67 | workspace.FeedBlob('I', I.astype(np.int32)) 68 | workspace.RunNet(net.Proto().name) 69 | np.testing.assert_allclose( 70 | workspace.FetchBlob('Y'), X[I], rtol=1e-5, atol=1e-08 71 | ) 72 | 73 | def test_forward_and_gradient(self): 74 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 75 | I = np.array([0, 1], dtype=np.int32) 76 | self._run_op_test(A, I, check_grad=True) 77 | 78 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 79 | I = np.array([1, 0], dtype=np.int32) 80 | self._run_op_test(A, I, check_grad=True) 81 | 82 | A = np.random.randn(10, 3, 5, 7).astype(np.float32) 83 | I = np.array(np.random.permutation(10), dtype=np.int32) 84 | self._run_op_test(A, I, check_grad=True) 85 | 86 | def test_size_exceptions(self): 87 | A = np.random.randn(2, 256, 42, 86).astype(np.float32) 88 | I = np.array(np.random.permutation(10), dtype=np.int32) 89 | with self.assertRaises(RuntimeError): 90 | self._run_op_test(A, I) 91 | 92 | # See doc string in _run_speed_test 93 | # def test_perf(self): 94 | # with core.DeviceScope(core.DeviceOption(caffe2_pb2.CUDA, 0)): 95 | # self._run_speed_test() 96 | 97 | 98 | if __name__ == '__main__': 99 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 100 | c2_utils.import_detectron_ops() 101 | assert 'BatchPermutation' in workspace.RegisteredOperators() 102 | logging_utils.setup_logging(__name__) 103 | unittest.main() 104 | -------------------------------------------------------------------------------- /eval/detectron/tests/test_bbox_transform.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from pycocotools import mask as COCOmask 17 | 18 | import detectron.utils.boxes as box_utils 19 | 20 | 21 | def random_boxes(mean_box, stdev, N): 22 | boxes = np.random.randn(N, 4) * stdev + mean_box 23 | return boxes.astype(dtype=np.float32) 24 | 25 | 26 | class TestBboxTransform(unittest.TestCase): 27 | def test_bbox_transform_and_inverse(self): 28 | weights = (5, 5, 10, 10) 29 | src_boxes = random_boxes([10, 10, 20, 20], 1, 10) 30 | dst_boxes = random_boxes([10, 10, 20, 20], 1, 10) 31 | deltas = box_utils.bbox_transform_inv( 32 | src_boxes, dst_boxes, weights=weights 33 | ) 34 | dst_boxes_reconstructed = box_utils.bbox_transform( 35 | src_boxes, deltas, weights=weights 36 | ) 37 | np.testing.assert_array_almost_equal( 38 | dst_boxes, dst_boxes_reconstructed, decimal=5 39 | ) 40 | 41 | def test_bbox_dataset_to_prediction_roundtrip(self): 42 | """Simulate the process of reading a ground-truth box from a dataset, 43 | make predictions from proposals, convert the predictions back to the 44 | dataset format, and then use the COCO API to compute IoU overlap between 45 | the gt box and the predictions. These should have IoU of 1. 46 | """ 47 | weights = (5, 5, 10, 10) 48 | # 1/ "read" a box from a dataset in the default (x1, y1, w, h) format 49 | gt_xywh_box = [10, 20, 100, 150] 50 | # 2/ convert it to our internal (x1, y1, x2, y2) format 51 | gt_xyxy_box = box_utils.xywh_to_xyxy(gt_xywh_box) 52 | # 3/ consider nearby proposal boxes 53 | prop_xyxy_boxes = random_boxes(gt_xyxy_box, 10, 10) 54 | # 4/ compute proposal-to-gt transformation deltas 55 | deltas = box_utils.bbox_transform_inv( 56 | prop_xyxy_boxes, np.array([gt_xyxy_box]), weights=weights 57 | ) 58 | # 5/ use deltas to transform proposals to xyxy predicted box 59 | pred_xyxy_boxes = box_utils.bbox_transform( 60 | prop_xyxy_boxes, deltas, weights=weights 61 | ) 62 | # 6/ convert xyxy predicted box to xywh predicted box 63 | pred_xywh_boxes = box_utils.xyxy_to_xywh(pred_xyxy_boxes) 64 | # 7/ use COCO API to compute IoU 65 | not_crowd = [int(False)] * pred_xywh_boxes.shape[0] 66 | ious = COCOmask.iou(pred_xywh_boxes, np.array([gt_xywh_box]), not_crowd) 67 | np.testing.assert_array_almost_equal(ious, np.ones(ious.shape)) 68 | 69 | def test_cython_bbox_iou_against_coco_api_bbox_iou(self): 70 | """Check that our cython implementation of bounding box IoU overlap 71 | matches the COCO API implementation. 72 | """ 73 | def _do_test(b1, b2): 74 | # Compute IoU overlap with the cython implementation 75 | cython_iou = box_utils.bbox_overlaps(b1, b2) 76 | # Compute IoU overlap with the COCO API implementation 77 | # (requires converting boxes from xyxy to xywh format) 78 | xywh_b1 = box_utils.xyxy_to_xywh(b1) 79 | xywh_b2 = box_utils.xyxy_to_xywh(b2) 80 | not_crowd = [int(False)] * b2.shape[0] 81 | coco_ious = COCOmask.iou(xywh_b1, xywh_b2, not_crowd) 82 | # IoUs should be similar 83 | np.testing.assert_array_almost_equal( 84 | cython_iou, coco_ious, decimal=5 85 | ) 86 | 87 | # Test small boxes 88 | b1 = random_boxes([10, 10, 20, 20], 5, 10) 89 | b2 = random_boxes([10, 10, 20, 20], 5, 10) 90 | _do_test(b1, b2) 91 | 92 | # Test bigger boxes 93 | b1 = random_boxes([10, 10, 110, 20], 20, 10) 94 | b2 = random_boxes([10, 10, 110, 20], 20, 10) 95 | _do_test(b1, b2) 96 | 97 | 98 | if __name__ == '__main__': 99 | unittest.main() 100 | -------------------------------------------------------------------------------- /eval/detectron/tests/test_loader.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import logging 15 | import unittest 16 | import mock 17 | 18 | from caffe2.proto import caffe2_pb2 19 | from caffe2.python import core 20 | from caffe2.python import muji 21 | from caffe2.python import workspace 22 | 23 | from detectron.core.config import assert_and_infer_cfg 24 | from detectron.core.config import cfg 25 | from detectron.roi_data.loader import RoIDataLoader 26 | import detectron.utils.logging as logging_utils 27 | 28 | 29 | def get_roidb_blobs(roidb): 30 | blobs = {} 31 | blobs['data'] = np.stack([entry['data'] for entry in roidb]) 32 | return blobs, True 33 | 34 | 35 | def get_net(data_loader, name): 36 | logger = logging.getLogger(__name__) 37 | blob_names = data_loader.get_output_names() 38 | net = core.Net(name) 39 | net.type = 'dag' 40 | for gpu_id in range(cfg.NUM_GPUS): 41 | with core.NameScope('gpu_{}'.format(gpu_id)): 42 | with core.DeviceScope(muji.OnGPU(gpu_id)): 43 | for blob_name in blob_names: 44 | blob = core.ScopedName(blob_name) 45 | workspace.CreateBlob(blob) 46 | net.DequeueBlobs( 47 | data_loader._blobs_queue_name, blob_names) 48 | logger.info("Protobuf:\n" + str(net.Proto())) 49 | 50 | return net 51 | 52 | 53 | def get_roidb_sample_data(sample_data): 54 | roidb = [] 55 | for _ in range(np.random.randint(4, 10)): 56 | roidb.append({'data': sample_data}) 57 | return roidb 58 | 59 | 60 | def create_loader_and_network(sample_data, name): 61 | roidb = get_roidb_sample_data(sample_data) 62 | loader = RoIDataLoader(roidb) 63 | net = get_net(loader, 'dequeue_net_train') 64 | loader.register_sigint_handler() 65 | loader.start(prefill=False) 66 | return loader, net 67 | 68 | 69 | def run_net(net): 70 | workspace.RunNetOnce(net) 71 | gpu_dev = core.DeviceOption(caffe2_pb2.CUDA, 0) 72 | name_scope = 'gpu_{}'.format(0) 73 | with core.NameScope(name_scope): 74 | with core.DeviceScope(gpu_dev): 75 | data = workspace.FetchBlob(core.ScopedName('data')) 76 | return data 77 | 78 | 79 | class TestRoIDataLoader(unittest.TestCase): 80 | @mock.patch( 81 | 'detectron.roi_data.loader.get_minibatch_blob_names', 82 | return_value=[u'data'] 83 | ) 84 | @mock.patch( 85 | 'detectron.roi_data.loader.get_minibatch', 86 | side_effect=get_roidb_blobs 87 | ) 88 | def test_two_parallel_loaders(self, _1, _2): 89 | train_data = np.random.rand(2, 3, 3).astype(np.float32) 90 | train_loader, train_net = create_loader_and_network(train_data, 91 | 'dequeue_net_train') 92 | test_data = np.random.rand(2, 4, 4).astype(np.float32) 93 | test_loader, test_net = create_loader_and_network(test_data, 94 | 'dequeue_net_test') 95 | for _ in range(5): 96 | data = run_net(train_net) 97 | self.assertEqual(data[0].tolist(), train_data.tolist()) 98 | data = run_net(test_net) 99 | self.assertEqual(data[0].tolist(), test_data.tolist()) 100 | test_loader.shutdown() 101 | train_loader.shutdown() 102 | 103 | 104 | if __name__ == '__main__': 105 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 106 | logger = logging_utils.setup_logging(__name__) 107 | logger.setLevel(logging.DEBUG) 108 | logging.getLogger('detectron.roi_data.loader').setLevel(logging.INFO) 109 | np.random.seed(cfg.RNG_SEED) 110 | cfg.TRAIN.ASPECT_GROUPING = False 111 | cfg.NUM_GPUS = 2 112 | assert_and_infer_cfg() 113 | unittest.main() 114 | -------------------------------------------------------------------------------- /eval/detectron/tests/test_smooth_l1_loss_op.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from caffe2.proto import caffe2_pb2 17 | from caffe2.python import core 18 | from caffe2.python import gradient_checker 19 | from caffe2.python import workspace 20 | 21 | import detectron.utils.c2 as c2_utils 22 | import detectron.utils.logging as logging_utils 23 | 24 | 25 | class SmoothL1LossTest(unittest.TestCase): 26 | def test_forward_and_gradient(self): 27 | Y = np.random.randn(128, 4 * 21).astype(np.float32) 28 | Y_hat = np.random.randn(128, 4 * 21).astype(np.float32) 29 | inside_weights = np.random.randn(128, 4 * 21).astype(np.float32) 30 | inside_weights[inside_weights < 0] = 0 31 | outside_weights = np.random.randn(128, 4 * 21).astype(np.float32) 32 | outside_weights[outside_weights < 0] = 0 33 | scale = np.random.random() 34 | beta = np.random.random() 35 | 36 | op = core.CreateOperator( 37 | 'SmoothL1Loss', ['Y_hat', 'Y', 'inside_weights', 'outside_weights'], 38 | ['loss'], 39 | scale=scale, 40 | beta=beta 41 | ) 42 | 43 | gc = gradient_checker.GradientChecker( 44 | stepsize=0.005, 45 | threshold=0.005, 46 | device_option=core.DeviceOption(caffe2_pb2.CUDA, 0) 47 | ) 48 | 49 | res, grad, grad_estimated = gc.CheckSimple( 50 | op, [Y_hat, Y, inside_weights, outside_weights], 0, [0] 51 | ) 52 | 53 | self.assertTrue( 54 | grad.shape == grad_estimated.shape, 55 | 'Fail check: grad.shape != grad_estimated.shape' 56 | ) 57 | 58 | # To inspect the gradient and estimated gradient: 59 | # np.set_printoptions(precision=3, suppress=True) 60 | # print('grad:') 61 | # print(grad) 62 | # print('grad_estimated:') 63 | # print(grad_estimated) 64 | 65 | self.assertTrue(res) 66 | 67 | 68 | if __name__ == '__main__': 69 | c2_utils.import_detectron_ops() 70 | assert 'SmoothL1Loss' in workspace.RegisteredOperators() 71 | logging_utils.setup_logging(__name__) 72 | unittest.main() 73 | -------------------------------------------------------------------------------- /eval/detectron/tests/test_spatial_narrow_as_op.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from caffe2.proto import caffe2_pb2 17 | from caffe2.python import core 18 | from caffe2.python import gradient_checker 19 | from caffe2.python import workspace 20 | 21 | import detectron.utils.c2 as c2_utils 22 | import detectron.utils.logging as logging_utils 23 | 24 | 25 | class SpatialNarrowAsOpTest(unittest.TestCase): 26 | def _run_test(self, A, B, check_grad=False): 27 | with core.DeviceScope(core.DeviceOption(caffe2_pb2.CUDA, 0)): 28 | op = core.CreateOperator('SpatialNarrowAs', ['A', 'B'], ['C']) 29 | workspace.FeedBlob('A', A) 30 | workspace.FeedBlob('B', B) 31 | workspace.RunOperatorOnce(op) 32 | C = workspace.FetchBlob('C') 33 | 34 | if check_grad: 35 | gc = gradient_checker.GradientChecker( 36 | stepsize=0.005, 37 | threshold=0.005, 38 | device_option=core.DeviceOption(caffe2_pb2.CUDA, 0) 39 | ) 40 | 41 | res, grad, grad_estimated = gc.CheckSimple(op, [A, B], 0, [0]) 42 | self.assertTrue(res, 'Grad check failed') 43 | 44 | dims = C.shape 45 | C_ref = A[:dims[0], :dims[1], :dims[2], :dims[3]] 46 | np.testing.assert_allclose(C, C_ref, rtol=1e-5, atol=1e-08) 47 | 48 | def test_small_forward_and_gradient(self): 49 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 50 | B = np.random.randn(2, 3, 2, 2).astype(np.float32) 51 | self._run_test(A, B, check_grad=True) 52 | 53 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 54 | B = np.random.randn(2, 3, 5).astype(np.float32) 55 | self._run_test(A, B, check_grad=True) 56 | 57 | def test_large_forward(self): 58 | A = np.random.randn(2, 256, 42, 100).astype(np.float32) 59 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 60 | self._run_test(A, B) 61 | 62 | A = np.random.randn(2, 256, 42, 87).astype(np.float32) 63 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 64 | self._run_test(A, B) 65 | 66 | def test_size_exceptions(self): 67 | A = np.random.randn(2, 256, 42, 86).astype(np.float32) 68 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 69 | with self.assertRaises(RuntimeError): 70 | self._run_test(A, B) 71 | 72 | A = np.random.randn(2, 255, 42, 88).astype(np.float32) 73 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 74 | with self.assertRaises(RuntimeError): 75 | self._run_test(A, B) 76 | 77 | 78 | if __name__ == '__main__': 79 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 80 | c2_utils.import_detectron_ops() 81 | assert 'SpatialNarrowAs' in workspace.RegisteredOperators() 82 | logging_utils.setup_logging(__name__) 83 | unittest.main() 84 | -------------------------------------------------------------------------------- /eval/detectron/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/eval/detectron/utils/__init__.py -------------------------------------------------------------------------------- /eval/detectron/utils/collections.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """A simple attribute dictionary used for representing configuration options.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | 16 | class AttrDict(dict): 17 | 18 | IMMUTABLE = '__immutable__' 19 | 20 | def __init__(self, *args, **kwargs): 21 | super(AttrDict, self).__init__(*args, **kwargs) 22 | self.__dict__[AttrDict.IMMUTABLE] = False 23 | 24 | def __getattr__(self, name): 25 | if name in self.__dict__: 26 | return self.__dict__[name] 27 | elif name in self: 28 | return self[name] 29 | else: 30 | raise AttributeError(name) 31 | 32 | def __setattr__(self, name, value): 33 | if not self.__dict__[AttrDict.IMMUTABLE]: 34 | if name in self.__dict__: 35 | self.__dict__[name] = value 36 | else: 37 | self[name] = value 38 | else: 39 | raise AttributeError( 40 | 'Attempted to set "{}" to "{}", but AttrDict is immutable'. 41 | format(name, value) 42 | ) 43 | 44 | def immutable(self, is_immutable): 45 | """Set immutability to is_immutable and recursively apply the setting 46 | to all nested AttrDicts. 47 | """ 48 | self.__dict__[AttrDict.IMMUTABLE] = is_immutable 49 | # Recursively set immutable state 50 | for v in self.__dict__.values(): 51 | if isinstance(v, AttrDict): 52 | v.immutable(is_immutable) 53 | for v in self.values(): 54 | if isinstance(v, AttrDict): 55 | v.immutable(is_immutable) 56 | 57 | def is_immutable(self): 58 | return self.__dict__[AttrDict.IMMUTABLE] 59 | -------------------------------------------------------------------------------- /eval/detectron/utils/colormap.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """An awesome colormap for really neat visualizations.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import numpy as np 16 | 17 | 18 | def colormap(rgb=False): 19 | color_list = np.array( 20 | [ 21 | 0.000, 0.447, 0.741, 22 | 0.850, 0.325, 0.098, 23 | 0.929, 0.694, 0.125, 24 | 0.494, 0.184, 0.556, 25 | 0.466, 0.674, 0.188, 26 | 0.301, 0.745, 0.933, 27 | 0.635, 0.078, 0.184, 28 | 0.300, 0.300, 0.300, 29 | 0.600, 0.600, 0.600, 30 | 1.000, 0.000, 0.000, 31 | 1.000, 0.500, 0.000, 32 | 0.749, 0.749, 0.000, 33 | 0.000, 1.000, 0.000, 34 | 0.000, 0.000, 1.000, 35 | 0.667, 0.000, 1.000, 36 | 0.333, 0.333, 0.000, 37 | 0.333, 0.667, 0.000, 38 | 0.333, 1.000, 0.000, 39 | 0.667, 0.333, 0.000, 40 | 0.667, 0.667, 0.000, 41 | 0.667, 1.000, 0.000, 42 | 1.000, 0.333, 0.000, 43 | 1.000, 0.667, 0.000, 44 | 1.000, 1.000, 0.000, 45 | 0.000, 0.333, 0.500, 46 | 0.000, 0.667, 0.500, 47 | 0.000, 1.000, 0.500, 48 | 0.333, 0.000, 0.500, 49 | 0.333, 0.333, 0.500, 50 | 0.333, 0.667, 0.500, 51 | 0.333, 1.000, 0.500, 52 | 0.667, 0.000, 0.500, 53 | 0.667, 0.333, 0.500, 54 | 0.667, 0.667, 0.500, 55 | 0.667, 1.000, 0.500, 56 | 1.000, 0.000, 0.500, 57 | 1.000, 0.333, 0.500, 58 | 1.000, 0.667, 0.500, 59 | 1.000, 1.000, 0.500, 60 | 0.000, 0.333, 1.000, 61 | 0.000, 0.667, 1.000, 62 | 0.000, 1.000, 1.000, 63 | 0.333, 0.000, 1.000, 64 | 0.333, 0.333, 1.000, 65 | 0.333, 0.667, 1.000, 66 | 0.333, 1.000, 1.000, 67 | 0.667, 0.000, 1.000, 68 | 0.667, 0.333, 1.000, 69 | 0.667, 0.667, 1.000, 70 | 0.667, 1.000, 1.000, 71 | 1.000, 0.000, 1.000, 72 | 1.000, 0.333, 1.000, 73 | 1.000, 0.667, 1.000, 74 | 0.167, 0.000, 0.000, 75 | 0.333, 0.000, 0.000, 76 | 0.500, 0.000, 0.000, 77 | 0.667, 0.000, 0.000, 78 | 0.833, 0.000, 0.000, 79 | 1.000, 0.000, 0.000, 80 | 0.000, 0.167, 0.000, 81 | 0.000, 0.333, 0.000, 82 | 0.000, 0.500, 0.000, 83 | 0.000, 0.667, 0.000, 84 | 0.000, 0.833, 0.000, 85 | 0.000, 1.000, 0.000, 86 | 0.000, 0.000, 0.167, 87 | 0.000, 0.000, 0.333, 88 | 0.000, 0.000, 0.500, 89 | 0.000, 0.000, 0.667, 90 | 0.000, 0.000, 0.833, 91 | 0.000, 0.000, 1.000, 92 | 0.000, 0.000, 0.000, 93 | 0.143, 0.143, 0.143, 94 | 0.286, 0.286, 0.286, 95 | 0.429, 0.429, 0.429, 96 | 0.571, 0.571, 0.571, 97 | 0.714, 0.714, 0.714, 98 | 0.857, 0.857, 0.857, 99 | 1.000, 1.000, 1.000 100 | ] 101 | ).astype(np.float32) 102 | color_list = color_list.reshape((-1, 3)) * 255 103 | if not rgb: 104 | color_list = color_list[:, ::-1] 105 | return color_list 106 | -------------------------------------------------------------------------------- /eval/detectron/utils/coordinator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Coordinated access to a shared multithreading/processing queue.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import contextlib 16 | import logging 17 | import Queue 18 | import threading 19 | import traceback 20 | 21 | log = logging.getLogger(__name__) 22 | 23 | 24 | class Coordinator(object): 25 | 26 | def __init__(self): 27 | self._event = threading.Event() 28 | 29 | def request_stop(self): 30 | log.debug('Coordinator stopping') 31 | self._event.set() 32 | 33 | def should_stop(self): 34 | return self._event.is_set() 35 | 36 | def wait_for_stop(self): 37 | return self._event.wait() 38 | 39 | @contextlib.contextmanager 40 | def stop_on_exception(self): 41 | try: 42 | yield 43 | except Exception: 44 | if not self.should_stop(): 45 | traceback.print_exc() 46 | self.request_stop() 47 | 48 | 49 | def coordinated_get(coordinator, queue): 50 | while not coordinator.should_stop(): 51 | try: 52 | return queue.get(block=True, timeout=1.0) 53 | except Queue.Empty: 54 | continue 55 | raise Exception('Coordinator stopped during get()') 56 | 57 | 58 | def coordinated_put(coordinator, queue, element): 59 | while not coordinator.should_stop(): 60 | try: 61 | queue.put(element, block=True, timeout=1.0) 62 | return 63 | except Queue.Full: 64 | continue 65 | raise Exception('Coordinator stopped during put()') 66 | -------------------------------------------------------------------------------- /eval/detectron/utils/cython_bbox.pyx: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017-present, Facebook, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ############################################################################## 15 | # 16 | # Based on: 17 | # -------------------------------------------------------- 18 | # Fast R-CNN 19 | # Copyright (c) 2015 Microsoft 20 | # Licensed under The MIT License [see LICENSE for details] 21 | # Written by Sergey Karayev 22 | # -------------------------------------------------------- 23 | 24 | cimport cython 25 | import numpy as np 26 | cimport numpy as np 27 | 28 | DTYPE = np.float32 29 | ctypedef np.float32_t DTYPE_t 30 | 31 | @cython.boundscheck(False) 32 | def bbox_overlaps( 33 | np.ndarray[DTYPE_t, ndim=2] boxes, 34 | np.ndarray[DTYPE_t, ndim=2] query_boxes): 35 | """ 36 | Parameters 37 | ---------- 38 | boxes: (N, 4) ndarray of float 39 | query_boxes: (K, 4) ndarray of float 40 | Returns 41 | ------- 42 | overlaps: (N, K) ndarray of overlap between boxes and query_boxes 43 | """ 44 | cdef unsigned int N = boxes.shape[0] 45 | cdef unsigned int K = query_boxes.shape[0] 46 | cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE) 47 | cdef DTYPE_t iw, ih, box_area 48 | cdef DTYPE_t ua 49 | cdef unsigned int k, n 50 | with nogil: 51 | for k in range(K): 52 | box_area = ( 53 | (query_boxes[k, 2] - query_boxes[k, 0] + 1) * 54 | (query_boxes[k, 3] - query_boxes[k, 1] + 1) 55 | ) 56 | for n in range(N): 57 | iw = ( 58 | min(boxes[n, 2], query_boxes[k, 2]) - 59 | max(boxes[n, 0], query_boxes[k, 0]) + 1 60 | ) 61 | if iw > 0: 62 | ih = ( 63 | min(boxes[n, 3], query_boxes[k, 3]) - 64 | max(boxes[n, 1], query_boxes[k, 1]) + 1 65 | ) 66 | if ih > 0: 67 | ua = float( 68 | (boxes[n, 2] - boxes[n, 0] + 1) * 69 | (boxes[n, 3] - boxes[n, 1] + 1) + 70 | box_area - iw * ih 71 | ) 72 | overlaps[n, k] = iw * ih / ua 73 | return overlaps 74 | -------------------------------------------------------------------------------- /eval/detectron/utils/env.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Environment helper functions.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import os 16 | import sys 17 | 18 | # Default value of the CMake install prefix 19 | _CMAKE_INSTALL_PREFIX = '/usr/local' 20 | 21 | 22 | def get_runtime_dir(): 23 | """Retrieve the path to the runtime directory.""" 24 | return sys.path[0] 25 | 26 | 27 | def get_py_bin_ext(): 28 | """Retrieve python binary extension.""" 29 | return '.py' 30 | 31 | 32 | def set_up_matplotlib(): 33 | """Set matplotlib up.""" 34 | import matplotlib 35 | # Use a non-interactive backend 36 | matplotlib.use('Agg') 37 | 38 | 39 | def exit_on_error(): 40 | """Exit from a detectron tool when there's an error.""" 41 | sys.exit(1) 42 | 43 | 44 | def import_nccl_ops(): 45 | """Import NCCL ops.""" 46 | # There is no need to load NCCL ops since the 47 | # NCCL dependency is built into the Caffe2 gpu lib 48 | pass 49 | 50 | 51 | def get_detectron_ops_lib(): 52 | """Retrieve Detectron ops library.""" 53 | # Candidate prefixes for the detectron ops lib path 54 | prefixes = [_CMAKE_INSTALL_PREFIX, sys.prefix, sys.exec_prefix] + sys.path 55 | # Search for detectron ops lib 56 | for prefix in prefixes: 57 | ops_path = os.path.join(prefix, 'lib/libcaffe2_detectron_ops_gpu.so') 58 | if os.path.exists(ops_path): 59 | # TODO(ilijar): Switch to using a logger 60 | print('Found Detectron ops lib: {}'.format(ops_path)) 61 | break 62 | assert os.path.exists(ops_path), \ 63 | ('Detectron ops lib not found; make sure that your Caffe2 ' 64 | 'version includes Detectron module') 65 | return ops_path 66 | 67 | 68 | def get_custom_ops_lib(): 69 | """Retrieve custom ops library.""" 70 | det_dir, _ = os.path.split(os.path.dirname(__file__)) 71 | root_dir, _ = os.path.split(det_dir) 72 | custom_ops_lib = os.path.join( 73 | root_dir, 'build/libcaffe2_detectron_custom_ops_gpu.so') 74 | assert os.path.exists(custom_ops_lib), \ 75 | 'Custom ops lib not found at \'{}\''.format(custom_ops_lib) 76 | return custom_ops_lib 77 | -------------------------------------------------------------------------------- /eval/detectron/utils/image.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Image helper functions.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import cv2 16 | import numpy as np 17 | 18 | 19 | def aspect_ratio_rel(im, aspect_ratio): 20 | """Performs width-relative aspect ratio transformation.""" 21 | im_h, im_w = im.shape[:2] 22 | im_ar_w = int(round(aspect_ratio * im_w)) 23 | im_ar = cv2.resize(im, dsize=(im_ar_w, im_h)) 24 | return im_ar 25 | 26 | 27 | def aspect_ratio_abs(im, aspect_ratio): 28 | """Performs absolute aspect ratio transformation.""" 29 | im_h, im_w = im.shape[:2] 30 | im_area = im_h * im_w 31 | 32 | im_ar_w = np.sqrt(im_area * aspect_ratio) 33 | im_ar_h = np.sqrt(im_area / aspect_ratio) 34 | assert np.isclose(im_ar_w / im_ar_h, aspect_ratio) 35 | 36 | im_ar = cv2.resize(im, dsize=(int(im_ar_w), int(im_ar_h))) 37 | return im_ar 38 | -------------------------------------------------------------------------------- /eval/detectron/utils/logging.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Utilities for logging.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | from collections import deque 16 | from email.mime.text import MIMEText 17 | import json 18 | import logging 19 | import numpy as np 20 | import smtplib 21 | import sys 22 | 23 | # Print lower precision floating point values than default FLOAT_REPR 24 | json.encoder.FLOAT_REPR = lambda o: format(o, '.6f') 25 | 26 | 27 | def log_json_stats(stats, sort_keys=True): 28 | print('json_stats: {:s}'.format(json.dumps(stats, sort_keys=sort_keys))) 29 | 30 | 31 | class SmoothedValue(object): 32 | """Track a series of values and provide access to smoothed values over a 33 | window or the global series average. 34 | """ 35 | 36 | def __init__(self, window_size): 37 | self.deque = deque(maxlen=window_size) 38 | self.series = [] 39 | self.total = 0.0 40 | self.count = 0 41 | 42 | def AddValue(self, value): 43 | self.deque.append(value) 44 | self.series.append(value) 45 | self.count += 1 46 | self.total += value 47 | 48 | def GetMedianValue(self): 49 | return np.median(self.deque) 50 | 51 | def GetAverageValue(self): 52 | return np.mean(self.deque) 53 | 54 | def GetGlobalAverageValue(self): 55 | return self.total / self.count 56 | 57 | 58 | def send_email(subject, body, to): 59 | s = smtplib.SMTP('localhost') 60 | mime = MIMEText(body) 61 | mime['Subject'] = subject 62 | mime['To'] = to 63 | s.sendmail('detectron', to, mime.as_string()) 64 | 65 | 66 | def setup_logging(name): 67 | FORMAT = '%(levelname)s %(filename)s:%(lineno)4d: %(message)s' 68 | # Manually clear root loggers to prevent any module that may have called 69 | # logging.basicConfig() from blocking our logging setup 70 | logging.root.handlers = [] 71 | logging.basicConfig(level=logging.INFO, format=FORMAT, stream=sys.stdout) 72 | logger = logging.getLogger(name) 73 | return logger 74 | -------------------------------------------------------------------------------- /eval/detectron/utils/lr_policy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Learning rate policies.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import numpy as np 16 | 17 | from detectron.core.config import cfg 18 | 19 | 20 | def get_lr_at_iter(it): 21 | """Get the learning rate at iteration it according to the cfg.SOLVER 22 | settings. 23 | """ 24 | lr = get_lr_func()(it) 25 | if it < cfg.SOLVER.WARM_UP_ITERS: 26 | method = cfg.SOLVER.WARM_UP_METHOD 27 | if method == 'constant': 28 | warmup_factor = cfg.SOLVER.WARM_UP_FACTOR 29 | elif method == 'linear': 30 | alpha = it / cfg.SOLVER.WARM_UP_ITERS 31 | warmup_factor = cfg.SOLVER.WARM_UP_FACTOR * (1 - alpha) + alpha 32 | else: 33 | raise KeyError('Unknown SOLVER.WARM_UP_METHOD: {}'.format(method)) 34 | lr *= warmup_factor 35 | return np.float32(lr) 36 | 37 | 38 | # ---------------------------------------------------------------------------- # 39 | # Learning rate policy functions 40 | # ---------------------------------------------------------------------------- # 41 | 42 | def lr_func_steps_with_lrs(cur_iter): 43 | """For cfg.SOLVER.LR_POLICY = 'steps_with_lrs' 44 | 45 | Change the learning rate to specified values at specified iterations. 46 | 47 | Example: 48 | cfg.SOLVER.MAX_ITER: 90 49 | cfg.SOLVER.STEPS: [0, 60, 80] 50 | cfg.SOLVER.LRS: [0.02, 0.002, 0.0002] 51 | for cur_iter in [0, 59] use 0.02 52 | in [60, 79] use 0.002 53 | in [80, inf] use 0.0002 54 | """ 55 | ind = get_step_index(cur_iter) 56 | return cfg.SOLVER.LRS[ind] 57 | 58 | 59 | def lr_func_steps_with_decay(cur_iter): 60 | """For cfg.SOLVER.LR_POLICY = 'steps_with_decay' 61 | 62 | Change the learning rate specified iterations based on the formula 63 | lr = base_lr * gamma ** lr_step_count. 64 | 65 | Example: 66 | cfg.SOLVER.MAX_ITER: 90 67 | cfg.SOLVER.STEPS: [0, 60, 80] 68 | cfg.SOLVER.BASE_LR: 0.02 69 | cfg.SOLVER.GAMMA: 0.1 70 | for cur_iter in [0, 59] use 0.02 = 0.02 * 0.1 ** 0 71 | in [60, 79] use 0.002 = 0.02 * 0.1 ** 1 72 | in [80, inf] use 0.0002 = 0.02 * 0.1 ** 2 73 | """ 74 | ind = get_step_index(cur_iter) 75 | return cfg.SOLVER.BASE_LR * cfg.SOLVER.GAMMA ** ind 76 | 77 | 78 | def lr_func_step(cur_iter): 79 | """For cfg.SOLVER.LR_POLICY = 'step' 80 | """ 81 | return ( 82 | cfg.SOLVER.BASE_LR * 83 | cfg.SOLVER.GAMMA ** (cur_iter // cfg.SOLVER.STEP_SIZE)) 84 | 85 | 86 | # ---------------------------------------------------------------------------- # 87 | # Helpers 88 | # ---------------------------------------------------------------------------- # 89 | 90 | def get_step_index(cur_iter): 91 | """Given an iteration, find which learning rate step we're at.""" 92 | assert cfg.SOLVER.STEPS[0] == 0, 'The first step should always start at 0.' 93 | steps = cfg.SOLVER.STEPS + [cfg.SOLVER.MAX_ITER] 94 | for ind, step in enumerate(steps): # NoQA 95 | if cur_iter < step: 96 | break 97 | return ind - 1 98 | 99 | 100 | def get_lr_func(): 101 | policy = 'lr_func_' + cfg.SOLVER.LR_POLICY 102 | if policy not in globals(): 103 | raise NotImplementedError( 104 | 'Unknown LR policy: {}'.format(cfg.SOLVER.LR_POLICY)) 105 | else: 106 | return globals()[policy] 107 | -------------------------------------------------------------------------------- /eval/detectron/utils/timer.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | # 8 | # Based on: 9 | # -------------------------------------------------------- 10 | # Fast R-CNN 11 | # Copyright (c) 2015 Microsoft 12 | # Licensed under The MIT License [see LICENSE for details] 13 | # Written by Ross Girshick 14 | # -------------------------------------------------------- 15 | 16 | """Timing related functions.""" 17 | 18 | from __future__ import absolute_import 19 | from __future__ import division 20 | from __future__ import print_function 21 | from __future__ import unicode_literals 22 | 23 | import time 24 | 25 | 26 | class Timer(object): 27 | """A simple timer.""" 28 | 29 | def __init__(self): 30 | self.reset() 31 | 32 | def tic(self): 33 | # using time.time instead of time.clock because time time.clock 34 | # does not normalize for multithreading 35 | self.start_time = time.time() 36 | 37 | def toc(self, average=True): 38 | self.diff = time.time() - self.start_time 39 | self.total_time += self.diff 40 | self.calls += 1 41 | self.average_time = self.total_time / self.calls 42 | if average: 43 | return self.average_time 44 | else: 45 | return self.diff 46 | 47 | def reset(self): 48 | self.total_time = 0. 49 | self.calls = 0 50 | self.start_time = 0. 51 | self.diff = 0. 52 | self.average_time = 0. 53 | -------------------------------------------------------------------------------- /eval/detectron/utils/training_stats.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Utilities for training.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import datetime 16 | import numpy as np 17 | 18 | from caffe2.python import utils as c2_py_utils 19 | 20 | from detectron.core.config import cfg 21 | from detectron.utils.logging import log_json_stats 22 | from detectron.utils.logging import SmoothedValue 23 | from detectron.utils.timer import Timer 24 | import detectron.utils.net as nu 25 | 26 | 27 | class TrainingStats(object): 28 | """Track vital training statistics.""" 29 | 30 | def __init__(self, model): 31 | # Window size for smoothing tracked values (with median filtering) 32 | self.WIN_SZ = 20 33 | # Output logging period in SGD iterations 34 | self.LOG_PERIOD = 20 35 | self.smoothed_losses_and_metrics = { 36 | key: SmoothedValue(self.WIN_SZ) 37 | for key in model.losses + model.metrics 38 | } 39 | self.losses_and_metrics = { 40 | key: 0 41 | for key in model.losses + model.metrics 42 | } 43 | self.smoothed_total_loss = SmoothedValue(self.WIN_SZ) 44 | self.smoothed_mb_qsize = SmoothedValue(self.WIN_SZ) 45 | self.iter_total_loss = np.nan 46 | self.iter_timer = Timer() 47 | self.model = model 48 | 49 | def IterTic(self): 50 | self.iter_timer.tic() 51 | 52 | def IterToc(self): 53 | return self.iter_timer.toc(average=False) 54 | 55 | def ResetIterTimer(self): 56 | self.iter_timer.reset() 57 | 58 | def UpdateIterStats(self): 59 | """Update tracked iteration statistics.""" 60 | for k in self.losses_and_metrics.keys(): 61 | if k in self.model.losses: 62 | self.losses_and_metrics[k] = nu.sum_multi_gpu_blob(k) 63 | else: 64 | self.losses_and_metrics[k] = nu.average_multi_gpu_blob(k) 65 | for k, v in self.smoothed_losses_and_metrics.items(): 66 | v.AddValue(self.losses_and_metrics[k]) 67 | self.iter_total_loss = np.sum( 68 | np.array([self.losses_and_metrics[k] for k in self.model.losses]) 69 | ) 70 | self.smoothed_total_loss.AddValue(self.iter_total_loss) 71 | self.smoothed_mb_qsize.AddValue( 72 | self.model.roi_data_loader._minibatch_queue.qsize() 73 | ) 74 | 75 | def LogIterStats(self, cur_iter, lr): 76 | """Log the tracked statistics.""" 77 | if (cur_iter % self.LOG_PERIOD == 0 or 78 | cur_iter == cfg.SOLVER.MAX_ITER - 1): 79 | stats = self.GetStats(cur_iter, lr) 80 | log_json_stats(stats) 81 | 82 | def GetStats(self, cur_iter, lr): 83 | eta_seconds = self.iter_timer.average_time * ( 84 | cfg.SOLVER.MAX_ITER - cur_iter 85 | ) 86 | eta = str(datetime.timedelta(seconds=int(eta_seconds))) 87 | mem_stats = c2_py_utils.GetGPUMemoryUsageStats() 88 | mem_usage = np.max(mem_stats['max_by_gpu'][:cfg.NUM_GPUS]) 89 | stats = dict( 90 | iter=cur_iter, 91 | lr=float(lr), 92 | time=self.iter_timer.average_time, 93 | loss=self.smoothed_total_loss.GetMedianValue(), 94 | eta=eta, 95 | mb_qsize=int( 96 | np.round(self.smoothed_mb_qsize.GetMedianValue()) 97 | ), 98 | mem=int(np.ceil(mem_usage / 1024 / 1024)) 99 | ) 100 | for k, v in self.smoothed_losses_and_metrics.items(): 101 | stats[k] = v.GetMedianValue() 102 | return stats 103 | -------------------------------------------------------------------------------- /eval/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use Caffe2 image as parent image 2 | FROM caffe2/caffe2:snapshot-py2-cuda9.0-cudnn7-ubuntu16.04 3 | 4 | RUN mv /usr/local/caffe2 /usr/local/caffe2_build 5 | ENV Caffe2_DIR /usr/local/caffe2_build 6 | 7 | ENV PYTHONPATH /usr/local/caffe2_build:${PYTHONPATH} 8 | ENV LD_LIBRARY_PATH /usr/local/caffe2_build/lib:${LD_LIBRARY_PATH} 9 | 10 | # Clone the Detectron repository 11 | RUN git clone https://github.com/facebookresearch/densepose /densepose 12 | 13 | # Install Python dependencies 14 | RUN pip install -r /densepose/requirements.txt 15 | 16 | # Install the COCO API 17 | RUN git clone https://github.com/cocodataset/cocoapi.git /cocoapi 18 | WORKDIR /cocoapi/PythonAPI 19 | RUN make install 20 | 21 | # Go to Densepose root 22 | WORKDIR /densepose 23 | 24 | # Set up Python modules 25 | RUN make 26 | 27 | # [Optional] Build custom ops 28 | RUN make ops 29 | -------------------------------------------------------------------------------- /eval/environment.yml: -------------------------------------------------------------------------------- 1 | name: py2 2 | channels: 3 | - pytorch 4 | - defaults 5 | dependencies: 6 | - _libgcc_mutex=0.1=main 7 | - blas=1.0=mkl 8 | - ca-certificates=2021.1.19=h06a4308_1 9 | - certifi=2020.6.20=pyhd3eb1b0_3 10 | - cffi=1.14.0=py27he30daa8_1 11 | - cuda80=1.0=h205658b_0 12 | - cudatoolkit=10.0.130=0 13 | - intel-openmp=2020.2=254 14 | - libedit=3.1.20191231=h14c3975_1 15 | - libffi=3.3=he6710b0_2 16 | - libgcc-ng=9.1.0=hdf63c60_0 17 | - libgfortran-ng=7.3.0=hdf63c60_0 18 | - libstdcxx-ng=9.1.0=hdf63c60_0 19 | - memory_profiler=0.58.0=py_0 20 | - mkl=2020.2=256 21 | - mkl-service=2.3.0=py27he904b0f_0 22 | - mkl_fft=1.0.15=py27ha843d7b_0 23 | - mkl_random=1.1.0=py27hd6b4f25_0 24 | - ncurses=6.2=he6710b0_1 25 | - ninja=1.9.0=py27hfd86e86_0 26 | - numpy=1.16.6=py27hbc911f0_0 27 | - numpy-base=1.16.6=py27hde5b4d6_0 28 | - pip=19.3.1=py27_0 29 | - psutil=5.6.7=py27h7b6447c_0 30 | - pycparser=2.20=py_2 31 | - python=2.7.18=h15b4118_1 32 | - pytorch-nightly=1.0.0.dev20190328=py2.7_cuda10.0.130_cudnn7.4.2_0 33 | - readline=8.1=h27cfd23_0 34 | - setuptools=44.0.0=py27_0 35 | - six=1.15.0=pyhd3eb1b0_0 36 | - sqlite=3.33.0=h62c20be_0 37 | - tk=8.6.10=hbc83047_0 38 | - wheel=0.36.2=pyhd3eb1b0_0 39 | - zlib=1.2.11=h7b6447c_3 40 | - pip: 41 | - backports-functools-lru-cache==1.6.1 42 | - cycler==0.10.0 43 | - cython==0.29.22 44 | - funcsigs==1.0.2 45 | - future==0.18.2 46 | - h5py==2.10.0 47 | - kiwisolver==1.1.0 48 | - matplotlib==2.2.5 49 | - mock==3.0.5 50 | - opencv-python==3.4.3.18 51 | - pillow==6.2.2 52 | - protobuf==3.15.6 53 | - pycocotools==2.0.2 54 | - pyparsing==2.4.7 55 | - python-dateutil==2.8.1 56 | - pytz==2021.1 57 | - pyyaml==3.12 58 | - scipy==1.2.3 59 | - subprocess32==3.5.4 60 | prefix: /home/songkey/miniconda3/envs/py2 61 | -------------------------------------------------------------------------------- /eval/eval_json.py: -------------------------------------------------------------------------------- 1 | from detectron.datasets import json_dataset 2 | from detectron.datasets import json_dataset_evaluator 3 | import json 4 | import cv2 5 | 6 | 7 | if __name__ == '__main__': 8 | # res_path = '/home/songkey/workspace/data/densepose-gen/result/yan.haonan/model_FCN_head.test.pkl' 9 | # res_path = '/home/songkey/workspace/data/densepose-gen/result/dp-model0317/res_dp_depth_ep100_ct8383_bs8_ws6_coco_data_fpn_model.pth.pkl' 10 | res_path = '/home/songkey/workspace/data/densepose-gen/result/15w/res2_dp_ep133_ct16755_bs10_ws8_big_data_pixel2pixelhd_model.pth.pkl' 11 | res_path = '/home/songkey/workspace/data/densepose-gen/result/coco-all-result/res2_dp_ep148_ct31905_bs10_ws8_coco_data_pixel2pixelhd_model.pth.pkl' 12 | res_path = '/home/songkey/workspace/data/densepose-gen/result/15w/res_dp_ep182_ct22880_bs10_ws8_big_data_pixel2pixelhd_model.pth.pkl' 13 | res_path = '/home/songkey/workspace/data/densepose-gen/result/coco-all-result/res_dp_ep136_ct26025_bs10_ws8_coco_data_pixel2pixelhd_model.pth.pkl' 14 | 15 | res_path = '/home/songkey/workspace/data/densepose-gen/result/coco-all-result/0317-coco-framework/model_FCN_head_15w.test.pkl' 16 | res_path = '/home/songkey/workspace/data/densepose-gen/result/15w/res_dp_ep273_ct34255_bs10_ws8_big_data_pixel2pixelhd_model.pth.pkl' 17 | 18 | 19 | # 2021-10-29 20 | # res_path = '/media/johnny/5CD86FA3D86F7A62/checkpoints/badDP/ultraTrans/res_dp_ep39_ct13320_bs6_ws2_coco_data_transformer_model.pth.pkl' # epoch 39 21 | res_path = "/media/johnny/5CD86FA3D86F7A62/checkpoints/badDP/ultraTrans/DL_15w.pkl" 22 | res_path = "/media/johnny/5CD86FA3D86F7A62/checkpoints/badDP/ultraTrans/DL_CONF_15w.pkl" 23 | res_path = "/media/johnny/5CD86FA3D86F7A62/checkpoints/badDP/ultraTrans/FCN_15w.pkl" 24 | res_path = "/media/johnny/5CD86FA3D86F7A62/checkpoints/badDP/ultraTrans/DL_4k.pkl" # dl 4k 25 | 26 | # import pickle 27 | # params = pickle.load(open(res_path, 'rb')) 28 | # for i in range(len(params)): 29 | # print(params[i]['uv'].shape, params[i]['uv_shape'], params[i]['bbox']) 30 | # parama = params[i] 31 | # cv2.imshow('show', parama['uv'].transpose(1, 2, 0)) 32 | # cv2.waitKey() 33 | # print('hello') 34 | 35 | # js_dataset = json_dataset.JsonDataset('dense_coco_2014_valminusminival') 36 | # js_dataset = json_dataset.JsonDataset('hn_densepose_val2014') 37 | js_dataset = json_dataset.JsonDataset('densepose_valminusminival2014') 38 | # js_dataset = json_dataset.JsonDataset('hn_densepose_train500') 39 | # js_dataset = json_dataset.JsonDataset('densepose_val5000') 40 | json_dataset_evaluator._do_body_uv_eval(js_dataset, res_path, ' ') -------------------------------------------------------------------------------- /eval/parse_json.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import json 4 | 5 | if __name__ == '__main__': 6 | json_path = '' -------------------------------------------------------------------------------- /eval/requirements.txt: -------------------------------------------------------------------------------- 1 | absl-py==0.15.0 2 | cached-property==1.5.2 3 | certifi==2021.10.8 4 | charset-normalizer==2.0.7 5 | contextlib2==21.6.0 6 | cycler==0.11.0 7 | Cython==0.29.24 8 | -e git+https://git.wemomo.com/songkey/ultrapose.git@2328826a7a3fcf8ff6fc1f8e2fb288e8cad2c988#egg=Detectron&subdirectory=eval 9 | future==0.18.2 10 | h5py==3.5.0 11 | idna==3.3 12 | imageio==2.10.1 13 | imgaug==0.4.0 14 | jsonpatch==1.32 15 | jsonpointer==2.1 16 | kiwisolver==1.3.2 17 | matplotlib==3.4.3 18 | mkl-fft==1.3.1 19 | mkl-random @ file:///tmp/build/80754af9/mkl_random_1626179032232/work 20 | mkl-service==2.4.0 21 | ml-collections==0.1.0 22 | networkx==2.6.3 23 | numpy @ file:///tmp/build/80754af9/numpy_and_numpy_base_1634106693478/work 24 | olefile==0.46 25 | opencv-python==4.5.4.58 26 | Pillow==8.4.0 27 | pycocotools==2.0.2 28 | pyparsing==3.0.4 29 | python-dateutil==2.8.2 30 | PyWavelets==1.1.1 31 | PyYAML==6.0 32 | pyzmq==22.3.0 33 | requests==2.26.0 34 | scikit-image==0.18.3 35 | scipy==1.7.1 36 | Shapely==1.8.0 37 | six @ file:///tmp/build/80754af9/six_1623709665295/work 38 | tifffile==2021.10.12 39 | torch==1.7.1 40 | torchfile==0.1.0 41 | torchvision==0.8.2 42 | tornado==6.1 43 | typing-extensions @ file:///tmp/build/80754af9/typing_extensions_1631814937681/work 44 | urllib3==1.26.7 45 | visdom==0.1.8.9 46 | websocket-client==1.2.1 47 | -------------------------------------------------------------------------------- /eval/setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | 12 | from Cython.Build import cythonize 13 | from setuptools import Extension 14 | from setuptools import setup 15 | 16 | import numpy as np 17 | 18 | _NP_INCLUDE_DIRS = np.get_include() 19 | 20 | 21 | # Extension modules 22 | ext_modules = [ 23 | Extension( 24 | name='detectron.utils.cython_bbox', 25 | sources=[ 26 | 'detectron/utils/cython_bbox.pyx' 27 | ], 28 | extra_compile_args=[ 29 | '-Wno-cpp' 30 | ], 31 | include_dirs=[ 32 | _NP_INCLUDE_DIRS 33 | ] 34 | ), 35 | Extension( 36 | name='detectron.utils.cython_nms', 37 | sources=[ 38 | 'detectron/utils/cython_nms.pyx' 39 | ], 40 | extra_compile_args=[ 41 | '-Wno-cpp' 42 | ], 43 | include_dirs=[ 44 | _NP_INCLUDE_DIRS 45 | ] 46 | ) 47 | ] 48 | 49 | setup( 50 | name='Detectron', 51 | packages=['detectron'], 52 | ext_modules=cythonize(ext_modules) 53 | ) 54 | -------------------------------------------------------------------------------- /eval/tools/test_net.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Perform inference on one or more datasets.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import argparse 16 | import cv2 # NOQA (Must import before importing caffe2 due to bug in cv2) 17 | import os 18 | import pprint 19 | import sys 20 | import time 21 | 22 | from caffe2.python import workspace 23 | 24 | from detectron.core.config import assert_and_infer_cfg 25 | from detectron.core.config import cfg 26 | from detectron.core.config import merge_cfg_from_file 27 | from detectron.core.config import merge_cfg_from_list 28 | from detectron.core.test_engine import run_inference 29 | from detectron.utils.logging import setup_logging 30 | import detectron.utils.c2 as c2_utils 31 | 32 | c2_utils.import_detectron_ops() 33 | c2_utils.import_custom_ops() 34 | 35 | 36 | #utils.c2.import_custom_ops() 37 | #utils.c2.import_detectron_ops() 38 | 39 | # OpenCL may be enabled by default in OpenCV3; disable it because it's not 40 | # thread safe and causes unwanted GPU memory allocations. 41 | cv2.ocl.setUseOpenCL(False) 42 | 43 | 44 | def parse_args(): 45 | parser = argparse.ArgumentParser(description='Test a Fast R-CNN network') 46 | parser.add_argument( 47 | '--cfg', 48 | dest='cfg_file', 49 | help='optional config file', 50 | default=None, 51 | type=str 52 | ) 53 | parser.add_argument( 54 | '--wait', 55 | dest='wait', 56 | help='wait until net file exists', 57 | default=True, 58 | type=bool 59 | ) 60 | parser.add_argument( 61 | '--vis', dest='vis', help='visualize detections', action='store_true' 62 | ) 63 | parser.add_argument( 64 | '--multi-gpu-testing', 65 | dest='multi_gpu_testing', 66 | help='using cfg.NUM_GPUS for inference', 67 | action='store_true' 68 | ) 69 | parser.add_argument( 70 | '--range', 71 | dest='range', 72 | help='start (inclusive) and end (exclusive) indices', 73 | default=None, 74 | type=int, 75 | nargs=2 76 | ) 77 | parser.add_argument( 78 | 'opts', 79 | help='See detectron/core/config.py for all options', 80 | default=None, 81 | nargs=argparse.REMAINDER 82 | ) 83 | if len(sys.argv) == 1: 84 | parser.print_help() 85 | sys.exit(1) 86 | return parser.parse_args() 87 | 88 | 89 | if __name__ == '__main__': 90 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 91 | logger = setup_logging(__name__) 92 | args = parse_args() 93 | logger.info('Called with args:') 94 | logger.info(args) 95 | if args.cfg_file is not None: 96 | merge_cfg_from_file(args.cfg_file) 97 | if args.opts is not None: 98 | merge_cfg_from_list(args.opts) 99 | assert_and_infer_cfg() 100 | logger.info('Testing with config:') 101 | logger.info(pprint.pformat(cfg)) 102 | 103 | while not os.path.exists(cfg.TEST.WEIGHTS) and args.wait: 104 | logger.info('Waiting for \'{}\' to exist...'.format(cfg.TEST.WEIGHTS)) 105 | time.sleep(10) 106 | 107 | run_inference( 108 | cfg.TEST.WEIGHTS, 109 | ind_range=args.range, 110 | multi_gpu_testing=args.multi_gpu_testing, 111 | check_expected_results=True, 112 | ) 113 | -------------------------------------------------------------------------------- /eval/tools/train_net.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Train a network with Detectron.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import argparse 16 | import cv2 # NOQA (Must import before importing caffe2 due to bug in cv2) 17 | import logging 18 | import numpy as np 19 | import pprint 20 | import sys 21 | 22 | from caffe2.python import workspace 23 | 24 | from detectron.core.config import assert_and_infer_cfg 25 | from detectron.core.config import cfg 26 | from detectron.core.config import merge_cfg_from_file 27 | from detectron.core.config import merge_cfg_from_list 28 | from detectron.core.test_engine import run_inference 29 | from detectron.utils.logging import setup_logging 30 | import detectron.utils.c2 as c2_utils 31 | import detectron.utils.train 32 | 33 | c2_utils.import_contrib_ops() 34 | c2_utils.import_detectron_ops() 35 | c2_utils.import_custom_ops() 36 | 37 | # OpenCL may be enabled by default in OpenCV3; disable it because it's not 38 | # thread safe and causes unwanted GPU memory allocations. 39 | cv2.ocl.setUseOpenCL(False) 40 | 41 | 42 | def parse_args(): 43 | parser = argparse.ArgumentParser( 44 | description='Train a network with Detectron' 45 | ) 46 | parser.add_argument( 47 | '--cfg', 48 | dest='cfg_file', 49 | help='Config file for training (and optionally testing)', 50 | default=None, 51 | type=str 52 | ) 53 | parser.add_argument( 54 | '--multi-gpu-testing', 55 | dest='multi_gpu_testing', 56 | help='Use cfg.NUM_GPUS GPUs for inference', 57 | action='store_true' 58 | ) 59 | parser.add_argument( 60 | '--skip-test', 61 | dest='skip_test', 62 | help='Do not test the final model', 63 | action='store_true' 64 | ) 65 | parser.add_argument( 66 | 'opts', 67 | help='See detectron/core/config.py for all options', 68 | default=None, 69 | nargs=argparse.REMAINDER 70 | ) 71 | if len(sys.argv) == 1: 72 | parser.print_help() 73 | sys.exit(1) 74 | return parser.parse_args() 75 | 76 | 77 | def main(): 78 | # Initialize C2 79 | workspace.GlobalInit( 80 | ['caffe2', '--caffe2_log_level=0', '--caffe2_gpu_memory_tracking=1'] 81 | ) 82 | # Set up logging and load config options 83 | logger = setup_logging(__name__) 84 | logging.getLogger('detectron.roi_data.loader').setLevel(logging.INFO) 85 | args = parse_args() 86 | logger.info('Called with args:') 87 | logger.info(args) 88 | if args.cfg_file is not None: 89 | merge_cfg_from_file(args.cfg_file) 90 | if args.opts is not None: 91 | merge_cfg_from_list(args.opts) 92 | assert_and_infer_cfg() 93 | logger.info('Training with config:') 94 | logger.info(pprint.pformat(cfg)) 95 | # Note that while we set the numpy random seed network training will not be 96 | # deterministic in general. There are sources of non-determinism that cannot 97 | # be removed with a reasonble execution-speed tradeoff (such as certain 98 | # non-deterministic cudnn functions). 99 | np.random.seed(cfg.RNG_SEED) 100 | # Execute the training run 101 | checkpoints = detectron.utils.train.train_model() 102 | # Test the trained model 103 | if not args.skip_test: 104 | test_model(checkpoints['final'], args.multi_gpu_testing, args.opts) 105 | 106 | 107 | def test_model(model_file, multi_gpu_testing, opts=None): 108 | """Test a model.""" 109 | # Clear memory before inference 110 | workspace.ResetWorkspace() 111 | # Run inference 112 | run_inference( 113 | model_file, multi_gpu_testing=multi_gpu_testing, 114 | check_expected_results=True, 115 | ) 116 | 117 | 118 | if __name__ == '__main__': 119 | main() 120 | -------------------------------------------------------------------------------- /eval/tools/visualize_results.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Script for visualizing results saved in a detections.pkl file.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import argparse 16 | import cPickle as pickle 17 | import cv2 18 | import os 19 | import sys 20 | 21 | from detectron.datasets.json_dataset import JsonDataset 22 | import detectron.utils.vis as vis_utils 23 | 24 | # OpenCL may be enabled by default in OpenCV3; disable it because it's not 25 | # thread safe and causes unwanted GPU memory allocations. 26 | cv2.ocl.setUseOpenCL(False) 27 | 28 | 29 | def parse_args(): 30 | parser = argparse.ArgumentParser() 31 | parser.add_argument( 32 | '--dataset', 33 | dest='dataset', 34 | help='dataset', 35 | default='coco_2014_minival', 36 | type=str 37 | ) 38 | parser.add_argument( 39 | '--detections', 40 | dest='detections', 41 | help='detections pkl file', 42 | default='', 43 | type=str 44 | ) 45 | parser.add_argument( 46 | '--thresh', 47 | dest='thresh', 48 | help='detection prob threshold', 49 | default=0.9, 50 | type=float 51 | ) 52 | parser.add_argument( 53 | '--output-dir', 54 | dest='output_dir', 55 | help='output directory', 56 | default='./tmp/vis-output', 57 | type=str 58 | ) 59 | parser.add_argument( 60 | '--first', 61 | dest='first', 62 | help='only visualize the first k images', 63 | default=0, 64 | type=int 65 | ) 66 | if len(sys.argv) == 1: 67 | parser.print_help() 68 | sys.exit(1) 69 | args = parser.parse_args() 70 | return args 71 | 72 | 73 | def vis(dataset, detections_pkl, thresh, output_dir, limit=0): 74 | ds = JsonDataset(dataset) 75 | roidb = ds.get_roidb() 76 | 77 | with open(detections_pkl, 'r') as f: 78 | dets = pickle.load(f) 79 | 80 | assert all(k in dets for k in ['all_boxes', 'all_segms', 'all_keyps']), \ 81 | 'Expected detections pkl file in the format used by test_engine.py' 82 | 83 | all_boxes = dets['all_boxes'] 84 | all_segms = dets['all_segms'] 85 | all_keyps = dets['all_keyps'] 86 | 87 | def id_or_index(ix, val): 88 | if len(val) == 0: 89 | return val 90 | else: 91 | return val[ix] 92 | 93 | for ix, entry in enumerate(roidb): 94 | if limit > 0 and ix >= limit: 95 | break 96 | if ix % 10 == 0: 97 | print('{:d}/{:d}'.format(ix + 1, len(roidb))) 98 | 99 | im = cv2.imread(entry['image']) 100 | im_name = os.path.splitext(os.path.basename(entry['image']))[0] 101 | 102 | cls_boxes_i = [ 103 | id_or_index(ix, cls_k_boxes) for cls_k_boxes in all_boxes 104 | ] 105 | cls_segms_i = [ 106 | id_or_index(ix, cls_k_segms) for cls_k_segms in all_segms 107 | ] 108 | cls_keyps_i = [ 109 | id_or_index(ix, cls_k_keyps) for cls_k_keyps in all_keyps 110 | ] 111 | 112 | vis_utils.vis_one_image( 113 | im[:, :, ::-1], 114 | '{:d}_{:s}'.format(ix, im_name), 115 | os.path.join(output_dir, 'vis'), 116 | cls_boxes_i, 117 | segms=cls_segms_i, 118 | keypoints=cls_keyps_i, 119 | thresh=thresh, 120 | box_alpha=0.8, 121 | dataset=ds, 122 | show_class=True 123 | ) 124 | 125 | 126 | if __name__ == '__main__': 127 | opts = parse_args() 128 | vis( 129 | opts.dataset, 130 | opts.detections, 131 | opts.thresh, 132 | opts.output_dir, 133 | limit=opts.first 134 | ) 135 | -------------------------------------------------------------------------------- /loss/dp_loss.py: -------------------------------------------------------------------------------- 1 | """ 2 | created by songkey@pku.edu.cn 3 | date @ 2021-10-15 4 | """ 5 | import torch 6 | import torch.nn as nn 7 | 8 | class SoftIOULoss(nn.Module): 9 | ''' 10 | Soft_Dice = 2*|dot(A, B)| / (|dot(A, A)| + |dot(B, B)| + eps) 11 | eps is a small constant to avoid zero division, 12 | ''' 13 | 14 | def __init__(self, weight=1.): 15 | super(SoftIOULoss, self).__init__() 16 | self.activation = nn.Softmax2d() 17 | self.weight = weight 18 | 19 | def setWeights(self, weights): 20 | self.weight = weights 21 | 22 | def forward(self, y_preds, y_truths, eps=1e-8): 23 | ''' 24 | :param y_preds: [bs,num_classes,768,1024] 25 | :param y_truths: [bs,num_calsses,768,1024] 26 | :param eps: 27 | :return: 28 | ''' 29 | bs = y_preds.size(0) 30 | num_classes = y_preds.size(1) 31 | ious_bs = torch.zeros(bs, num_classes).to(y_preds.device) 32 | for idx in range(bs): 33 | y_pred = y_preds[idx] # [num_classes,768,1024] 34 | y_truth = y_truths[idx] # [num_classes,768,1024] 35 | intersection = torch.sum(torch.mul(y_pred, y_truth), dim=(1, 2)) + eps / 2 36 | union = torch.sum(torch.mul(y_pred, y_pred), dim=(1, 2)) + torch.sum(torch.mul(y_truth, y_truth), 37 | dim=(1, 2)) + eps 38 | 39 | ious_sub = intersection / (union - intersection) 40 | ious_bs[idx] = ious_sub 41 | 42 | ious = torch.mean(ious_bs, dim=0) 43 | iou = torch.mean(ious) 44 | iou_loss = 1 - iou 45 | return iou_loss * self.weight -------------------------------------------------------------------------------- /networks/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | 3 | def find_model_using_name(model_name): 4 | model_filename = "networks." + model_name 5 | modellib = importlib.import_module(model_filename+'_net') 6 | create_fnc = None 7 | target_model_name = 'create_' + model_name + '_net' 8 | for name, cls in modellib.__dict__.items(): 9 | if name.lower() == target_model_name.lower(): 10 | create_fnc = cls 11 | 12 | if create_fnc is None: 13 | print("In %s.py, there should be a subclass of BaseModel with class name that matches %s in lowercase." % (model_filename, target_model_name)) 14 | exit(0) 15 | 16 | return create_fnc 17 | 18 | def create_model(args, device): 19 | create_fnc = find_model_using_name(args.model_name) 20 | instance = create_fnc(args, args.lr, isTrain=True, device=device) 21 | print("model [{}] was created (rand{})".format(args.model_name, args.rank)) 22 | return instance 23 | -------------------------------------------------------------------------------- /options/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/options/__init__.py -------------------------------------------------------------------------------- /options/base_options.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import dataset 3 | 4 | class BaseOptions(): 5 | def __init__(self): 6 | self.initialized = False 7 | 8 | def initialize(self, parser): 9 | parser.add_argument('--dataroot', required=True, help='path to train data') 10 | parser.add_argument('--device', default='cuda', help='device to use for training / testing') 11 | parser.add_argument('--max_dataset_size', type=int, default=500000, help='max_dataset_size') 12 | 13 | parser.add_argument('--dataset_name', type=str, default='coco', help='[coco]') 14 | parser.add_argument('--model_name', type=str, default='transformer', help='[transformer]') 15 | return parser 16 | 17 | def gather_options(self): 18 | if not self.initialized: # check if it has been initialized 19 | parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) 20 | parser = self.initialize(parser) 21 | 22 | # get the basic options 23 | args, _ = parser.parse_known_args() 24 | 25 | # modify model-related parser options 26 | # model_name = args.model_name 27 | # model_option_setter = models.get_option_setter(model_name) 28 | # parser = model_option_setter(parser, self.isTrain) 29 | # opt, _ = parser.parse_known_args() # parse again with new defaults 30 | 31 | # modify dataset-related parser options 32 | dataset_name = args.dataset_name 33 | dataset_option_setter = dataset.get_option_setter(dataset_name) 34 | parser = dataset_option_setter(parser) 35 | 36 | # save and return the parser 37 | self.parser = parser 38 | return parser.parse_args() 39 | 40 | def print_options(self, opt): 41 | message = '' 42 | message += '----------------- Options ---------------\n' 43 | for k, v in sorted(vars(opt).items()): 44 | comment = '' 45 | default = self.parser.get_default(k) 46 | if v != default: 47 | comment = '\t[default: %s]' % str(default) 48 | message += '{:>25}: {:<30}{}\n'.format(str(k), str(v), comment) 49 | message += '----------------- End -------------------' 50 | print(message) 51 | 52 | def parse(self): 53 | opt = self.gather_options() 54 | self.opt = opt 55 | return self.opt 56 | -------------------------------------------------------------------------------- /options/train_options.py: -------------------------------------------------------------------------------- 1 | from .base_options import BaseOptions 2 | 3 | class TrainOptions(BaseOptions): 4 | """This class includes training options. 5 | 6 | It also includes shared options defined in BaseOptions. 7 | """ 8 | 9 | def initialize(self, parser): 10 | parser = BaseOptions.initialize(self, parser) 11 | parser.add_argument('--lr', type=float, default=1e-4, help='initial learning rate for adam') 12 | parser.add_argument('--grad_clip_thresh', type=float, default=1.0, help='grad clip thresh') 13 | 14 | parser.add_argument('--checkpoints_dir', type=str, default='./checkpoints', help='models are saved here') 15 | parser.add_argument('--finetune_model_path', type=str, default=r'', help='finetune_model_path') 16 | parser.add_argument('--check_per_epoch', type=int, default=5, help='check per iteration') 17 | parser.add_argument('--num_threads', default=1, type=int, help='# threads for loading data') 18 | parser.add_argument('--batch_size', type=int, default=1, help='input batch size') 19 | parser.add_argument('--total_epoch_num', type=int, default=80, help='total_epoch_num') 20 | 21 | parser.add_argument('--distributed_run', action='store_true', help='distributed_run') 22 | parser.add_argument('--seed', type=int, default=1234, help='dataset random seed') 23 | parser.add_argument('--world_size', type=int, default=1, help='num procedure') 24 | parser.add_argument('--rank', type=int, default=0, help='procedure rank') 25 | parser.add_argument('--dist_backend', type=str, default=r'nccl', help='dist backend') 26 | parser.add_argument('--group_name', type=str, default=r'sk_gan', help='dist group name') 27 | parser.add_argument('--dist_url', type=str, default=r'tcp://localhost:54321', help='dist url') 28 | 29 | parser.add_argument('--use_visdom', action='store_true', help='use visdom') 30 | parser.add_argument('--visdom_name', type=str, default='TransUltra', help='visdom name') 31 | parser.add_argument('--visdom_ip', type=str, default='127.0.0.1', help='visdom ip') 32 | parser.add_argument('--visdom_port', type=int, default=8097, help='visdom port') 33 | parser.add_argument('--visdom_id', type=str, default='', help='user name') 34 | parser.add_argument('--visdom_pw', type=str, default='', help='user passwd') 35 | 36 | self.isTrain = True 37 | return parser 38 | -------------------------------------------------------------------------------- /png/fig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/png/fig2.png -------------------------------------------------------------------------------- /png/fig4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MomoAILab/ultrapose/3abf39fe5fe16dc245f703de6f0fde032ad03756/png/fig4.png -------------------------------------------------------------------------------- /train_transformer.sh: -------------------------------------------------------------------------------- 1 | dataset=data/ultrapose 2 | check_dir=checkpoints 3 | finetune_path=checkpoints/transUltra.pth 4 | bsPerGPU=2 5 | threads=4 6 | gpus=0,1,2,3 7 | gpu_num=4 8 | dataset_name="coco" 9 | model_name="transformer" 10 | lr=1e-4 11 | visname="TransUltra" 12 | cpe=10 13 | group_name=${visname} 14 | disturl="tcp://localhost:54322" 15 | ws=${gpu_num} 16 | 17 | CUDA_VISIBLE_DEVICES=${gpus} python -m torch.distributed.launch --nproc_per_node=${gpu_num} --use_env train.py \ 18 | --load_pair --check_per_epoch ${cpe} --visdom_name ${visname} --dist_url ${disturl} --dataset_name ${dataset_name} \ 19 | --model_name ${model_name} --dataroot ${dataset} --use_visdom --batch_size ${bsPerGPU} --checkpoints_dir ${check_dir} \ 20 | --num_threads ${threads} --lr ${lr} --world_size=${ws} --finetune_model_path ${finetune_path} \ 21 | --distributed_run --group_name ${group_name} 22 | --------------------------------------------------------------------------------