SAFECount

October 10, 2023 ยท View on GitHub

Official PyTorch Implementation of Few-shot Object Counting with Similarity-Aware Feature Enhancement, Accepted by WACV 2023.

SAFECount Image text

1. Quick Start

1.1 FSC147 in Original Setting

  • Create the FSC147 dataset directory. Download the FSC147 dataset from here. Unzip the file and move some to ./data/FSC147_384_V2/. The FSC147 dataset directory should be as follows.
|-- data
    |-- FSC147_384_V2
        |-- images_384_VarV2
        |-- gt_density_map_adaptive_384_VarV2
        |-- train.json
        |-- val.json
        |-- test.json
        |-- fold0.json
        |-- fold1.json
        |-- fold2.json
        |-- fold3.json
  • cd the experiment directory by running cd ./experiments/FSC147/.

  • Train, eval, or test by running:

    (1) For slurm group: sh train.sh #NUM_GPUS #PARTITION, sh eval.sh #NUM_GPUS #PARTITION, or sh test.sh #NUM_GPUS #PARTITION.

    (2) For torch.distributed.launch: sh train_torch.sh #NUM_GPUS #GPU_IDS, sh eval_torch.sh #NUM_GPUS #GPU_IDS, or sh test_torch.sh #NUM_GPUS #GPU_IDS, e.g., train with GPU 1,3,4,6 (4 GPU in total): sh train_torch.sh 4 1,3,4,6.

    Note: During eval or test, please set config.saver.load_path to load the checkpoints.

  • Results and checkpoints.

PlatformVal MAEVal RMSETest MAETest RMSECheckpoints
8 GPUs (NVIDIA Tesla V100 16GB)14.4251.7213.5691.30here

1.2 FSC147 in Cross Validation Setting

Here we provide one example (3 shot, fold0 as val set), and others are similar.

  • Create the FSC147 dataset directory, the same as in 1.1.

  • cd the experiment directory by running cd experiments/FSC147_fold/3shot/fold0/.

  • Train or eval by running:

    (1) For slurm group: sh train.sh #NUM_GPUS #PARTITION or sh eval.sh #NUM_GPUS #PARTITION.

    (2) For torch.distributed.launch: sh train_torch.sh #NUM_GPUS #GPU_IDS or sh eval_torch.sh #NUM_GPUS #GPU_IDS.

    Note: During eval or test, please set config.saver.load_path to load the checkpoints.

  • Results. Training on 8 GPUs (NVIDIA Tesla V100 16GB) results in following performance.

ShotVal FoldVal MAEVal RMSEShotVal FoldVal MAEVal RMSE
1015.6251.203013.8443.99
117.1415.77316.2913.89
1214.0592.483211.1986.81
1313.8838.383311.7333.85

1.3 Cross-dataset Generalization (FSC147 to CARPK)

  • Create the FSC147 & CARPK dataset directory, the same as in 1.1 & 1.4.

  • cd the experiment directory by running cd experiments/FSC147_to_CARPK/.

  • Pretrain, finetune, or eval. The pretrain, finetune, or eval are similar to FSC147.

  • Results. Training on 8 GPUs (NVIDIA Tesla V100 16GB) results in following performance.

MAE (pretrain on FSC147)RMSE (pretrain on FSC147)MAE (finetune on CARPK)RMSE (finetune on CARPK)
17.7820.954.916.32

1.4 Class-specific Counting

The train and eval of class-specific counting are similar to FSC147. Here we only provide the construction of the dataset directory. The checkpoints (trained on 8 NVIDIA Tesla V100 16GB GPUs) and the corresponding results are given.

CARPKPUCPR+UCSDMallShanghaiTech PartAShanghaiTech PartB
MAE4.912.241.011.7774.369.75
RMSE6.323.441.342.24121.1515.87
checkpointsherehereherehereherehere

1) CARPK

  • Download the CARPK dataset from here. Unzip the file and move some to ./data/CARPK_devkit/. The CARPK dataset directory should be as follows.
|-- data
    |-- CARPK_devkit
        |-- Images
        |-- gen_gt_density.py
        |-- train.json
        |-- test.json
        |-- exemplar.json
  • run python gen_gt_density.py to generate ground-truth density map. The ground-truth density map will be saved to ./data/CARPK_devkit/gt_density_map/.

2) PUCPR+

  • Download the PUCPR+ dataset from here. Unzip the file and move some to ./data/PUCPR+_devkit/. The PUCPR+ dataset directory should be as follows.
|-- data
    |-- PUCPR+_devkit
        |-- Images
        |-- gen_gt_density.py
        |-- train.json
        |-- test.json
        |-- exemplar.json
  • run python gen_gt_density.py to generate ground-truth density map. The ground-truth density map will be saved to ./data/PUCPR+_devkit/gt_density_map/.

3) UCSD

  • Download the UCSD dataset from here. Unzip the file and move some to ./data/UCSD/. The UCSD dataset directory should be as follows.
|-- data
    |-- UCSD
        |-- ucsdpeds_vidf
        |-- gen_gt_density.py
        |-- train.json
        |-- test.json
        |-- exemplar.json
        |-- mask.png
  • We use the annotations in vidf-cvpr.zip, which corresponds to 10 directories (from ucsdpeds_vidf/video/vidf/vidf1_33_000.y/ to ucsdpeds_vidf/video/vidf/vidf1_33_009.y/). Merge all images under these 10 directories to ucsdpeds_vidf/video/vidf/. Other directories could be removed.

  • run python gen_gt_density.py to generate ground-truth density map. The ground-truth density map will be saved to ./data/UCSD/gt_density_map/.

4) Mall

  • Download the Mall dataset from here. Unzip the file and move some to ./data/Mall/. The Mall dataset directory should be as follows.
|-- data
    |-- Mall
        |-- frames
        |-- gen_gt_density.py
        |-- train.json
        |-- test.json
        |-- exemplar.json
        |-- mask.png
  • run python gen_gt_density.py to generate ground-truth density map. The ground-truth density map will be saved to ./data/Mall/gt_density_map/.

5) ShanghaiTech

  • Download the ShanghaiTech dataset from here. Unzip the file and move some to ./data/ShanghaiTech/. The ShanghaiTech dataset directory should be as follows.
|-- data
    |-- ShanghaiTech
        |-- part_A
            |-- train_data
                |-- images
            |-- test_data
                |-- images
            |-- gen_gt_density.py
            |-- train.json
            |-- test.json
            |-- exemplar.json
        |-- part_B
            |-- train_data
                |-- images
            |-- test_data
                |-- images
            |-- gen_gt_density.py
            |-- train.json
            |-- test.json
            |-- exemplar.json
  • run python gen_gt_density.py to generate ground-truth density map. Note that you should run this twice for both part_A and part_B. The ground-truth density map will be saved to (1) ./data/ShanghaiTech/part_A/train_data/gt_density_map/, (2) ./data/ShanghaiTech/part_A/test_data/gt_density_map/, (3) ./data/ShanghaiTech/part_B/train_data/gt_density_map/, (4) ./data/ShanghaiTech/part_B/test_data/gt_density_map/.

2. Learn More About Our Methods

  • We provide two datasets: custom_dataset.py & custom_exemplar_dataset.py, and three models: safecount.py, safecount_exemplar.py, & safecount_crossdataset.py. They should be cooperated and used as follows.
datasetmodelcircumstance
custom_dataset.pysafecount.pyThe support images are parts of the query image, and annotated by bounding boxes, e.g., FSC147.
custom_exemplar_dataset.pysafecount_exemplar.pyThe support images are sampled then fixed, and not parts of the query image, e.g., CARPK, PUCPR+, UCSD, Mall, and ShanghaiTech.
custom_dataset.pysafecount_crossdataset.pyIn cross-dataset generalization, pretraining a model on FSC147 and finetuning on class-specific counting.

3. Questions

  • CUDA Out of Memory.

    (1). Choose a smaller image size (config.dataset.input_size).

    (2). Set a smaller exemplar number (config.dataset.shot for FSC147, config.dataset.exemplar.num_exemplar for class-specific counting).

    (3). Set a larger out_stride (config.net.kwargs.backbone.out_stride), but you also need to revise the Regressor (in models.utils.py) to upsample the feature to the original image size.