Home

Awesome

Beyond Part Models: Person Retrieval with Refined Part Pooling

Related Projects: Strong Triplet Loss Baseline

This project implements PCB (Part-based Convolutional Baseline) of paper Beyond Part Models: Person Retrieval with Refined Part Pooling using pytorch.

Current Results

The reproduced PCB is as follows.

Rank-1 (%)mAP (%)R.R. Rank-1 (%)R.R. mAP (%)
Market1501 (Shared 1x1 Conv)90.8673.2592.5888.02
Market1501 (Independent 1x1 Conv)92.8778.5493.9490.17
Market1501 (Paper)92.4077.30--
Duke (Shared 1x1 Conv)82.0064.8886.4081.77
Duke (Independent 1x1 Conv)84.4769.9488.7884.73
Duke (Paper)81.9065.30--
CUHK03 (Shared 1x1 Conv)47.2942.0556.5057.91
CUHK03 (Independent 1x1 Conv)59.1453.9369.0770.17
CUHK03 (Paper)61.3054.20--

We can see that independent 1x1 conv layers for different stripes are critical for the performance. The performance on CUHK03 is still worse than the paper, while those on Market1501 and Duke are better.

Resources

This repository contains following resources

Installation

It's recommended that you create and enter a python virtual environment, if versions of the packages required here conflict with yours.

I use Python 2.7 and Pytorch 0.3. For installing Pytorch, follow the official guide. Other packages are specified in requirements.txt.

pip install -r requirements.txt

Then clone the repository:

git clone https://github.com/huanghoujing/beyond-part-models.git
cd beyond-part-models

Dataset Preparation

Inspired by Tong Xiao's open-reid project, dataset directories are refactored to support a unified dataset interface.

Transformed dataset has following features

Market1501

You can download what I have transformed for the project from Google Drive or BaiduYun. Otherwise, you can download the original dataset and transform it using my script, described below.

Download the Market1501 dataset from here. Run the following script to transform the dataset, replacing the paths with yours.

python script/dataset/transform_market1501.py \
--zip_file ~/Dataset/market1501/Market-1501-v15.09.15.zip \
--save_dir ~/Dataset/market1501

CUHK03

We follow the new training/testing protocol proposed in paper

@article{zhong2017re,
  title={Re-ranking Person Re-identification with k-reciprocal Encoding},
  author={Zhong, Zhun and Zheng, Liang and Cao, Donglin and Li, Shaozi},
  booktitle={CVPR},
  year={2017}
}

Details of the new protocol can be found here.

You can download what I have transformed for the project from Google Drive or BaiduYun. Otherwise, you can download the original dataset and transform it using my script, described below.

Download the CUHK03 dataset from here. Then download the training/testing partition file from Google Drive or BaiduYun. This partition file specifies which images are in training, query or gallery set. Finally run the following script to transform the dataset, replacing the paths with yours.

python script/dataset/transform_cuhk03.py \
--zip_file ~/Dataset/cuhk03/cuhk03_release.zip \
--train_test_partition_file ~/Dataset/cuhk03/re_ranking_train_test_split.pkl \
--save_dir ~/Dataset/cuhk03

DukeMTMC-reID

You can download what I have transformed for the project from Google Drive or BaiduYun. Otherwise, you can download the original dataset and transform it using my script, described below.

Download the DukeMTMC-reID dataset from here. Run the following script to transform the dataset, replacing the paths with yours.

python script/dataset/transform_duke.py \
--zip_file ~/Dataset/duke/DukeMTMC-reID.zip \
--save_dir ~/Dataset/duke

Combining Trainval Set of Market1501, CUHK03, DukeMTMC-reID

Larger training set tends to benefit deep learning models, so I combine trainval set of three datasets Market1501, CUHK03 and DukeMTMC-reID. After training on the combined trainval set, the model can be tested on three test sets as usual.

Transform three separate datasets as introduced above if you have not done it.

For the trainval set, you can download what I have transformed from Google Drive or BaiduYun. Otherwise, you can run the following script to combine the trainval sets, replacing the paths with yours.

python script/dataset/combine_trainval_sets.py \
--market1501_im_dir ~/Dataset/market1501/images \
--market1501_partition_file ~/Dataset/market1501/partitions.pkl \
--cuhk03_im_dir ~/Dataset/cuhk03/detected/images \
--cuhk03_partition_file ~/Dataset/cuhk03/detected/partitions.pkl \
--duke_im_dir ~/Dataset/duke/images \
--duke_partition_file ~/Dataset/duke/partitions.pkl \
--save_dir ~/Dataset/market1501_cuhk03_duke

Configure Dataset Path

The project requires you to configure the dataset paths. In bpm/dataset/__init__.py, modify the following snippet according to your saving paths used in preparing datasets.

# In file bpm/dataset/__init__.py

########################################
# Specify Directory and Partition File #
########################################

if name == 'market1501':
  im_dir = ospeu('~/Dataset/market1501/images')
  partition_file = ospeu('~/Dataset/market1501/partitions.pkl')

elif name == 'cuhk03':
  im_type = ['detected', 'labeled'][0]
  im_dir = ospeu(ospj('~/Dataset/cuhk03', im_type, 'images'))
  partition_file = ospeu(ospj('~/Dataset/cuhk03', im_type, 'partitions.pkl'))

elif name == 'duke':
  im_dir = ospeu('~/Dataset/duke/images')
  partition_file = ospeu('~/Dataset/duke/partitions.pkl')

elif name == 'combined':
  assert part in ['trainval'], \
    "Only trainval part of the combined dataset is available now."
  im_dir = ospeu('~/Dataset/market1501_cuhk03_duke/trainval_images')
  partition_file = ospeu('~/Dataset/market1501_cuhk03_duke/partitions.pkl')

Evaluation Protocol

Datasets used in this project all follow the standard evaluation protocol of Market1501, using CMC and mAP metric. According to open-reid, the setting of CMC is as follows

# In file bpm/dataset/__init__.py

cmc_kwargs = dict(separate_camera_set=False,
                  single_gallery_shot=False,
                  first_match_break=True)

To play with different CMC options, you can modify it accordingly.

# In open-reid's reid/evaluators.py

# Compute all kinds of CMC scores
cmc_configs = {
  'allshots': dict(separate_camera_set=False,
                   single_gallery_shot=False,
                   first_match_break=False),
  'cuhk03': dict(separate_camera_set=True,
                 single_gallery_shot=True,
                 first_match_break=False),
  'market1501': dict(separate_camera_set=False,
                     single_gallery_shot=False,
                     first_match_break=True)}

Examples

Test PCB

My training log and saved model weights (trained with independent 1x1 conv) for three datasets can be downloaded from Google Drive or BaiduYun.

Specify

in the following command and run it.

python script/experiment/train_pcb.py \
-d '(0,)' \
--only_test true \
--dataset DATASET_NAME \
--exp_dir EXPERIMENT_DIRECTORY \
--model_weight_file THE_DOWNLOADED_MODEL_WEIGHT_FILE

Train PCB

You can also train it by yourself. The following command performs training, validation and finally testing automatically.

Specify

in the following command and run it.

python script/experiment/train_pcb.py \
-d '(0,)' \
--only_test false \
--dataset DATASET_NAME \
--trainset_part TRAINVAL_OR_TRAIN \
--exp_dir EXPERIMENT_DIRECTORY \
--steps_per_log 20 \
--epochs_per_val 1

Log

During training, you can run the TensorBoard and access port 6006 to watch the loss curves etc. E.g.

# Modify the path for `--logdir` accordingly.
tensorboard --logdir YOUR_EXPERIMENT_DIRECTORY/tensorboard

For more usage of TensorBoard, see the website and the help:

tensorboard --help

Visualize Ranking List

Specify

in the following command and run it.

python script/experiment/visualize_rank_list.py \
-d '(0,)' \
--num_queries 16 \
--rank_list_size 10 \
--dataset DATASET_NAME \
--exp_dir EXPERIMENT_DIRECTORY \
--model_weight_file '' \
--ckpt_file ''

Each query image and its ranking list would be saved to an image in directory EXPERIMENT_DIRECTORY/rank_lists. As shown in following examples, green boundary is added to true positive, and red to false positve.

Time and Space Consumption

Test with CentOS 7, Intel(R) Xeon(R) CPU E5-2618L v3 @ 2.30GHz, GeForce GTX TITAN X.

Note that the following time consumption is not gauranteed across machines, especially when the system is busy.

GPU Consumption in Training

For following settings

it occupies ~11000MB GPU memory.

If not having a 12 GB GPU, you can decrease batch_size or use multiple GPUs.

Training Time

Taking Market1501 as an example, it contains 31969 training images; each epoch takes ~205s; training for 60 epochs takes ~3.5 hours.

Testing Time

Taking Market1501 as an example

References & Credits