├── .gitignore ├── CHANGELOG.md ├── GETTING_STARTED.md ├── HEADS.NORM ├── INSTALL.md ├── LICENSE ├── MODEL_ZOO.md ├── README.md ├── configs ├── Base-AGW.yml ├── Base-MGN.yml ├── Base-SBS.yml ├── Base-bagtricks.yml ├── DukeMTMC │ ├── AGW_R101-ibn.yml │ ├── AGW_R50-ibn.yml │ ├── AGW_R50.yml │ ├── AGW_S50.yml │ ├── bagtricks_R101-ibn.yml │ ├── bagtricks_R50-ibn.yml │ ├── bagtricks_R50.yml │ ├── bagtricks_S50.yml │ ├── mgn_R50-ibn.yml │ ├── sbs_R101-ibn.yml │ ├── sbs_R50-ibn.yml │ ├── sbs_R50.yml │ └── sbs_S50.yml ├── MSMT17 │ ├── AGW_R101-ibn.yml │ ├── AGW_R50-ibn.yml │ ├── AGW_R50.yml │ ├── AGW_S50.yml │ ├── bagtricks_R101-ibn.yml │ ├── bagtricks_R50-ibn.yml │ ├── bagtricks_R50.yml │ ├── bagtricks_S50.yml │ ├── mgn_R50-ibn.yml │ ├── sbs_R101-ibn.yml │ ├── sbs_R50-ibn.yml │ ├── sbs_R50.yml │ └── sbs_S50.yml ├── Market1501 │ ├── AGW_R101-ibn.yml │ ├── AGW_R50-ibn.yml │ ├── AGW_R50.yml │ ├── AGW_S50.yml │ ├── bagtricks_R101-ibn.yml │ ├── bagtricks_R50-ibn.yml │ ├── bagtricks_R50.yml │ ├── bagtricks_S50.yml │ ├── bagtricks_vit.yml │ ├── mgn_R50-ibn.yml │ ├── sbs_R101-ibn.yml │ ├── sbs_R50-ibn.yml │ ├── sbs_R50.yml │ └── sbs_S50.yml ├── VERIWild │ └── bagtricks_R50-ibn.yml ├── VeRi │ └── sbs_R50-ibn.yml └── VehicleID │ └── bagtricks_R50-ibn.yml ├── datasets ├── README.md ├── output.png ├── p1.jpg └── p2.jpg ├── demo ├── README.md ├── demo.py ├── plot_roc_with_pickle.py ├── predictor.py └── visualize_result.py ├── docker ├── Dockerfile └── README.md ├── docs ├── .gitignore ├── Makefile ├── README.md ├── _static │ └── css │ │ └── custom.css ├── conf.py ├── index.rst ├── modules │ ├── checkpoint.rst │ ├── config.rst │ ├── data.rst │ ├── data_transforms.rst │ ├── engine.rst │ ├── evaluation.rst │ ├── index.rst │ ├── layers.rst │ ├── modeling.rst │ ├── solver.rst │ └── utils.rst └── requirements.txt ├── fastreid ├── __init__.py ├── config │ ├── __init__.py │ ├── config.py │ └── defaults.py ├── data │ ├── __init__.py │ ├── build.py │ ├── common.py │ ├── data_utils.py │ ├── datasets │ │ ├── AirportALERT.py │ │ ├── __init__.py │ │ ├── bases.py │ │ ├── caviara.py │ │ ├── cuhk03.py │ │ ├── cuhk_sysu.py │ │ ├── dukemtmcreid.py │ │ ├── grid.py │ │ ├── iLIDS.py │ │ ├── lpw.py │ │ ├── market1501.py │ │ ├── msmt17.py │ │ ├── pes3d.py │ │ ├── pku.py │ │ ├── prai.py │ │ ├── prid.py │ │ ├── saivt.py │ │ ├── sensereid.py │ │ ├── shinpuhkan.py │ │ ├── sysu_mm.py │ │ ├── thermalworld.py │ │ ├── vehicleid.py │ │ ├── veri.py │ │ ├── veriwild.py │ │ ├── viper.py │ │ └── wildtracker.py │ ├── samplers │ │ ├── __init__.py │ │ ├── data_sampler.py │ │ ├── imbalance_sampler.py │ │ └── triplet_sampler.py │ └── transforms │ │ ├── __init__.py │ │ ├── autoaugment.py │ │ ├── build.py │ │ ├── functional.py │ │ └── transforms.py ├── engine │ ├── __init__.py │ ├── defaults.py │ ├── hooks.py │ ├── launch.py │ └── train_loop.py ├── evaluation │ ├── __init__.py │ ├── clas_evaluator.py │ ├── evaluator.py │ ├── query_expansion.py │ ├── rank.py │ ├── rank_cylib │ │ ├── Makefile │ │ ├── __init__.py │ │ ├── rank_cy.c │ │ ├── rank_cy.pyx │ │ ├── roc_cy.c │ │ ├── roc_cy.pyx │ │ ├── setup.py │ │ └── test_cython.py │ ├── reid_evaluation.py │ ├── rerank.py │ ├── roc.py │ └── testing.py ├── layers │ ├── __init__.py │ ├── activation.py │ ├── any_softmax.py │ ├── batch_norm.py │ ├── context_block.py │ ├── drop.py │ ├── frn.py │ ├── gather_layer.py │ ├── helpers.py │ ├── non_local.py │ ├── pooling.py │ ├── se_layer.py │ ├── splat.py │ └── weight_init.py ├── modeling │ ├── __init__.py │ ├── backbones │ │ ├── __init__.py │ │ ├── build.py │ │ ├── mobilenet.py │ │ ├── mobilenetv3.py │ │ ├── osnet.py │ │ ├── regnet │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── effnet.py │ │ │ ├── effnet │ │ │ │ ├── EN-B0_dds_8gpu.yaml │ │ │ │ ├── EN-B1_dds_8gpu.yaml │ │ │ │ ├── EN-B2_dds_8gpu.yaml │ │ │ │ ├── EN-B3_dds_8gpu.yaml │ │ │ │ ├── EN-B4_dds_8gpu.yaml │ │ │ │ └── EN-B5_dds_8gpu.yaml │ │ │ ├── regnet.py │ │ │ ├── regnetx │ │ │ │ ├── RegNetX-1.6GF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-12GF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-16GF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-200MF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-3.2GF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-32GF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-4.0GF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-400MF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-6.4GF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-600MF_dds_8gpu.yaml │ │ │ │ ├── RegNetX-8.0GF_dds_8gpu.yaml │ │ │ │ └── RegNetX-800MF_dds_8gpu.yaml │ │ │ └── regnety │ │ │ │ ├── RegNetY-1.6GF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-12GF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-16GF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-200MF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-3.2GF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-32GF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-4.0GF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-400MF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-6.4GF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-600MF_dds_8gpu.yaml │ │ │ │ ├── RegNetY-8.0GF_dds_8gpu.yaml │ │ │ │ └── RegNetY-800MF_dds_8gpu.yaml │ │ ├── repvgg.py │ │ ├── resnest.py │ │ ├── resnet.py │ │ ├── resnext.py │ │ ├── shufflenet.py │ │ └── vision_transformer.py │ ├── heads │ │ ├── __init__.py │ │ ├── build.py │ │ ├── clas_head.py │ │ └── embedding_head.py │ ├── losses │ │ ├── __init__.py │ │ ├── circle_loss.py │ │ ├── cross_entroy_loss.py │ │ ├── focal_loss.py │ │ ├── triplet_loss.py │ │ └── utils.py │ └── meta_arch │ │ ├── __init__.py │ │ ├── baseline.py │ │ ├── build.py │ │ ├── distiller.py │ │ ├── mgn.py │ │ └── moco.py ├── solver │ ├── __init__.py │ ├── build.py │ ├── lr_scheduler.py │ └── optim │ │ ├── __init__.py │ │ ├── lamb.py │ │ ├── radam.py │ │ └── swa.py └── utils │ ├── __init__.py │ ├── checkpoint.py │ ├── collect_env.py │ ├── comm.py │ ├── compute_dist.py │ ├── env.py │ ├── events.py │ ├── faiss_utils.py │ ├── file_io.py │ ├── history_buffer.py │ ├── logger.py │ ├── params.py │ ├── precision_bn.py │ ├── registry.py │ ├── summary.py │ ├── timer.py │ └── visualizer.py ├── projects └── CAViT │ ├── FastVideo │ ├── __init__.py │ ├── config.py │ ├── data │ │ ├── __init__.py │ │ ├── build.py │ │ ├── data_utils.py │ │ ├── datasets │ │ │ ├── __init__.py │ │ │ ├── dukev.py │ │ │ ├── dukev2.py │ │ │ ├── dukev_dl.py │ │ │ ├── gait.py │ │ │ ├── ilidsvid.py │ │ │ ├── lsvid.py │ │ │ ├── mars.py │ │ │ ├── mars_dl.py │ │ │ ├── prid2011.py │ │ │ ├── vdataset.py │ │ │ ├── video_bases.py │ │ │ └── vveri901.py │ │ ├── sampler.py │ │ ├── temporal_transforms.py │ │ ├── temporal_transforms2.py │ │ └── video_dataset.py │ ├── evaluator.py │ └── modeling │ │ ├── CAViT.py │ │ ├── Swin3D.py │ │ ├── ViT3D.py │ │ ├── ViTBaseline.py │ │ ├── VideoBaseline.py │ │ ├── __init__.py │ │ ├── backbone │ │ ├── __init__.py │ │ ├── ap3d.py │ │ ├── bicknet.py │ │ ├── cavit.py │ │ ├── resnet_tsm.py │ │ ├── shift_token.py │ │ ├── swin3d.py │ │ ├── swin_vit.py │ │ ├── time_former.py │ │ └── vit.py │ │ ├── head │ │ ├── __init__.py │ │ └── temp_head.py │ │ ├── layers │ │ ├── AP3D.py │ │ ├── NonLocal.py │ │ ├── __init__.py │ │ ├── bick.py │ │ ├── inflate.py │ │ └── transformer.py │ │ └── resnet3d.py │ ├── configs │ ├── cavit_ilid.yml │ ├── cavit_lsvid.yml │ ├── cavit_lsvid_epoch20.yml │ ├── cavit_lsvid_lr0.01.yml │ ├── cavit_mars_lr.yml │ ├── cavit_marsdl.yml │ ├── cavit_prid2011.yml │ └── cavit_vveri901.yml │ └── train.py ├── run.sh ├── tests ├── __init__.py ├── dataset_test.py ├── feature_align.py ├── interp_test.py ├── lr_scheduler_test.py ├── model_test.py ├── sampler_test.py └── test_repvgg.py └── tools ├── deploy ├── Caffe │ ├── ReadMe.md │ ├── __init__.py │ ├── caffe.proto │ ├── caffe_lmdb.py │ ├── caffe_net.py │ ├── caffe_pb2.py │ ├── layer_param.py │ └── net.py ├── README.md ├── caffe_export.py ├── caffe_inference.py ├── onnx_export.py ├── onnx_inference.py ├── pytorch_to_caffe.py ├── test_data │ ├── 0022_c6s1_002976_01.jpg │ ├── 0027_c2s2_091032_02.jpg │ ├── 0032_c6s1_002851_01.jpg │ ├── 0048_c1s1_005351_01.jpg │ └── 0065_c6s1_009501_02.jpg ├── trt_calibrator.py ├── trt_export.py └── trt_inference.py ├── plain_train_net.py └── train_net.py /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | logs 3 | 4 | # compilation and distribution 5 | __pycache__ 6 | _ext 7 | *.pyc 8 | *.pyd 9 | *.so 10 | *.dll 11 | *.egg-info/ 12 | build/ 13 | dist/ 14 | wheels/ 15 | 16 | # pytorch/python/numpy formats 17 | *.pth 18 | *.pkl 19 | *.npy 20 | *.ts 21 | model_ts*.txt 22 | 23 | # ipython/jupyter notebooks 24 | *.ipynb 25 | **/.ipynb_checkpoints/ 26 | 27 | # Editor temporaries 28 | *.swn 29 | *.swo 30 | *.swp 31 | *~ 32 | 33 | # editor settings 34 | .idea 35 | .vscode 36 | _darcs 37 | .DS_Store 38 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### v1.3 4 | 5 | #### New Features 6 | - Vision Transformer backbone, see config in `configs/Market1501/bagtricks_vit.yml` 7 | - Self-Distillation with EMA update 8 | - Gradient Clip 9 | 10 | #### Improvements 11 | - Faster dataloader with pre-fetch thread and cuda stream 12 | - Optimize DDP training speed by removing `find_unused_parameters` in DDP 13 | 14 | 15 | ### v1.2 (06/04/2021) 16 | 17 | #### New Features 18 | 19 | - Multiple machine training support 20 | - [RepVGG](https://github.com/DingXiaoH/RepVGG) backbone 21 | - [Partial FC](projects/FastFace) 22 | 23 | #### Improvements 24 | 25 | - Torch2trt pipeline 26 | - Decouple linear transforms and softmax 27 | - config decorator 28 | 29 | ### v1.1 (29/01/2021) 30 | 31 | #### New Features 32 | 33 | - NAIC20(reid track) [1-st solution](projects/NAIC20) 34 | - Multi-teacher Knowledge Distillation 35 | - TRT network definition APIs in [FastRT](projects/FastRT) 36 | 37 | #### Bug Fixes 38 | 39 | #### Improvements -------------------------------------------------------------------------------- /GETTING_STARTED.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Fastreid 2 | 3 | ## Prepare pretrained model 4 | 5 | If you use backbones supported by fastreid, you do not need to do anything. It will automatically download the pre-train models. 6 | But if your network is not connected, you can download pre-train models manually and put it in `~/.cache/torch/checkpoints`. 7 | 8 | If you want to use other pre-train models, such as MoCo pre-train, you can download by yourself and set the pre-train model path in `configs/Base-bagtricks.yml`. 9 | 10 | ## Compile with cython to accelerate evalution 11 | 12 | ```bash 13 | cd fastreid/evaluation/rank_cylib; make all 14 | ``` 15 | 16 | ## Training & Evaluation in Command Line 17 | 18 | We provide a script in "tools/train_net.py", that is made to train all the configs provided in fastreid. 19 | You may want to use it as a reference to write your own training script. 20 | 21 | To train a model with "train_net.py", first setup up the corresponding datasets following [datasets/README.md](https://github.com/JDAI-CV/fast-reid/tree/master/datasets), then run: 22 | 23 | ```bash 24 | python3 tools/train_net.py --config-file ./configs/Market1501/bagtricks_R50.yml MODEL.DEVICE "cuda:0" 25 | ``` 26 | 27 | The configs are made for 1-GPU training. 28 | 29 | If you want to train model with 4 GPUs, you can run: 30 | 31 | ```bash 32 | python3 tools/train_net.py --config-file ./configs/Market1501/bagtricks_R50.yml --num-gpus 4 33 | ``` 34 | 35 | If you want to train model with multiple machines, you can run: 36 | 37 | ``` 38 | # machine 1 39 | export GLOO_SOCKET_IFNAME=eth0 40 | export NCCL_SOCKET_IFNAME=eth0 41 | 42 | python3 tools/train_net.py --config-file configs/Market1501/bagtricks_R50.yml \ 43 | --num-gpus 4 --num-machines 2 --machine-rank 0 --dist-url tcp://ip:port 44 | 45 | # machine 2 46 | export GLOO_SOCKET_IFNAME=eth0 47 | export NCCL_SOCKET_IFNAME=eth0 48 | 49 | python3 tools/train_net.py --config-file configs/Market1501/bagtricks_R50.yml \ 50 | --num-gpus 4 --num-machines 2 --machine-rank 1 --dist-url tcp://ip:port 51 | ``` 52 | 53 | Make sure the dataset path and code are the same in different machines, and machines can communicate with each other. 54 | 55 | To evaluate a model's performance, use 56 | 57 | ```bash 58 | python3 tools/train_net.py --config-file ./configs/Market1501/bagtricks_R50.yml --eval-only \ 59 | MODEL.WEIGHTS /path/to/checkpoint_file MODEL.DEVICE "cuda:0" 60 | ``` 61 | 62 | For more options, see `python3 tools/train_net.py -h`. 63 | -------------------------------------------------------------------------------- /HEADS.NORM: -------------------------------------------------------------------------------- 1 | Command Line Args: Namespace(config_file='projects/FastVideo/configs/vit3/vit_base_st_cross_slow-fast.yml', dist_url='tcp://127.0.0.1:49152', eval_only=False, machine_rank=0, num_gpus=1, num_machines=1, opts=['MODEL', 'BN'], resume=False) 2 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | ## Requirements 4 | 5 | - Linux or macOS with python ≥ 3.6 6 | - PyTorch ≥ 1.6 7 | - torchvision that matches the Pytorch installation. You can install them together at [pytorch.org](https://pytorch.org/) to make sure of this. 8 | - [yacs](https://github.com/rbgirshick/yacs) 9 | - Cython (optional to compile evaluation code) 10 | - tensorboard (needed for visualization): `pip install tensorboard` 11 | - gdown (for automatically downloading pre-train model) 12 | - sklearn 13 | - termcolor 14 | - tabulate 15 | - [faiss](https://github.com/facebookresearch/faiss) `pip install faiss-cpu` 16 | 17 | 18 | 19 | # Set up with Conda 20 | ```shell script 21 | conda create -n fastreid python=3.7 22 | conda activate fastreid 23 | conda install pytorch==1.6.0 torchvision tensorboard -c pytorch 24 | pip install -r docs/requirements.txt 25 | ``` 26 | 27 | # Set up with Dockder 28 | comming soon 29 | -------------------------------------------------------------------------------- /configs/Base-AGW.yml: -------------------------------------------------------------------------------- 1 | _BASE_: Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_NL: True 6 | 7 | HEADS: 8 | POOL_LAYER: GeneralizedMeanPooling 9 | 10 | LOSSES: 11 | NAME: ("CrossEntropyLoss", "TripletLoss") 12 | CE: 13 | EPSILON: 0.1 14 | SCALE: 1.0 15 | 16 | TRI: 17 | MARGIN: 0.0 18 | HARD_MINING: False 19 | SCALE: 1.0 20 | -------------------------------------------------------------------------------- /configs/Base-MGN.yml: -------------------------------------------------------------------------------- 1 | _BASE_: Base-SBS.yml 2 | 3 | MODEL: 4 | META_ARCHITECTURE: MGN 5 | 6 | FREEZE_LAYERS: [backbone, b1, b2, b3,] 7 | 8 | BACKBONE: 9 | WITH_NL: False 10 | 11 | HEADS: 12 | EMBEDDING_DIM: 256 13 | -------------------------------------------------------------------------------- /configs/Base-SBS.yml: -------------------------------------------------------------------------------- 1 | _BASE_: Base-bagtricks.yml 2 | 3 | MODEL: 4 | FREEZE_LAYERS: [ backbone ] 5 | 6 | BACKBONE: 7 | WITH_NL: True 8 | 9 | HEADS: 10 | NECK_FEAT: after 11 | POOL_LAYER: GeneralizedMeanPoolingP 12 | CLS_LAYER: CircleSoftmax 13 | SCALE: 64 14 | MARGIN: 0.35 15 | 16 | LOSSES: 17 | NAME: ("CrossEntropyLoss", "TripletLoss",) 18 | CE: 19 | EPSILON: 0.1 20 | SCALE: 1.0 21 | 22 | TRI: 23 | MARGIN: 0.0 24 | HARD_MINING: True 25 | NORM_FEAT: False 26 | SCALE: 1.0 27 | 28 | INPUT: 29 | SIZE_TRAIN: [ 384, 128 ] 30 | SIZE_TEST: [ 384, 128 ] 31 | 32 | AUTOAUG: 33 | ENABLED: True 34 | PROB: 0.1 35 | 36 | DATALOADER: 37 | NUM_INSTANCE: 16 38 | 39 | SOLVER: 40 | AMP: 41 | ENABLED: True 42 | OPT: Adam 43 | MAX_EPOCH: 60 44 | BASE_LR: 0.00035 45 | WEIGHT_DECAY: 0.0005 46 | IMS_PER_BATCH: 64 47 | 48 | SCHED: CosineAnnealingLR 49 | DELAY_EPOCHS: 30 50 | ETA_MIN_LR: 0.0000007 51 | 52 | WARMUP_FACTOR: 0.1 53 | WARMUP_ITERS: 2000 54 | 55 | FREEZE_ITERS: 1000 56 | 57 | CHECKPOINT_PERIOD: 20 58 | 59 | TEST: 60 | EVAL_PERIOD: 10 61 | IMS_PER_BATCH: 128 62 | 63 | CUDNN_BENCHMARK: True 64 | -------------------------------------------------------------------------------- /configs/Base-bagtricks.yml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | META_ARCHITECTURE: Baseline 3 | 4 | BACKBONE: 5 | NAME: build_resnet_backbone 6 | NORM: BN 7 | DEPTH: 50x 8 | LAST_STRIDE: 1 9 | FEAT_DIM: 2048 10 | WITH_IBN: False 11 | PRETRAIN: True 12 | 13 | HEADS: 14 | NAME: EmbeddingHead 15 | NORM: BN 16 | WITH_BNNECK: True 17 | POOL_LAYER: GlobalAvgPool 18 | NECK_FEAT: before 19 | CLS_LAYER: Linear 20 | 21 | LOSSES: 22 | NAME: ("CrossEntropyLoss", "TripletLoss",) 23 | 24 | CE: 25 | EPSILON: 0.1 26 | SCALE: 1. 27 | 28 | TRI: 29 | MARGIN: 0.3 30 | HARD_MINING: True 31 | NORM_FEAT: False 32 | SCALE: 1. 33 | 34 | INPUT: 35 | SIZE_TRAIN: [ 256, 128 ] 36 | SIZE_TEST: [ 256, 128 ] 37 | 38 | REA: 39 | ENABLED: True 40 | PROB: 0.5 41 | 42 | FLIP: 43 | ENABLED: True 44 | 45 | PADDING: 46 | ENABLED: True 47 | 48 | DATALOADER: 49 | SAMPLER_TRAIN: NaiveIdentitySampler 50 | NUM_INSTANCE: 4 51 | NUM_WORKERS: 8 52 | 53 | SOLVER: 54 | AMP: 55 | ENABLED: True 56 | OPT: Adam 57 | MAX_EPOCH: 120 58 | BASE_LR: 0.00035 59 | WEIGHT_DECAY: 0.0005 60 | WEIGHT_DECAY_NORM: 0.0005 61 | IMS_PER_BATCH: 64 62 | 63 | SCHED: MultiStepLR 64 | STEPS: [ 40, 90 ] 65 | GAMMA: 0.1 66 | 67 | WARMUP_FACTOR: 0.1 68 | WARMUP_ITERS: 2000 69 | 70 | CHECKPOINT_PERIOD: 30 71 | 72 | TEST: 73 | EVAL_PERIOD: 30 74 | IMS_PER_BATCH: 128 75 | 76 | CUDNN_BENCHMARK: True 77 | -------------------------------------------------------------------------------- /configs/DukeMTMC/AGW_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("DukeMTMC",) 10 | TESTS: ("DukeMTMC",) 11 | 12 | OUTPUT_DIR: logs/dukemtmc/agw_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/DukeMTMC/AGW_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("DukeMTMC",) 9 | TESTS: ("DukeMTMC",) 10 | 11 | OUTPUT_DIR: logs/dukemtmc/agw_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/DukeMTMC/AGW_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | DATASETS: 4 | NAMES: ("DukeMTMC",) 5 | TESTS: ("DukeMTMC",) 6 | 7 | OUTPUT_DIR: logs/dukemtmc/agw_R50 8 | -------------------------------------------------------------------------------- /configs/DukeMTMC/AGW_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("DukeMTMC",) 9 | TESTS: ("DukeMTMC",) 10 | 11 | OUTPUT_DIR: logs/dukemtmc/agw_S50 12 | -------------------------------------------------------------------------------- /configs/DukeMTMC/bagtricks_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("DukeMTMC",) 10 | TESTS: ("DukeMTMC",) 11 | 12 | OUTPUT_DIR: logs/dukemtmc/bagtricks_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/DukeMTMC/bagtricks_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("DukeMTMC",) 9 | TESTS: ("DukeMTMC",) 10 | 11 | OUTPUT_DIR: logs/dukemtmc/bagtricks_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/DukeMTMC/bagtricks_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | DATASETS: 4 | NAMES: ("DukeMTMC",) 5 | TESTS: ("DukeMTMC",) 6 | 7 | OUTPUT_DIR: logs/dukemtmc/bagtricks_R50 8 | -------------------------------------------------------------------------------- /configs/DukeMTMC/bagtricks_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("DukeMTMC",) 9 | TESTS: ("DukeMTMC",) 10 | 11 | OUTPUT_DIR: logs/dukemtmc/bagtricks_S50 12 | -------------------------------------------------------------------------------- /configs/DukeMTMC/mgn_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-MGN.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("DukeMTMC",) 9 | TESTS: ("DukeMTMC",) 10 | 11 | OUTPUT_DIR: logs/dukemtmc/mgn_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/DukeMTMC/sbs_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("DukeMTMC",) 10 | TESTS: ("DukeMTMC",) 11 | 12 | OUTPUT_DIR: logs/dukemtmc/sbs_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/DukeMTMC/sbs_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("DukeMTMC",) 9 | TESTS: ("DukeMTMC",) 10 | 11 | OUTPUT_DIR: logs/dukemtmc/sbs_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/DukeMTMC/sbs_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | DATASETS: 4 | NAMES: ("DukeMTMC",) 5 | TESTS: ("DukeMTMC",) 6 | 7 | OUTPUT_DIR: logs/dukemtmc/sbs_R50 8 | -------------------------------------------------------------------------------- /configs/DukeMTMC/sbs_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("DukeMTMC",) 9 | TESTS: ("DukeMTMC",) 10 | 11 | OUTPUT_DIR: logs/dukemtmc/sbs_S50 12 | -------------------------------------------------------------------------------- /configs/MSMT17/AGW_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("MSMT17",) 10 | TESTS: ("MSMT17",) 11 | 12 | OUTPUT_DIR: logs/msmt17/agw_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/MSMT17/AGW_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("MSMT17",) 9 | TESTS: ("MSMT17",) 10 | 11 | OUTPUT_DIR: logs/msmt17/agw_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/MSMT17/AGW_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | DATASETS: 4 | NAMES: ("MSMT17",) 5 | TESTS: ("MSMT17",) 6 | 7 | OUTPUT_DIR: logs/msmt17/agw_R50 8 | -------------------------------------------------------------------------------- /configs/MSMT17/AGW_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("MSMT17",) 9 | TESTS: ("MSMT17",) 10 | 11 | OUTPUT_DIR: logs/msmt17/agw_S50 12 | -------------------------------------------------------------------------------- /configs/MSMT17/bagtricks_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("MSMT17",) 10 | TESTS: ("MSMT17",) 11 | 12 | OUTPUT_DIR: logs/msmt17/bagtricks_R101-ibn 13 | 14 | -------------------------------------------------------------------------------- /configs/MSMT17/bagtricks_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("MSMT17",) 9 | TESTS: ("MSMT17",) 10 | 11 | OUTPUT_DIR: logs/msmt17/bagtricks_R50-ibn 12 | 13 | -------------------------------------------------------------------------------- /configs/MSMT17/bagtricks_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | DATASETS: 4 | NAMES: ("MSMT17",) 5 | TESTS: ("MSMT17",) 6 | 7 | OUTPUT_DIR: logs/msmt17/bagtricks_R50 8 | -------------------------------------------------------------------------------- /configs/MSMT17/bagtricks_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("MSMT17",) 9 | TESTS: ("MSMT17",) 10 | 11 | OUTPUT_DIR: logs/msmt17/bagtricks_S50 12 | 13 | -------------------------------------------------------------------------------- /configs/MSMT17/mgn_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-MGN.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("MSMT17",) 9 | TESTS: ("MSMT17",) 10 | 11 | OUTPUT_DIR: logs/msmt17/mgn_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/MSMT17/sbs_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("MSMT17",) 10 | TESTS: ("MSMT17",) 11 | 12 | OUTPUT_DIR: logs/msmt17/sbs_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/MSMT17/sbs_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("MSMT17",) 9 | TESTS: ("MSMT17",) 10 | 11 | OUTPUT_DIR: logs/msmt17/sbs_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/MSMT17/sbs_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | DATASETS: 4 | NAMES: ("MSMT17",) 5 | TESTS: ("MSMT17",) 6 | 7 | OUTPUT_DIR: logs/msmt17/sbs_R50 8 | -------------------------------------------------------------------------------- /configs/MSMT17/sbs_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("MSMT17",) 9 | TESTS: ("MSMT17",) 10 | 11 | OUTPUT_DIR: logs/msmt17/sbs_S50 12 | -------------------------------------------------------------------------------- /configs/Market1501/AGW_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("Market1501",) 10 | TESTS: ("Market1501",) 11 | 12 | OUTPUT_DIR: logs/market1501/agw_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/Market1501/AGW_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("Market1501",) 9 | TESTS: ("Market1501",) 10 | 11 | OUTPUT_DIR: logs/market1501/agw_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/Market1501/AGW_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | DATASETS: 4 | NAMES: ("Market1501",) 5 | TESTS: ("Market1501",) 6 | 7 | OUTPUT_DIR: logs/market1501/agw_R50 8 | -------------------------------------------------------------------------------- /configs/Market1501/AGW_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-AGW.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("Market1501",) 9 | TESTS: ("Market1501",) 10 | 11 | OUTPUT_DIR: logs/market1501/agw_S50 12 | -------------------------------------------------------------------------------- /configs/Market1501/bagtricks_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("Market1501",) 10 | TESTS: ("Market1501",) 11 | 12 | OUTPUT_DIR: logs/market1501/bagtricks_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/Market1501/bagtricks_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("Market1501",) 9 | TESTS: ("Market1501",) 10 | 11 | OUTPUT_DIR: logs/market1501/bagtricks_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/Market1501/bagtricks_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | DATASETS: 4 | NAMES: ("Market1501",) 5 | TESTS: ("Market1501",) 6 | 7 | OUTPUT_DIR: logs/market1501/bagtricks_R50 8 | -------------------------------------------------------------------------------- /configs/Market1501/bagtricks_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("Market1501",) 9 | TESTS: ("Market1501",) 10 | 11 | OUTPUT_DIR: logs/market1501/bagtricks_S50 12 | -------------------------------------------------------------------------------- /configs/Market1501/bagtricks_vit.yml: -------------------------------------------------------------------------------- 1 | 2 | MODEL: 3 | META_ARCHITECTURE: Baseline 4 | PIXEL_MEAN: [127.5, 127.5, 127.5] 5 | PIXEL_STD: [127.5, 127.5, 127.5] 6 | 7 | BACKBONE: 8 | NAME: build_vit_backbone 9 | DEPTH: base 10 | FEAT_DIM: 768 11 | PRETRAIN: True 12 | PRETRAIN_PATH: /export/home/lxy/.cache/torch/checkpoints/jx_vit_base_p16_224-80ecf9dd.pth 13 | STRIDE_SIZE: (16, 16) 14 | DROP_PATH_RATIO: 0.1 15 | DROP_RATIO: 0.0 16 | ATT_DROP_RATE: 0.0 17 | 18 | HEADS: 19 | NAME: EmbeddingHead 20 | NORM: BN 21 | WITH_BNNECK: True 22 | POOL_LAYER: Identity 23 | NECK_FEAT: before 24 | CLS_LAYER: Linear 25 | 26 | LOSSES: 27 | NAME: ("CrossEntropyLoss", "TripletLoss",) 28 | 29 | CE: 30 | EPSILON: 0. # no smooth 31 | SCALE: 1. 32 | 33 | TRI: 34 | MARGIN: 0.0 35 | HARD_MINING: True 36 | NORM_FEAT: False 37 | SCALE: 1. 38 | 39 | INPUT: 40 | SIZE_TRAIN: [ 256, 128 ] 41 | SIZE_TEST: [ 256, 128 ] 42 | 43 | REA: 44 | ENABLED: True 45 | PROB: 0.5 46 | 47 | FLIP: 48 | ENABLED: True 49 | 50 | PADDING: 51 | ENABLED: True 52 | 53 | DATALOADER: 54 | SAMPLER_TRAIN: NaiveIdentitySampler 55 | NUM_INSTANCE: 4 56 | NUM_WORKERS: 8 57 | 58 | SOLVER: 59 | AMP: 60 | ENABLED: False 61 | OPT: SGD 62 | MAX_EPOCH: 120 63 | BASE_LR: 0.008 64 | WEIGHT_DECAY: 0.0001 65 | IMS_PER_BATCH: 64 66 | 67 | SCHED: CosineAnnealingLR 68 | ETA_MIN_LR: 0.000016 69 | 70 | WARMUP_FACTOR: 0.01 71 | WARMUP_ITERS: 1000 72 | 73 | CLIP_GRADIENTS: 74 | ENABLED: True 75 | 76 | CHECKPOINT_PERIOD: 30 77 | 78 | TEST: 79 | EVAL_PERIOD: 5 80 | IMS_PER_BATCH: 128 81 | 82 | CUDNN_BENCHMARK: True 83 | 84 | DATASETS: 85 | NAMES: ("Market1501",) 86 | TESTS: ("Market1501",) 87 | 88 | OUTPUT_DIR: logs/market1501/sbs_vit_base 89 | -------------------------------------------------------------------------------- /configs/Market1501/mgn_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-MGN.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("Market1501",) 9 | TESTS: ("Market1501",) 10 | 11 | OUTPUT_DIR: logs/market1501/mgn_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/Market1501/sbs_R101-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | DEPTH: 101x 6 | WITH_IBN: True 7 | 8 | DATASETS: 9 | NAMES: ("Market1501",) 10 | TESTS: ("Market1501",) 11 | 12 | OUTPUT_DIR: logs/market1501/sbs_R101-ibn 13 | -------------------------------------------------------------------------------- /configs/Market1501/sbs_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | WITH_IBN: True 6 | 7 | DATASETS: 8 | NAMES: ("Market1501",) 9 | TESTS: ("Market1501",) 10 | 11 | OUTPUT_DIR: logs/market1501/sbs_R50-ibn 12 | -------------------------------------------------------------------------------- /configs/Market1501/sbs_R50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | DATASETS: 4 | NAMES: ("Market1501",) 5 | TESTS: ("Market1501",) 6 | 7 | OUTPUT_DIR: logs/market1501/sbs_R50 8 | -------------------------------------------------------------------------------- /configs/Market1501/sbs_S50.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | MODEL: 4 | BACKBONE: 5 | NAME: build_resnest_backbone 6 | 7 | DATASETS: 8 | NAMES: ("Market1501",) 9 | TESTS: ("Market1501",) 10 | 11 | OUTPUT_DIR: logs/market1501/sbs_S50 12 | -------------------------------------------------------------------------------- /configs/VERIWild/bagtricks_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | INPUT: 4 | SIZE_TRAIN: [256, 256] 5 | SIZE_TEST: [256, 256] 6 | 7 | MODEL: 8 | BACKBONE: 9 | WITH_IBN: True 10 | 11 | HEADS: 12 | POOL_LAYER: GeneralizedMeanPooling 13 | 14 | LOSSES: 15 | TRI: 16 | HARD_MINING: False 17 | MARGIN: 0.0 18 | 19 | DATASETS: 20 | NAMES: ("VeRiWild",) 21 | TESTS: ("SmallVeRiWild", "MediumVeRiWild", "LargeVeRiWild",) 22 | 23 | SOLVER: 24 | IMS_PER_BATCH: 512 # 512 For 4 GPUs 25 | MAX_EPOCH: 120 26 | STEPS: [30, 70, 90] 27 | WARMUP_ITERS: 5000 28 | 29 | CHECKPOINT_PERIOD: 20 30 | 31 | TEST: 32 | EVAL_PERIOD: 10 33 | IMS_PER_BATCH: 128 34 | 35 | OUTPUT_DIR: logs/veriwild/bagtricks_R50-ibn_4gpu 36 | -------------------------------------------------------------------------------- /configs/VeRi/sbs_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-SBS.yml 2 | 3 | INPUT: 4 | SIZE_TRAIN: [256, 256] 5 | SIZE_TEST: [256, 256] 6 | 7 | MODEL: 8 | BACKBONE: 9 | WITH_IBN: True 10 | WITH_NL: True 11 | 12 | SOLVER: 13 | OPT: SGD 14 | BASE_LR: 0.01 15 | ETA_MIN_LR: 7.7e-5 16 | 17 | IMS_PER_BATCH: 64 18 | MAX_EPOCH: 60 19 | WARMUP_ITERS: 3000 20 | FREEZE_ITERS: 3000 21 | 22 | CHECKPOINT_PERIOD: 10 23 | 24 | DATASETS: 25 | NAMES: ("VeRi",) 26 | TESTS: ("VeRi",) 27 | 28 | DATALOADER: 29 | SAMPLER_TRAIN: BalancedIdentitySampler 30 | 31 | TEST: 32 | EVAL_PERIOD: 10 33 | IMS_PER_BATCH: 256 34 | 35 | OUTPUT_DIR: logs/veri/sbs_R50-ibn 36 | -------------------------------------------------------------------------------- /configs/VehicleID/bagtricks_R50-ibn.yml: -------------------------------------------------------------------------------- 1 | _BASE_: ../Base-bagtricks.yml 2 | 3 | INPUT: 4 | SIZE_TRAIN: [256, 256] 5 | SIZE_TEST: [256, 256] 6 | 7 | MODEL: 8 | BACKBONE: 9 | WITH_IBN: True 10 | HEADS: 11 | POOL_LAYER: GeneralizedMeanPooling 12 | 13 | LOSSES: 14 | TRI: 15 | HARD_MINING: False 16 | MARGIN: 0.0 17 | 18 | DATASETS: 19 | NAMES: ("VehicleID",) 20 | TESTS: ("SmallVehicleID", "MediumVehicleID", "LargeVehicleID",) 21 | 22 | SOLVER: 23 | BIAS_LR_FACTOR: 1. 24 | 25 | IMS_PER_BATCH: 512 26 | MAX_EPOCH: 60 27 | STEPS: [30, 50] 28 | WARMUP_ITERS: 2000 29 | 30 | CHECKPOINT_PERIOD: 20 31 | 32 | TEST: 33 | EVAL_PERIOD: 20 34 | IMS_PER_BATCH: 128 35 | 36 | OUTPUT_DIR: logs/vehicleid/bagtricks_R50-ibn_4gpu 37 | -------------------------------------------------------------------------------- /datasets/README.md: -------------------------------------------------------------------------------- 1 | # Setup Buildin Dataset 2 | 3 | Fastreid has buildin support for a few datasets. The datasets are assumed to exist in a directory specified by the environment variable `FASTREID_DATASETS`. Under this directory, fastreid expects to find datasets in the structure described below. 4 | 5 | You can set the location for builtin datasets by `export FASTREID_DATASETS=/path/to/datasets/`. If left unset, the default is `datasets/` relative to your current working directory. 6 | 7 | The [model zoo](https://github.com/JDAI-CV/fast-reid/blob/master/MODEL_ZOO.md) contains configs and models that use these buildin datasets. 8 | 9 | ## Expected dataset structure for [Market1501](https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/Zheng_Scalable_Person_Re-Identification_ICCV_2015_paper.pdf) 10 | 11 | 1. Download dataset to `datasets/` from [baidu pan](https://pan.baidu.com/s/1ntIi2Op) or [google driver](https://drive.google.com/file/d/0B8-rUzbwVRk0c054eEozWG9COHM/view) 12 | 2. Extract dataset. The dataset structure would like: 13 | 14 | ```bash 15 | datasets/ 16 | Market-1501-v15.09.15/ 17 | bounding_box_test/ 18 | bounding_box_train/ 19 | ``` 20 | 21 | ## Expected dataset structure for [DukeMTMC-reID](https://openaccess.thecvf.com/content_ICCV_2017/papers/Zheng_Unlabeled_Samples_Generated_ICCV_2017_paper.pdf) 22 | 23 | 1. Download datasets to `datasets/` 24 | 2. Extract dataset. The dataset structure would like: 25 | 26 | ```bash 27 | datasets/ 28 | DukeMTMC-reID/ 29 | bounding_box_train/ 30 | bounding_box_test/ 31 | ``` 32 | 33 | ## Expected dataset structure for [MSMT17](https://arxiv.org/abs/1711.08565) 34 | 35 | 1. Download datasets to `datasets/` 36 | 2. Extract dataset. The dataset structure would like: 37 | 38 | ```bash 39 | datasets/ 40 | MSMT17_V2/ 41 | mask_train_v2/ 42 | mask_test_v2/ 43 | ``` 44 | -------------------------------------------------------------------------------- /datasets/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/datasets/output.png -------------------------------------------------------------------------------- /datasets/p1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/datasets/p1.jpg -------------------------------------------------------------------------------- /datasets/p2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/datasets/p2.jpg -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # FastReID Demo 2 | 3 | We provide a command line tool to run a simple demo of builtin models. 4 | 5 | You can run this command to get cosine similarites between different images 6 | 7 | ```bash 8 | cd demo/ 9 | sh run_demo.sh 10 | ``` -------------------------------------------------------------------------------- /demo/demo.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import argparse 8 | import glob 9 | import os 10 | import sys 11 | 12 | import torch.nn.functional as F 13 | import cv2 14 | import numpy as np 15 | import tqdm 16 | from torch.backends import cudnn 17 | 18 | sys.path.append('.') 19 | 20 | from fastreid.config import get_cfg 21 | from fastreid.utils.logger import setup_logger 22 | from fastreid.utils.file_io import PathManager 23 | 24 | from predictor import FeatureExtractionDemo 25 | 26 | # import some modules added in project like this below 27 | # sys.path.append("projects/PartialReID") 28 | # from partialreid import * 29 | 30 | cudnn.benchmark = True 31 | setup_logger(name="fastreid") 32 | 33 | 34 | def setup_cfg(args): 35 | # load config from file and command-line arguments 36 | cfg = get_cfg() 37 | # add_partialreid_config(cfg) 38 | cfg.merge_from_file(args.config_file) 39 | cfg.merge_from_list(args.opts) 40 | cfg.freeze() 41 | return cfg 42 | 43 | 44 | def get_parser(): 45 | parser = argparse.ArgumentParser(description="Feature extraction with reid models") 46 | parser.add_argument( 47 | "--config-file", 48 | metavar="FILE", 49 | help="path to config file", 50 | ) 51 | parser.add_argument( 52 | "--parallel", 53 | action='store_true', 54 | help='If use multiprocess for feature extraction.' 55 | ) 56 | parser.add_argument( 57 | "--input", 58 | nargs="+", 59 | help="A list of space separated input images; " 60 | "or a single glob pattern such as 'directory/*.jpg'", 61 | ) 62 | parser.add_argument( 63 | "--output", 64 | default='demo_output', 65 | help='path to save features' 66 | ) 67 | parser.add_argument( 68 | "--opts", 69 | help="Modify config options using the command-line 'KEY VALUE' pairs", 70 | default=[], 71 | nargs=argparse.REMAINDER, 72 | ) 73 | return parser 74 | 75 | 76 | def postprocess(features): 77 | # Normalize feature to compute cosine distance 78 | features = F.normalize(features) 79 | features = features.cpu().data.numpy() 80 | return features 81 | 82 | 83 | if __name__ == '__main__': 84 | args = get_parser().parse_args() 85 | cfg = setup_cfg(args) 86 | demo = FeatureExtractionDemo(cfg, parallel=args.parallel) 87 | 88 | PathManager.mkdirs(args.output) 89 | if args.input: 90 | if PathManager.isdir(args.input[0]): 91 | args.input = glob.glob(os.path.expanduser(args.input[0])) 92 | assert args.input, "The input path(s) was not found" 93 | for path in tqdm.tqdm(args.input): 94 | img = cv2.imread(path) 95 | feat = demo.run_on_image(img) 96 | feat = postprocess(feat) 97 | np.save(os.path.join(args.output, os.path.basename(path).split('.')[0] + '.npy'), feat) 98 | -------------------------------------------------------------------------------- /demo/plot_roc_with_pickle.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import matplotlib.pyplot as plt 8 | import sys 9 | 10 | sys.path.append('.') 11 | from fastreid.utils.visualizer import Visualizer 12 | 13 | if __name__ == "__main__": 14 | baseline_res = Visualizer.load_roc_info("logs/duke_vis/roc_info.pickle") 15 | mgn_res = Visualizer.load_roc_info("logs/mgn_duke_vis/roc_info.pickle") 16 | 17 | fig = Visualizer.plot_roc_curve(baseline_res['fpr'], baseline_res['tpr'], name='baseline') 18 | Visualizer.plot_roc_curve(mgn_res['fpr'], mgn_res['tpr'], name='mgn', fig=fig) 19 | plt.savefig('roc.jpg') 20 | 21 | fig = Visualizer.plot_distribution(baseline_res['pos'], baseline_res['neg'], name='baseline') 22 | Visualizer.plot_distribution(mgn_res['pos'], mgn_res['neg'], name='mgn', fig=fig) 23 | plt.savefig('dist.jpg') 24 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nvidia/cuda:10.1-cudnn7-devel 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | RUN apt-get update && apt-get install -y \ 5 | python3-opencv ca-certificates python3-dev git wget sudo ninja-build 6 | RUN ln -sv /usr/bin/python3 /usr/bin/python 7 | 8 | # create a non-root user 9 | ARG USER_ID=1000 10 | RUN useradd -m --no-log-init --system --uid ${USER_ID} appuser -g sudo 11 | RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers 12 | USER appuser 13 | WORKDIR /home/appuser 14 | 15 | ENV PATH="/home/appuser/.local/bin:${PATH}" 16 | RUN wget https://bootstrap.pypa.io/get-pip.py && \ 17 | python3 get-pip.py --user && \ 18 | rm get-pip.py 19 | 20 | # install dependencies 21 | # See https://pytorch.org/ for other options if you use a different version of CUDA 22 | RUN pip install --user tensorboard cmake # cmake from apt-get is too old 23 | RUN pip install --user torch==1.6.0+cu101 torchvision==0.7.0+cu101 -f https://download.pytorch.org/whl/cu101/torch_stable.html 24 | RUN pip install --user -i https://pypi.tuna.tsinghua.edu.cn/simple tensorboard opencv-python cython yacs termcolor scikit-learn tabulate gdown gpustat faiss-gpu ipdb h5py 25 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Use the container 2 | 3 | ```shell script 4 | cd docker/ 5 | # Build: 6 | docker build -t=fastreid:v0 . 7 | # Launch (requires GPUs) 8 | nvidia-docker run -v server_path:docker_path --name=fastreid --net=host --ipc=host -it fastreid:v0 /bin/sh 9 | ``` 10 | 11 | ## Install new dependencies 12 | 13 | Add the following to `Dockerfile` to make persist changes. 14 | ```shell script 15 | RUN sudo apt-get update && sudo apt-get install -y vim 16 | ``` 17 | 18 | Or run them in the container to make temporary changes. 19 | 20 | ## A more complete docker container 21 | 22 | If you want to use a complete docker container which contains many useful tools, you can check my development environment [Dockerfile](https://github.com/L1aoXingyu/fastreid_docker) -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _build -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SOURCEDIR = . 8 | BUILDDIR = _build 9 | 10 | # Put it first so that "make" without argument is like "make help". 11 | help: 12 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 13 | 14 | .PHONY: help Makefile 15 | 16 | # Catch-all target: route all unknown targets to Sphinx using the new 17 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 18 | %: Makefile 19 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 20 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Read the docs: 2 | 3 | The latest documentation built from this directory is available at [detectron2.readthedocs.io](https://detectron2.readthedocs.io/). 4 | Documents in this directory are not meant to be read on github. 5 | 6 | # Build the docs: 7 | 8 | 1. Install detectron2 according to [INSTALL.md](https://github.com/facebookresearch/detectron2/blob/master/INSTALL.md). 9 | 2. Install additional libraries required to build docs: 10 | - docutils==0.16 11 | - Sphinx==3.0.0 12 | - recommonmark==0.6.0 13 | - sphinx_rtd_theme 14 | - mock 15 | 16 | 3. Run `make html` from this directory. 17 | -------------------------------------------------------------------------------- /docs/_static/css/custom.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * some extra css to make markdown look similar between github/sphinx 4 | */ 5 | 6 | /* 7 | * Below is for install.md: 8 | */ 9 | .rst-content code { 10 | white-space: pre; 11 | border: 0px; 12 | } 13 | 14 | .rst-content th { 15 | border: 1px solid #e1e4e5; 16 | } 17 | 18 | .rst-content th p { 19 | /* otherwise will be default 24px for regular paragraph */ 20 | margin-bottom: 0px; 21 | } 22 | 23 | div.section > details { 24 | padding-bottom: 1em; 25 | } 26 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. fastreid documentation master file, created by 2 | sphinx-quickstart on Sat Sep 21 13:46:45 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to fastreid's documentation! 7 | ====================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | 12 | tutorials/index 13 | notes/index 14 | modules/index 15 | -------------------------------------------------------------------------------- /docs/modules/checkpoint.rst: -------------------------------------------------------------------------------- 1 | fastreid.checkpoint 2 | ============================= 3 | 4 | .. automodule:: fastreid.utils.checkpoint 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/modules/config.rst: -------------------------------------------------------------------------------- 1 | fastreid.config 2 | ========================= 3 | 4 | Related tutorials: :doc:`../tutorials/configs`, :doc:`../tutorials/extend`. 5 | 6 | .. automodule:: fastreid.config 7 | :members: 8 | :undoc-members: 9 | :show-inheritance: 10 | :inherited-members: 11 | 12 | 13 | Config References 14 | ----------------- 15 | 16 | .. literalinclude:: ../../fastreid/config/defaults.py 17 | :language: python 18 | :linenos: 19 | :lines: 4- 20 | -------------------------------------------------------------------------------- /docs/modules/data.rst: -------------------------------------------------------------------------------- 1 | fastreid.data 2 | ======================= 3 | 4 | .. automodule:: fastreid.data.build 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | 10 | fastreid.data.data\_utils module 11 | --------------------------------------- 12 | 13 | .. automodule:: fastreid.data.data_utils 14 | :members: 15 | :undoc-members: 16 | :show-inheritance: 17 | 18 | 19 | fastreid.data.datasets module 20 | --------------------------------------- 21 | 22 | .. automodule:: fastreid.data.datasets.market1501 23 | :members: 24 | 25 | .. automodule:: fastreid.data.datasets.cuhk03 26 | :members: 27 | 28 | .. automodule:: fastreid.data.datasets.dukemtmcreid 29 | :members: 30 | 31 | .. automodule:: fastreid.data.datasets.msmt17 32 | :members: 33 | 34 | .. automodule:: fastreid.data.datasets.AirportALERT 35 | :members: 36 | 37 | .. automodule:: fastreid.data.datasets.iLIDS 38 | :members: 39 | 40 | .. automodule:: fastreid.data.datasets.pku 41 | :members: 42 | 43 | .. automodule:: fastreid.data.datasets.prai 44 | :members: 45 | 46 | .. automodule:: fastreid.data.datasets.saivt 47 | :members: 48 | 49 | .. automodule:: fastreid.data.datasets.sensereid 50 | :members: 51 | 52 | .. automodule:: fastreid.data.datasets.sysu_mm 53 | :members: 54 | 55 | .. automodule:: fastreid.data.datasets.thermalworld 56 | :members: 57 | 58 | .. automodule:: fastreid.data.datasets.pes3d 59 | :members: 60 | 61 | .. automodule:: fastreid.data.datasets.caviara 62 | :members: 63 | 64 | .. automodule:: fastreid.data.datasets.viper 65 | :members: 66 | 67 | .. automodule:: fastreid.data.datasets.lpw 68 | :members: 69 | 70 | .. automodule:: fastreid.data.datasets.shinpuhkan 71 | :members: 72 | 73 | .. automodule:: fastreid.data.datasets.wildtracker 74 | :members: 75 | 76 | .. automodule:: fastreid.data.datasets.cuhk_sysu 77 | :members: 78 | 79 | 80 | fastreid.data.samplers module 81 | --------------------------------------- 82 | 83 | .. automodule:: fastreid.data.samplers 84 | :members: 85 | :undoc-members: 86 | :show-inheritance: 87 | 88 | 89 | fastreid.data.transforms module 90 | --------------------------------------- 91 | 92 | .. automodule:: fastreid.data.transforms 93 | :members: 94 | :undoc-members: 95 | :show-inheritance: 96 | :imported-members: 97 | -------------------------------------------------------------------------------- /docs/modules/data_transforms.rst: -------------------------------------------------------------------------------- 1 | fastreid.data.transforms 2 | ==================================== 3 | 4 | 5 | .. automodule:: fastreid.data.transforms 6 | :members: 7 | :undoc-members: 8 | :show-inheritance: 9 | :imported-members: 10 | -------------------------------------------------------------------------------- /docs/modules/engine.rst: -------------------------------------------------------------------------------- 1 | fastreid.engine 2 | ========================= 3 | 4 | .. automodule:: fastreid.engine 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | 10 | fastreid.engine.defaults module 11 | --------------------------------- 12 | 13 | .. automodule:: fastreid.engine.defaults 14 | :members: 15 | :undoc-members: 16 | :show-inheritance: 17 | 18 | fastreid.engine.hooks module 19 | --------------------------------- 20 | 21 | .. automodule:: fastreid.engine.hooks 22 | :members: 23 | :undoc-members: 24 | :show-inheritance: 25 | -------------------------------------------------------------------------------- /docs/modules/evaluation.rst: -------------------------------------------------------------------------------- 1 | fastreid.evaluation 2 | ============================= 3 | 4 | .. automodule:: fastreid.evaluation 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/modules/index.rst: -------------------------------------------------------------------------------- 1 | API Documentation 2 | ================== 3 | 4 | .. toctree:: 5 | 6 | checkpoint 7 | config 8 | data 9 | data_transforms 10 | engine 11 | evaluation 12 | layers 13 | model_zoo 14 | modeling 15 | solver 16 | utils 17 | export 18 | -------------------------------------------------------------------------------- /docs/modules/layers.rst: -------------------------------------------------------------------------------- 1 | fastreid.layers 2 | ========================= 3 | 4 | .. automodule:: fastreid.layers 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/modules/modeling.rst: -------------------------------------------------------------------------------- 1 | fastreid.modeling 2 | =========================== 3 | 4 | .. automodule:: fastreid.modeling 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | 9 | Model Registries 10 | ----------------- 11 | 12 | These are different registries provided in modeling. 13 | Each registry provide you the ability to replace it with your customized component, 14 | without having to modify fastreid's code. 15 | 16 | Note that it is impossible to allow users to customize any line of code directly. 17 | Even just to add one line at some place, 18 | you'll likely need to find out the smallest registry which contains that line, 19 | and register your component to that registry. 20 | 21 | 22 | .. autodata:: fastreid.modeling.BACKBONE_REGISTRY 23 | .. autodata:: fastreid.modeling.META_ARCH_REGISTRY 24 | .. autodata:: fastreid.modeling.REID_HEADS_REGISTRY 25 | -------------------------------------------------------------------------------- /docs/modules/solver.rst: -------------------------------------------------------------------------------- 1 | fastreid.solver 2 | ========================= 3 | 4 | .. automodule:: fastreid.solver 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/modules/utils.rst: -------------------------------------------------------------------------------- 1 | fastreid.utils 2 | ======================== 3 | 4 | fastreid.utils.colormap module 5 | -------------------------------- 6 | 7 | .. automodule:: fastreid.utils.colormap 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | fastreid.utils.comm module 13 | ---------------------------- 14 | 15 | .. automodule:: fastreid.utils.comm 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | 20 | 21 | fastreid.utils.events module 22 | ------------------------------ 23 | 24 | .. automodule:: fastreid.utils.events 25 | :members: 26 | :undoc-members: 27 | :show-inheritance: 28 | 29 | 30 | fastreid.utils.logger module 31 | ------------------------------ 32 | 33 | .. automodule:: fastreid.utils.logger 34 | :members: 35 | :undoc-members: 36 | :show-inheritance: 37 | 38 | 39 | fastreid.utils.registry module 40 | -------------------------------- 41 | 42 | .. automodule:: fastreid.utils.registry 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | fastreid.utils.memory module 48 | ---------------------------------- 49 | 50 | .. automodule:: fastreid.utils.memory 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | 55 | 56 | fastreid.utils.analysis module 57 | ---------------------------------- 58 | 59 | .. automodule:: fastreid.utils.analysis 60 | :members: 61 | :undoc-members: 62 | :show-inheritance: 63 | 64 | 65 | fastreid.utils.visualizer module 66 | ---------------------------------- 67 | 68 | .. automodule:: fastreid.utils.visualizer 69 | :members: 70 | :undoc-members: 71 | :show-inheritance: 72 | 73 | fastreid.utils.video\_visualizer module 74 | ----------------------------------------- 75 | 76 | .. automodule:: fastreid.utils.video_visualizer 77 | :members: 78 | :undoc-members: 79 | :show-inheritance: 80 | 81 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | matplotlib 2 | scipy 3 | Pillow 4 | numpy 5 | prettytable 6 | easydict 7 | scikit-learn 8 | pyyaml 9 | yacs 10 | termcolor 11 | tabulate 12 | tensorboard 13 | opencv-python 14 | pyyaml 15 | yacs 16 | termcolor 17 | scikit-learn 18 | tabulate 19 | gdown 20 | faiss-gpu -------------------------------------------------------------------------------- /fastreid/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | 8 | __version__ = "1.3" 9 | -------------------------------------------------------------------------------- /fastreid/config/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: l1aoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .config import CfgNode, get_cfg, global_cfg, set_global_cfg, configurable 8 | 9 | __all__ = [ 10 | 'CfgNode', 11 | 'get_cfg', 12 | 'global_cfg', 13 | 'set_global_cfg', 14 | 'configurable' 15 | ] 16 | -------------------------------------------------------------------------------- /fastreid/data/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: sherlock 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from . import transforms # isort:skip 8 | from .build import ( 9 | build_reid_train_loader, 10 | build_reid_test_loader 11 | ) 12 | from .common import CommDataset 13 | 14 | # ensure the builtin datasets are registered 15 | from . import datasets, samplers # isort:skip 16 | 17 | __all__ = [k for k in globals().keys() if not k.startswith("_")] 18 | -------------------------------------------------------------------------------- /fastreid/data/common.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from torch.utils.data import Dataset 8 | 9 | from .data_utils import read_image 10 | 11 | 12 | class CommDataset(Dataset): 13 | """Image Person ReID Dataset""" 14 | 15 | def __init__(self, img_items, transform=None, relabel=True): 16 | self.img_items = img_items 17 | self.transform = transform 18 | self.relabel = relabel 19 | 20 | pid_set = set() 21 | cam_set = set() 22 | for i in img_items: 23 | pid_set.add(i[1]) 24 | cam_set.add(i[2]) 25 | 26 | self.pids = sorted(list(pid_set)) 27 | self.cams = sorted(list(cam_set)) 28 | if relabel: 29 | self.pid_dict = dict([(p, i) for i, p in enumerate(self.pids)]) 30 | self.cam_dict = dict([(p, i) for i, p in enumerate(self.cams)]) 31 | 32 | def __len__(self): 33 | return len(self.img_items) 34 | 35 | def __getitem__(self, index): 36 | img_item = self.img_items[index] 37 | img_path = img_item[0] 38 | pid = img_item[1] 39 | camid = img_item[2] 40 | img = read_image(img_path) 41 | if self.transform is not None: img = self.transform(img) 42 | if self.relabel: 43 | pid = self.pid_dict[pid] 44 | camid = self.cam_dict[camid] 45 | return { 46 | "images": img, 47 | "targets": pid, 48 | "camids": camid, 49 | "img_paths": img_path, 50 | } 51 | 52 | @property 53 | def num_classes(self): 54 | return len(self.pids) 55 | 56 | @property 57 | def num_cameras(self): 58 | return len(self.cams) 59 | -------------------------------------------------------------------------------- /fastreid/data/datasets/AirportALERT.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | 9 | from fastreid.data.datasets import DATASET_REGISTRY 10 | from fastreid.data.datasets.bases import ImageDataset 11 | 12 | __all__ = ['AirportALERT', ] 13 | 14 | 15 | @DATASET_REGISTRY.register() 16 | class AirportALERT(ImageDataset): 17 | """Airport 18 | 19 | """ 20 | dataset_dir = "AirportALERT" 21 | dataset_name = "airport" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | self.train_file = os.path.join(self.root, self.dataset_dir, 'filepath.txt') 27 | 28 | required_files = [self.train_file, self.train_path] 29 | self.check_before_run(required_files) 30 | 31 | train = self.process_train(self.train_path, self.train_file) 32 | 33 | super().__init__(train, [], [], **kwargs) 34 | 35 | def process_train(self, dir_path, train_file): 36 | data = [] 37 | with open(train_file, "r") as f: 38 | img_paths = [line.strip('\n') for line in f.readlines()] 39 | 40 | for path in img_paths: 41 | split_path = path.split('\\') 42 | img_path = '/'.join(split_path) 43 | camid = self.dataset_name + "_" + split_path[0] 44 | pid = self.dataset_name + "_" + split_path[1] 45 | img_path = os.path.join(dir_path, img_path) 46 | # if 11001 <= int(split_path[1]) <= 401999: 47 | if 11001 <= int(split_path[1]): 48 | data.append([img_path, pid, camid]) 49 | 50 | return data 51 | -------------------------------------------------------------------------------- /fastreid/data/datasets/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from ...utils.registry import Registry 8 | 9 | DATASET_REGISTRY = Registry("DATASET") 10 | DATASET_REGISTRY.__doc__ = """ 11 | Registry for datasets 12 | It must returns an instance of :class:`Backbone`. 13 | """ 14 | 15 | # Person re-id datasets 16 | from .cuhk03 import CUHK03 17 | from .dukemtmcreid import DukeMTMC 18 | from .market1501 import Market1501 19 | from .msmt17 import MSMT17 20 | from .AirportALERT import AirportALERT 21 | from .iLIDS import iLIDS 22 | from .pku import PKU 23 | from .prai import PRAI 24 | from .prid import PRID 25 | from .grid import GRID 26 | from .saivt import SAIVT 27 | from .sensereid import SenseReID 28 | from .sysu_mm import SYSU_mm 29 | from .thermalworld import Thermalworld 30 | from .pes3d import PeS3D 31 | from .caviara import CAVIARa 32 | from .viper import VIPeR 33 | from .lpw import LPW 34 | from .shinpuhkan import Shinpuhkan 35 | from .wildtracker import WildTrackCrop 36 | from .cuhk_sysu import cuhkSYSU 37 | 38 | # Vehicle re-id datasets 39 | from .veri import VeRi 40 | from .vehicleid import VehicleID, SmallVehicleID, MediumVehicleID, LargeVehicleID 41 | from .veriwild import VeRiWild, SmallVeRiWild, MediumVeRiWild, LargeVeRiWild 42 | 43 | __all__ = [k for k in globals().keys() if "builtin" not in k and not k.startswith("_")] 44 | -------------------------------------------------------------------------------- /fastreid/data/datasets/caviara.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['CAVIARa', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class CAVIARa(ImageDataset): 18 | """CAVIARa 19 | """ 20 | dataset_dir = "CAVIARa" 21 | dataset_name = "caviara" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | 37 | img_list = glob(os.path.join(train_path, "*.jpg")) 38 | for img_path in img_list: 39 | img_name = img_path.split('/')[-1] 40 | pid = self.dataset_name + "_" + img_name[:4] 41 | camid = self.dataset_name + "_cam0" 42 | data.append([img_path, pid, camid]) 43 | 44 | return data 45 | -------------------------------------------------------------------------------- /fastreid/data/datasets/cuhk_sysu.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import glob 8 | import os.path as osp 9 | import re 10 | import warnings 11 | 12 | from .bases import ImageDataset 13 | from ..datasets import DATASET_REGISTRY 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class cuhkSYSU(ImageDataset): 18 | """CUHK SYSU datasets. 19 | 20 | The dataset is collected from two sources: street snap and movie. 21 | In street snap, 12,490 images and 6,057 query persons were collected 22 | with movable cameras across hundreds of scenes while 5,694 images and 23 | 2,375 query persons were selected from movies and TV dramas. 24 | 25 | Dataset statistics: 26 | - identities: xxx. 27 | - images: 12936 (train). 28 | """ 29 | dataset_dir = 'cuhk_sysu' 30 | dataset_name = "cuhksysu" 31 | 32 | def __init__(self, root='datasets', **kwargs): 33 | self.root = root 34 | self.dataset_dir = osp.join(self.root, self.dataset_dir) 35 | 36 | self.data_dir = osp.join(self.dataset_dir, "cropped_images") 37 | 38 | required_files = [self.data_dir] 39 | self.check_before_run(required_files) 40 | 41 | train = self.process_dir(self.data_dir) 42 | query = [] 43 | gallery = [] 44 | 45 | super(cuhkSYSU, self).__init__(train, query, gallery, **kwargs) 46 | 47 | def process_dir(self, dir_path): 48 | img_paths = glob.glob(osp.join(dir_path, '*.jpg')) 49 | pattern = re.compile(r'p([-\d]+)_s(\d)') 50 | 51 | data = [] 52 | for img_path in img_paths: 53 | pid, _ = map(int, pattern.search(img_path).groups()) 54 | pid = self.dataset_name + "_" + str(pid) 55 | camid = self.dataset_name + "_0" 56 | data.append((img_path, pid, camid)) 57 | 58 | return data 59 | -------------------------------------------------------------------------------- /fastreid/data/datasets/dukemtmcreid.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: liaoxingyu2@jd.com 5 | """ 6 | 7 | import glob 8 | import os.path as osp 9 | import re 10 | 11 | from .bases import ImageDataset 12 | from ..datasets import DATASET_REGISTRY 13 | 14 | 15 | @DATASET_REGISTRY.register() 16 | class DukeMTMC(ImageDataset): 17 | """DukeMTMC-reID. 18 | 19 | Reference: 20 | - Ristani et al. Performance Measures and a Data Set for Multi-Target, Multi-Camera Tracking. ECCVW 2016. 21 | - Zheng et al. Unlabeled Samples Generated by GAN Improve the Person Re-identification Baseline in vitro. ICCV 2017. 22 | 23 | URL: ``_ 24 | 25 | Dataset statistics: 26 | - identities: 1404 (train + query). 27 | - images:16522 (train) + 2228 (query) + 17661 (gallery). 28 | - cameras: 8. 29 | """ 30 | dataset_dir = 'DukeMTMC-reID' 31 | dataset_url = 'http://vision.cs.duke.edu/DukeMTMC/data/misc/DukeMTMC-reID.zip' 32 | dataset_name = "dukemtmc" 33 | 34 | def __init__(self, root='datasets', **kwargs): 35 | # self.root = osp.abspath(osp.expanduser(root)) 36 | self.root = root 37 | self.dataset_dir = osp.join(self.root, self.dataset_dir) 38 | self.train_dir = osp.join(self.dataset_dir, 'bounding_box_train') 39 | self.query_dir = osp.join(self.dataset_dir, 'query') 40 | self.gallery_dir = osp.join(self.dataset_dir, 'bounding_box_test') 41 | 42 | required_files = [ 43 | self.dataset_dir, 44 | self.train_dir, 45 | self.query_dir, 46 | self.gallery_dir, 47 | ] 48 | self.check_before_run(required_files) 49 | 50 | train = self.process_dir(self.train_dir) 51 | query = self.process_dir(self.query_dir, is_train=False) 52 | gallery = self.process_dir(self.gallery_dir, is_train=False) 53 | 54 | super(DukeMTMC, self).__init__(train, query, gallery, **kwargs) 55 | 56 | def process_dir(self, dir_path, is_train=True): 57 | img_paths = glob.glob(osp.join(dir_path, '*.jpg')) 58 | pattern = re.compile(r'([-\d]+)_c(\d)') 59 | 60 | data = [] 61 | for img_path in img_paths: 62 | pid, camid = map(int, pattern.search(img_path).groups()) 63 | assert 1 <= camid <= 8 64 | camid -= 1 # index starts from 0 65 | if is_train: 66 | pid = self.dataset_name + "_" + str(pid) 67 | camid = self.dataset_name + "_" + str(camid) 68 | data.append((img_path, pid, camid)) 69 | 70 | return data 71 | -------------------------------------------------------------------------------- /fastreid/data/datasets/grid.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['GRID', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class GRID(ImageDataset): 18 | """GRID 19 | """ 20 | dataset_dir = "underground_reid" 21 | dataset_name = 'grid' 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir, 'images') 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | img_paths = glob(os.path.join(train_path, "*.jpeg")) 37 | 38 | for img_path in img_paths: 39 | img_name = os.path.basename(img_path) 40 | img_info = img_name.split('_') 41 | pid = self.dataset_name + "_" + img_info[0] 42 | camid = self.dataset_name + "_" + img_info[1] 43 | data.append([img_path, pid, camid]) 44 | return data 45 | -------------------------------------------------------------------------------- /fastreid/data/datasets/iLIDS.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['iLIDS', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class iLIDS(ImageDataset): 18 | """iLIDS 19 | """ 20 | dataset_dir = "iLIDS" 21 | dataset_name = "ilids" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | file_path = os.listdir(train_path) 37 | for pid_dir in file_path: 38 | img_file = os.path.join(train_path, pid_dir) 39 | img_paths = glob(os.path.join(img_file, "*.png")) 40 | for img_path in img_paths: 41 | split_path = img_path.split('/') 42 | pid = self.dataset_name + "_" + split_path[-2] 43 | camid = self.dataset_name + "_" + split_path[-1].split('_')[0] 44 | data.append([img_path, pid, camid]) 45 | return data 46 | -------------------------------------------------------------------------------- /fastreid/data/datasets/lpw.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['LPW', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class LPW(ImageDataset): 18 | """LPW 19 | """ 20 | dataset_dir = "pep_256x128/data_slim" 21 | dataset_name = "lpw" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | 37 | file_path_list = ['scen1', 'scen2', 'scen3'] 38 | 39 | for scene in file_path_list: 40 | cam_list = os.listdir(os.path.join(train_path, scene)) 41 | for cam in cam_list: 42 | camid = self.dataset_name + "_" + cam 43 | pid_list = os.listdir(os.path.join(train_path, scene, cam)) 44 | for pid_dir in pid_list: 45 | img_paths = glob(os.path.join(train_path, scene, cam, pid_dir, "*.jpg")) 46 | for img_path in img_paths: 47 | pid = self.dataset_name + "_" + scene + "-" + pid_dir 48 | data.append([img_path, pid, camid]) 49 | return data 50 | -------------------------------------------------------------------------------- /fastreid/data/datasets/pes3d.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['PeS3D',] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class PeS3D(ImageDataset): 18 | """3Dpes 19 | """ 20 | dataset_dir = "3DPeS" 21 | dataset_name = "pes3d" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | 37 | pid_list = os.listdir(train_path) 38 | for pid_dir in pid_list: 39 | pid = self.dataset_name + "_" + pid_dir 40 | img_list = glob(os.path.join(train_path, pid_dir, "*.bmp")) 41 | for img_path in img_list: 42 | camid = self.dataset_name + "_cam0" 43 | data.append([img_path, pid, camid]) 44 | return data 45 | -------------------------------------------------------------------------------- /fastreid/data/datasets/pku.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['PKU', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class PKU(ImageDataset): 18 | """PKU 19 | """ 20 | dataset_dir = "PKUv1a_128x48" 21 | dataset_name = 'pku' 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | img_paths = glob(os.path.join(train_path, "*.png")) 37 | 38 | for img_path in img_paths: 39 | split_path = img_path.split('/') 40 | img_info = split_path[-1].split('_') 41 | pid = self.dataset_name + "_" + img_info[0] 42 | camid = self.dataset_name + "_" + img_info[1] 43 | data.append([img_path, pid, camid]) 44 | return data 45 | -------------------------------------------------------------------------------- /fastreid/data/datasets/prai.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['PRAI', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class PRAI(ImageDataset): 18 | """PRAI 19 | """ 20 | dataset_dir = "PRAI-1581" 21 | dataset_name = 'prai' 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir, 'images') 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | img_paths = glob(os.path.join(train_path, "*.jpg")) 37 | for img_path in img_paths: 38 | split_path = img_path.split('/') 39 | img_info = split_path[-1].split('_') 40 | pid = self.dataset_name + "_" + img_info[0] 41 | camid = self.dataset_name + "_" + img_info[1] 42 | data.append([img_path, pid, camid]) 43 | return data 44 | -------------------------------------------------------------------------------- /fastreid/data/datasets/prid.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | 9 | from fastreid.data.datasets import DATASET_REGISTRY 10 | from fastreid.data.datasets.bases import ImageDataset 11 | 12 | __all__ = ['PRID', ] 13 | 14 | 15 | @DATASET_REGISTRY.register() 16 | class PRID(ImageDataset): 17 | """PRID 18 | """ 19 | dataset_dir = "prid_2011" 20 | dataset_name = 'prid' 21 | 22 | def __init__(self, root='datasets', **kwargs): 23 | self.root = root 24 | self.train_path = os.path.join(self.root, self.dataset_dir, 'slim_train') 25 | 26 | required_files = [self.train_path] 27 | self.check_before_run(required_files) 28 | 29 | train = self.process_train(self.train_path) 30 | 31 | super().__init__(train, [], [], **kwargs) 32 | 33 | def process_train(self, train_path): 34 | data = [] 35 | for root, dirs, files in os.walk(train_path): 36 | for img_name in filter(lambda x: x.endswith('.png'), files): 37 | img_path = os.path.join(root, img_name) 38 | pid = self.dataset_name + '_' + root.split('/')[-1].split('_')[1] 39 | camid = self.dataset_name + '_' + img_name.split('_')[0] 40 | data.append([img_path, pid, camid]) 41 | return data 42 | -------------------------------------------------------------------------------- /fastreid/data/datasets/saivt.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['SAIVT', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class SAIVT(ImageDataset): 18 | """SAIVT 19 | """ 20 | dataset_dir = "SAIVT-SoftBio" 21 | dataset_name = "saivt" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | 37 | pid_path = os.path.join(train_path, "cropped_images") 38 | pid_list = os.listdir(pid_path) 39 | 40 | for pid_name in pid_list: 41 | pid = self.dataset_name + '_' + pid_name 42 | img_list = glob(os.path.join(pid_path, pid_name, "*.jpeg")) 43 | for img_path in img_list: 44 | img_name = os.path.basename(img_path) 45 | camid = self.dataset_name + '_' + img_name.split('-')[2] 46 | data.append([img_path, pid, camid]) 47 | return data 48 | -------------------------------------------------------------------------------- /fastreid/data/datasets/sensereid.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['SenseReID', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class SenseReID(ImageDataset): 18 | """Sense reid 19 | """ 20 | dataset_dir = "SenseReID" 21 | dataset_name = "senseid" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | file_path_list = ['test_gallery', 'test_prob'] 37 | 38 | for file_path in file_path_list: 39 | sub_file = os.path.join(train_path, file_path) 40 | img_name = glob(os.path.join(sub_file, "*.jpg")) 41 | for img_path in img_name: 42 | img_name = img_path.split('/')[-1] 43 | img_info = img_name.split('_') 44 | pid = self.dataset_name + "_" + img_info[0] 45 | camid = self.dataset_name + "_" + img_info[1].split('.')[0] 46 | data.append([img_path, pid, camid]) 47 | return data 48 | -------------------------------------------------------------------------------- /fastreid/data/datasets/shinpuhkan.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | 9 | from fastreid.data.datasets import DATASET_REGISTRY 10 | from fastreid.data.datasets.bases import ImageDataset 11 | 12 | __all__ = ['Shinpuhkan', ] 13 | 14 | 15 | @DATASET_REGISTRY.register() 16 | class Shinpuhkan(ImageDataset): 17 | """shinpuhkan 18 | """ 19 | dataset_dir = "shinpuhkan" 20 | dataset_name = 'shinpuhkan' 21 | 22 | def __init__(self, root='datasets', **kwargs): 23 | self.root = root 24 | self.train_path = os.path.join(self.root, self.dataset_dir) 25 | 26 | required_files = [self.train_path] 27 | self.check_before_run(required_files) 28 | 29 | train = self.process_train(self.train_path) 30 | 31 | super().__init__(train, [], [], **kwargs) 32 | 33 | def process_train(self, train_path): 34 | data = [] 35 | 36 | for root, dirs, files in os.walk(train_path): 37 | img_names = list(filter(lambda x: x.endswith(".jpg"), files)) 38 | # fmt: off 39 | if len(img_names) == 0: continue 40 | # fmt: on 41 | for img_name in img_names: 42 | img_path = os.path.join(root, img_name) 43 | split_path = img_name.split('_') 44 | pid = self.dataset_name + "_" + split_path[0] 45 | camid = self.dataset_name + "_" + split_path[2] 46 | data.append((img_path, pid, camid)) 47 | 48 | return data 49 | -------------------------------------------------------------------------------- /fastreid/data/datasets/sysu_mm.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['SYSU_mm', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class SYSU_mm(ImageDataset): 18 | """sysu mm 19 | """ 20 | dataset_dir = "SYSU-MM01" 21 | dataset_name = "sysumm01" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | 37 | file_path_list = ['cam1', 'cam2', 'cam4', 'cam5'] 38 | 39 | for file_path in file_path_list: 40 | camid = self.dataset_name + "_" + file_path 41 | pid_list = os.listdir(os.path.join(train_path, file_path)) 42 | for pid_dir in pid_list: 43 | pid = self.dataset_name + "_" + pid_dir 44 | img_list = glob(os.path.join(train_path, file_path, pid_dir, "*.jpg")) 45 | for img_path in img_list: 46 | data.append([img_path, pid, camid]) 47 | return data 48 | -------------------------------------------------------------------------------- /fastreid/data/datasets/thermalworld.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['Thermalworld', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class Thermalworld(ImageDataset): 18 | """thermal world 19 | """ 20 | dataset_dir = "thermalworld_rgb" 21 | dataset_name = "thermalworld" 22 | 23 | def __init__(self, root='datasets', **kwargs): 24 | self.root = root 25 | self.train_path = os.path.join(self.root, self.dataset_dir) 26 | 27 | required_files = [self.train_path] 28 | self.check_before_run(required_files) 29 | 30 | train = self.process_train(self.train_path) 31 | 32 | super().__init__(train, [], [], **kwargs) 33 | 34 | def process_train(self, train_path): 35 | data = [] 36 | pid_list = os.listdir(train_path) 37 | for pid_dir in pid_list: 38 | pid = self.dataset_name + "_" + pid_dir 39 | img_list = glob(os.path.join(train_path, pid_dir, "*.jpg")) 40 | for img_path in img_list: 41 | camid = self.dataset_name + "_cam0" 42 | data.append([img_path, pid, camid]) 43 | return data 44 | -------------------------------------------------------------------------------- /fastreid/data/datasets/veri.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: Jinkai Zheng 4 | @contact: 1315673509@qq.com 5 | """ 6 | 7 | import glob 8 | import os.path as osp 9 | import re 10 | 11 | from .bases import ImageDataset 12 | from ..datasets import DATASET_REGISTRY 13 | 14 | 15 | @DATASET_REGISTRY.register() 16 | class VeRi(ImageDataset): 17 | """VeRi. 18 | 19 | Reference: 20 | Xinchen Liu et al. A Deep Learning based Approach for Progressive Vehicle Re-Identification. ECCV 2016. 21 | Xinchen Liu et al. PROVID: Progressive and Multimodal Vehicle Reidentification for Large-Scale Urban Surveillance. IEEE TMM 2018. 22 | 23 | URL: ``_ 24 | 25 | Dataset statistics: 26 | - identities: 775. 27 | - images: 37778 (train) + 1678 (query) + 11579 (gallery). 28 | """ 29 | dataset_dir = "veri" 30 | dataset_name = "veri" 31 | 32 | def __init__(self, root='datasets', **kwargs): 33 | self.dataset_dir = osp.join(root, self.dataset_dir) 34 | 35 | self.train_dir = osp.join(self.dataset_dir, 'image_train') 36 | self.query_dir = osp.join(self.dataset_dir, 'image_query') 37 | self.gallery_dir = osp.join(self.dataset_dir, 'image_test') 38 | 39 | required_files = [ 40 | self.dataset_dir, 41 | self.train_dir, 42 | self.query_dir, 43 | self.gallery_dir, 44 | ] 45 | self.check_before_run(required_files) 46 | 47 | train = self.process_dir(self.train_dir) 48 | query = self.process_dir(self.query_dir, is_train=False) 49 | gallery = self.process_dir(self.gallery_dir, is_train=False) 50 | 51 | super(VeRi, self).__init__(train, query, gallery, **kwargs) 52 | 53 | def process_dir(self, dir_path, is_train=True): 54 | img_paths = glob.glob(osp.join(dir_path, '*.jpg')) 55 | pattern = re.compile(r'([\d]+)_c(\d\d\d)') 56 | 57 | data = [] 58 | for img_path in img_paths: 59 | pid, camid = map(int, pattern.search(img_path).groups()) 60 | if pid == -1: continue # junk images are just ignored 61 | assert 0 <= pid <= 776 62 | assert 1 <= camid <= 20 63 | camid -= 1 # index starts from 0 64 | if is_train: 65 | pid = self.dataset_name + "_" + str(pid) 66 | camid = self.dataset_name + "_" + str(camid) 67 | data.append((img_path, pid, camid)) 68 | 69 | return data 70 | -------------------------------------------------------------------------------- /fastreid/data/datasets/viper.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import os 8 | from glob import glob 9 | 10 | from fastreid.data.datasets import DATASET_REGISTRY 11 | from fastreid.data.datasets.bases import ImageDataset 12 | 13 | __all__ = ['VIPeR', ] 14 | 15 | 16 | @DATASET_REGISTRY.register() 17 | class VIPeR(ImageDataset): 18 | dataset_dir = "VIPeR" 19 | dataset_name = "viper" 20 | 21 | def __init__(self, root='datasets', **kwargs): 22 | self.root = root 23 | self.train_path = os.path.join(self.root, self.dataset_dir) 24 | 25 | required_files = [self.train_path] 26 | self.check_before_run(required_files) 27 | 28 | train = self.process_train(self.train_path) 29 | 30 | super().__init__(train, [], [], **kwargs) 31 | 32 | def process_train(self, train_path): 33 | data = [] 34 | 35 | file_path_list = ['cam_a', 'cam_b'] 36 | 37 | for file_path in file_path_list: 38 | camid = self.dataset_name + "_" + file_path 39 | img_list = glob(os.path.join(train_path, file_path, "*.bmp")) 40 | for img_path in img_list: 41 | img_name = img_path.split('/')[-1] 42 | pid = self.dataset_name + "_" + img_name.split('_')[0] 43 | data.append([img_path, pid, camid]) 44 | 45 | return data 46 | -------------------------------------------------------------------------------- /fastreid/data/datasets/wildtracker.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: wangguanan 4 | @contact: guan.wang0706@gmail.com 5 | """ 6 | 7 | import glob 8 | import os 9 | 10 | from .bases import ImageDataset 11 | from ..datasets import DATASET_REGISTRY 12 | 13 | 14 | @DATASET_REGISTRY.register() 15 | class WildTrackCrop(ImageDataset): 16 | """WildTrack. 17 | Reference: 18 | WILDTRACK: A Multi-camera HD Dataset for Dense Unscripted Pedestrian Detection 19 | T. Chavdarova; P. Baqué; A. Maksai; S. Bouquet; C. Jose et al. 20 | URL: ``_ 21 | Dataset statistics: 22 | - identities: 313 23 | - images: 33979 (train only) 24 | - cameras: 7 25 | Args: 26 | data_path(str): path to WildTrackCrop dataset 27 | combineall(bool): combine train and test sets as train set if True 28 | """ 29 | dataset_url = None 30 | dataset_dir = 'Wildtrack_crop_dataset' 31 | dataset_name = 'wildtrack' 32 | 33 | def __init__(self, root='datasets', **kwargs): 34 | self.root = root 35 | self.dataset_dir = os.path.join(self.root, self.dataset_dir) 36 | 37 | self.train_dir = os.path.join(self.dataset_dir, "crop") 38 | 39 | train = self.process_dir(self.train_dir) 40 | query = [] 41 | gallery = [] 42 | 43 | super(WildTrackCrop, self).__init__(train, query, gallery, **kwargs) 44 | 45 | def process_dir(self, dir_path): 46 | r""" 47 | :param dir_path: directory path saving images 48 | Returns 49 | data(list) = [img_path, pid, camid] 50 | """ 51 | data = [] 52 | for dir_name in os.listdir(dir_path): 53 | img_lists = glob.glob(os.path.join(dir_path, dir_name, "*.png")) 54 | for img_path in img_lists: 55 | pid = self.dataset_name + "_" + dir_name 56 | camid = img_path.split('/')[-1].split('_')[0] 57 | camid = self.dataset_name + "_" + camid 58 | data.append([img_path, pid, camid]) 59 | return data 60 | -------------------------------------------------------------------------------- /fastreid/data/samplers/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .triplet_sampler import BalancedIdentitySampler, NaiveIdentitySampler, SetReWeightSampler 8 | from .data_sampler import TrainingSampler, InferenceSampler 9 | from .imbalance_sampler import ImbalancedDatasetSampler 10 | 11 | __all__ = [ 12 | "BalancedIdentitySampler", 13 | "NaiveIdentitySampler", 14 | "SetReWeightSampler", 15 | "TrainingSampler", 16 | "InferenceSampler", 17 | "ImbalancedDatasetSampler", 18 | ] 19 | -------------------------------------------------------------------------------- /fastreid/data/samplers/data_sampler.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: l1aoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | import itertools 7 | from typing import Optional 8 | 9 | import numpy as np 10 | from torch.utils.data import Sampler 11 | 12 | from fastreid.utils import comm 13 | 14 | 15 | class TrainingSampler(Sampler): 16 | """ 17 | In training, we only care about the "infinite stream" of training data. 18 | So this sampler produces an infinite stream of indices and 19 | all workers cooperate to correctly shuffle the indices and sample different indices. 20 | The samplers in each worker effectively produces `indices[worker_id::num_workers]` 21 | where `indices` is an infinite stream of indices consisting of 22 | `shuffle(range(size)) + shuffle(range(size)) + ...` (if shuffle is True) 23 | or `range(size) + range(size) + ...` (if shuffle is False) 24 | """ 25 | 26 | def __init__(self, size: int, shuffle: bool = True, seed: Optional[int] = None): 27 | """ 28 | Args: 29 | size (int): the total number of data of the underlying dataset to sample from 30 | shuffle (bool): whether to shuffle the indices or not 31 | seed (int): the initial seed of the shuffle. Must be the same 32 | across all workers. If None, will use a random seed shared 33 | among workers (require synchronization among all workers). 34 | """ 35 | self._size = size 36 | assert size > 0 37 | self._shuffle = shuffle 38 | if seed is None: 39 | seed = comm.shared_random_seed() 40 | self._seed = int(seed) 41 | 42 | self._rank = comm.get_rank() 43 | self._world_size = comm.get_world_size() 44 | 45 | def __iter__(self): 46 | start = self._rank 47 | yield from itertools.islice(self._infinite_indices(), start, None, self._world_size) 48 | 49 | def _infinite_indices(self): 50 | np.random.seed(self._seed) 51 | while True: 52 | if self._shuffle: 53 | yield from np.random.permutation(self._size) 54 | else: 55 | yield from np.arange(self._size) 56 | 57 | 58 | class InferenceSampler(Sampler): 59 | """ 60 | Produce indices for inference. 61 | Inference needs to run on the __exact__ set of samples, 62 | therefore when the total number of samples is not divisible by the number of workers, 63 | this sampler produces different number of samples on different workers. 64 | """ 65 | 66 | def __init__(self, size: int): 67 | """ 68 | Args: 69 | size (int): the total number of data of the underlying dataset to sample from 70 | """ 71 | self._size = size 72 | assert size > 0 73 | self._rank = comm.get_rank() 74 | self._world_size = comm.get_world_size() 75 | 76 | shard_size = (self._size - 1) // self._world_size + 1 77 | begin = shard_size * self._rank 78 | end = min(shard_size * (self._rank + 1), self._size) 79 | self._local_indices = range(begin, end) 80 | 81 | def __iter__(self): 82 | yield from self._local_indices 83 | 84 | def __len__(self): 85 | return len(self._local_indices) 86 | -------------------------------------------------------------------------------- /fastreid/data/samplers/imbalance_sampler.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | # based on: 8 | # https://github.com/ufoym/imbalanced-dataset-sampler/blob/master/torchsampler/imbalanced.py 9 | 10 | 11 | import itertools 12 | from typing import Optional, List, Callable 13 | 14 | import numpy as np 15 | import torch 16 | from torch.utils.data.sampler import Sampler 17 | 18 | from fastreid.utils import comm 19 | 20 | 21 | class ImbalancedDatasetSampler(Sampler): 22 | """Samples elements randomly from a given list of indices for imbalanced dataset 23 | Arguments: 24 | data_source: a list of data items 25 | size: number of samples to draw 26 | """ 27 | 28 | def __init__(self, data_source: List, size: int = None, seed: Optional[int] = None, 29 | callback_get_label: Callable = None): 30 | self.data_source = data_source 31 | # consider all elements in the dataset 32 | self.indices = list(range(len(data_source))) 33 | # if num_samples is not provided, draw `len(indices)` samples in each iteration 34 | self._size = len(self.indices) if size is None else size 35 | self.callback_get_label = callback_get_label 36 | 37 | # distribution of classes in the dataset 38 | label_to_count = {} 39 | for idx in self.indices: 40 | label = self._get_label(data_source, idx) 41 | label_to_count[label] = label_to_count.get(label, 0) + 1 42 | 43 | # weight for each sample 44 | weights = [1.0 / label_to_count[self._get_label(data_source, idx)] for idx in self.indices] 45 | self.weights = torch.DoubleTensor(weights) 46 | 47 | if seed is None: 48 | seed = comm.shared_random_seed() 49 | self._seed = int(seed) 50 | self._rank = comm.get_rank() 51 | self._world_size = comm.get_world_size() 52 | 53 | def _get_label(self, dataset, idx): 54 | if self.callback_get_label: 55 | return self.callback_get_label(dataset, idx) 56 | else: 57 | return dataset[idx][1] 58 | 59 | def __iter__(self): 60 | start = self._rank 61 | yield from itertools.islice(self._infinite_indices(), start, None, self._world_size) 62 | 63 | def _infinite_indices(self): 64 | np.random.seed(self._seed) 65 | while True: 66 | for i in torch.multinomial(self.weights, self._size, replacement=True): 67 | yield self.indices[i] 68 | -------------------------------------------------------------------------------- /fastreid/data/transforms/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: sherlock 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .autoaugment import AutoAugment 8 | from .build import build_transforms 9 | from .transforms import * 10 | 11 | __all__ = [k for k in globals().keys() if not k.startswith("_")] 12 | -------------------------------------------------------------------------------- /fastreid/engine/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | from .train_loop import * 7 | 8 | __all__ = [k for k in globals().keys() if not k.startswith("_")] 9 | 10 | 11 | # prefer to let hooks and defaults live in separate namespaces (therefore not in __all__) 12 | # but still make them available here 13 | from .hooks import * 14 | from .defaults import * 15 | from .launch import * 16 | -------------------------------------------------------------------------------- /fastreid/evaluation/__init__.py: -------------------------------------------------------------------------------- 1 | from .evaluator import DatasetEvaluator, inference_context, inference_on_dataset 2 | from .rank import evaluate_rank 3 | from .reid_evaluation import ReidEvaluator 4 | from .clas_evaluator import ClasEvaluator 5 | from .roc import evaluate_roc 6 | from .testing import print_csv_format, verify_results 7 | 8 | __all__ = [k for k in globals().keys() if not k.startswith("_")] 9 | -------------------------------------------------------------------------------- /fastreid/evaluation/clas_evaluator.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import copy 8 | import itertools 9 | import logging 10 | from collections import OrderedDict 11 | 12 | import torch 13 | 14 | from fastreid.utils import comm 15 | from .evaluator import DatasetEvaluator 16 | 17 | logger = logging.getLogger(__name__) 18 | 19 | 20 | def accuracy(output, target, topk=(1,)): 21 | """Computes the accuracy over the k top predictions for the specified values of k""" 22 | with torch.no_grad(): 23 | maxk = max(topk) 24 | batch_size = target.size(0) 25 | 26 | _, pred = output.topk(maxk, 1, True, True) 27 | pred = pred.t() 28 | correct = pred.eq(target.view(1, -1).expand_as(pred)) 29 | 30 | res = [] 31 | for k in topk: 32 | correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True) 33 | res.append(correct_k.mul_(100.0 / batch_size)) 34 | return res 35 | 36 | 37 | class ClasEvaluator(DatasetEvaluator): 38 | def __init__(self, cfg, output_dir=None): 39 | self.cfg = cfg 40 | self._output_dir = output_dir 41 | self._cpu_device = torch.device('cpu') 42 | 43 | self._predictions = [] 44 | 45 | def reset(self): 46 | self._predictions = [] 47 | 48 | def process(self, inputs, outputs): 49 | pred_logits = outputs.to(self._cpu_device, torch.float32) 50 | labels = inputs["targets"].to(self._cpu_device) 51 | 52 | # measure accuracy 53 | acc1, = accuracy(pred_logits, labels, topk=(1,)) 54 | num_correct_acc1 = acc1 * labels.size(0) / 100 55 | 56 | self._predictions.append({"num_correct": num_correct_acc1, "num_samples": labels.size(0)}) 57 | 58 | def evaluate(self): 59 | if comm.get_world_size() > 1: 60 | comm.synchronize() 61 | predictions = comm.gather(self._predictions, dst=0) 62 | predictions = list(itertools.chain(*predictions)) 63 | 64 | if not comm.is_main_process(): return {} 65 | 66 | else: 67 | predictions = self._predictions 68 | 69 | total_correct_num = 0 70 | total_samples = 0 71 | for prediction in predictions: 72 | total_correct_num += prediction["num_correct"] 73 | total_samples += prediction["num_samples"] 74 | 75 | acc1 = total_correct_num / total_samples * 100 76 | 77 | self._results = OrderedDict() 78 | self._results["Acc@1"] = acc1 79 | self._results["metric"] = acc1 80 | 81 | return copy.deepcopy(self._results) 82 | -------------------------------------------------------------------------------- /fastreid/evaluation/query_expansion.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | # based on 8 | # https://github.com/PyRetri/PyRetri/blob/master/pyretri/index/re_ranker/re_ranker_impl/query_expansion.py 9 | 10 | import numpy as np 11 | import torch 12 | import torch.nn.functional as F 13 | 14 | 15 | def aqe(query_feat: torch.tensor, gallery_feat: torch.tensor, 16 | qe_times: int = 1, qe_k: int = 10, alpha: float = 3.0): 17 | """ 18 | Combining the retrieved topk nearest neighbors with the original query and doing another retrieval. 19 | c.f. https://www.robots.ox.ac.uk/~vgg/publications/papers/chum07b.pdf 20 | Args : 21 | query_feat (torch.tensor): 22 | gallery_feat (torch.tensor): 23 | qe_times (int): number of query expansion times. 24 | qe_k (int): number of the neighbors to be combined. 25 | alpha (float): 26 | """ 27 | num_query = query_feat.shape[0] 28 | all_feat = torch.cat((query_feat, gallery_feat), dim=0) 29 | norm_feat = F.normalize(all_feat, p=2, dim=1) 30 | 31 | all_feat = all_feat.numpy() 32 | for i in range(qe_times): 33 | all_feat_list = [] 34 | sims = torch.mm(norm_feat, norm_feat.t()) 35 | sims = sims.data.cpu().numpy() 36 | for sim in sims: 37 | init_rank = np.argpartition(-sim, range(1, qe_k + 1)) 38 | weights = sim[init_rank[:qe_k]].reshape((-1, 1)) 39 | weights = np.power(weights, alpha) 40 | all_feat_list.append(np.mean(all_feat[init_rank[:qe_k], :] * weights, axis=0)) 41 | all_feat = np.stack(all_feat_list, axis=0) 42 | norm_feat = F.normalize(torch.from_numpy(all_feat), p=2, dim=1) 43 | 44 | query_feat = torch.from_numpy(all_feat[:num_query]) 45 | gallery_feat = torch.from_numpy(all_feat[num_query:]) 46 | return query_feat, gallery_feat 47 | -------------------------------------------------------------------------------- /fastreid/evaluation/rank_cylib/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | python3 setup.py build_ext --inplace 3 | rm -rf build 4 | python3 test_cython.py 5 | clean: 6 | rm -rf build 7 | rm -f rank_cy.c *.so 8 | -------------------------------------------------------------------------------- /fastreid/evaluation/rank_cylib/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ -------------------------------------------------------------------------------- /fastreid/evaluation/rank_cylib/roc_cy.pyx: -------------------------------------------------------------------------------- 1 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True 2 | # credits: https://github.com/KaiyangZhou/deep-person-reid/blob/master/torchreid/metrics/rank_cylib/rank_cy.pyx 3 | 4 | import cython 5 | import faiss 6 | import numpy as np 7 | cimport numpy as np 8 | 9 | 10 | """ 11 | Compiler directives: 12 | https://github.com/cython/cython/wiki/enhancements-compilerdirectives 13 | Cython tutorial: 14 | https://cython.readthedocs.io/en/latest/src/userguide/numpy_tutorial.html 15 | Credit to https://github.com/luzai 16 | """ 17 | 18 | 19 | # Main interface 20 | cpdef evaluate_roc_cy(float[:,:] distmat, long[:] q_pids, long[:]g_pids, 21 | long[:]q_camids, long[:]g_camids): 22 | 23 | distmat = np.asarray(distmat, dtype=np.float32) 24 | q_pids = np.asarray(q_pids, dtype=np.int64) 25 | g_pids = np.asarray(g_pids, dtype=np.int64) 26 | q_camids = np.asarray(q_camids, dtype=np.int64) 27 | g_camids = np.asarray(g_camids, dtype=np.int64) 28 | 29 | cdef long num_q = distmat.shape[0] 30 | cdef long num_g = distmat.shape[1] 31 | 32 | cdef: 33 | long[:,:] indices = np.argsort(distmat, axis=1) 34 | long[:,:] matches = (np.asarray(g_pids)[np.asarray(indices)] == np.asarray(q_pids)[:, np.newaxis]).astype(np.int64) 35 | 36 | float[:] pos = np.zeros(num_q*num_g, dtype=np.float32) 37 | float[:] neg = np.zeros(num_q*num_g, dtype=np.float32) 38 | 39 | long valid_pos = 0 40 | long valid_neg = 0 41 | long ind 42 | 43 | long q_idx, q_pid, q_camid, g_idx 44 | long[:] order = np.zeros(num_g, dtype=np.int64) 45 | 46 | float[:] raw_cmc = np.zeros(num_g, dtype=np.float32) # binary vector, positions with value 1 are correct matches 47 | long[:] sort_idx = np.zeros(num_g, dtype=np.int64) 48 | 49 | long idx 50 | 51 | for q_idx in range(num_q): 52 | # get query pid and camid 53 | q_pid = q_pids[q_idx] 54 | q_camid = q_camids[q_idx] 55 | 56 | for g_idx in range(num_g): 57 | order[g_idx] = indices[q_idx, g_idx] 58 | num_g_real = 0 59 | 60 | # remove gallery samples that have the same pid and camid with query 61 | for g_idx in range(num_g): 62 | if (g_pids[order[g_idx]] != q_pid) or (g_camids[order[g_idx]] != q_camid): 63 | raw_cmc[num_g_real] = matches[q_idx][g_idx] 64 | sort_idx[num_g_real] = order[g_idx] 65 | num_g_real += 1 66 | 67 | q_dist = distmat[q_idx] 68 | 69 | for valid_idx in range(num_g_real): 70 | if raw_cmc[valid_idx] == 1: 71 | pos[valid_pos] = q_dist[sort_idx[valid_idx]] 72 | valid_pos += 1 73 | elif raw_cmc[valid_idx] == 0: 74 | neg[valid_neg] = q_dist[sort_idx[valid_idx]] 75 | valid_neg += 1 76 | 77 | cdef float[:] scores = np.hstack((pos[:valid_pos], neg[:valid_neg])) 78 | cdef float[:] labels = np.hstack((np.zeros(valid_pos, dtype=np.float32), 79 | np.ones(valid_neg, dtype=np.float32))) 80 | return np.asarray(scores), np.asarray(labels) 81 | 82 | 83 | # Compute the cumulative sum 84 | cdef void function_cumsum(cython.numeric[:] src, cython.numeric[:] dst, long n): 85 | cdef long i 86 | dst[0] = src[0] 87 | for i in range(1, n): 88 | dst[i] = src[i] + dst[i - 1] -------------------------------------------------------------------------------- /fastreid/evaluation/rank_cylib/setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | from distutils.extension import Extension 3 | 4 | import numpy as np 5 | from Cython.Build import cythonize 6 | 7 | 8 | def numpy_include(): 9 | try: 10 | numpy_include = np.get_include() 11 | except AttributeError: 12 | numpy_include = np.get_numpy_include() 13 | return numpy_include 14 | 15 | 16 | ext_modules = [ 17 | Extension( 18 | 'rank_cy', 19 | ['rank_cy.pyx'], 20 | include_dirs=[numpy_include()], 21 | ), 22 | Extension( 23 | 'roc_cy', 24 | ['roc_cy.pyx'], 25 | include_dirs=[numpy_include()], 26 | ) 27 | ] 28 | 29 | setup( 30 | name='Cython-based reid evaluation code', 31 | ext_modules=cythonize(ext_modules) 32 | ) 33 | -------------------------------------------------------------------------------- /fastreid/evaluation/roc.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: l1aoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import warnings 8 | 9 | import faiss 10 | import numpy as np 11 | 12 | try: 13 | from .rank_cylib.roc_cy import evaluate_roc_cy 14 | 15 | IS_CYTHON_AVAI = True 16 | except ImportError: 17 | IS_CYTHON_AVAI = False 18 | warnings.warn( 19 | 'Cython roc evaluation (very fast so highly recommended) is ' 20 | 'unavailable, now use python evaluation.' 21 | ) 22 | 23 | 24 | def evaluate_roc_py(distmat, q_pids, g_pids, q_camids, g_camids): 25 | r"""Evaluation with ROC curve. 26 | Key: for each query identity, its gallery images from the same camera view are discarded. 27 | 28 | Args: 29 | distmat (np.ndarray): cosine distance matrix 30 | """ 31 | num_q, num_g = distmat.shape 32 | 33 | indices = np.argsort(distmat, axis=1) 34 | matches = (g_pids[indices] == q_pids[:, np.newaxis]).astype(np.int32) 35 | 36 | pos = [] 37 | neg = [] 38 | for q_idx in range(num_q): 39 | # get query pid and camid 40 | q_pid = q_pids[q_idx] 41 | q_camid = q_camids[q_idx] 42 | 43 | # Remove gallery samples that have the same pid and camid with query 44 | order = indices[q_idx] 45 | remove = (g_pids[order] == q_pid) & (g_camids[order] == q_camid) 46 | keep = np.invert(remove) 47 | raw_cmc = matches[q_idx][keep] 48 | 49 | sort_idx = order[keep] 50 | 51 | q_dist = distmat[q_idx] 52 | ind_pos = np.where(raw_cmc == 1)[0] 53 | pos.extend(q_dist[sort_idx[ind_pos]]) 54 | 55 | ind_neg = np.where(raw_cmc == 0)[0] 56 | neg.extend(q_dist[sort_idx[ind_neg]]) 57 | 58 | scores = np.hstack((pos, neg)) 59 | 60 | labels = np.hstack((np.zeros(len(pos)), np.ones(len(neg)))) 61 | return scores, labels 62 | 63 | 64 | def evaluate_roc( 65 | distmat, 66 | q_pids, 67 | g_pids, 68 | q_camids, 69 | g_camids, 70 | use_cython=True 71 | ): 72 | """Evaluates CMC rank. 73 | Args: 74 | distmat (numpy.ndarray): distance matrix of shape (num_query, num_gallery). 75 | q_pids (numpy.ndarray): 1-D array containing person identities 76 | of each query instance. 77 | g_pids (numpy.ndarray): 1-D array containing person identities 78 | of each gallery instance. 79 | q_camids (numpy.ndarray): 1-D array containing camera views under 80 | which each query instance is captured. 81 | g_camids (numpy.ndarray): 1-D array containing camera views under 82 | which each gallery instance is captured. 83 | use_cython (bool, optional): use cython code for evaluation. Default is True. 84 | This is highly recommended as the cython code can speed up the cmc computation 85 | by more than 10x. This requires Cython to be installed. 86 | """ 87 | if use_cython and IS_CYTHON_AVAI: 88 | return evaluate_roc_cy(distmat, q_pids, g_pids, q_camids, g_camids) 89 | else: 90 | return evaluate_roc_py(distmat, q_pids, g_pids, q_camids, g_camids) 91 | -------------------------------------------------------------------------------- /fastreid/evaluation/testing.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved 2 | import logging 3 | import pprint 4 | import sys 5 | from collections import Mapping, OrderedDict 6 | 7 | import numpy as np 8 | from tabulate import tabulate 9 | from termcolor import colored 10 | 11 | 12 | def print_csv_format(results): 13 | """ 14 | Print main metrics in a format similar to Detectron2, 15 | so that they are easy to copypaste into a spreadsheet. 16 | Args: 17 | results (OrderedDict): {metric -> score} 18 | """ 19 | # unordered results cannot be properly printed 20 | assert isinstance(results, OrderedDict) or not len(results), results 21 | logger = logging.getLogger(__name__) 22 | 23 | dataset_name = results.pop('dataset') 24 | metrics = ["Dataset"] + [k for k in results] 25 | csv_results = [(dataset_name, *list(results.values()))] 26 | 27 | # tabulate it 28 | table = tabulate( 29 | csv_results, 30 | tablefmt="pipe", 31 | floatfmt=".2f", 32 | headers=metrics, 33 | numalign="left", 34 | ) 35 | 36 | logger.info("Evaluation results in csv format: \n" + colored(table, "cyan")) 37 | 38 | 39 | def verify_results(cfg, results): 40 | """ 41 | Args: 42 | results (OrderedDict[dict]): task_name -> {metric -> score} 43 | Returns: 44 | bool: whether the verification succeeds or not 45 | """ 46 | expected_results = cfg.TEST.EXPECTED_RESULTS 47 | if not len(expected_results): 48 | return True 49 | 50 | ok = True 51 | for task, metric, expected, tolerance in expected_results: 52 | actual = results[task][metric] 53 | if not np.isfinite(actual): 54 | ok = False 55 | diff = abs(actual - expected) 56 | if diff > tolerance: 57 | ok = False 58 | 59 | logger = logging.getLogger(__name__) 60 | if not ok: 61 | logger.error("Result verification failed!") 62 | logger.error("Expected Results: " + str(expected_results)) 63 | logger.error("Actual Results: " + pprint.pformat(results)) 64 | 65 | sys.exit(1) 66 | else: 67 | logger.info("Results verification passed.") 68 | return ok 69 | 70 | 71 | def flatten_results_dict(results): 72 | """ 73 | Expand a hierarchical dict of scalars into a flat dict of scalars. 74 | If results[k1][k2][k3] = v, the returned dict will have the entry 75 | {"k1/k2/k3": v}. 76 | Args: 77 | results (dict): 78 | """ 79 | r = {} 80 | for k, v in results.items(): 81 | if isinstance(v, Mapping): 82 | v = flatten_results_dict(v) 83 | for kk, vv in v.items(): 84 | r[k + "/" + kk] = vv 85 | else: 86 | r[k] = v 87 | return r 88 | -------------------------------------------------------------------------------- /fastreid/layers/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .activation import * 8 | from .batch_norm import * 9 | from .context_block import ContextBlock 10 | from .drop import DropPath, DropBlock2d, drop_block_2d, drop_path 11 | from .frn import FRN, TLU 12 | from .gather_layer import GatherLayer 13 | from .helpers import to_ntuple, to_2tuple, to_3tuple, to_4tuple, make_divisible 14 | from .non_local import Non_local 15 | from .se_layer import SELayer 16 | from .splat import SplAtConv2d, DropBlock2D 17 | from .weight_init import ( 18 | trunc_normal_, variance_scaling_, lecun_normal_, weights_init_kaiming, weights_init_classifier 19 | ) 20 | -------------------------------------------------------------------------------- /fastreid/layers/activation.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import math 8 | 9 | import torch 10 | import torch.nn as nn 11 | import torch.nn.functional as F 12 | 13 | __all__ = [ 14 | 'Mish', 15 | 'Swish', 16 | 'MemoryEfficientSwish', 17 | 'GELU'] 18 | 19 | 20 | class Mish(nn.Module): 21 | def __init__(self): 22 | super().__init__() 23 | 24 | def forward(self, x): 25 | # inlining this saves 1 second per epoch (V100 GPU) vs having a temp x and then returning x(!) 26 | return x * (torch.tanh(F.softplus(x))) 27 | 28 | 29 | class Swish(nn.Module): 30 | def forward(self, x): 31 | return x * torch.sigmoid(x) 32 | 33 | 34 | class SwishImplementation(torch.autograd.Function): 35 | @staticmethod 36 | def forward(ctx, i): 37 | result = i * torch.sigmoid(i) 38 | ctx.save_for_backward(i) 39 | return result 40 | 41 | @staticmethod 42 | def backward(ctx, grad_output): 43 | i = ctx.saved_variables[0] 44 | sigmoid_i = torch.sigmoid(i) 45 | return grad_output * (sigmoid_i * (1 + i * (1 - sigmoid_i))) 46 | 47 | 48 | class MemoryEfficientSwish(nn.Module): 49 | def forward(self, x): 50 | return SwishImplementation.apply(x) 51 | 52 | 53 | class GELU(nn.Module): 54 | """ 55 | Paper Section 3.4, last paragraph notice that BERT used the GELU instead of RELU 56 | """ 57 | 58 | def forward(self, x): 59 | return 0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3)))) 60 | -------------------------------------------------------------------------------- /fastreid/layers/any_softmax.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import torch 8 | import torch.nn as nn 9 | 10 | __all__ = [ 11 | "Linear", 12 | "ArcSoftmax", 13 | "CosSoftmax", 14 | "CircleSoftmax" 15 | ] 16 | 17 | 18 | class Linear(nn.Module): 19 | def __init__(self, num_classes, scale, margin): 20 | super().__init__() 21 | self.num_classes = num_classes 22 | self.s = scale 23 | self.m = margin 24 | 25 | def forward(self, logits, targets): 26 | return logits.mul_(self.s) 27 | 28 | def extra_repr(self): 29 | return f"num_classes={self.num_classes}, scale={self.s}, margin={self.m}" 30 | 31 | 32 | class CosSoftmax(Linear): 33 | r"""Implement of large margin cosine distance: 34 | """ 35 | 36 | def forward(self, logits, targets): 37 | index = torch.where(targets != -1)[0] 38 | m_hot = torch.zeros(index.size()[0], logits.size()[1], device=logits.device, dtype=logits.dtype) 39 | m_hot.scatter_(1, targets[index, None], self.m) 40 | logits[index] -= m_hot 41 | logits.mul_(self.s) 42 | return logits 43 | 44 | 45 | class ArcSoftmax(Linear): 46 | 47 | def forward(self, logits, targets): 48 | index = torch.where(targets != -1)[0] 49 | m_hot = torch.zeros(index.size()[0], logits.size()[1], device=logits.device, dtype=logits.dtype) 50 | m_hot.scatter_(1, targets[index, None], self.m) 51 | logits.acos_() 52 | logits[index] += m_hot 53 | logits.cos_().mul_(self.s) 54 | return logits 55 | 56 | 57 | class CircleSoftmax(Linear): 58 | 59 | def forward(self, logits, targets): 60 | alpha_p = torch.clamp_min(-logits.detach() + 1 + self.m, min=0.) 61 | alpha_n = torch.clamp_min(logits.detach() + self.m, min=0.) 62 | delta_p = 1 - self.m 63 | delta_n = self.m 64 | 65 | # When use model parallel, there are some targets not in class centers of local rank 66 | index = torch.where(targets != -1)[0] 67 | m_hot = torch.zeros(index.size()[0], logits.size()[1], device=logits.device, dtype=logits.dtype) 68 | m_hot.scatter_(1, targets[index, None], 1) 69 | 70 | logits_p = alpha_p * (logits - delta_p) 71 | logits_n = alpha_n * (logits - delta_n) 72 | 73 | logits[index] = logits_p[index] * m_hot + logits_n[index] * (1 - m_hot) 74 | 75 | neg_index = torch.where(targets == -1)[0] 76 | logits[neg_index] = logits_n[neg_index] 77 | 78 | logits.mul_(self.s) 79 | 80 | return logits 81 | -------------------------------------------------------------------------------- /fastreid/layers/gather_layer.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | # based on: https://github.com/open-mmlab/OpenSelfSup/blob/master/openselfsup/models/utils/gather_layer.py 8 | 9 | import torch 10 | import torch.distributed as dist 11 | 12 | 13 | class GatherLayer(torch.autograd.Function): 14 | """Gather tensors from all process, supporting backward propagation. 15 | """ 16 | 17 | @staticmethod 18 | def forward(ctx, input): 19 | ctx.save_for_backward(input) 20 | output = [torch.zeros_like(input) \ 21 | for _ in range(dist.get_world_size())] 22 | dist.all_gather(output, input) 23 | return tuple(output) 24 | 25 | @staticmethod 26 | def backward(ctx, *grads): 27 | input, = ctx.saved_tensors 28 | grad_out = torch.zeros_like(input) 29 | grad_out[:] = grads[dist.get_rank()] 30 | return grad_out 31 | -------------------------------------------------------------------------------- /fastreid/layers/helpers.py: -------------------------------------------------------------------------------- 1 | """ Layer/Module Helpers 2 | Hacked together by / Copyright 2020 Ross Wightman 3 | """ 4 | import collections.abc 5 | from itertools import repeat 6 | 7 | 8 | # From PyTorch internals 9 | def _ntuple(n): 10 | def parse(x): 11 | if isinstance(x, collections.abc.Iterable): 12 | return x 13 | return tuple(repeat(x, n)) 14 | 15 | return parse 16 | 17 | 18 | to_1tuple = _ntuple(1) 19 | to_2tuple = _ntuple(2) 20 | to_3tuple = _ntuple(3) 21 | to_4tuple = _ntuple(4) 22 | to_ntuple = _ntuple 23 | 24 | 25 | def make_divisible(v, divisor=8, min_value=None): 26 | min_value = min_value or divisor 27 | new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) 28 | # Make sure that round down does not go down by more than 10%. 29 | if new_v < 0.9 * v: 30 | new_v += divisor 31 | return new_v 32 | -------------------------------------------------------------------------------- /fastreid/layers/non_local.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | 4 | import torch 5 | from torch import nn 6 | from .batch_norm import get_norm 7 | 8 | 9 | class Non_local(nn.Module): 10 | def __init__(self, in_channels, bn_norm, reduc_ratio=2): 11 | super(Non_local, self).__init__() 12 | 13 | self.in_channels = in_channels 14 | self.inter_channels = reduc_ratio // reduc_ratio 15 | 16 | self.g = nn.Conv2d(in_channels=self.in_channels, out_channels=self.inter_channels, 17 | kernel_size=1, stride=1, padding=0) 18 | 19 | self.W = nn.Sequential( 20 | nn.Conv2d(in_channels=self.inter_channels, out_channels=self.in_channels, 21 | kernel_size=1, stride=1, padding=0), 22 | get_norm(bn_norm, self.in_channels), 23 | ) 24 | nn.init.constant_(self.W[1].weight, 0.0) 25 | nn.init.constant_(self.W[1].bias, 0.0) 26 | 27 | self.theta = nn.Conv2d(in_channels=self.in_channels, out_channels=self.inter_channels, 28 | kernel_size=1, stride=1, padding=0) 29 | 30 | self.phi = nn.Conv2d(in_channels=self.in_channels, out_channels=self.inter_channels, 31 | kernel_size=1, stride=1, padding=0) 32 | 33 | def forward(self, x): 34 | """ 35 | :param x: (b, t, h, w) 36 | :return x: (b, t, h, w) 37 | """ 38 | batch_size = x.size(0) 39 | g_x = self.g(x).view(batch_size, self.inter_channels, -1) 40 | g_x = g_x.permute(0, 2, 1) 41 | 42 | theta_x = self.theta(x).view(batch_size, self.inter_channels, -1) 43 | theta_x = theta_x.permute(0, 2, 1) 44 | phi_x = self.phi(x).view(batch_size, self.inter_channels, -1) 45 | f = torch.matmul(theta_x, phi_x) 46 | N = f.size(-1) 47 | f_div_C = f / N 48 | 49 | y = torch.matmul(f_div_C, g_x) 50 | y = y.permute(0, 2, 1).contiguous() 51 | y = y.view(batch_size, self.inter_channels, *x.size()[2:]) 52 | W_y = self.W(y) 53 | z = W_y + x 54 | return z 55 | -------------------------------------------------------------------------------- /fastreid/layers/se_layer.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from torch import nn 8 | 9 | 10 | class SELayer(nn.Module): 11 | def __init__(self, channel, reduction=16): 12 | super(SELayer, self).__init__() 13 | self.avg_pool = nn.AdaptiveAvgPool2d(1) 14 | self.fc = nn.Sequential( 15 | nn.Linear(channel, int(channel / reduction), bias=False), 16 | nn.ReLU(inplace=True), 17 | nn.Linear(int(channel / reduction), channel, bias=False), 18 | nn.Sigmoid() 19 | ) 20 | 21 | def forward(self, x): 22 | b, c, _, _ = x.size() 23 | y = self.avg_pool(x).view(b, c) 24 | y = self.fc(y).view(b, c, 1, 1) 25 | return x * y.expand_as(x) 26 | -------------------------------------------------------------------------------- /fastreid/modeling/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: sherlock 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from . import losses 8 | from .backbones import ( 9 | BACKBONE_REGISTRY, 10 | build_resnet_backbone, 11 | build_backbone, 12 | ) 13 | from .heads import ( 14 | REID_HEADS_REGISTRY, 15 | build_heads, 16 | EmbeddingHead, 17 | ) 18 | from .meta_arch import ( 19 | build_model, 20 | META_ARCH_REGISTRY, 21 | ) 22 | 23 | __all__ = [k for k in globals().keys() if not k.startswith("_")] -------------------------------------------------------------------------------- /fastreid/modeling/backbones/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .build import build_backbone, BACKBONE_REGISTRY 8 | 9 | from .resnet import build_resnet_backbone 10 | from .osnet import build_osnet_backbone 11 | from .resnest import build_resnest_backbone 12 | from .resnext import build_resnext_backbone 13 | from .regnet import build_regnet_backbone, build_effnet_backbone 14 | from .shufflenet import build_shufflenetv2_backbone 15 | from .mobilenet import build_mobilenetv2_backbone 16 | from .repvgg import build_repvgg_backbone 17 | from .vision_transformer import build_vit_backbone 18 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/build.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from ...utils.registry import Registry 8 | 9 | BACKBONE_REGISTRY = Registry("BACKBONE") 10 | BACKBONE_REGISTRY.__doc__ = """ 11 | Registry for backbones, which extract feature maps from images 12 | The registered object must be a callable that accepts two arguments: 13 | 1. A :class:`fastreid.config.CfgNode` 14 | It must returns an instance of :class:`Backbone`. 15 | """ 16 | 17 | 18 | def build_backbone(cfg): 19 | """ 20 | Build a backbone from `cfg.MODEL.BACKBONE.NAME`. 21 | Returns: 22 | an instance of :class:`Backbone` 23 | """ 24 | 25 | backbone_name = cfg.MODEL.BACKBONE.NAME 26 | backbone = BACKBONE_REGISTRY.get(backbone_name)(cfg) 27 | return backbone 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | from .regnet import build_regnet_backbone 4 | from .effnet import build_effnet_backbone 5 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/effnet/EN-B0_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: effnet 3 | NUM_CLASSES: 1000 4 | EN: 5 | STEM_W: 32 6 | STRIDES: [1, 2, 2, 2, 1, 2, 1] 7 | DEPTHS: [1, 2, 2, 3, 3, 4, 1] 8 | WIDTHS: [16, 24, 40, 80, 112, 192, 320] 9 | EXP_RATIOS: [1, 6, 6, 6, 6, 6, 6] 10 | KERNELS: [3, 3, 5, 3, 5, 5, 3] 11 | HEAD_W: 1280 12 | OPTIM: 13 | LR_POLICY: cos 14 | BASE_LR: 0.4 15 | MAX_EPOCH: 100 16 | MOMENTUM: 0.9 17 | WEIGHT_DECAY: 1e-5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 256 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 200 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/effnet/EN-B1_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: effnet 3 | NUM_CLASSES: 1000 4 | EN: 5 | STEM_W: 32 6 | STRIDES: [1, 2, 2, 2, 1, 2, 1] 7 | DEPTHS: [2, 3, 3, 4, 4, 5, 2] 8 | WIDTHS: [16, 24, 40, 80, 112, 192, 320] 9 | EXP_RATIOS: [1, 6, 6, 6, 6, 6, 6] 10 | KERNELS: [3, 3, 5, 3, 5, 5, 3] 11 | HEAD_W: 1280 12 | OPTIM: 13 | LR_POLICY: cos 14 | BASE_LR: 0.4 15 | MAX_EPOCH: 100 16 | MOMENTUM: 0.9 17 | WEIGHT_DECAY: 1e-5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 240 21 | BATCH_SIZE: 256 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 274 25 | BATCH_SIZE: 200 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/effnet/EN-B2_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: effnet 3 | NUM_CLASSES: 1000 4 | EN: 5 | STEM_W: 32 6 | STRIDES: [1, 2, 2, 2, 1, 2, 1] 7 | DEPTHS: [2, 3, 3, 4, 4, 5, 2] 8 | WIDTHS: [16, 24, 48, 88, 120, 208, 352] 9 | EXP_RATIOS: [1, 6, 6, 6, 6, 6, 6] 10 | KERNELS: [3, 3, 5, 3, 5, 5, 3] 11 | HEAD_W: 1408 12 | OPTIM: 13 | LR_POLICY: cos 14 | BASE_LR: 0.4 15 | MAX_EPOCH: 100 16 | MOMENTUM: 0.9 17 | WEIGHT_DECAY: 1e-5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 260 21 | BATCH_SIZE: 256 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 298 25 | BATCH_SIZE: 200 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/effnet/EN-B3_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: effnet 3 | NUM_CLASSES: 1000 4 | EN: 5 | STEM_W: 40 6 | STRIDES: [1, 2, 2, 2, 1, 2, 1] 7 | DEPTHS: [2, 3, 3, 5, 5, 6, 2] 8 | WIDTHS: [24, 32, 48, 96, 136, 232, 384] 9 | EXP_RATIOS: [1, 6, 6, 6, 6, 6, 6] 10 | KERNELS: [3, 3, 5, 3, 5, 5, 3] 11 | HEAD_W: 1536 12 | OPTIM: 13 | LR_POLICY: cos 14 | BASE_LR: 0.4 15 | MAX_EPOCH: 100 16 | MOMENTUM: 0.9 17 | WEIGHT_DECAY: 1e-5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 300 21 | BATCH_SIZE: 256 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 342 25 | BATCH_SIZE: 200 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/effnet/EN-B4_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: effnet 3 | NUM_CLASSES: 1000 4 | EN: 5 | STEM_W: 48 6 | STRIDES: [1, 2, 2, 2, 1, 2, 1] 7 | DEPTHS: [2, 4, 4, 6, 6, 8, 2] 8 | WIDTHS: [24, 32, 56, 112, 160, 272, 448] 9 | EXP_RATIOS: [1, 6, 6, 6, 6, 6, 6] 10 | KERNELS: [3, 3, 5, 3, 5, 5, 3] 11 | HEAD_W: 1792 12 | OPTIM: 13 | LR_POLICY: cos 14 | BASE_LR: 0.2 15 | MAX_EPOCH: 100 16 | MOMENTUM: 0.9 17 | WEIGHT_DECAY: 1e-5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 380 21 | BATCH_SIZE: 128 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 434 25 | BATCH_SIZE: 104 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/effnet/EN-B5_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: effnet 3 | NUM_CLASSES: 1000 4 | EN: 5 | STEM_W: 48 6 | STRIDES: [1, 2, 2, 2, 1, 2, 1] 7 | DEPTHS: [3, 5, 5, 7, 7, 9, 3] 8 | WIDTHS: [24, 40, 64, 128, 176, 304, 512] 9 | EXP_RATIOS: [1, 6, 6, 6, 6, 6, 6] 10 | KERNELS: [3, 3, 5, 3, 5, 5, 3] 11 | HEAD_W: 2048 12 | OPTIM: 13 | LR_POLICY: cos 14 | BASE_LR: 0.1 15 | MAX_EPOCH: 100 16 | MOMENTUM: 0.9 17 | WEIGHT_DECAY: 1e-5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 456 21 | BATCH_SIZE: 64 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 522 25 | BATCH_SIZE: 48 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-1.6GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 18 6 | W0: 80 7 | WA: 34.01 8 | WM: 2.25 9 | GROUP_W: 24 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.8 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 1024 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 800 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-12GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 19 6 | W0: 168 7 | WA: 73.36 8 | WM: 2.37 9 | GROUP_W: 112 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.4 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 512 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 400 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-16GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 22 6 | W0: 216 7 | WA: 55.59 8 | WM: 2.1 9 | GROUP_W: 128 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.4 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 512 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 400 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-200MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 13 6 | W0: 24 7 | WA: 36.44 8 | WM: 2.49 9 | GROUP_W: 8 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.8 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 1024 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 800 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-3.2GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 25 6 | W0: 88 7 | WA: 26.31 8 | WM: 2.25 9 | GROUP_W: 48 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.4 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 512 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 400 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-32GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 23 6 | W0: 320 7 | WA: 69.86 8 | WM: 2.0 9 | GROUP_W: 168 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.2 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 256 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 200 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-4.0GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 23 6 | W0: 96 7 | WA: 38.65 8 | WM: 2.43 9 | GROUP_W: 40 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.4 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 512 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 400 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-400MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 22 6 | W0: 24 7 | WA: 24.48 8 | WM: 2.54 9 | GROUP_W: 16 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.8 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 1024 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 800 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-6.4GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 17 6 | W0: 184 7 | WA: 60.83 8 | WM: 2.07 9 | GROUP_W: 56 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.4 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 512 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 400 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-600MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 16 6 | W0: 48 7 | WA: 36.97 8 | WM: 2.24 9 | GROUP_W: 24 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.8 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 1024 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 800 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-8.0GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 23 6 | W0: 80 7 | WA: 49.56 8 | WM: 2.88 9 | GROUP_W: 120 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.4 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 512 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 400 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnetx/RegNetX-800MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | DEPTH: 16 6 | W0: 56 7 | WA: 35.73 8 | WM: 2.28 9 | GROUP_W: 16 10 | OPTIM: 11 | LR_POLICY: cos 12 | BASE_LR: 0.8 13 | MAX_EPOCH: 100 14 | MOMENTUM: 0.9 15 | WEIGHT_DECAY: 5e-5 16 | WARMUP_ITERS: 5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 1024 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 800 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-1.6GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 27 7 | W0: 48 8 | WA: 20.71 9 | WM: 2.65 10 | GROUP_W: 24 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.8 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 1024 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 800 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-12GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 19 7 | W0: 168 8 | WA: 73.36 9 | WM: 2.37 10 | GROUP_W: 112 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.4 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 512 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 400 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-16GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 18 7 | W0: 200 8 | WA: 106.23 9 | WM: 2.48 10 | GROUP_W: 112 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.2 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 256 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 200 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-200MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 13 7 | W0: 24 8 | WA: 36.44 9 | WM: 2.49 10 | GROUP_W: 8 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.8 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | TRAIN: 18 | DATASET: imagenet 19 | IM_SIZE: 224 20 | BATCH_SIZE: 1024 21 | TEST: 22 | DATASET: imagenet 23 | IM_SIZE: 256 24 | BATCH_SIZE: 800 25 | NUM_GPUS: 8 26 | OUT_DIR: . 27 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-3.2GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 21 7 | W0: 80 8 | WA: 42.63 9 | WM: 2.66 10 | GROUP_W: 24 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.4 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 512 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 400 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-32GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 20 7 | W0: 232 8 | WA: 115.89 9 | WM: 2.53 10 | GROUP_W: 232 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.2 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 256 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 200 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-4.0GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 22 7 | W0: 96 8 | WA: 31.41 9 | WM: 2.24 10 | GROUP_W: 64 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.4 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 512 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 400 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-400MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 16 7 | W0: 48 8 | WA: 27.89 9 | WM: 2.09 10 | GROUP_W: 8 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.8 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 1024 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 800 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-6.4GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 25 7 | W0: 112 8 | WA: 33.22 9 | WM: 2.27 10 | GROUP_W: 72 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.4 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 512 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 400 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-600MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 15 7 | W0: 48 8 | WA: 32.54 9 | WM: 2.32 10 | GROUP_W: 16 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.8 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 1024 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 800 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-8.0GF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: true 6 | DEPTH: 17 7 | W0: 192 8 | WA: 76.82 9 | WM: 2.19 10 | GROUP_W: 56 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.4 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 512 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 400 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/backbones/regnet/regnety/RegNetY-800MF_dds_8gpu.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: regnet 3 | NUM_CLASSES: 1000 4 | REGNET: 5 | SE_ON: True 6 | DEPTH: 14 7 | W0: 56 8 | WA: 38.84 9 | WM: 2.4 10 | GROUP_W: 16 11 | OPTIM: 12 | LR_POLICY: cos 13 | BASE_LR: 0.8 14 | MAX_EPOCH: 100 15 | MOMENTUM: 0.9 16 | WEIGHT_DECAY: 5e-5 17 | WARMUP_ITERS: 5 18 | TRAIN: 19 | DATASET: imagenet 20 | IM_SIZE: 224 21 | BATCH_SIZE: 1024 22 | TEST: 23 | DATASET: imagenet 24 | IM_SIZE: 256 25 | BATCH_SIZE: 800 26 | NUM_GPUS: 8 27 | OUT_DIR: . 28 | -------------------------------------------------------------------------------- /fastreid/modeling/heads/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .build import REID_HEADS_REGISTRY, build_heads 8 | 9 | # import all the meta_arch, so they will be registered 10 | from .embedding_head import EmbeddingHead 11 | from .clas_head import ClasHead 12 | -------------------------------------------------------------------------------- /fastreid/modeling/heads/build.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from ...utils.registry import Registry 8 | 9 | REID_HEADS_REGISTRY = Registry("HEADS") 10 | REID_HEADS_REGISTRY.__doc__ = """ 11 | Registry for reid heads in a baseline model. 12 | 13 | ROIHeads take feature maps and region proposals, and 14 | perform per-region computation. 15 | The registered object will be called with `obj(cfg, input_shape)`. 16 | The call is expected to return an :class:`ROIHeads`. 17 | """ 18 | 19 | 20 | def build_heads(cfg): 21 | """ 22 | Build REIDHeads defined by `cfg.MODEL.REID_HEADS.NAME`. 23 | """ 24 | head = cfg.MODEL.HEADS.NAME 25 | return REID_HEADS_REGISTRY.get(head)(cfg) 26 | -------------------------------------------------------------------------------- /fastreid/modeling/heads/clas_head.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import torch.nn.functional as F 8 | 9 | from fastreid.modeling.heads import REID_HEADS_REGISTRY, EmbeddingHead 10 | 11 | 12 | @REID_HEADS_REGISTRY.register() 13 | class ClasHead(EmbeddingHead): 14 | def forward(self, features, targets=None): 15 | """ 16 | See :class:`ClsHeads.forward`. 17 | """ 18 | pool_feat = self.pool_layer(features) 19 | neck_feat = self.bottleneck(pool_feat) 20 | neck_feat = neck_feat.view(neck_feat.size(0), -1) 21 | 22 | if self.cls_layer.__class__.__name__ == 'Linear': 23 | logits = F.linear(neck_feat, self.weight) 24 | else: 25 | logits = F.linear(F.normalize(neck_feat), F.normalize(self.weight)) 26 | 27 | # Evaluation 28 | if not self.training: return logits.mul_(self.cls_layer.s) 29 | 30 | cls_outputs = self.cls_layer(logits.clone(), targets) 31 | 32 | return { 33 | "cls_outputs": cls_outputs, 34 | "pred_class_logits": logits.mul_(self.cls_layer.s), 35 | "features": neck_feat, 36 | } 37 | -------------------------------------------------------------------------------- /fastreid/modeling/losses/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: l1aoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .circle_loss import * 8 | from .cross_entroy_loss import cross_entropy_loss, log_accuracy 9 | from .focal_loss import focal_loss 10 | from .triplet_loss import triplet_loss 11 | 12 | __all__ = [k for k in globals().keys() if not k.startswith("_")] -------------------------------------------------------------------------------- /fastreid/modeling/losses/circle_loss.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import torch 8 | import torch.nn.functional as F 9 | 10 | __all__ = ["pairwise_circleloss", "pairwise_cosface"] 11 | 12 | 13 | def pairwise_circleloss( 14 | embedding: torch.Tensor, 15 | targets: torch.Tensor, 16 | margin: float, 17 | gamma: float, ) -> torch.Tensor: 18 | embedding = F.normalize(embedding, dim=1) 19 | 20 | dist_mat = torch.matmul(embedding, embedding.t()) 21 | 22 | N = dist_mat.size(0) 23 | 24 | is_pos = targets.view(N, 1).expand(N, N).eq(targets.view(N, 1).expand(N, N).t()).float() 25 | is_neg = targets.view(N, 1).expand(N, N).ne(targets.view(N, 1).expand(N, N).t()).float() 26 | 27 | # Mask scores related to itself 28 | is_pos = is_pos - torch.eye(N, N, device=is_pos.device) 29 | 30 | s_p = dist_mat * is_pos 31 | s_n = dist_mat * is_neg 32 | 33 | alpha_p = torch.clamp_min(-s_p.detach() + 1 + margin, min=0.) 34 | alpha_n = torch.clamp_min(s_n.detach() + margin, min=0.) 35 | delta_p = 1 - margin 36 | delta_n = margin 37 | 38 | logit_p = - gamma * alpha_p * (s_p - delta_p) + (-99999999.) * (1 - is_pos) 39 | logit_n = gamma * alpha_n * (s_n - delta_n) + (-99999999.) * (1 - is_neg) 40 | 41 | loss = F.softplus(torch.logsumexp(logit_p, dim=1) + torch.logsumexp(logit_n, dim=1)).mean() 42 | 43 | return loss 44 | 45 | 46 | def pairwise_cosface( 47 | embedding: torch.Tensor, 48 | targets: torch.Tensor, 49 | margin: float, 50 | gamma: float, ) -> torch.Tensor: 51 | # Normalize embedding features 52 | embedding = F.normalize(embedding, dim=1) 53 | 54 | dist_mat = torch.matmul(embedding, embedding.t()) 55 | 56 | N = dist_mat.size(0) 57 | is_pos = targets.view(N, 1).expand(N, N).eq(targets.view(N, 1).expand(N, N).t()).float() 58 | is_neg = targets.view(N, 1).expand(N, N).ne(targets.view(N, 1).expand(N, N).t()).float() 59 | 60 | # Mask scores related to itself 61 | is_pos = is_pos - torch.eye(N, N, device=is_pos.device) 62 | 63 | s_p = dist_mat * is_pos 64 | s_n = dist_mat * is_neg 65 | 66 | logit_p = -gamma * s_p + (-99999999.) * (1 - is_pos) 67 | logit_n = gamma * (s_n + margin) + (-99999999.) * (1 - is_neg) 68 | 69 | loss = F.softplus(torch.logsumexp(logit_p, dim=1) + torch.logsumexp(logit_n, dim=1)).mean() 70 | 71 | return loss 72 | -------------------------------------------------------------------------------- /fastreid/modeling/losses/cross_entroy_loss.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: l1aoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | import torch 7 | import torch.nn.functional as F 8 | 9 | from fastreid.utils.events import get_event_storage 10 | 11 | 12 | def log_accuracy(pred_class_logits, gt_classes, topk=(1,)): 13 | """ 14 | Log the accuracy metrics to EventStorage. 15 | """ 16 | bsz = pred_class_logits.size(0) 17 | maxk = max(topk) 18 | _, pred_class = pred_class_logits.topk(maxk, 1, True, True) 19 | pred_class = pred_class.t() 20 | correct = pred_class.eq(gt_classes.view(1, -1).expand_as(pred_class)) 21 | 22 | ret = [] 23 | for k in topk: 24 | correct_k = correct[:k].view(-1).float().sum(dim=0, keepdim=True) 25 | ret.append(correct_k.mul_(1. / bsz)) 26 | 27 | storage = get_event_storage() 28 | storage.put_scalar("cls_accuracy", ret[0]) 29 | 30 | 31 | def cross_entropy_loss(pred_class_outputs, gt_classes, eps, alpha=0.2): 32 | num_classes = pred_class_outputs.size(1) 33 | 34 | if eps >= 0: 35 | smooth_param = eps 36 | else: 37 | # Adaptive label smooth regularization 38 | soft_label = F.softmax(pred_class_outputs, dim=1) 39 | smooth_param = alpha * soft_label[torch.arange(soft_label.size(0)), gt_classes].unsqueeze(1) 40 | 41 | log_probs = F.log_softmax(pred_class_outputs, dim=1) 42 | with torch.no_grad(): 43 | targets = torch.ones_like(log_probs) 44 | targets *= smooth_param / (num_classes - 1) 45 | targets.scatter_(1, gt_classes.data.unsqueeze(1), (1 - smooth_param)) 46 | 47 | loss = (-targets * log_probs).sum(dim=1) 48 | 49 | with torch.no_grad(): 50 | non_zero_cnt = max(loss.nonzero(as_tuple=False).size(0), 1) 51 | 52 | loss = loss.sum() / non_zero_cnt 53 | 54 | return loss 55 | -------------------------------------------------------------------------------- /fastreid/modeling/losses/utils.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import torch 8 | import torch.nn.functional as F 9 | 10 | 11 | def concat_all_gather(tensor): 12 | """ 13 | Performs all_gather operation on the provided tensors. 14 | *** Warning ***: torch.distributed.all_gather has no gradient. 15 | """ 16 | tensors_gather = [torch.ones_like(tensor) 17 | for _ in range(torch.distributed.get_world_size())] 18 | torch.distributed.all_gather(tensors_gather, tensor, async_op=False) 19 | 20 | output = torch.cat(tensors_gather, dim=0) 21 | return output 22 | 23 | 24 | def normalize(x, axis=-1): 25 | """Normalizing to unit length along the specified dimension. 26 | Args: 27 | x: pytorch Variable 28 | Returns: 29 | x: pytorch Variable, same shape as input 30 | """ 31 | x = 1. * x / (torch.norm(x, 2, axis, keepdim=True).expand_as(x) + 1e-12) 32 | return x 33 | 34 | 35 | def euclidean_dist(x, y): 36 | m, n = x.size(0), y.size(0) 37 | xx = torch.pow(x, 2).sum(1, keepdim=True).expand(m, n) 38 | yy = torch.pow(y, 2).sum(1, keepdim=True).expand(n, m).t() 39 | dist = xx + yy - 2 * torch.matmul(x, y.t()) 40 | dist = dist.clamp(min=1e-12).sqrt() # for numerical stability 41 | return dist 42 | 43 | 44 | def cosine_dist(x, y): 45 | x = F.normalize(x, dim=1) 46 | y = F.normalize(y, dim=1) 47 | dist = 2 - 2 * torch.mm(x, y.t()) 48 | return dist 49 | -------------------------------------------------------------------------------- /fastreid/modeling/meta_arch/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .build import META_ARCH_REGISTRY, build_model 8 | 9 | 10 | # import all the meta_arch, so they will be registered 11 | from .baseline import Baseline 12 | from .mgn import MGN 13 | from .moco import MoCo 14 | from .distiller import Distiller 15 | -------------------------------------------------------------------------------- /fastreid/modeling/meta_arch/build.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | import torch 7 | 8 | from fastreid.utils.registry import Registry 9 | 10 | META_ARCH_REGISTRY = Registry("META_ARCH") # noqa F401 isort:skip 11 | META_ARCH_REGISTRY.__doc__ = """ 12 | Registry for meta-architectures, i.e. the whole model. 13 | The registered object will be called with `obj(cfg)` 14 | and expected to return a `nn.Module` object. 15 | """ 16 | 17 | 18 | def build_model(cfg): 19 | """ 20 | Build the whole model architecture, defined by ``cfg.MODEL.META_ARCHITECTURE``. 21 | Note that it does not load any weights from ``cfg``. 22 | """ 23 | meta_arch = cfg.MODEL.META_ARCHITECTURE 24 | model = META_ARCH_REGISTRY.get(meta_arch)(cfg) 25 | model.to(torch.device(cfg.MODEL.DEVICE)) 26 | return model 27 | -------------------------------------------------------------------------------- /fastreid/solver/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | 8 | from .build import build_lr_scheduler, build_optimizer -------------------------------------------------------------------------------- /fastreid/solver/lr_scheduler.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from typing import List 8 | 9 | import torch 10 | from torch.optim.lr_scheduler import * 11 | 12 | 13 | class WarmupLR(torch.optim.lr_scheduler._LRScheduler): 14 | def __init__( 15 | self, 16 | optimizer: torch.optim.Optimizer, 17 | warmup_factor: float = 0.1, 18 | warmup_iters: int = 1000, 19 | warmup_method: str = "linear", 20 | last_epoch: int = -1, 21 | ): 22 | self.warmup_factor = warmup_factor 23 | self.warmup_iters = warmup_iters 24 | self.warmup_method = warmup_method 25 | super().__init__(optimizer, last_epoch) 26 | 27 | def get_lr(self) -> List[float]: 28 | warmup_factor = _get_warmup_factor_at_epoch( 29 | self.warmup_method, self.last_epoch, self.warmup_iters, self.warmup_factor 30 | ) 31 | return [ 32 | base_lr * warmup_factor for base_lr in self.base_lrs 33 | ] 34 | 35 | def _compute_values(self) -> List[float]: 36 | # The new interface 37 | return self.get_lr() 38 | 39 | 40 | def _get_warmup_factor_at_epoch( 41 | method: str, iter: int, warmup_iters: int, warmup_factor: float 42 | ) -> float: 43 | """ 44 | Return the learning rate warmup factor at a specific iteration. 45 | See https://arxiv.org/abs/1706.02677 for more details. 46 | Args: 47 | method (str): warmup method; either "constant" or "linear". 48 | iter (int): iter at which to calculate the warmup factor. 49 | warmup_iters (int): the number of warmup epochs. 50 | warmup_factor (float): the base warmup factor (the meaning changes according 51 | to the method used). 52 | Returns: 53 | float: the effective warmup factor at the given iteration. 54 | """ 55 | if iter >= warmup_iters: 56 | return 1.0 57 | 58 | if method == "constant": 59 | return warmup_factor 60 | elif method == "linear": 61 | alpha = iter / warmup_iters 62 | return warmup_factor * (1 - alpha) + alpha 63 | elif method == "exp": 64 | return warmup_factor ** (1 - iter / warmup_iters) 65 | else: 66 | raise ValueError("Unknown warmup method: {}".format(method)) 67 | -------------------------------------------------------------------------------- /fastreid/solver/optim/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | from .lamb import Lamb 8 | from .swa import SWA 9 | from .radam import RAdam 10 | from torch.optim import * 11 | -------------------------------------------------------------------------------- /fastreid/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: sherlock 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | -------------------------------------------------------------------------------- /fastreid/utils/history_buffer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. 3 | 4 | import numpy as np 5 | from typing import List, Tuple 6 | 7 | 8 | class HistoryBuffer: 9 | """ 10 | Track a series of scalar values and provide access to smoothed values over a 11 | window or the global average of the series. 12 | """ 13 | 14 | def __init__(self, max_length: int = 1000000): 15 | """ 16 | Args: 17 | max_length: maximal number of values that can be stored in the 18 | buffer. When the capacity of the buffer is exhausted, old 19 | values will be removed. 20 | """ 21 | self._max_length: int = max_length 22 | self._data: List[Tuple[float, float]] = [] # (value, iteration) pairs 23 | self._count: int = 0 24 | self._global_avg: float = 0 25 | 26 | def update(self, value: float, iteration: float = None): 27 | """ 28 | Add a new scalar value produced at certain iteration. If the length 29 | of the buffer exceeds self._max_length, the oldest element will be 30 | removed from the buffer. 31 | """ 32 | if iteration is None: 33 | iteration = self._count 34 | if len(self._data) == self._max_length: 35 | self._data.pop(0) 36 | self._data.append((value, iteration)) 37 | 38 | self._count += 1 39 | self._global_avg += (value - self._global_avg) / self._count 40 | 41 | def latest(self): 42 | """ 43 | Return the latest scalar value added to the buffer. 44 | """ 45 | return self._data[-1][0] 46 | 47 | def median(self, window_size: int): 48 | """ 49 | Return the median of the latest `window_size` values in the buffer. 50 | """ 51 | return np.median([x[0] for x in self._data[-window_size:]]) 52 | 53 | def avg(self, window_size: int): 54 | """ 55 | Return the mean of the latest `window_size` values in the buffer. 56 | """ 57 | return np.mean([x[0] for x in self._data[-window_size:]]) 58 | 59 | def global_avg(self): 60 | """ 61 | Return the mean of all the elements in the buffer. Note that this 62 | includes those getting removed due to limited buffer storage. 63 | """ 64 | return self._global_avg 65 | 66 | def values(self): 67 | """ 68 | Returns: 69 | list[(number, iteration)]: content of the current buffer. 70 | """ 71 | return self._data 72 | -------------------------------------------------------------------------------- /fastreid/utils/registry.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved 3 | 4 | from typing import Dict, Optional 5 | 6 | 7 | class Registry(object): 8 | """ 9 | The registry that provides name -> object mapping, to support third-party 10 | users' custom modules. 11 | To create a registry (e.g. a backbone registry): 12 | .. code-block:: python 13 | BACKBONE_REGISTRY = Registry('BACKBONE') 14 | To register an object: 15 | .. code-block:: python 16 | @BACKBONE_REGISTRY.register() 17 | class MyBackbone(): 18 | ... 19 | Or: 20 | .. code-block:: python 21 | BACKBONE_REGISTRY.register(MyBackbone) 22 | """ 23 | 24 | def __init__(self, name: str) -> None: 25 | """ 26 | Args: 27 | name (str): the name of this registry 28 | """ 29 | self._name: str = name 30 | self._obj_map: Dict[str, object] = {} 31 | 32 | def _do_register(self, name: str, obj: object) -> None: 33 | assert ( 34 | name not in self._obj_map 35 | ), "An object named '{}' was already registered in '{}' registry!".format( 36 | name, self._name 37 | ) 38 | self._obj_map[name] = obj 39 | 40 | def register(self, obj: object = None) -> Optional[object]: 41 | """ 42 | Register the given object under the the name `obj.__name__`. 43 | Can be used as either a decorator or not. See docstring of this class for usage. 44 | """ 45 | if obj is None: 46 | # used as a decorator 47 | def deco(func_or_class: object) -> object: 48 | name = func_or_class.__name__ # pyre-ignore 49 | self._do_register(name, func_or_class) 50 | return func_or_class 51 | 52 | return deco 53 | 54 | # used as a function call 55 | name = obj.__name__ # pyre-ignore 56 | self._do_register(name, obj) 57 | 58 | def get(self, name: str) -> object: 59 | ret = self._obj_map.get(name) 60 | if ret is None: 61 | raise KeyError( 62 | "No object named '{}' found in '{}' registry!".format( 63 | name, self._name 64 | ) 65 | ) 66 | return ret 67 | -------------------------------------------------------------------------------- /fastreid/utils/timer.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. 2 | # -*- coding: utf-8 -*- 3 | 4 | from time import perf_counter 5 | from typing import Optional 6 | 7 | 8 | class Timer: 9 | """ 10 | A timer which computes the time elapsed since the start/reset of the timer. 11 | """ 12 | 13 | def __init__(self): 14 | self.reset() 15 | 16 | def reset(self): 17 | """ 18 | Reset the timer. 19 | """ 20 | self._start = perf_counter() 21 | self._paused: Optional[float] = None 22 | self._total_paused = 0 23 | self._count_start = 1 24 | 25 | def pause(self): 26 | """ 27 | Pause the timer. 28 | """ 29 | if self._paused is not None: 30 | raise ValueError("Trying to pause a Timer that is already paused!") 31 | self._paused = perf_counter() 32 | 33 | def is_paused(self) -> bool: 34 | """ 35 | Returns: 36 | bool: whether the timer is currently paused 37 | """ 38 | return self._paused is not None 39 | 40 | def resume(self): 41 | """ 42 | Resume the timer. 43 | """ 44 | if self._paused is None: 45 | raise ValueError("Trying to resume a Timer that is not paused!") 46 | self._total_paused += perf_counter() - self._paused 47 | self._paused = None 48 | self._count_start += 1 49 | 50 | def seconds(self) -> float: 51 | """ 52 | Returns: 53 | (float): the total number of seconds since the start/reset of the 54 | timer, excluding the time when the timer is paused. 55 | """ 56 | if self._paused is not None: 57 | end_time: float = self._paused # type: ignore 58 | else: 59 | end_time = perf_counter() 60 | return end_time - self._start - self._total_paused 61 | 62 | def avg_seconds(self) -> float: 63 | """ 64 | Returns: 65 | (float): the average number of seconds between every start/reset and 66 | pause. 67 | """ 68 | return self.seconds() / self._count_start 69 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/__init__.py: -------------------------------------------------------------------------------- 1 | from .data import * 2 | from .modeling import * 3 | 4 | from .config import add_temp_config, add_swin_config 5 | from .config import add_vit_config, add_reweight_config, add_cascade_config, add_slowfast_config 6 | 7 | from .evaluator import VideoReidEvaluator, NewVideoReidEvaluator 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/config.py: -------------------------------------------------------------------------------- 1 | from fastreid.config import CfgNode as CN 2 | 3 | def add_temp_config(cfg): 4 | _C = cfg 5 | 6 | _C.TEMP = CN() 7 | _C.TEMP.REDUCE = 'avg' 8 | 9 | _C.TEMP.DATA = CN() 10 | _C.TEMP.DATA.DENSE = False 11 | _C.TEMP.DATA.SAMPLING_STEP = 32 12 | 13 | _C.TEMP.TRAIN = CN() 14 | _C.TEMP.TRAIN.SAMPLER = 'TemporalRestrictedCrop' 15 | _C.TEMP.TRAIN.SEQ_SIZE = 8 16 | _C.TEMP.TRAIN.STRIDE = 4 17 | 18 | _C.TEMP.TEST = CN() 19 | _C.TEMP.TEST.ALL = False 20 | _C.TEMP.TEST.SAMPLER = 'TemporalRestrictedBeginCrop' 21 | _C.TEMP.TEST.SEQ_SIZE = 4 22 | _C.TEMP.TEST.STRIDE = 8 23 | _C.TEMP.TEST.TRACK_SPLIT = 64 24 | 25 | _C.TEMP.CLUSTER = CN() 26 | _C.TEMP.CLUSTER.NUM = 5 27 | _C.TEMP.CLUSTER.EPOCH = 5 28 | _C.TEMP.CLUSTER.FRAMES = 16 29 | _C.TEMP.CLUSTER.DATA_RATIO = 0.5 30 | 31 | 32 | def add_reweight_config(cfg): 33 | _C = cfg 34 | _C.REWEIGHT = CN() 35 | _C.REWEIGHT.EPOCH = 50 36 | _C.REWEIGHT.UPPER = 0.85 37 | _C.REWEIGHT.LOWER = 0.6 38 | 39 | 40 | def add_swin_config(cfg): 41 | 42 | _C = cfg 43 | 44 | _C.MODEL.BACKBONE.PATCH_SIZE = 4 45 | _C.MODEL.BACKBONE.PADDING_SIZE = (0, 1) 46 | _C.MODEL.BACKBONE.WINDOW_SIZE = 4 47 | _C.MODEL.BACKBONE.QKV_BIAS = True 48 | _C.MODEL.BACKBONE.QK_SCALE = None 49 | _C.MODEL.BACKBONE.MLP_RATIO = 4. 50 | _C.MODEL.BACKBONE.APE = False 51 | _C.MODEL.BACKBONE.PATCH_NORM = True 52 | 53 | 54 | 55 | def add_vit_config(cfg): 56 | 57 | _C = cfg 58 | 59 | _C.MODEL.BACKBONE.SHIFT_NUM = 5 60 | _C.MODEL.BACKBONE.SHUFFLE_GROUP = 2 61 | _C.MODEL.BACKBONE.DEVIDE_LENGTH = 4 62 | _C.MODEL.BACKBONE.RE_ARRANGE = True 63 | _C.MODEL.BACKBONE.INFERENCE_DEPTH = 12 64 | _C.MODEL.BACKBONE.LAYER_NUM = 12 65 | _C.MODEL.BACKBONE.NORM_OUT = False 66 | _C.MODEL.BACKBONE.PART_POOL = 'max' 67 | _C.MODEL.BACKBONE.TOKEN = 'all' 68 | _C.MODEL.BACKBONE.PADDING_SIZE = (0, 0) 69 | _C.MODEL.BACKBONE.NUM_CAMERA = 0 70 | _C.MODEL.BACKBONE.SEQ_MAX = 1000 71 | _C.MODEL.BACKBONE.T_DEPTH = 2 72 | _C.MODEL.BACKBONE.ATT_TYPE = 'divided_space_time' #["divided_space_time", "space_only", ""] 73 | _C.MODEL.BACKBONE.NUM_FRAMES = 8 74 | _C.MODEL.BACKBONE.CONVE_SHARE = False 75 | _C.MODEL.BACKBONE.DILATION = 1 76 | _C.MODEL.BACKBONE.PATCH_SIZE = (16, 16) 77 | 78 | 79 | def add_cascade_config(cfg): 80 | _C = cfg 81 | 82 | _C.CASCADE = CN() 83 | 84 | _C.CASCADE.PATCH1 = (16, 16) 85 | _C.CASCADE.STRIDE1 = (16, 16) 86 | 87 | _C.CASCADE.PATCH2 = (16, 32) 88 | _C.CASCADE.STRIDE2 = (16, 32) 89 | 90 | _C.CASCADE.PATCH3 = (32, 16) 91 | _C.CASCADE.STRIDE3 = (32, 16) 92 | 93 | _C.CASCADE.TPE = 'flow' 94 | _C.CASCADE.MAX_LEN = 1000 95 | 96 | 97 | def add_slowfast_config(cfg): 98 | _C = cfg 99 | 100 | 101 | _C.SLOW = CN() 102 | _C.SLOW.FRAME_NUM = 4 103 | _C.SLOW.IMG_SIZE = (384, 192) 104 | _C.SLOW.PATCH = (16, 16) 105 | _C.SLOW.STRIDE = (16, 16) 106 | 107 | 108 | _C.FAST = CN() 109 | _C.FAST.FRAME_NUM = 8 110 | _C.FAST.IMG_SIZE = (256, 128) 111 | _C.FAST.PATCH = (16, 16) 112 | _C.FAST.STRIDE = (16, 16) 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/data/__init__.py: -------------------------------------------------------------------------------- 1 | # from .datasets import MARS 2 | # from .datasets import DukeV_DL, DukeV 3 | # from .datasets import PRID2011 4 | # from .datasets import iLIDSVID 5 | # from .datasets import MARSDL 6 | # from .datasets import LSVID 7 | # from .datasets import iLIDSVID 8 | from .datasets import * 9 | 10 | from .video_dataset import VideoCommonDataset 11 | from .temporal_transforms import TemporalBeginCrop, TemporalRandomCrop, TemporalRandomContinueCrop 12 | from .data_utils import read_json, write_json 13 | 14 | from .build import build_video_reid_test_loader, build_video_reid_train_loader 15 | 16 | from .sampler import BalancedIdentitySamplerV2, WeightedTrackSampler 17 | 18 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/data/data_utils.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import json 3 | import errno 4 | import os 5 | import os.path as osp 6 | logger = logging.getLogger("fastreid."+__name__) 7 | 8 | def mkdir_if_missing(dirname): 9 | """Creates dirname if it is missing.""" 10 | if not osp.exists(dirname): 11 | try: 12 | os.makedirs(dirname) 13 | logger.info(f"making dir {dirname}") 14 | except OSError as e: 15 | if e.errno != errno.EEXIST: 16 | raise 17 | 18 | 19 | def read_json(fpath): 20 | """Reads json file from a path.""" 21 | with open(fpath, 'r') as f: 22 | logger.info(f"loading json from {fpath}") 23 | obj = json.load(f) 24 | return obj 25 | 26 | 27 | 28 | def write_json(obj, fpath): 29 | """Writes to a json file.""" 30 | mkdir_if_missing(osp.dirname(fpath)) 31 | with open(fpath, 'w') as f: 32 | logger.info(f"dumping json from {fpath}") 33 | json.dump(obj, f, indent=4, separators=(',', ': ')) 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/data/datasets/__init__.py: -------------------------------------------------------------------------------- 1 | from .mars import MARS 2 | from .dukev import DukeV 3 | from .dukev_dl import DukeV_DL 4 | from .prid2011 import PRID2011 5 | from .ilidsvid import iLIDSVID 6 | 7 | from .mars_dl import MARSDL 8 | from .lsvid import LSVID 9 | from .vveri901 import VVERI901 10 | from .gait import CASIA_B 11 | 12 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/modeling/__init__.py: -------------------------------------------------------------------------------- 1 | from .head import TempHead 2 | 3 | from .backbone import * 4 | from .layers import * 5 | 6 | from .VideoBaseline import VideoBaseline 7 | from .ViT3D import ViT3D 8 | from .ViTBaseline import ViTBaseline 9 | from .CAViT import CAViT 10 | 11 | from .Swin3D import Swin3D 12 | from .resnet3d import Res3D -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/modeling/backbone/__init__.py: -------------------------------------------------------------------------------- 1 | from .swin_vit import build_swin_vit_backbone 2 | from .vit import build_myvit_backbone 3 | from .time_former import build_vit3d_backbone 4 | 5 | ### cross atteniton 6 | from .cavit import build_cavit_backbone 7 | from .resnet_tsm import build_resnet_tsm_backbone 8 | 9 | from .shift_token import build_shift_token_vit 10 | from .swin3d import build_swin3d_base, build_swin3d_small, build_swin3d_tiny 11 | 12 | from .ap3d import build_ap3d_backbone, build_ap3d_nl_backbone, build_c2d_backbone 13 | from .bicknet import build_bick_backbone 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/modeling/head/__init__.py: -------------------------------------------------------------------------------- 1 | # # from .conv3d_head import Conv3DHead 2 | from .temp_head import TempHead -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/modeling/head/temp_head.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | import ipdb 7 | import torch 8 | import torch.nn.functional as F 9 | 10 | from fastreid.modeling.heads import REID_HEADS_REGISTRY, EmbeddingHead 11 | 12 | 13 | @REID_HEADS_REGISTRY.register() 14 | class TempHead(EmbeddingHead): 15 | 16 | 17 | def __init__(self, cfg): 18 | super().__init__(cfg) 19 | self.temp_reduce = cfg.TEMP.REDUCE 20 | 21 | def forward(self, features, targets=None, reduce=True): 22 | """ 23 | See :class:`ClsHeads.forward`. 24 | features: [b * t, c, h, w] 25 | """ 26 | # ipdb.set_trace() 27 | b, t, c, h, w = features.size() 28 | features = features.view(b*t, c, h, w) 29 | # b = bt // t_size 30 | 31 | pool_feat = self.pool_layer(features) # [b*t, 2048, 1, 1] 32 | neck_feat = self.bottleneck(pool_feat) # [b*t, 2048, 1, 1] 33 | neck_feat = neck_feat[..., 0, 0] 34 | 35 | # temp funsion 36 | pool_feat = pool_feat.view(b, t, -1) # [b, t, 2048] 37 | neck_feat = neck_feat.view(b, t, -1) # [b, t, 2048] 38 | 39 | if reduce and self.temp_reduce != None: 40 | if self.temp_reduce == 'avg': 41 | pool_feat = torch.mean(pool_feat, dim=1) 42 | neck_feat = torch.mean(neck_feat, dim=1) 43 | elif self.temp_reduce == 'max': 44 | pool_feat = torch.max(pool_feat, 1)[0] 45 | neck_feat = torch.max(neck_feat, 1)[0] 46 | else: 47 | raise KeyError(f"{self.temp_reduce} is invalid in ['avg', 'max', 'None'] ") 48 | else: 49 | pool_feat = pool_feat.view(b, t, c) 50 | neck_feat = neck_feat.view(b, t, c) 51 | 52 | 53 | 54 | # Evaluation 55 | # fmt: off 56 | if not self.training: return neck_feat 57 | # fmt: on 58 | 59 | # Training 60 | if self.cls_layer.__class__.__name__ == 'Linear': 61 | logits = F.linear(neck_feat, self.weight) 62 | else: 63 | logits = F.linear(F.normalize(neck_feat), F.normalize(self.weight)) 64 | 65 | # Pass logits.clone() into cls_layer, because there is in-place operations 66 | cls_outputs = self.cls_layer(logits.clone(), targets) 67 | 68 | # fmt: off 69 | if self.neck_feat == 'before': 70 | feat = pool_feat 71 | elif self.neck_feat == 'after': 72 | feat = neck_feat 73 | else: 74 | raise KeyError(f"{self.neck_feat} is invalid for MODEL.HEADS.NECK_FEAT") 75 | # fmt: on 76 | 77 | return { 78 | "cls_outputs": cls_outputs, 79 | "pred_class_logits": logits.mul(self.cls_layer.s), 80 | "features": feat, 81 | } 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /projects/CAViT/FastVideo/modeling/layers/__init__.py: -------------------------------------------------------------------------------- 1 | # from .clone_2d import CloneBottleneck, clone_conv, clone_batch_norm 2 | # from .inflate import inflate_conv, inflate_pool, inflate_linear, inflate_batch_norm 3 | # from .TSB import TSB 4 | # from .TSE import TSE 5 | # from .pooling import * 6 | from .inflate import inflate_conv,inflate_pool, inflate_linear, inflate_batch_norm 7 | from .transformer import * -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_ilid.yml: -------------------------------------------------------------------------------- 1 | # _BASE_: ../VBASE_SBS.yml 2 | 3 | MODEL: 4 | META_ARCHITECTURE: CAViT 5 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 6 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 7 | 8 | BACKBONE: 9 | NAME: build_cavit_backbone 10 | DEPTH: base 11 | FEAT_DIM: 768 12 | PRETRAIN: True 13 | PRETRAIN_PATH: ../jx_vit_base_p16_224-80ecf9dd.pth 14 | STRIDE_SIZE: (16, 16) 15 | DROP_PATH_RATIO: 0.1 16 | DROP_RATIO: 0.0 17 | ATT_DROP_RATE: 0.0 18 | SHIFT_NUM: 5 19 | SHUFFLE_GROUP: 2 20 | DEVIDE_LENGTH: 4 21 | RE_ARRANGE: True 22 | LAYER_NUM: 10 23 | INFERENCE_DEPTH: 10 24 | NORM_OUT: True 25 | 26 | 27 | HEADS: 28 | NAME: TempHead 29 | NORM: BN 30 | WITH_BNNECK: True 31 | POOL_LAYER: Identity 32 | NECK_FEAT: before 33 | CLS_LAYER: CircleSoftmax 34 | SCALE: 64 35 | MARGIN: 0.3 36 | 37 | LOSSES: 38 | NAME: ("CrossEntropyLoss",) 39 | CE: 40 | EPSILON: 0.1 41 | SCALE: 1.0 42 | 43 | TRI: 44 | MARGIN: 0.0 45 | HARD_MINING: True 46 | NORM_FEAT: False 47 | SCALE: 1.0 48 | 49 | 50 | INPUT: 51 | SIZE_TRAIN: [ 256, 128 ] 52 | SIZE_TEST: [ 256, 128 ] 53 | 54 | REA: 55 | ENABLED: True 56 | PROB: 0.5 57 | 58 | FLIP: 59 | ENABLED: True 60 | 61 | PADDING: 62 | ENABLED: True 63 | 64 | DATASETS: 65 | NAMES: ("iLIDSVID",) 66 | TESTS: ("iLIDSVID",) 67 | 68 | DATALOADER: 69 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 70 | NUM_INSTANCE: 4 71 | NUM_WORKERS: 8 72 | 73 | SOLVER: 74 | AMP: 75 | ENABLED: True 76 | OPT: SGD 77 | MAX_EPOCH: 60 78 | BASE_LR: 0.01 79 | BIAS_LR_FACTOR: 2. 80 | WEIGHT_DECAY: 1e-4 81 | WEIGHT_DECAY_BIAS: 1e-4 82 | IMS_PER_BATCH: 16 83 | 84 | SCHED: CosineAnnealingLR 85 | ETA_MIN_LR: 0.000016 86 | 87 | WARMUP_FACTOR: 0.01 88 | WARMUP_ITERS: 1000 89 | 90 | CLIP_GRADIENTS: 91 | ENABLED: True 92 | 93 | CHECKPOINT_PERIOD: 30 94 | 95 | TEST: 96 | EVAL_PERIOD: 5 97 | IMS_PER_BATCH: 16 98 | 99 | CUDNN_BENCHMARK: True 100 | 101 | TEMP: 102 | REDUCE: 'avg' 103 | DATA: 104 | DENSE: True 105 | SAMPLING_STEP: 32 106 | TRAIN: 107 | SAMPLER: 'TemporalRestrictedBeginCrop' 108 | SEQ_SIZE: 8 109 | STRIDE: 4 110 | TEST: 111 | ALL: False 112 | SEQ_SIZE: 8 113 | TRACK_SPLIT: 128 114 | 115 | CASCADE: 116 | PATCH1: (16, 16) 117 | STRIDE1: (12, 12) 118 | 119 | PATCH2: (32, 16) 120 | STRIDE2: (28, 12) 121 | 122 | PATCH3: (16, 32) 123 | STRIDE3: (12, 28) 124 | 125 | TPE: flow 126 | 127 | 128 | OUTPUT_DIR: logs/iLIDSVID/ 129 | -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_lsvid.yml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | META_ARCHITECTURE: CAViT 3 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 4 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 5 | 6 | BACKBONE: 7 | NAME: build_cavit_backbone 8 | DEPTH: base 9 | FEAT_DIM: 768 10 | PRETRAIN: True 11 | PRETRAIN_PATH: ../jx_vit_base_p16_224-80ecf9dd.pth 12 | STRIDE_SIZE: (16, 16) 13 | DROP_PATH_RATIO: 0.1 14 | DROP_RATIO: 0.0 15 | ATT_DROP_RATE: 0.0 16 | SHIFT_NUM: 5 17 | SHUFFLE_GROUP: 2 18 | DEVIDE_LENGTH: 4 19 | RE_ARRANGE: True 20 | LAYER_NUM: 10 21 | INFERENCE_DEPTH: 10 22 | NORM_OUT: True 23 | 24 | 25 | HEADS: 26 | NAME: TempHead 27 | NORM: BN 28 | WITH_BNNECK: True 29 | POOL_LAYER: Identity 30 | NECK_FEAT: before 31 | CLS_LAYER: CircleSoftmax 32 | SCALE: 64 33 | MARGIN: 0.3 34 | 35 | LOSSES: 36 | NAME: ("CrossEntropyLoss",) 37 | CE: 38 | EPSILON: 0.1 39 | SCALE: 1.0 40 | 41 | TRI: 42 | MARGIN: 0.0 43 | HARD_MINING: True 44 | NORM_FEAT: False 45 | SCALE: 1.0 46 | 47 | 48 | INPUT: 49 | SIZE_TRAIN: [ 256, 128 ] 50 | SIZE_TEST: [ 256, 128 ] 51 | 52 | REA: 53 | ENABLED: True 54 | PROB: 0.5 55 | 56 | FLIP: 57 | ENABLED: True 58 | 59 | PADDING: 60 | ENABLED: True 61 | 62 | DATASETS: 63 | NAMES: ("LSVID",) 64 | TESTS: ("LSVID",) 65 | 66 | DATALOADER: 67 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 68 | NUM_INSTANCE: 4 69 | NUM_WORKERS: 8 70 | 71 | SOLVER: 72 | AMP: 73 | ENABLED: True 74 | OPT: SGD 75 | MAX_EPOCH: 30 76 | BASE_LR: 0.008 77 | BIAS_LR_FACTOR: 2. 78 | WEIGHT_DECAY: 1e-4 79 | WEIGHT_DECAY_BIAS: 1e-4 80 | IMS_PER_BATCH: 16 81 | 82 | SCHED: CosineAnnealingLR 83 | ETA_MIN_LR: 0.000016 84 | 85 | WARMUP_FACTOR: 0.01 86 | WARMUP_ITERS: 1000 87 | 88 | CLIP_GRADIENTS: 89 | ENABLED: True 90 | 91 | CHECKPOINT_PERIOD: 30 92 | 93 | TEST: 94 | EVAL_PERIOD: 5 95 | IMS_PER_BATCH: 16 96 | 97 | CUDNN_BENCHMARK: True 98 | 99 | TEMP: 100 | REDUCE: 'avg' 101 | DATA: 102 | DENSE: True 103 | SAMPLING_STEP: 32 104 | TRAIN: 105 | SAMPLER: 'TemporalRestrictedBeginCrop' 106 | SEQ_SIZE: 8 107 | STRIDE: 4 108 | TEST: 109 | ALL: False 110 | SEQ_SIZE: 8 111 | TRACK_SPLIT: 128 112 | 113 | CASCADE: 114 | PATCH1: (16, 16) 115 | STRIDE1: (12, 12) 116 | 117 | PATCH2: (32, 16) 118 | STRIDE2: (28, 12) 119 | 120 | PATCH3: (16, 32) 121 | STRIDE3: (12, 28) 122 | 123 | TPE: flow 124 | 125 | 126 | OUTPUT_DIR: logs/lsvid -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_lsvid_epoch20.yml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | META_ARCHITECTURE: CAViT 3 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 4 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 5 | 6 | BACKBONE: 7 | NAME: build_cavit_backbone 8 | DEPTH: base 9 | FEAT_DIM: 768 10 | PRETRAIN: True 11 | PRETRAIN_PATH: ../jx_vit_base_p16_224-80ecf9dd.pth 12 | STRIDE_SIZE: (16, 16) 13 | DROP_PATH_RATIO: 0.1 14 | DROP_RATIO: 0.0 15 | ATT_DROP_RATE: 0.0 16 | SHIFT_NUM: 5 17 | SHUFFLE_GROUP: 2 18 | DEVIDE_LENGTH: 4 19 | RE_ARRANGE: True 20 | LAYER_NUM: 10 21 | INFERENCE_DEPTH: 10 22 | NORM_OUT: True 23 | 24 | 25 | HEADS: 26 | NAME: TempHead 27 | NORM: BN 28 | WITH_BNNECK: True 29 | POOL_LAYER: Identity 30 | NECK_FEAT: before 31 | CLS_LAYER: CircleSoftmax 32 | SCALE: 64 33 | MARGIN: 0.3 34 | 35 | LOSSES: 36 | NAME: ("CrossEntropyLoss",) 37 | CE: 38 | EPSILON: 0.1 39 | SCALE: 1.0 40 | 41 | TRI: 42 | MARGIN: 0.0 43 | HARD_MINING: True 44 | NORM_FEAT: False 45 | SCALE: 1.0 46 | 47 | 48 | INPUT: 49 | SIZE_TRAIN: [ 256, 128 ] 50 | SIZE_TEST: [ 256, 128 ] 51 | 52 | REA: 53 | ENABLED: True 54 | PROB: 0.5 55 | 56 | FLIP: 57 | ENABLED: True 58 | 59 | PADDING: 60 | ENABLED: True 61 | 62 | DATASETS: 63 | NAMES: ("LSVID",) 64 | TESTS: ("LSVID",) 65 | 66 | DATALOADER: 67 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 68 | NUM_INSTANCE: 4 69 | NUM_WORKERS: 8 70 | 71 | SOLVER: 72 | AMP: 73 | ENABLED: True 74 | OPT: SGD 75 | MAX_EPOCH: 20 76 | BASE_LR: 0.02 77 | BIAS_LR_FACTOR: 2. 78 | WEIGHT_DECAY: 1e-4 79 | WEIGHT_DECAY_BIAS: 1e-4 80 | IMS_PER_BATCH: 16 81 | 82 | SCHED: CosineAnnealingLR 83 | ETA_MIN_LR: 0.000016 84 | 85 | WARMUP_FACTOR: 0.01 86 | WARMUP_ITERS: 1000 87 | 88 | CLIP_GRADIENTS: 89 | ENABLED: True 90 | 91 | CHECKPOINT_PERIOD: 30 92 | 93 | TEST: 94 | EVAL_PERIOD: 5 95 | IMS_PER_BATCH: 16 96 | 97 | CUDNN_BENCHMARK: True 98 | 99 | TEMP: 100 | REDUCE: 'avg' 101 | DATA: 102 | DENSE: True 103 | SAMPLING_STEP: 32 104 | TRAIN: 105 | SAMPLER: 'TemporalRestrictedBeginCrop' 106 | SEQ_SIZE: 8 107 | STRIDE: 4 108 | TEST: 109 | ALL: False 110 | SEQ_SIZE: 8 111 | TRACK_SPLIT: 128 112 | 113 | CASCADE: 114 | PATCH1: (16, 16) 115 | STRIDE1: (12, 12) 116 | 117 | PATCH2: (32, 16) 118 | STRIDE2: (28, 12) 119 | 120 | PATCH3: (16, 32) 121 | STRIDE3: (12, 28) 122 | 123 | TPE: flow 124 | 125 | 126 | OUTPUT_DIR: logs/lsvid_epoch20 -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_lsvid_lr0.01.yml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | META_ARCHITECTURE: CAViT 3 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 4 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 5 | 6 | BACKBONE: 7 | NAME: build_cavit_backbone 8 | DEPTH: base 9 | FEAT_DIM: 768 10 | PRETRAIN: True 11 | PRETRAIN_PATH: ../jx_vit_base_p16_224-80ecf9dd.pth 12 | STRIDE_SIZE: (16, 16) 13 | DROP_PATH_RATIO: 0.1 14 | DROP_RATIO: 0.0 15 | ATT_DROP_RATE: 0.0 16 | SHIFT_NUM: 5 17 | SHUFFLE_GROUP: 2 18 | DEVIDE_LENGTH: 4 19 | RE_ARRANGE: True 20 | LAYER_NUM: 10 21 | INFERENCE_DEPTH: 10 22 | NORM_OUT: True 23 | 24 | 25 | HEADS: 26 | NAME: TempHead 27 | NORM: BN 28 | WITH_BNNECK: True 29 | POOL_LAYER: Identity 30 | NECK_FEAT: before 31 | CLS_LAYER: CircleSoftmax 32 | SCALE: 64 33 | MARGIN: 0.3 34 | 35 | LOSSES: 36 | NAME: ("CrossEntropyLoss",) 37 | CE: 38 | EPSILON: 0.1 39 | SCALE: 1.0 40 | 41 | TRI: 42 | MARGIN: 0.0 43 | HARD_MINING: True 44 | NORM_FEAT: False 45 | SCALE: 1.0 46 | 47 | 48 | INPUT: 49 | SIZE_TRAIN: [ 256, 128 ] 50 | SIZE_TEST: [ 256, 128 ] 51 | 52 | REA: 53 | ENABLED: True 54 | PROB: 0.5 55 | 56 | FLIP: 57 | ENABLED: True 58 | 59 | PADDING: 60 | ENABLED: True 61 | 62 | DATASETS: 63 | NAMES: ("LSVID",) 64 | TESTS: ("LSVID",) 65 | 66 | DATALOADER: 67 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 68 | NUM_INSTANCE: 4 69 | NUM_WORKERS: 8 70 | 71 | SOLVER: 72 | AMP: 73 | ENABLED: True 74 | OPT: SGD 75 | MAX_EPOCH: 30 76 | BASE_LR: 0.01 77 | BIAS_LR_FACTOR: 2. 78 | WEIGHT_DECAY: 1e-4 79 | WEIGHT_DECAY_BIAS: 1e-4 80 | IMS_PER_BATCH: 16 81 | 82 | SCHED: CosineAnnealingLR 83 | ETA_MIN_LR: 0.000016 84 | 85 | WARMUP_FACTOR: 0.01 86 | WARMUP_ITERS: 1000 87 | 88 | CLIP_GRADIENTS: 89 | ENABLED: True 90 | 91 | CHECKPOINT_PERIOD: 30 92 | 93 | TEST: 94 | EVAL_PERIOD: 5 95 | IMS_PER_BATCH: 16 96 | 97 | CUDNN_BENCHMARK: True 98 | 99 | TEMP: 100 | REDUCE: 'avg' 101 | DATA: 102 | DENSE: True 103 | SAMPLING_STEP: 32 104 | TRAIN: 105 | SAMPLER: 'TemporalRestrictedBeginCrop' 106 | SEQ_SIZE: 8 107 | STRIDE: 4 108 | TEST: 109 | ALL: False 110 | SEQ_SIZE: 8 111 | TRACK_SPLIT: 128 112 | 113 | CASCADE: 114 | PATCH1: (16, 16) 115 | STRIDE1: (12, 12) 116 | 117 | PATCH2: (32, 16) 118 | STRIDE2: (28, 12) 119 | 120 | PATCH3: (16, 32) 121 | STRIDE3: (12, 28) 122 | 123 | TPE: flow 124 | 125 | 126 | OUTPUT_DIR: logs/lsvid_lr0.01 -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_mars_lr.yml: -------------------------------------------------------------------------------- 1 | # _BASE_: ../VBASE_SBS.yml 2 | 3 | MODEL: 4 | META_ARCHITECTURE: CAViT 5 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 6 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 7 | 8 | BACKBONE: 9 | NAME: build_cavit_backbone 10 | DEPTH: base 11 | FEAT_DIM: 768 12 | PRETRAIN: True 13 | PRETRAIN_PATH: ../jx_vit_base_p16_224-80ecf9dd.pth 14 | STRIDE_SIZE: (16, 16) 15 | DROP_PATH_RATIO: 0.1 16 | DROP_RATIO: 0.0 17 | ATT_DROP_RATE: 0.0 18 | SHIFT_NUM: 5 19 | SHUFFLE_GROUP: 2 20 | DEVIDE_LENGTH: 4 21 | RE_ARRANGE: True 22 | LAYER_NUM: 10 23 | INFERENCE_DEPTH: 10 24 | NORM_OUT: True 25 | 26 | 27 | HEADS: 28 | NAME: TempHead 29 | NORM: BN 30 | WITH_BNNECK: True 31 | POOL_LAYER: Identity 32 | NECK_FEAT: before 33 | CLS_LAYER: CircleSoftmax 34 | SCALE: 64 35 | MARGIN: 0.3 36 | 37 | LOSSES: 38 | NAME: ("CrossEntropyLoss",) 39 | CE: 40 | EPSILON: 0.1 41 | SCALE: 1.0 42 | 43 | TRI: 44 | MARGIN: 0.0 45 | HARD_MINING: True 46 | NORM_FEAT: False 47 | SCALE: 1.0 48 | 49 | 50 | INPUT: 51 | SIZE_TRAIN: [ 256, 128 ] 52 | SIZE_TEST: [ 256, 128 ] 53 | 54 | REA: 55 | ENABLED: True 56 | PROB: 0.5 57 | 58 | FLIP: 59 | ENABLED: True 60 | 61 | PADDING: 62 | ENABLED: True 63 | 64 | DATASETS: 65 | NAMES: ("MARS",) 66 | TESTS: ("MARS",) 67 | 68 | DATALOADER: 69 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 70 | NUM_INSTANCE: 4 71 | NUM_WORKERS: 8 72 | 73 | SOLVER: 74 | AMP: 75 | ENABLED: True 76 | OPT: SGD 77 | MAX_EPOCH: 30 78 | BASE_LR: 0.01 79 | BIAS_LR_FACTOR: 2. 80 | WEIGHT_DECAY: 1e-4 81 | WEIGHT_DECAY_BIAS: 1e-4 82 | IMS_PER_BATCH: 16 83 | 84 | SCHED: CosineAnnealingLR 85 | ETA_MIN_LR: 0.000016 86 | 87 | WARMUP_FACTOR: 0.01 88 | WARMUP_ITERS: 1000 89 | 90 | CLIP_GRADIENTS: 91 | ENABLED: True 92 | 93 | CHECKPOINT_PERIOD: 30 94 | 95 | TEST: 96 | EVAL_PERIOD: 5 97 | IMS_PER_BATCH: 16 98 | 99 | CUDNN_BENCHMARK: True 100 | 101 | TEMP: 102 | REDUCE: 'avg' 103 | DATA: 104 | DENSE: False 105 | SAMPLING_STEP: 32 106 | TRAIN: 107 | SAMPLER: 'TemporalRestrictedBeginCrop' 108 | SEQ_SIZE: 8 109 | STRIDE: 4 110 | TEST: 111 | ALL: False 112 | SEQ_SIZE: 8 113 | TRACK_SPLIT: 128 114 | 115 | CASCADE: 116 | PATCH1: (16, 16) 117 | STRIDE1: (12, 12) 118 | 119 | PATCH2: (32, 16) 120 | STRIDE2: (28, 12) 121 | 122 | PATCH3: (16, 32) 123 | STRIDE3: (12, 28) 124 | 125 | TPE: flow 126 | 127 | OUTPUT_DIR: logs/mars_flow -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_marsdl.yml: -------------------------------------------------------------------------------- 1 | # _BASE_: ../VBASE_SBS.yml 2 | 3 | MODEL: 4 | META_ARCHITECTURE: CAViT 5 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 6 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 7 | 8 | BACKBONE: 9 | NAME: build_cavit_backbone 10 | DEPTH: base 11 | FEAT_DIM: 768 12 | PRETRAIN: True 13 | PRETRAIN_PATH: ../jx_vit_base_p16_224-80ecf9dd.pth 14 | STRIDE_SIZE: (16, 16) 15 | DROP_PATH_RATIO: 0.1 16 | DROP_RATIO: 0.0 17 | ATT_DROP_RATE: 0.0 18 | SHIFT_NUM: 5 19 | SHUFFLE_GROUP: 2 20 | DEVIDE_LENGTH: 4 21 | RE_ARRANGE: True 22 | LAYER_NUM: 10 23 | INFERENCE_DEPTH: 10 24 | NORM_OUT: True 25 | 26 | 27 | HEADS: 28 | NAME: TempHead 29 | NORM: BN 30 | WITH_BNNECK: True 31 | POOL_LAYER: Identity 32 | NECK_FEAT: before 33 | CLS_LAYER: CircleSoftmax 34 | SCALE: 64 35 | MARGIN: 0.3 36 | 37 | LOSSES: 38 | NAME: ("CrossEntropyLoss",) 39 | CE: 40 | EPSILON: 0.1 41 | SCALE: 1.0 42 | 43 | TRI: 44 | MARGIN: 0.0 45 | HARD_MINING: True 46 | NORM_FEAT: False 47 | SCALE: 1.0 48 | 49 | 50 | INPUT: 51 | SIZE_TRAIN: [ 256, 128 ] 52 | SIZE_TEST: [ 256, 128 ] 53 | 54 | REA: 55 | ENABLED: True 56 | PROB: 0.5 57 | 58 | FLIP: 59 | ENABLED: True 60 | 61 | PADDING: 62 | ENABLED: True 63 | 64 | DATASETS: 65 | NAMES: ("MARSDL",) 66 | TESTS: ("MARSDL",) 67 | 68 | DATALOADER: 69 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 70 | NUM_INSTANCE: 4 71 | NUM_WORKERS: 8 72 | 73 | SOLVER: 74 | AMP: 75 | ENABLED: True 76 | OPT: SGD 77 | MAX_EPOCH: 30 78 | BASE_LR: 0.02 79 | BIAS_LR_FACTOR: 2. 80 | WEIGHT_DECAY: 1e-4 81 | WEIGHT_DECAY_BIAS: 1e-4 82 | IMS_PER_BATCH: 16 83 | 84 | SCHED: CosineAnnealingLR 85 | ETA_MIN_LR: 0.000016 86 | 87 | WARMUP_FACTOR: 0.01 88 | WARMUP_ITERS: 1000 89 | 90 | CLIP_GRADIENTS: 91 | ENABLED: True 92 | 93 | CHECKPOINT_PERIOD: 30 94 | 95 | TEST: 96 | EVAL_PERIOD: 5 97 | IMS_PER_BATCH: 16 98 | 99 | CUDNN_BENCHMARK: True 100 | 101 | TEMP: 102 | REDUCE: 'avg' 103 | DATA: 104 | DENSE: False 105 | SAMPLING_STEP: 32 106 | TRAIN: 107 | SAMPLER: 'TemporalRestrictedBeginCrop' 108 | SEQ_SIZE: 8 109 | STRIDE: 4 110 | TEST: 111 | ALL: False 112 | SEQ_SIZE: 8 113 | TRACK_SPLIT: 128 114 | 115 | CASCADE: 116 | PATCH1: (16, 16) 117 | STRIDE1: (12, 12) 118 | 119 | PATCH2: (32, 16) 120 | STRIDE2: (28, 12) 121 | 122 | PATCH3: (16, 32) 123 | STRIDE3: (12, 28) 124 | 125 | TPE: flow 126 | 127 | 128 | OUTPUT_DIR: logs/marsdl -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_prid2011.yml: -------------------------------------------------------------------------------- 1 | # _BASE_: ../VBASE_SBS.yml 2 | 3 | MODEL: 4 | META_ARCHITECTURE: CAViT 5 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 6 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 7 | 8 | BACKBONE: 9 | NAME: build_cavit_backbone 10 | DEPTH: base 11 | FEAT_DIM: 768 12 | PRETRAIN: True 13 | PRETRAIN_PATH: ../jx_vit_base_p16_224-80ecf9dd.pth 14 | STRIDE_SIZE: (16, 16) 15 | DROP_PATH_RATIO: 0.1 16 | DROP_RATIO: 0.0 17 | ATT_DROP_RATE: 0.0 18 | SHIFT_NUM: 5 19 | SHUFFLE_GROUP: 2 20 | DEVIDE_LENGTH: 4 21 | RE_ARRANGE: True 22 | LAYER_NUM: 10 23 | INFERENCE_DEPTH: 10 24 | NORM_OUT: True 25 | 26 | 27 | HEADS: 28 | NAME: TempHead 29 | NORM: BN 30 | WITH_BNNECK: True 31 | POOL_LAYER: Identity 32 | NECK_FEAT: before 33 | CLS_LAYER: CircleSoftmax 34 | SCALE: 64 35 | MARGIN: 0.3 36 | 37 | LOSSES: 38 | NAME: ("CrossEntropyLoss",) 39 | CE: 40 | EPSILON: 0.1 41 | SCALE: 1.0 42 | 43 | TRI: 44 | MARGIN: 0.0 45 | HARD_MINING: True 46 | NORM_FEAT: False 47 | SCALE: 1.0 48 | 49 | 50 | INPUT: 51 | SIZE_TRAIN: [ 256, 128 ] 52 | SIZE_TEST: [ 256, 128 ] 53 | 54 | REA: 55 | ENABLED: True 56 | PROB: 0.5 57 | 58 | FLIP: 59 | ENABLED: True 60 | 61 | PADDING: 62 | ENABLED: True 63 | 64 | DATASETS: 65 | NAMES: ("PRID2011",) 66 | TESTS: ("PRID2011",) 67 | 68 | DATALOADER: 69 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 70 | NUM_INSTANCE: 4 71 | NUM_WORKERS: 8 72 | 73 | SOLVER: 74 | AMP: 75 | ENABLED: True 76 | OPT: SGD 77 | MAX_EPOCH: 60 78 | BASE_LR: 0.01 79 | BIAS_LR_FACTOR: 2. 80 | WEIGHT_DECAY: 1e-4 81 | WEIGHT_DECAY_BIAS: 1e-4 82 | IMS_PER_BATCH: 16 83 | 84 | SCHED: CosineAnnealingLR 85 | ETA_MIN_LR: 0.000016 86 | 87 | WARMUP_FACTOR: 0.01 88 | WARMUP_ITERS: 100 89 | 90 | CLIP_GRADIENTS: 91 | ENABLED: True 92 | 93 | CHECKPOINT_PERIOD: 30 94 | 95 | TEST: 96 | EVAL_PERIOD: 5 97 | IMS_PER_BATCH: 16 98 | 99 | CUDNN_BENCHMARK: True 100 | 101 | TEMP: 102 | REDUCE: 'avg' 103 | DATA: 104 | DENSE: True 105 | SAMPLING_STEP: 32 106 | TRAIN: 107 | SAMPLER: 'TemporalRestrictedBeginCrop' 108 | SEQ_SIZE: 8 109 | STRIDE: 4 110 | TEST: 111 | ALL: False 112 | SEQ_SIZE: 10 113 | TRACK_SPLIT: 128 114 | 115 | CASCADE: 116 | PATCH1: (16, 16) 117 | STRIDE1: (12, 12) 118 | 119 | PATCH2: (32, 16) 120 | STRIDE2: (28, 12) 121 | 122 | PATCH3: (16, 32) 123 | STRIDE3: (12, 28) 124 | 125 | TPE: flow 126 | 127 | 128 | OUTPUT_DIR: logs/prid2011/ 129 | -------------------------------------------------------------------------------- /projects/CAViT/configs/cavit_vveri901.yml: -------------------------------------------------------------------------------- 1 | # _BASE_: ../VBASE_SBS.yml 2 | 3 | MODEL: 4 | META_ARCHITECTURE: CAViT 5 | PIXEL_MEAN: [ 127.5, 127.5, 127.5 ] 6 | PIXEL_STD: [ 127.5, 127.5, 127.5 ] 7 | 8 | BACKBONE: 9 | NAME: build_cavit_backbone 10 | DEPTH: base 11 | FEAT_DIM: 768 12 | PRETRAIN: True 13 | PRETRAIN_PATH: ../models/vit/jx_vit_base_p16_224-80ecf9dd.pth 14 | STRIDE_SIZE: (16, 16) 15 | DROP_PATH_RATIO: 0.1 16 | DROP_RATIO: 0.0 17 | ATT_DROP_RATE: 0.0 18 | SHIFT_NUM: 5 19 | SHUFFLE_GROUP: 2 20 | DEVIDE_LENGTH: 4 21 | RE_ARRANGE: True 22 | LAYER_NUM: 10 23 | INFERENCE_DEPTH: 10 24 | NORM_OUT: True 25 | 26 | 27 | HEADS: 28 | NAME: TempHead 29 | NORM: syncBN 30 | WITH_BNNECK: True 31 | POOL_LAYER: Identity 32 | NECK_FEAT: before 33 | CLS_LAYER: CircleSoftmax 34 | SCALE: 64 35 | MARGIN: 0.3 36 | 37 | LOSSES: 38 | NAME: ("CrossEntropyLoss",) 39 | CE: 40 | EPSILON: 0.1 41 | SCALE: 1.0 42 | 43 | TRI: 44 | MARGIN: 0.0 45 | HARD_MINING: True 46 | NORM_FEAT: False 47 | SCALE: 1.0 48 | 49 | 50 | INPUT: 51 | SIZE_TRAIN: [ 256, 128 ] 52 | SIZE_TEST: [ 256, 128 ] 53 | 54 | REA: 55 | ENABLED: True 56 | PROB: 0.5 57 | 58 | FLIP: 59 | ENABLED: True 60 | 61 | PADDING: 62 | ENABLED: True 63 | 64 | DATASETS: 65 | NAMES: ("VVERI901",) 66 | TESTS: ("VVERI901",) 67 | 68 | DATALOADER: 69 | SAMPLER_TRAIN: BalancedIdentitySamplerV2 70 | NUM_INSTANCE: 4 71 | NUM_WORKERS: 8 72 | 73 | SOLVER: 74 | AMP: 75 | ENABLED: True 76 | OPT: SGD 77 | MAX_EPOCH: 30 78 | BASE_LR: 0.02 79 | BIAS_LR_FACTOR: 2. 80 | WEIGHT_DECAY: 1e-4 81 | WEIGHT_DECAY_BIAS: 1e-4 82 | IMS_PER_BATCH: 16 83 | 84 | SCHED: CosineAnnealingLR 85 | ETA_MIN_LR: 0.000016 86 | 87 | WARMUP_FACTOR: 0.01 88 | WARMUP_ITERS: 1000 89 | 90 | CLIP_GRADIENTS: 91 | ENABLED: True 92 | 93 | CHECKPOINT_PERIOD: 30 94 | 95 | TEST: 96 | EVAL_PERIOD: 5 97 | IMS_PER_BATCH: 16 98 | 99 | CUDNN_BENCHMARK: True 100 | 101 | TEMP: 102 | REDUCE: 'avg' 103 | DATA: 104 | DENSE: True 105 | SAMPLING_STEP: 16 106 | TRAIN: 107 | SAMPLER: 'TemporalRestrictedBeginCrop' 108 | SEQ_SIZE: 8 109 | STRIDE: 4 110 | TEST: 111 | ALL: False 112 | SEQ_SIZE: 8 113 | TRACK_SPLIT: 128 114 | 115 | CASCADE: 116 | PATCH1: (16, 16) 117 | STRIDE1: (12, 12) 118 | 119 | PATCH2: (32, 16) 120 | STRIDE2: (28, 12) 121 | 122 | PATCH3: (16, 32) 123 | STRIDE3: (12, 28) 124 | 125 | TPE: flow 126 | 127 | 128 | OUTPUT_DIR: logs/vveri901 129 | -------------------------------------------------------------------------------- /projects/CAViT/train.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | import ipdb 5 | import torch 6 | import logging 7 | import sys 8 | 9 | sys.path.append('.') 10 | 11 | from fastreid.config import get_cfg 12 | from fastreid.engine import DefaultTrainer 13 | from fastreid.engine import default_argument_parser, default_setup, launch 14 | from fastreid.utils.checkpoint import Checkpointer 15 | 16 | from FastVideo import * 17 | 18 | class VideoTrainer(DefaultTrainer): 19 | 20 | @classmethod 21 | def build_train_loader(cls, cfg): 22 | train_loader = build_video_reid_train_loader(cfg) 23 | return train_loader 24 | 25 | @classmethod 26 | def build_test_loader(cls, cfg, dataset_name): 27 | test_loader, num_query = build_video_reid_test_loader(cfg, dataset_name=dataset_name) 28 | 29 | return test_loader, num_query 30 | 31 | 32 | @classmethod 33 | def build_evaluator(cls, cfg, dataset_name, output_dir=None): 34 | 35 | data_loader, num_query = build_video_reid_test_loader(cfg, dataset_name) 36 | 37 | return data_loader, NewVideoReidEvaluator(cfg, num_query, output_dir) 38 | 39 | 40 | def setup(args): 41 | """ 42 | Create configs and perform basic setups. 43 | """ 44 | cfg = get_cfg() 45 | add_temp_config(cfg) 46 | add_swin_config(cfg) 47 | add_vit_config(cfg) 48 | add_cascade_config(cfg) 49 | add_slowfast_config(cfg) 50 | cfg.merge_from_file(args.config_file) 51 | cfg.merge_from_list(args.opts) 52 | cfg.freeze() 53 | default_setup(cfg, args) 54 | return cfg 55 | 56 | 57 | def main(args): 58 | cfg = setup(args) 59 | 60 | if args.eval_only: 61 | cfg.defrost() 62 | cfg.MODEL.BACKBONE.PRETRAIN = False 63 | model = VideoTrainer.build_model(cfg) 64 | 65 | Checkpointer(model).load(cfg.MODEL.WEIGHTS) # load trained model 66 | 67 | res = VideoTrainer.test(cfg, model) 68 | return res 69 | 70 | trainer = VideoTrainer(cfg) 71 | 72 | # trainer.test(trainer.cfg, trainer.model) 73 | trainer.resume_or_load(resume=args.resume) 74 | return trainer.train() 75 | 76 | 77 | if __name__ == "__main__": 78 | args = default_argument_parser().parse_args() 79 | print("Command Line Args:", args) 80 | launch( 81 | main, 82 | args.num_gpus, 83 | num_machines=args.num_machines, 84 | machine_rank=args.machine_rank, 85 | dist_url=args.dist_url, 86 | args=(args,), 87 | ) 88 | 89 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | 2 | CUDA_VISIBLE_DEVICES=2,3,4,5 python3 projects/CAViT/train.py --config-file projects/CAViT/configs/cavit_prid2011.yml --num-gpus 4 3 | 4 | # CUDA_VISIBLE_DEVICES=2 python3 projects/CAViT/train.py --config-file projects/CAViT/configs/cavit_prid2011.yml --num-gpus 1 --eval-only MODEL.WEIGHTS logs/11.113/base4_shift-att-v12_prid2011/model_best.pth TEMP.TEST.ALL True 5 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: sherlock 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | -------------------------------------------------------------------------------- /tests/dataset_test.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: liaoxingyu 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import sys 8 | sys.path.append('.') 9 | from data import get_dataloader 10 | from config import cfg 11 | import argparse 12 | from data.datasets import init_dataset 13 | # cfg.DATALOADER.SAMPLER = 'triplet' 14 | cfg.DATASETS.NAMES = ("market1501", "dukemtmc", "cuhk03", "msmt17",) 15 | 16 | 17 | if __name__ == '__main__': 18 | parser = argparse.ArgumentParser(description="ReID Baseline Training") 19 | parser.add_argument( 20 | '-cfg', "--config_file", 21 | default="", 22 | metavar="FILE", 23 | help="path to config file", 24 | type=str 25 | ) 26 | # parser.add_argument("--local_rank", type=int, default=0) 27 | parser.add_argument("opts", help="Modify config options using the command-line", default=None, 28 | nargs=argparse.REMAINDER) 29 | args = parser.parse_args() 30 | cfg.merge_from_list(args.opts) 31 | 32 | # dataset = init_dataset('msmt17', combineall=True) 33 | get_dataloader(cfg) 34 | # tng_dataloader, val_dataloader, num_classes, num_query = get_dataloader(cfg) 35 | # def get_ex(): return open_image('datasets/beijingStation/query/000245_c10s2_1561732033722.000000.jpg') 36 | # im = get_ex() 37 | # print(data.train_ds[0]) 38 | # print(data.test_ds[0]) 39 | # a = next(iter(data.train_dl)) 40 | # from IPython import embed; embed() 41 | # from ipdb import set_trace; set_trace() 42 | # im.apply_tfms(crop_pad(size=(300, 300))) 43 | -------------------------------------------------------------------------------- /tests/feature_align.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | import os 4 | from glob import glob 5 | 6 | 7 | class TestFeatureAlign(unittest.TestCase): 8 | def test_caffe_pytorch_feat_align(self): 9 | caffe_feat_path = "/export/home/lxy/cvpalgo-fast-reid/tools/deploy/caffe_R50_output" 10 | pytorch_feat_path = "/export/home/lxy/cvpalgo-fast-reid/demo/logs/R50_256x128_pytorch_feat_output" 11 | feat_filenames = os.listdir(caffe_feat_path) 12 | for feat_name in feat_filenames: 13 | caffe_feat = np.load(os.path.join(caffe_feat_path, feat_name)) 14 | pytorch_feat = np.load(os.path.join(pytorch_feat_path, feat_name)) 15 | sim = np.dot(caffe_feat, pytorch_feat.transpose())[0][0] 16 | assert sim > 0.97, f"Got similarity {sim} and feature of {feat_name} is not aligned" 17 | 18 | def test_model_performance(self): 19 | caffe_feat_path = "/export/home/lxy/cvpalgo-fast-reid/tools/deploy/caffe_R50_output" 20 | feat_filenames = os.listdir(caffe_feat_path) 21 | feats = [] 22 | for feat_name in feat_filenames: 23 | caffe_feat = np.load(os.path.join(caffe_feat_path, feat_name)) 24 | feats.append(caffe_feat) 25 | from ipdb import set_trace; set_trace() 26 | 27 | 28 | 29 | if __name__ == '__main__': 30 | unittest.main() 31 | -------------------------------------------------------------------------------- /tests/interp_test.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from fastai.vision import * 3 | from fastai.basic_data import * 4 | from fastai.layers import * 5 | 6 | import sys 7 | sys.path.append('.') 8 | from engine.interpreter import ReidInterpretation 9 | 10 | from data import get_data_bunch 11 | from modeling import build_model 12 | from config import cfg 13 | cfg.DATASETS.NAMES = ('market1501',) 14 | cfg.DATASETS.TEST_NAMES = 'market1501' 15 | cfg.MODEL.BACKBONE = 'resnet50' 16 | 17 | data_bunch, test_labels, num_query = get_data_bunch(cfg) 18 | 19 | model = build_model(cfg, 10) 20 | model.load_params_wo_fc(torch.load('logs/2019.8.14/market/baseline/models/model_149.pth')['model']) 21 | learn = Learner(data_bunch, model) 22 | 23 | feats, _ = learn.get_preds(DatasetType.Test, activ=Lambda(lambda x: x)) -------------------------------------------------------------------------------- /tests/lr_scheduler_test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import unittest 3 | 4 | import torch 5 | from torch import nn 6 | 7 | sys.path.append('.') 8 | from solver.lr_scheduler import WarmupMultiStepLR 9 | from solver.build import make_optimizer 10 | from config import cfg 11 | 12 | 13 | class MyTestCase(unittest.TestCase): 14 | def test_something(self): 15 | net = nn.Linear(10, 10) 16 | optimizer = make_optimizer(cfg, net) 17 | lr_scheduler = WarmupMultiStepLR(optimizer, [20, 40], warmup_iters=10) 18 | for i in range(50): 19 | lr_scheduler.step() 20 | for j in range(3): 21 | print(i, lr_scheduler.get_lr()[0]) 22 | optimizer.step() 23 | 24 | 25 | if __name__ == '__main__': 26 | unittest.main() 27 | -------------------------------------------------------------------------------- /tests/model_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import torch 4 | 5 | import sys 6 | sys.path.append('.') 7 | from fastreid.config import cfg 8 | from fastreid.modeling.backbones import build_resnet_backbone 9 | from fastreid.modeling.backbones.resnet_ibn_a import se_resnet101_ibn_a 10 | from torch import nn 11 | 12 | 13 | class MyTestCase(unittest.TestCase): 14 | def test_se_resnet101(self): 15 | cfg.MODEL.BACKBONE.NAME = 'resnet101' 16 | cfg.MODEL.BACKBONE.DEPTH = 101 17 | cfg.MODEL.BACKBONE.WITH_IBN = True 18 | cfg.MODEL.BACKBONE.WITH_SE = True 19 | cfg.MODEL.BACKBONE.PRETRAIN_PATH = '/export/home/lxy/.cache/torch/checkpoints/se_resnet101_ibn_a.pth.tar' 20 | 21 | net1 = build_resnet_backbone(cfg) 22 | net1.cuda() 23 | net2 = nn.DataParallel(se_resnet101_ibn_a()) 24 | res = net2.load_state_dict(torch.load(cfg.MODEL.BACKBONE.PRETRAIN_PATH)['state_dict'], strict=False) 25 | net2.cuda() 26 | x = torch.randn(10, 3, 256, 128).cuda() 27 | y1 = net1(x) 28 | y2 = net2(x) 29 | assert y1.sum() == y2.sum(), 'train mode problem' 30 | net1.eval() 31 | net2.eval() 32 | y1 = net1(x) 33 | y2 = net2(x) 34 | assert y1.sum() == y2.sum(), 'eval mode problem' 35 | 36 | 37 | if __name__ == '__main__': 38 | unittest.main() 39 | -------------------------------------------------------------------------------- /tests/sampler_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import sys 3 | sys.path.append('.') 4 | from fastreid.data.samplers import TrainingSampler 5 | 6 | 7 | class SamplerTestCase(unittest.TestCase): 8 | def test_training_sampler(self): 9 | sampler = TrainingSampler(5) 10 | for i in sampler: 11 | from ipdb import set_trace; set_trace() 12 | print(i) 13 | 14 | 15 | if __name__ == '__main__': 16 | unittest.main() 17 | -------------------------------------------------------------------------------- /tests/test_repvgg.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import unittest 3 | 4 | import torch 5 | 6 | sys.path.append('.') 7 | from fastreid.config import get_cfg 8 | from fastreid.modeling.backbones import build_backbone 9 | 10 | 11 | class MyTestCase(unittest.TestCase): 12 | def test_fusebn(self): 13 | cfg = get_cfg() 14 | cfg.defrost() 15 | cfg.MODEL.BACKBONE.NAME = 'build_repvgg_backbone' 16 | cfg.MODEL.BACKBONE.DEPTH = 'B1g2' 17 | cfg.MODEL.BACKBONE.PRETRAIN = False 18 | model = build_backbone(cfg) 19 | model.eval() 20 | 21 | test_inp = torch.randn((1, 3, 256, 128)) 22 | 23 | y = model(test_inp) 24 | 25 | model.deploy(mode=True) 26 | from ipdb import set_trace; set_trace() 27 | fused_y = model(test_inp) 28 | 29 | print("final error :", torch.max(torch.abs(fused_y - y)).item()) 30 | 31 | 32 | if __name__ == '__main__': 33 | unittest.main() 34 | -------------------------------------------------------------------------------- /tools/deploy/Caffe/ReadMe.md: -------------------------------------------------------------------------------- 1 | # The Caffe in nn_tools Provides some convenient API 2 | If there are some problem in parse your prototxt or caffemodel, Please replace 3 | the caffe.proto with your own version and compile it with command 4 | `protoc --python_out ./ caffe.proto` 5 | 6 | ## caffe_net.py 7 | Using `from nn_tools.Caffe import caffe_net` to import this model 8 | ### Prototxt 9 | + `net=caffe_net.Prototxt(file_name)` to open a prototxt file 10 | + `net.init_caffemodel(caffe_cmd_path='caffe')` to generate a caffemodel file in the current work directory \ 11 | if your `caffe` cmd not in the $PATH, specify your caffe cmd path by the `caffe_cmd_path` kwargs. 12 | ### Caffemodel 13 | + `net=caffe_net.Caffemodel(file_name)` to open a caffemodel 14 | + `net.save_prototxt(path)` to save the caffemodel to a prototxt file (not containing the weight data) 15 | + `net.get_layer_data(layer_name)` return the numpy ndarray data of the layer 16 | + `net.set_layer_date(layer_name, datas)` specify the data of one layer in the caffemodel .`datas` is normally a list of numpy ndarray `[weights,bias]` 17 | + `net.save(path)` save the changed caffemodel 18 | ### Functions for both Prototxt and Caffemodel 19 | + `net.add_layer(layer_params,before='',after='')` add a new layer with `Layer_Param` object 20 | + `net.remove_layer_by_name(layer_name)` 21 | + `net.get_layer_by_name(layer_name)` or `net.layer(layer_name)` get the raw Layer object defined in caffe_pb2 22 | -------------------------------------------------------------------------------- /tools/deploy/Caffe/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/tools/deploy/Caffe/__init__.py -------------------------------------------------------------------------------- /tools/deploy/Caffe/caffe_lmdb.py: -------------------------------------------------------------------------------- 1 | import lmdb 2 | from Caffe import caffe_pb2 as pb2 3 | import numpy as np 4 | 5 | class Read_Caffe_LMDB(): 6 | def __init__(self,path,dtype=np.uint8): 7 | 8 | self.env=lmdb.open(path, readonly=True) 9 | self.dtype=dtype 10 | self.txn=self.env.begin() 11 | self.cursor=self.txn.cursor() 12 | 13 | @staticmethod 14 | def to_numpy(value,dtype=np.uint8): 15 | datum = pb2.Datum() 16 | datum.ParseFromString(value) 17 | flat_x = np.fromstring(datum.data, dtype=dtype) 18 | data = flat_x.reshape(datum.channels, datum.height, datum.width) 19 | label=flat_x = datum.label 20 | return data,label 21 | 22 | def iterator(self): 23 | while True: 24 | key,value=self.cursor.key(),self.cursor.value() 25 | yield self.to_numpy(value,self.dtype) 26 | if not self.cursor.next(): 27 | return 28 | 29 | def __iter__(self): 30 | self.cursor.first() 31 | it = self.iterator() 32 | return it 33 | 34 | def __len__(self): 35 | return int(self.env.stat()['entries']) 36 | -------------------------------------------------------------------------------- /tools/deploy/Caffe/net.py: -------------------------------------------------------------------------------- 1 | raise ImportError("the nn_tools.Caffe.net is no longer used, please use nn_tools.Caffe.caffe_net") 2 | 3 | -------------------------------------------------------------------------------- /tools/deploy/caffe_export.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import argparse 8 | import logging 9 | import sys 10 | 11 | import torch 12 | 13 | sys.path.append('.') 14 | 15 | import pytorch_to_caffe 16 | from fastreid.config import get_cfg 17 | from fastreid.modeling.meta_arch import build_model 18 | from fastreid.utils.file_io import PathManager 19 | from fastreid.utils.checkpoint import Checkpointer 20 | from fastreid.utils.logger import setup_logger 21 | 22 | # import some modules added in project like this below 23 | # sys.path.append("projects/PartialReID") 24 | # from partialreid import * 25 | 26 | setup_logger(name='fastreid') 27 | logger = logging.getLogger("fastreid.caffe_export") 28 | 29 | 30 | def setup_cfg(args): 31 | cfg = get_cfg() 32 | cfg.merge_from_file(args.config_file) 33 | cfg.merge_from_list(args.opts) 34 | cfg.freeze() 35 | return cfg 36 | 37 | 38 | def get_parser(): 39 | parser = argparse.ArgumentParser(description="Convert Pytorch to Caffe model") 40 | 41 | parser.add_argument( 42 | "--config-file", 43 | metavar="FILE", 44 | help="path to config file", 45 | ) 46 | parser.add_argument( 47 | "--name", 48 | default="baseline", 49 | help="name for converted model" 50 | ) 51 | parser.add_argument( 52 | "--output", 53 | default='caffe_model', 54 | help='path to save converted caffe model' 55 | ) 56 | parser.add_argument( 57 | "--opts", 58 | help="Modify config options using the command-line 'KEY VALUE' pairs", 59 | default=[], 60 | nargs=argparse.REMAINDER, 61 | ) 62 | return parser 63 | 64 | 65 | if __name__ == '__main__': 66 | args = get_parser().parse_args() 67 | cfg = setup_cfg(args) 68 | 69 | cfg.defrost() 70 | cfg.MODEL.BACKBONE.PRETRAIN = False 71 | cfg.MODEL.HEADS.POOL_LAYER = "Identity" 72 | cfg.MODEL.BACKBONE.WITH_NL = False 73 | 74 | model = build_model(cfg) 75 | Checkpointer(model).load(cfg.MODEL.WEIGHTS) 76 | model.eval() 77 | logger.info(model) 78 | 79 | inputs = torch.randn(1, 3, cfg.INPUT.SIZE_TEST[0], cfg.INPUT.SIZE_TEST[1]).to(torch.device(cfg.MODEL.DEVICE)) 80 | PathManager.mkdirs(args.output) 81 | pytorch_to_caffe.trans_net(model, inputs, args.name) 82 | pytorch_to_caffe.save_prototxt(f"{args.output}/{args.name}.prototxt") 83 | pytorch_to_caffe.save_caffemodel(f"{args.output}/{args.name}.caffemodel") 84 | 85 | logger.info(f"Export caffe model in {args.output} sucessfully!") 86 | -------------------------------------------------------------------------------- /tools/deploy/caffe_inference.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import caffe 8 | import tqdm 9 | import glob 10 | import os 11 | import cv2 12 | import numpy as np 13 | 14 | caffe.set_mode_gpu() 15 | 16 | import argparse 17 | 18 | 19 | def get_parser(): 20 | parser = argparse.ArgumentParser(description="Caffe model inference") 21 | 22 | parser.add_argument( 23 | "--model-def", 24 | default="logs/test_caffe/baseline_R50.prototxt", 25 | help="caffe model prototxt" 26 | ) 27 | parser.add_argument( 28 | "--model-weights", 29 | default="logs/test_caffe/baseline_R50.caffemodel", 30 | help="caffe model weights" 31 | ) 32 | parser.add_argument( 33 | "--input", 34 | nargs="+", 35 | help="A list of space separated input images; " 36 | "or a single glob pattern such as 'directory/*.jpg'", 37 | ) 38 | parser.add_argument( 39 | "--output", 40 | default='caffe_output', 41 | help='path to save converted caffe model' 42 | ) 43 | parser.add_argument( 44 | "--height", 45 | type=int, 46 | default=256, 47 | help="height of image" 48 | ) 49 | parser.add_argument( 50 | "--width", 51 | type=int, 52 | default=128, 53 | help="width of image" 54 | ) 55 | return parser 56 | 57 | 58 | def preprocess(image_path, image_height, image_width): 59 | original_image = cv2.imread(image_path) 60 | # the model expects RGB inputs 61 | original_image = original_image[:, :, ::-1] 62 | 63 | # Apply pre-processing to image. 64 | image = cv2.resize(original_image, (image_width, image_height), interpolation=cv2.INTER_CUBIC) 65 | image = image.astype("float32").transpose(2, 0, 1)[np.newaxis] # (1, 3, h, w) 66 | image = (image - np.array([0.485 * 255, 0.456 * 255, 0.406 * 255]).reshape((1, -1, 1, 1))) / np.array( 67 | [0.229 * 255, 0.224 * 255, 0.225 * 255]).reshape((1, -1, 1, 1)) 68 | return image 69 | 70 | 71 | def normalize(nparray, order=2, axis=-1): 72 | """Normalize a N-D numpy array along the specified axis.""" 73 | norm = np.linalg.norm(nparray, ord=order, axis=axis, keepdims=True) 74 | return nparray / (norm + np.finfo(np.float32).eps) 75 | 76 | 77 | if __name__ == "__main__": 78 | args = get_parser().parse_args() 79 | 80 | net = caffe.Net(args.model_def, args.model_weights, caffe.TEST) 81 | net.blobs['blob1'].reshape(1, 3, args.height, args.width) 82 | 83 | if not os.path.exists(args.output): os.makedirs(args.output) 84 | 85 | if args.input: 86 | if os.path.isdir(args.input[0]): 87 | args.input = glob.glob(os.path.expanduser(args.input[0])) 88 | assert args.input, "The input path(s) was not found" 89 | for path in tqdm.tqdm(args.input): 90 | image = preprocess(path, args.height, args.width) 91 | net.blobs["blob1"].data[...] = image 92 | feat = net.forward()["output"] 93 | feat = normalize(feat[..., 0, 0], axis=1) 94 | np.save(os.path.join(args.output, os.path.basename(path).split('.')[0] + '.npy'), feat) 95 | 96 | -------------------------------------------------------------------------------- /tools/deploy/onnx_inference.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | """ 3 | @author: xingyu liao 4 | @contact: sherlockliao01@gmail.com 5 | """ 6 | 7 | import argparse 8 | import glob 9 | import os 10 | 11 | import cv2 12 | import numpy as np 13 | import onnxruntime 14 | import tqdm 15 | 16 | 17 | def get_parser(): 18 | parser = argparse.ArgumentParser(description="onnx model inference") 19 | 20 | parser.add_argument( 21 | "--model-path", 22 | default="onnx_model/baseline.onnx", 23 | help="onnx model path" 24 | ) 25 | parser.add_argument( 26 | "--input", 27 | nargs="+", 28 | help="A list of space separated input images; " 29 | "or a single glob pattern such as 'directory/*.jpg'", 30 | ) 31 | parser.add_argument( 32 | "--output", 33 | default='onnx_output', 34 | help='path to save converted caffe model' 35 | ) 36 | parser.add_argument( 37 | "--height", 38 | type=int, 39 | default=256, 40 | help="height of image" 41 | ) 42 | parser.add_argument( 43 | "--width", 44 | type=int, 45 | default=128, 46 | help="width of image" 47 | ) 48 | return parser 49 | 50 | 51 | def preprocess(image_path, image_height, image_width): 52 | original_image = cv2.imread(image_path) 53 | # the model expects RGB inputs 54 | original_image = original_image[:, :, ::-1] 55 | 56 | # Apply pre-processing to image. 57 | img = cv2.resize(original_image, (image_width, image_height), interpolation=cv2.INTER_CUBIC) 58 | img = img.astype("float32").transpose(2, 0, 1)[np.newaxis] # (1, 3, h, w) 59 | return img 60 | 61 | 62 | def normalize(nparray, order=2, axis=-1): 63 | """Normalize a N-D numpy array along the specified axis.""" 64 | norm = np.linalg.norm(nparray, ord=order, axis=axis, keepdims=True) 65 | return nparray / (norm + np.finfo(np.float32).eps) 66 | 67 | 68 | if __name__ == "__main__": 69 | args = get_parser().parse_args() 70 | 71 | ort_sess = onnxruntime.InferenceSession(args.model_path) 72 | 73 | input_name = ort_sess.get_inputs()[0].name 74 | 75 | if not os.path.exists(args.output): os.makedirs(args.output) 76 | 77 | if args.input: 78 | if os.path.isdir(args.input[0]): 79 | args.input = glob.glob(os.path.expanduser(args.input[0])) 80 | assert args.input, "The input path(s) was not found" 81 | for path in tqdm.tqdm(args.input): 82 | image = preprocess(path, args.height, args.width) 83 | feat = ort_sess.run(None, {input_name: image})[0] 84 | feat = normalize(feat, axis=1) 85 | np.save(os.path.join(args.output, path.replace('.jpg', '.npy').split('/')[-1]), feat) 86 | -------------------------------------------------------------------------------- /tools/deploy/test_data/0022_c6s1_002976_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/tools/deploy/test_data/0022_c6s1_002976_01.jpg -------------------------------------------------------------------------------- /tools/deploy/test_data/0027_c2s2_091032_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/tools/deploy/test_data/0027_c2s2_091032_02.jpg -------------------------------------------------------------------------------- /tools/deploy/test_data/0032_c6s1_002851_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/tools/deploy/test_data/0032_c6s1_002851_01.jpg -------------------------------------------------------------------------------- /tools/deploy/test_data/0048_c1s1_005351_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/tools/deploy/test_data/0048_c1s1_005351_01.jpg -------------------------------------------------------------------------------- /tools/deploy/test_data/0065_c6s1_009501_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KimWu1994/CAViT/891bfdf161bd16a3e2cc532f2d1e381bbc085683/tools/deploy/test_data/0065_c6s1_009501_02.jpg -------------------------------------------------------------------------------- /tools/train_net.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | @author: sherlock 5 | @contact: sherlockliao01@gmail.com 6 | """ 7 | 8 | import sys 9 | 10 | sys.path.append('.') 11 | 12 | from fastreid.config import get_cfg 13 | from fastreid.engine import DefaultTrainer, default_argument_parser, default_setup, launch 14 | from fastreid.utils.checkpoint import Checkpointer 15 | 16 | 17 | def setup(args): 18 | """ 19 | Create configs and perform basic setups. 20 | """ 21 | cfg = get_cfg() 22 | cfg.merge_from_file(args.config_file) 23 | cfg.merge_from_list(args.opts) 24 | cfg.freeze() 25 | default_setup(cfg, args) 26 | return cfg 27 | 28 | 29 | def main(args): 30 | cfg = setup(args) 31 | 32 | if args.eval_only: 33 | cfg.defrost() 34 | cfg.MODEL.BACKBONE.PRETRAIN = False 35 | model = DefaultTrainer.build_model(cfg) 36 | 37 | Checkpointer(model).load(cfg.MODEL.WEIGHTS) # load trained model 38 | 39 | res = DefaultTrainer.test(cfg, model) 40 | return res 41 | 42 | trainer = DefaultTrainer(cfg) 43 | 44 | trainer.resume_or_load(resume=args.resume) 45 | return trainer.train() 46 | 47 | 48 | if __name__ == "__main__": 49 | args = default_argument_parser().parse_args() 50 | print("Command Line Args:", args) 51 | launch( 52 | main, 53 | args.num_gpus, 54 | num_machines=args.num_machines, 55 | machine_rank=args.machine_rank, 56 | dist_url=args.dist_url, 57 | args=(args,), 58 | ) 59 | --------------------------------------------------------------------------------