Skip to content

Taylor3691/person-reidentification

 
 

Repository files navigation

CA-Jaccard

This repository contains a working CA-Jaccard person re-identification setup and a Gradio demo app for interactive retrieval, re-ranking, and visualization.

All commands assume they are run from the repository root with the project environment active.

Prerequisites

Environment Setup

Create a Python 3.11+ environment, activate it, and install the required packages:

python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -r requirements.txt

For faster package resolution and installation, you can use uv:

pip install uv
uv pip install -r requirements.txt

Dataset Downloads

The demo app only requires Market1501:

python scripts/download_datasets.py market1501

By default, archives are stored in data/_downloads and Market1501 is extracted to:

  • data/market1501/Market-1501-v15.09.15

Downloaded archives are removed after successful extraction. Use --keep-archives if you want to keep the zip file:

python scripts/download_datasets.py market1501 --keep-archives

MSMT17 is only needed for the reproduction experiments:

python scripts/download_datasets.py msmt17

Pretrained Weights

Download the three Market1501 checkpoints used by the demo app:

python scripts/download_pretrained_models.py demo

This writes:

  • pretrained_models/market_resnet50_model_120_rank1_945.pth
  • pretrained_models/CC_market1501_81.0.tar
  • pretrained_models/CC+CAJ_market1501_84.8.tar

The BoT checkpoint is downloaded as split Google Drive zip parts, combined, extracted, then the staged zip files are removed. Use --keep-archives if you want to keep the downloaded parts:

python scripts/download_pretrained_models.py demo --keep-archives

To download only one demo weight:

python scripts/download_pretrained_models.py market-bot
python scripts/download_pretrained_models.py cc-market
python scripts/download_pretrained_models.py caj-market

The ImageNet ResNet50 initialization is only needed for training and experiment reproduction:

python scripts/download_pretrained_models.py resnet50

This writes:

  • pretrained_models/resnet50-11ad3fa6.pth

Demo App

The Gradio demo provides a quick way to inspect person retrieval behavior on Market1501.

Key features:

  • Query: upload a person image or let the app randomly select a query image from the dataset. The app returns the 10 most similar gallery images and can save the result list as JSON for later use.
  • Re-rank: load a saved query result JSON from the Query page and apply CA-Jaccard re-ranking to reorder the candidates.
  • Visualization: project image features into clusters so you can visually compare how different methods group people and inspect image metadata directly on the plot.

The app expects Market1501 at data/market1501/Market-1501-v15.09.15 and these checkpoints in pretrained_models/:

  • market_resnet50_model_120_rank1_945.pth
  • CC_market1501_81.0.tar
  • CC+CAJ_market1501_84.8.tar

To start it:

python app/main.py

The web interface is available at http://localhost:7860 by default:

  • Query: http://localhost:7860
  • Re-rank: http://localhost:7860/rerank
  • Visualization: http://localhost:7860/visual

The first query may take longer because gallery features are extracted and cached under .cache/gallery_features. Saved query result JSON files are stored under .cache/rank_lists and can be loaded from the Re-rank page.

Experiments

The following sections are for reproducing the CA-Jaccard paper analyses:

  • Table 3: CKRNNs/CLQE/CAJ ablations
  • Figure 3: neighbor analysis over clustering epochs
  • Figure 4: parameter analysis

MSMT17 for BoT Re-ranking

This setup is only needed if you want to reproduce MSMT17 BoT re-ranking experiments. It is not required for the demo app.

CAJ uses data/msmt17/MSMT17_V1/{train,test}. The bundled BoT loader expects data/msmt17/MSMT17_V2/{mask_train_v2,mask_test_v2}. If your files are in the CAJ layout, create a BoT-compatible layout with symlinks:

python scripts/adapt_msmt17_for_bot.py

Use --copy only if symlinks are not acceptable:

python scripts/adapt_msmt17_for_bot.py --copy

To train BoT on MSMT17:

cd thirdparty/bot
python tools/train.py \
  --config_file configs/softmax_triplet_with_center_msmt17.yml

Use configs/softmax_triplet_with_center_msmt17.yml for the CA-Jaccard paper's BoT setting. It is the all-tricks BoT setup with BNNeck, cross entropy, triplet loss, and center loss. The main hyperparameters are 256x128 images, Adam, learning rate 0.00035, batch size 64, 120 epochs, steps [40, 70], random erasing 0.5, label smoothing on, and center loss weight 0.0005.

The config assumes ImageNet ResNet50 weights at: pretrained_models/resnet50-11ad3fa6.pth. If that file is elsewhere, override it:

cd thirdparty/bot
python tools/train.py \
  --config_file configs/softmax_triplet_with_center_msmt17.yml \
  MODEL.PRETRAIN_PATH "../../pretrained_models/resnet50-11ad3fa6.pth"

To enable faster training, you can set SOLVER.EVAL_PERIOD to 120 either in the config file or via command line. This evaluates only at the end of training, which is sufficient for Table 3's re-ranking ablation. The default SOLVER.EVAL_PERIOD of 40 evaluates every 40 epochs, which is useful for monitoring training progress and selecting a checkpoint.

The resulting checkpoint can be evaluated by CAJ test.py with --checkpoint-format bot. In this mode, test.py builds BoT's own ResNet50 BNNeck model from thirdparty/bot, loads the BoT checkpoint directly, normalizes test features by default, and then passes those features through CAJ's evaluation or re-ranking code. This avoids evaluating BoT weights through CAJ's different ResNet implementation.

Table 3 Ablation

Clustering ablation for Market1501:

python scripts/run_tab3_ablation.py \
  --dataset market1501 \
  --scene clustering

Clustering ablation for MSMT17:

python scripts/run_tab3_ablation.py \
  --dataset msmt17 \
  --scene clustering

To skip clustering training and evaluate existing CAJ checkpoints, pass a checkpoint path. The path may include {dataset} and {variant} placeholders:

python scripts/run_tab3_ablation.py \
  --dataset market1501 \
  --scene clustering \
  --cluster-checkpoint "logs/experiments/tab3/clustering/{dataset}/{variant}/model_best.pth.tar"

BoT re-ranking ablation needs a BoT checkpoint:

python scripts/run_tab3_ablation.py \
  --dataset market1501 \
  --scene reranking \
  --bot-checkpoint pretrained_models/market_resnet50_model_120_rank1_945.pth

For MSMT17, use the BoT checkpoint you trained:

python scripts/run_tab3_ablation.py \
  --dataset msmt17 \
  --scene reranking \
  --bot-checkpoint pretrained_models/msmt17_resnet50_model_120_rank1_750.pth

The runner forwards --checkpoint-format bot --bot-neck-feat after to test.py. This matches the BoT config's TEST.NECK_FEAT: 'after' and TEST.FEAT_NORM: 'yes'. To reproduce a different BoT test setting, use:

python scripts/run_tab3_ablation.py \
  --dataset market1501 \
  --scene reranking \
  --bot-checkpoint pretrained_models/market_resnet50_model_120_rank1_945.pth \
  --bot-neck-feat before

Use --bot-no-feat-norm only if you intentionally want to disable BoT's default feature normalization.

Use --dry-run first to inspect commands. Clustering runs retrain models, while re-ranking only evaluates a pretrained checkpoint.

For clustering runs, --jaccard-memory {auto,dense,sparse} is forwarded to train_caj.py. The default is auto; use sparse when the dense Jaccard distance matrix is too large for available memory, or dense to force the original dense path.

The runner writes:

  • commands: results/tab3_commands.csv
  • parsed metrics after real runs: results/tab3_results.csv, including mAP, Rank-1, and Rank-5 when present in the log

Figure 3 Neighbor Analysis

Market1501 is the default dataset:

python scripts/run_fig3_neighbors.py

MSMT17:

python scripts/run_fig3_neighbors.py --dataset msmt17

Each variant writes a neighbor_analysis.csv under its log directory. The CSV contains:

  • avg_inter_camera_proportion
  • avg_inter_camera_weight
  • avg_same_id_accuracy
  • avg_same_id_weight

The implementation excludes each sample itself from its neighbor statistics to avoid a trivial same-ID intra-camera self-match.

--jaccard-memory {auto,dense,sparse} controls the clustering Jaccard distance memory strategy used by train_caj.py. The default is auto; use sparse for lower memory usage on large datasets.

Figure 4 Parameter Analysis

Clustering sweep:

python scripts/run_fig4_params.py \
  --dataset market1501 \
  --scene clustering \
  --sweep all

Re-ranking sweep with BoT:

python scripts/run_fig4_params.py \
  --dataset market1501 \
  --scene reranking \
  --bot-checkpoint pretrained_models/market_resnet50_model_120_rank1_945.pth

Useful narrower sweeps:

python scripts/run_fig4_params.py --sweep k1-intra --dry-run
python scripts/run_fig4_params.py --sweep k1-inter --dry-run
python scripts/run_fig4_params.py --sweep k2 --dry-run

The default values are:

  • k1-intra: 1,5,10,15,20,25,40
  • k1-inter: 5,10,15,20,25,30,40
  • k2-intra/k2-inter: 1/5,2/4,3/3,4/2,5/1

For clustering sweeps, --jaccard-memory {auto,dense,sparse} is forwarded to train_caj.py. The default is auto; use sparse if parameter sweeps run out of memory while building the Jaccard distance matrix.

The runner writes:

  • commands: results/fig4_commands.csv
  • parsed metrics after real runs: results/fig4_results.csv

Plotting

Plot Figure 3-style curves from neighbor-analysis CSV files:

python scripts/plot_experiments.py \
  --kind fig3 \
  --input logs/experiments/fig3_neighbors/market1501/*/neighbor_analysis.csv

Plot Figure 4-style curves from parsed sweep results:

python scripts/plot_experiments.py \
  --kind fig4 \
  --input results/fig4_results.csv \
  --metric mAP

Render a Table 3-style Markdown table:

python scripts/plot_experiments.py \
  --kind tab3 \
  --input results/tab3_results.csv

Figures and tables are saved to results/figures by default.

Acknowledgement

This repository builds on the official CA-Jaccard implementation and includes code adapted from Cluster Contrast and BoT for person re-identification experiments.

Citation

If you use CA-Jaccard in your research, cite the original paper:

@inproceedings{yiyu2024caj,
  title={CA-Jaccard: Camera-aware Jaccard Distance for Person Re-identification},
  author={Chen, Yiyu and Fan, Zheyi and Chen, Zhaoru and Zhu, Yixuan},
  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
  year={2024}
}

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages