How to compute in-domain classification metrics and out-of-domain detection scores from a trained model.
- A trained model directory (
exp/.../anti-spoofing_feat_model.pth+args.json). - The pre-encoded dataset the model was trained on (
data/prepared_ds_seg_enc/). - For hierarchical models: the canonical label files committed at
data/(label_assignment.txt,label_assignment_superclass.txt,superclass_mapping_known.csv,superclass_mapping_test.csv). The path-resolution helper accepts either a repo-relative path or a name relative to--path_to_dataset.
Both eval scripts read args.json next to the model checkpoint to know what architecture to instantiate (flat / H-Shared / H-Arch) and how to scale logits (ArcFace vs sub-center).
Script: scripts/get_classification_metrics.py.
uv run scripts/get_classification_metrics.py \
--model_path exp/trained_models/<run_name>/anti-spoofing_feat_model.pth \
--path_to_dataset data/prepared_ds_seg_enc \
--superclass_lut data/superclass_mapping_known.csv \
--batch_size 32--superclass_lut accepts either a repo-relative path (as above) or a name resolved relative to --path_to_dataset. Required for hierarchical models; ignored for flat.
Or via makefile:
make id_evalOutput files (written next to the model):
exp/trained_models/<run_name>/
├── dev_in_domain_results.txt # classification report on dev
├── eval_in_domain_results.txt # classification report on eval (ID classes only)
├── dev_in_domain_results_sup.txt # superclass report (hier only)
└── eval_in_domain_results_sup.txt # superclass report (hier only)
The eval reports cover only samples whose model_name was in the train split — OOD samples are excluded here; they're scored by the OOD detector instead.
Script: scripts/ood_detector.py. Supports four scoring methods (--ood_method):
| Method | Description |
|---|---|
mahalanobis |
Class-conditional Mahalanobis distance on penultimate features (default) |
nsd |
Negative Stable Diffusion score (REFD baseline) |
msp |
Maximum Softmax Probability |
energy |
Energy-based score |
For hierarchical models, --confidence_scaling selects how superclass and subclass scores are combined: local (subclass-only), sup (superclass-only), avg (average), none.
The first invocation against a given model extracts and caches per-split features to <model_dir>/ood/{train,dev,eval}_dict.npy:
uv run scripts/ood_detector.py \
--model_path exp/trained_models/<run_name>/anti-spoofing_feat_model.pth \
--path_to_dataset data/prepared_ds_seg_enc \
--label_assignment_file data/label_assignment.txt \
--sup_label_assignment_file data/label_assignment_superclass.txt \
--superclass_lut_known data/superclass_mapping_known.csv \
--superclass_lut_full data/superclass_mapping_test.csv \
--confidence_scaling sup \
--ood_method mahalanobis \
--batch_size 32For flat models, the --sup_label_assignment_file and --superclass_lut_* arguments are accepted but not used. The --confidence_scaling argument is also a no-op.
Once <model_dir>/ood/*.npy exists, add --ood_only to skip the slow feature-extraction step:
uv run scripts/ood_detector.py \
--model_path exp/trained_models/<run_name>/anti-spoofing_feat_model.pth \
--path_to_dataset data/prepared_ds_seg_enc \
--label_assignment_file data/label_assignment.txt \
--sup_label_assignment_file data/label_assignment_superclass.txt \
--superclass_lut_known data/superclass_mapping_known.csv \
--superclass_lut_full data/superclass_mapping_test.csv \
--confidence_scaling sup \
--ood_method nsd \
--ood_onlyThe makefile target ood_eval is one example invocation:
make ood_evalexp/trained_models/<run_name>/ood/
├── train_dict.npy # cached features per split
├── dev_dict.npy
├── eval_dict.npy
├── OOD_eval_results_<method>.txt # classification report on eval (ID vs OOD)
├── OOD_eval_results_sup_<method>.txt # superclass-level report (hier only)
└── OOD_summary_<method>.json # EER, threshold, AUC summary
The detector computes the EER threshold on dev (which must contain OOD examples), then applies it to eval and reports detection accuracy. If your dev split has no OOD samples, EER computation fails with All-NaN slice encountered.
- EER (Equal Error Rate) — operating point where FPR = FNR. Lower is better. The detector picks the EER-optimal threshold on dev and reports both
Dev EERand the resultingEval EERusing that threshold. - AUC-ROC — area under the OOD-score ROC. Higher is better.
- Per-class precision/recall/F1 — in the printed classification reports, class
0is ID and class1is OOD for OOD reports; for ID reports the class IDs matchlabel_assignment.txt. - Superclass vs Global — for hierarchical models,
Globalis the leaf-class prediction (after combining superclass + subclass),Superclassis the parent-only prediction.