Skip to content

Train ReID

Use train to fit a ReID backbone on a supported person or vehicle re-identification dataset.

Examples

Example

Train on Market1501:

boxmot train \
  --model osnet_x0_25 \
  --dataset market1501 \
  --data-dir /data/reid \
  --device 0

Joint training on multiple datasets:

boxmot train \
  --model lmbn_n \
  --dataset market1501,duke,cuhk03 \
  --data-dir /data/reid \
  --loss triplet \
  --preprocess crop_letterbox \
  --epochs 120 \
  --project runs/reid_train \
  --name lmbn_joint

Joint training from ReID data YAMLs:

boxmot train \
  --model csl_tinyvit_23m \
  --data market1501.yaml \
  --data duke.yaml \
  --epochs 120 \
  --device 0

Train from a BoxMOT ReID config:

boxmot train --cfg custom_config.yaml

Explicit CLI flags override the config:

boxmot train --cfg custom_config.yaml --epochs 3

Example market1501.yaml:

dataset: market1501
path: ../datasets/Market-1501-v15.09.15
train: bounding_box_train
query: query
gallery: bounding_box_test
download: |
  from pathlib import Path
  Path(yaml["path"]).mkdir(parents=True, exist_ok=True)

Core idea

train builds a ReID backbone, loads one or more registered ReID datasets, and optimizes the model with either softmax or triplet-style training.

The crop preprocessing you choose here should match the preprocessing used later at inference time.

Supported datasets

The built-in dataset registry currently includes common ReID benchmarks such as:

  • market1501
  • duke / dukemtmcreid
  • cuhk03
  • msmt17
  • msmt17_merged

You pass the dataset root through --data-dir, and BoxMOT resolves the expected subdirectory layout for the selected dataset.

Alternatively, pass one or more --data YAML configs. YAML path values are resolved relative to the YAML file, and download is a local Python block executed only when that root is missing or empty. Built-in ReID datasets still use their registered parsers; train, query, and gallery are saved in hparams as dataset metadata.

Main outputs

Training writes an experiment directory under --project/--name, typically containing:

  • best and last checkpoints
  • training logs and metrics
  • periodic validation results

When training finishes, BoxMOT reports the best checkpoint path along with the best validation mAP and rank-1 score.

Resuming and evaluation during training

  • Use --resume with a checkpoint directory or last.pt file to continue an interrupted run.
  • Use --eval-interval to control how often validation runs during training.
  • Use --eval-datasets for extra cross-domain checks during training.

Scope

train is available from both the CLI and the high-level BoxMOT.train(...) Python facade.

from boxmot import BoxMOT

model = BoxMOT("mobilenetv4")
model.train(cfg="mobilenetv4_custom.yaml")

When the first positional argument matches a registered ReID training recipe or backbone, it is used as the training profile; detector names still configure tracking detectors. A ReID weight filename can also seed the training profile while binding the object to that weight for later export or embedding:

reid = BoxMOT(reid="mobilenetv4.pt")
reid.train(cfg="custom_config.yaml")

CLI Arguments

boxmot train

Train a ReID model

Usage:

boxmot train [OPTIONS]

Options:

Name Type Description Default
--cfg file BoxMOT ReID training YAML config. Explicit CLI flags override config values. None
--recipe choice (csl_tinyvit_11m | csl_tinyvit_23m | csl_tinyvit_7m | lmbn_n | lmbn_n_market1501 | mobilenetv4 | mobilenetv4_conv_large | mobilenetv4_conv_medium | mobilenetv4_conv_small | vit) Training recipe preset (overrides defaults; CLI flags still take priority). Available: csl_tinyvit_11m, csl_tinyvit_23m, csl_tinyvit_7m, lmbn_n, lmbn_n_market1501, mobilenetv4, mobilenetv4_conv_large, mobilenetv4_conv_medium, mobilenetv4_conv_small, vit None
--model choice (csl_tinyvit_11m | csl_tinyvit_11m_lmbn | csl_tinyvit_23m | csl_tinyvit_23m_lmbn | csl_tinyvit_7m | csl_tinyvit_7m_lmbn | csl_tinyvit_large | csl_tinyvit_lmbn | csl_tinyvit_normal | csl_tinyvit_small | hacnn | lmbn_ain_n | lmbn_n | mlfn | mobilenetv2_x1_0 | mobilenetv2_x1_4 | mobilenetv4_conv_large | mobilenetv4_conv_medium | mobilenetv4_conv_small | mobilenetv4_hybrid_large | mobilenetv4_hybrid_medium | osnet_ain_x0_25 | osnet_ain_x0_5 | osnet_ain_x0_75 | osnet_ain_x1_0 | osnet_ibn_x1_0 | osnet_x0_25 | osnet_x0_5 | osnet_x0_75 | osnet_x1_0 | resnet101 | resnet152 | resnet18 | resnet34 | resnet50 | resnet50_fc512 | resnext101_32x8d | resnext50_32x4d) ReID backbone architecture csl_tinyvit_11m
--data text ReID dataset name or YAML data config. Repeat or comma-separate for multi-dataset training, e.g. --data market1501.yaml --data duke.yaml. YAML supports dataset/name, path, train, val, query, gallery, and download. ()
--dataset text Training dataset (comma-separated for joint training, e.g. market1501,duke,cuhk03,msmt17). Available: cuhk03, duke, dukemtmcreid, market1501, mot171501, msmt17, msmt17_merged, veri, veri776 market1501
--data-dir path Root directory of the dataset (inferred from hparams.json when --resume is used) None
--loss choice (softmax | triplet | circle | ms) Metric loss type (triplet=batch-hard triplet, circle=Circle loss, ms=multi-similarity, softmax=classifier only) triplet
--classifier-loss choice (ce | arcface | cosface) ID classifier loss: ce, arcface, or cosface ce
--preprocess choice (resize | resize_pad) Crop preprocessing method; must match inference-time preprocessing resize
--imgsz text Image size as H,W (e.g. 256,128) 384,128
--batch-size integer Evaluation batch size; training uses --p-ids × --k-instances 64
--lr float Base learning rate 0.0007
--weight-decay float Weight decay 0.1
--epochs integer Number of training epochs 250
--warmup-epochs integer Linear warmup epochs 20
--vit-lr-profile choice (layer_decay | reid_lrd) Transformer LR grouping profile: geometric layer decay or ReID stage-wise decay layer_decay
--backbone-freeze-epochs integer Freeze pretrained backbone layers for the first N epochs 10
--gradual-unfreeze / --no-gradual-unfreeze boolean Use staged ReID unfreeze: head/neck, last backbone stage, then full model False
--gradual-unfreeze-head-epochs integer Gradual unfreeze head/neck-only epoch boundary 0
--gradual-unfreeze-stage-epochs integer Gradual unfreeze last-stage epoch boundary before full model training 0
--gradual-unfreeze-backbone-lr-mult float Backbone LR multiplier for early full-model gradual-unfreeze epochs 1.0
--gradual-unfreeze-backbone-lr-epochs integer Number of full-model epochs using the gradual-unfreeze backbone LR multiplier 0
--eval-interval integer Validate every N epochs 10
--p-ids integer Number of identities per PK batch 16
--k-instances integer Number of instances per identity 4
--source-balance text Source-balanced PK sampler spec, e.g. 'market1501:8,4;mot17_1501:8,4'. Empty uses the global --p-ids x --k-instances sampler. ``
--margin float Triplet loss margin 0.3
--triplet-soft-margin / --triplet-hard-margin boolean Use softplus batch-hard triplet instead of the hard margin. Default: auto for transformer-family recipes, hard margin otherwise. None
--arcface-scale float ArcFace logit scale 30.0
--arcface-margin float ArcFace angular margin 0.5
--cosface-scale float CosFace logit scale 30.0
--cosface-margin float CosFace cosine margin 0.35
--label-smooth float Label smoothing epsilon 0.05
--center-loss-weight float Center loss weight 0.005
--id-loss-weight float Weight applied to the ID classification loss term 1.0
--metric-loss-weight float Weight applied to the metric loss term (triplet/circle/ms) 1.0
--early-id-loss-weight float Temporary ID loss weight for the first --early-id-loss-epochs epochs; 0 disables 0.0
--early-id-loss-epochs integer Number of initial epochs using --early-id-loss-weight 0
--center-loss-ramp-start-epoch integer Epoch through which center loss weight stays at 0; 0 disables unless end is set 0
--center-loss-ramp-end-epoch integer Epoch where center loss reaches --center-loss-weight; 0 disables ramping 0
--aux-ce-weight float Relative CE weight for auxiliary branch classifiers; 1.0 preserves equal branch averaging 1.0
--aux-ce-drop-epoch integer Set auxiliary CE weight to 0 after this epoch; 0 keeps it active for all epochs 0
--branch-loss-agg choice (mean | sum) How to aggregate multi-branch losses before weighting mean
--metric-feature choice (auto | global | raw_mean | raw_concat | concat_bn | dse_weighted | dse_mix) Feature representation used for metric losses when the model supports multiple branches raw_concat
--inference-feature choice (concat_bn | norm_concat_bn | global | raw_mean | raw_concat | visibility_weighted_parts | evidence_sinkhorn | dse_weighted | dse_mix) Feature representation emitted by CSL-TinyViT at validation/inference time norm_concat_bn
--feature-fusion choice (final | last2 | last3 | last4_layer0_target | last3_stage2_target | last3_stage1_concat | global_final_parts_stage1_concat | global_final_parts_fpn_layer0 | last3_fpn_stage1_add | last3_fpn_stage1_split | last3_panet_stage1_split | last3_panet_stage1_shared | last3_panet_stage1_scale_aware | last3_bifpn_stage1_split | last3_bifpn_stage1_branch_aware | global_final_parts_hierarchical_fpn | last3_fpn_stage2 | last3_pafpn_stage2 | last4_fpn_layer0_target | global_final_parts_stage2 | late_concat_stage2 | weighted_last2 | weighted_last3 | normpres_last2 | normpres_last3 | dynamic_last3 | dynamic_last3_scale_token | dpt_fpn) CSL-TinyViT static or per-image dynamic spatial fusion before the ReID head last2
--post-fusion-mixer choice (none | dwconv) Optional zero-gated local mixer after CSL-TinyViT feature fusion none
--post-fusion-mixer-reduction integer Channel reduction ratio for the post-fusion local mixer 4
--post-fusion-mixer-kernel text Post-fusion depthwise mixer kernel as H,W, e.g. 5,3 5,3
--post-fusion-mixer-gamma-init float Initial residual scale for the post-fusion local mixer 0.0
--feat-dim integer Per-branch embedding dimension for ReID heads that support projection 512
--neck-dim integer Neck channel dimension for ReID backbones that support a feature neck 512
--drop-path-rate float Maximum stochastic-depth probability for CSL-TinyViT 0.1
--attention-window-layout choice (legacy | rect) CSL-TinyViT attention windows: legacy square windows or ReID rectangular windows legacy
--attention-bias choice (absolute | signed_factorized) CSL-TinyViT relative attention bias parameterization absolute
--attention-mask / --no-attention-mask boolean Mask padded tokens in CSL-TinyViT window attention False
--attention-shift / --no-attention-shift boolean Alternate shifted CSL-TinyViT windows in attention stages 1 and 2 False
--stage3-global / --no-stage3-global boolean Use full 24x8 attention in the final CSL-TinyViT block False
--reid-adapter-stages text CSL-TinyViT attention stages that receive zero-gated ReID residual adapters ``
--reid-adapter-reduction integer Channel reduction ratio for CSL-TinyViT ReID residual adapters 4
--head-pool choice (avg | gem | dse | gelu_gem | relu_gem | softplus_gem) Pooling layer used by CSL-TinyViT multi-branch heads gelu_gem
--head-parts text CSL-TinyViT head granularities, e.g. 1,2 for global+2 parts or 1,2,4 for MGN 1,2
--head-type choice (standard | gpc_lite) CSL-TinyViT branch head: standard or global/part/channel lite standard
--part-pooling choice (stripes | overlap_stripes | tokens | semantic_parts) CSL-TinyViT local pooling: fixed, overlapping, learned-token, or semantic-visibility parts stripes
--num-part-tokens integer Number of learned local/evidence queries for token or semantic-part pooling 4
--evidence-num-roles integer Number of latent semantic role bins for CSL-TinyViT evidence tokens 8
--decouple-patterns / --no-decouple-patterns boolean Use separate zero-initialized residual adapters for global and local features False
--pattern-adapter-dim integer Bottleneck width of each global/local pattern adapter 128
--stripe-visibility / --no-stripe-visibility boolean Learn a per-image confidence for each fixed local stripe False
--drop-global-aux / --no-drop-global-aux boolean Add a training-only dropped-global CE auxiliary classifier to the standard CSL-TinyViT head False
--drop-global-aux-ratio float Horizontal activation-band ratio suppressed by --drop-global-aux 0.25
--branch-aware-metric / --no-branch-aware-metric boolean Apply metric loss separately to CSL-TinyViT global and part branches False
--branch-metric-part-weight float Weight for each part branch metric loss when branch-aware metric is enabled 0.5
--evidence-alignment-loss-weight float Weight for batch Sinkhorn evidence alignment loss; 0 disables 0.0
--evidence-alignment-margin float Negative-pair margin for evidence alignment loss 0.2
--evidence-sinkhorn-iters integer Sinkhorn iterations for evidence alignment and reranking 20
--evidence-sinkhorn-temperature float Sinkhorn temperature for evidence alignment and reranking 0.1
--evidence-rerank-topk integer Gallery top-K reranked with evidence Sinkhorn distance; 0 reranks all 100
--evidence-null-loss-weight float Weight for explicit final-token null/background supervision; 0 disables 0.0
--evidence-diversity-loss-weight float Weight for role/descriptor diversity regularization across evidence tokens 0.0
--head-warmup-epochs integer Train only CSL-TinyViT neck/head for the first N epochs 0
--head-warmup-lr-mult float LR multiplier for neck/head parameter groups during head warmup 2.0
--eta-min float Minimum learning rate for cosine annealing schedule 1e-07
--pretrained / --no-pretrained boolean Use ImageNet-pretrained backbone True
--device text cuda device, e.g. 0 or cpu or mps cpu
--project path Save directory runs/reid_train
--name text Experiment name exp
--num-workers integer Dataloader workers 4
--seed integer Global random seed for Python, NumPy, PyTorch, samplers, and dataloader workers 0
--deterministic / --no-deterministic boolean Require deterministic PyTorch algorithms and backend behavior True
--eval-datasets text Comma-separated list of extra datasets for cross-domain evaluation (e.g. duke,cuhk03,msmt17) ``
--flip-tta / --no-flip-tta boolean Use horizontal flip augmentation during validation (default: recipe value) None
--ema-decay float EMA momentum decay for model averaging (e.g. 0.999). Disabled by default. Inspired by DynaMix 0
--gaussian-blur / --no-gaussian-blur boolean Apply random Gaussian blur augmentation True
--color-jitter / --no-color-jitter boolean Apply color jitter augmentation (auto-enabled for transformer-family recipes) True
--random-grayscale float Probability of random grayscale conversion (0 to disable) 0.1
--random-erasing float Probability of random erasing augmentation (0 to disable) 0.5
--random-patch / --no-random-patch boolean Apply random patch augmentation True
--random-crop-scale float Random2DTranslation resize factor before crop; 1.05 matches LMBN implementation 1.05
--color-augmentation / --no-color-augmentation boolean Enable additional color augmentation mix used by LMBN-style recipes True
--resume path Resume training from a checkpoint dir or last.pt file None
--help boolean Show this message and exit. False