Release Anima Style Embedding v1.0
Browse files- .gitattributes +4 -0
- README.md +172 -0
- SHA256SUMS.json +4 -0
- assets/generalization_and_gallery_size.png +3 -0
- assets/learned_vs_frozen_baseline.png +3 -0
- assets/reference_count_curve.png +3 -0
- assets/training_validation_curves.png +3 -0
- config.json +75 -0
- metrics/model_card_metrics.json +169 -0
- metrics/retrieval_metrics.csv +21 -0
- metrics/test_k_curve.json +204 -0
- metrics/training_metrics.jsonl +0 -0
- metrics/validation_k_curve.json +254 -0
- model.safetensors +3 -0
- modeling_anima_style_embedding.py +341 -0
- requirements.txt +3 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
assets/generalization_and_gallery_size.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
assets/learned_vs_frozen_baseline.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
assets/reference_count_curve.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
assets/training_validation_curves.png filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
library_name: pytorch
|
| 3 |
+
pipeline_tag: feature-extraction
|
| 4 |
+
tags:
|
| 5 |
+
- anime
|
| 6 |
+
- style-embedding
|
| 7 |
+
- image-retrieval
|
| 8 |
+
- reference-image
|
| 9 |
+
- siglip2
|
| 10 |
+
- anima
|
| 11 |
+
- pytorch
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# Anima Style Embedding v1.0
|
| 15 |
+
|
| 16 |
+
**A multi-reference style encoder for person-centric anime and illustration images.**
|
| 17 |
+
|
| 18 |
+
Anima Style Embedding converts one to eight reference images into a normalized 512-dimensional style vector. It combines multi-level SigLIP2 features from the full image and face with internal Anima features, then grounds the result across the complete reference set. The embedding is designed for open-set style retrieval and reference-driven style transfer systems rather than a fixed bank of known artists.
|
| 19 |
+
|
| 20 |
+
| Model size | References | Embedding | Modalities |
|
| 21 |
+
|---:|---:|---:|---|
|
| 22 |
+
| 17.49M parameters | 1–8 images | 512-D, L2-normalized | Full image + face + Anima internals |
|
| 23 |
+
|
| 24 |
+

|
| 25 |
+
|
| 26 |
+
## Highlights
|
| 27 |
+
|
| 28 |
+
- **Open-set style representation:** unseen artists can be embedded directly from reference images.
|
| 29 |
+
- **Native multi-reference grounding:** Reference Consensus Re-reading lets each image be interpreted in the context of the complete 1–8 image set.
|
| 30 |
+
- **Full-image and face awareness:** the encoder combines global composition and rendering cues with face-specific style information.
|
| 31 |
+
- **Anima-aware features:** three internal Anima blocks complement SigLIP2 visual features with representations aligned to the target generator.
|
| 32 |
+
- **Strong retrieval gains:** unseen synthetic-style MRR improves from 32.0% with the frozen SigLIP2 Full+Face baseline to 60.8% with the learned encoder on the 4,500-way validation gallery.
|
| 33 |
+
|
| 34 |
+
## Performance
|
| 35 |
+
|
| 36 |
+
Retrieval uses cosine similarity between normalized query embeddings and five-image style prototypes.
|
| 37 |
+
|
| 38 |
+
### 4,500-way validation — unseen identities
|
| 39 |
+
|
| 40 |
+
The unseen subset contains 500 identities retrieved against a gallery of 4,500 styles.
|
| 41 |
+
|
| 42 |
+
| Source | Top-1 | Top-5 | MRR |
|
| 43 |
+
|---|---:|---:|---:|
|
| 44 |
+
| Synthetic | 51.8% | 71.7% | 60.8% |
|
| 45 |
+
| Human | 56.4% | 75.3% | 65.0% |
|
| 46 |
+
|
| 47 |
+
### 500-way sealed test — unseen identities
|
| 48 |
+
|
| 49 |
+
| Source | Top-1 | Top-5 | MRR |
|
| 50 |
+
|---|---:|---:|---:|
|
| 51 |
+
| Synthetic | 73.8% | 90.3% | 81.1% |
|
| 52 |
+
| Human | 76.1% | 92.0% | 83.0% |
|
| 53 |
+
|
| 54 |
+
The sealed test uses a smaller gallery than validation, so its absolute scores should be read independently.
|
| 55 |
+
|
| 56 |
+

|
| 57 |
+
|
| 58 |
+
### Reference count
|
| 59 |
+
|
| 60 |
+
More references consistently improve human-style grounding. Synthetic K=5 uses the locked controlled/matched/cross-content protocol and is shown separately from the generic K diagnostics.
|
| 61 |
+
|
| 62 |
+

|
| 63 |
+
|
| 64 |
+
## Architecture
|
| 65 |
+
|
| 66 |
+
The encoder projects full-image, face, and Anima tokens into a shared 512-wide space and reads them with four eight-head mixer blocks. Functional Style Factorization introduces four auxiliary style queries during training. Reference Consensus Re-reading computes a consensus across the reference set, re-reads every image under that context, and forms an agreement-weighted prototype.
|
| 67 |
+
|
| 68 |
+
| Input | Shape per batch |
|
| 69 |
+
|---|---|
|
| 70 |
+
| Full-image SigLIP2 features | `[B, R, 30, 1152]` |
|
| 71 |
+
| Face SigLIP2 features | `[B, R, 30, 1152]` |
|
| 72 |
+
| Face validity mask | `[B, R]` |
|
| 73 |
+
| Anima internal features | `[B, R, 3, 4096]` |
|
| 74 |
+
| Reference mask | `[B, R]` |
|
| 75 |
+
|
| 76 |
+
SigLIP2 features use [`timm/vit_so400m_patch16_siglip_gap_512.v2_webli`](https://huggingface.co/timm/vit_so400m_patch16_siglip_gap_512.v2_webli) at 512×512 and three backbone depths. Anima features use 768×768 inputs and blocks 8, 18, and 26 at sigma 0.1.
|
| 77 |
+
|
| 78 |
+
## Quick start
|
| 79 |
+
|
| 80 |
+
```python
|
| 81 |
+
import json
|
| 82 |
+
|
| 83 |
+
import torch
|
| 84 |
+
from huggingface_hub import hf_hub_download
|
| 85 |
+
from safetensors.torch import load_file
|
| 86 |
+
|
| 87 |
+
from modeling_anima_style_embedding import UnifiedStyleEncoder
|
| 88 |
+
|
| 89 |
+
repo_id = "Baragi-AI/Anima-Style-Embedding"
|
| 90 |
+
config = json.load(open(hf_hub_download(repo_id, "config.json"), encoding="utf-8"))
|
| 91 |
+
cfg = config["architecture"]
|
| 92 |
+
|
| 93 |
+
encoder = UnifiedStyleEncoder(
|
| 94 |
+
width=cfg["width"],
|
| 95 |
+
blocks=cfg["blocks"],
|
| 96 |
+
heads=cfg["heads"],
|
| 97 |
+
embedding_dim=cfg["embedding_dim"],
|
| 98 |
+
dropout=cfg["dropout"],
|
| 99 |
+
use_anima=True,
|
| 100 |
+
reference_grounding=cfg["reference_grounding"],
|
| 101 |
+
functional_factors=cfg["functional_factors"],
|
| 102 |
+
)
|
| 103 |
+
encoder.load_state_dict(
|
| 104 |
+
load_file(hf_hub_download(repo_id, "model.safetensors")),
|
| 105 |
+
strict=True,
|
| 106 |
+
)
|
| 107 |
+
encoder.eval()
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
```python
|
| 111 |
+
with torch.inference_mode():
|
| 112 |
+
style_embedding, per_image_embeddings = encoder(
|
| 113 |
+
full_features,
|
| 114 |
+
reference_mask,
|
| 115 |
+
face_features=face_features,
|
| 116 |
+
face_mask=face_mask,
|
| 117 |
+
anima_features=anima_features,
|
| 118 |
+
)
|
| 119 |
+
|
| 120 |
+
assert style_embedding.shape == (full_features.shape[0], 512)
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
`modeling_anima_style_embedding.py` contains the matching encoder definition. The checkpoint expects precomputed SigLIP2 and Anima features; RGB and Anima feature extraction are supplied by downstream integrations.
|
| 124 |
+
|
| 125 |
+
## Training
|
| 126 |
+
|
| 127 |
+
The model was trained on 320,000 person-centric style records: 160,000 Anima-generated images and 160,000 human-created illustrations across 8,000 training identities. Synthetic and human examples are mixed within each batch. Training uses four RTX 5090 GPUs, BF16 DistributedDataParallel, 16-way episodes, two queries per prototype, variable 1–8 image support, global negatives, and weak hard-negative sampling. The 4,500-step checkpoint produced the best full-validation score.
|
| 128 |
+
|
| 129 |
+

|
| 130 |
+
|
| 131 |
+
The training record is available in [Weights & Biases](https://wandb.ai/1wndrla17-kyung-hee-university/anima-style-embedding/runs/5c9ae843a14f46529fe9aaa604a78d3b). Machine-readable evaluation results are included under `metrics/`.
|
| 132 |
+
|
| 133 |
+
## Applications
|
| 134 |
+
|
| 135 |
+
- reference-driven style transfer for Anima;
|
| 136 |
+
- artist-style retrieval and clustering;
|
| 137 |
+
- aggregation of multiple references into a single style prototype;
|
| 138 |
+
- open-set style recognition for previously unseen artists;
|
| 139 |
+
- similarity scoring and reference-set curation.
|
| 140 |
+
|
| 141 |
+
## Files
|
| 142 |
+
|
| 143 |
+
| File | Contents |
|
| 144 |
+
|---|---|
|
| 145 |
+
| `model.safetensors` | Encoder weights |
|
| 146 |
+
| `config.json` | Architecture and feature contract |
|
| 147 |
+
| `modeling_anima_style_embedding.py` | PyTorch model definition |
|
| 148 |
+
| `metrics/` | Training curves and retrieval results |
|
| 149 |
+
| `SHA256SUMS.json` | Release checksums |
|
| 150 |
+
|
| 151 |
+
## Limitations
|
| 152 |
+
|
| 153 |
+
- The model is optimized for person-centric anime and illustration images; other domains are not evaluated.
|
| 154 |
+
- Retrieval metrics measure representation quality, not generated-image fidelity.
|
| 155 |
+
- Style and artist-associated content preferences are not completely disentangled.
|
| 156 |
+
- Anima features must follow the documented model, block, resolution, and sigma configuration.
|
| 157 |
+
|
| 158 |
+
## License
|
| 159 |
+
|
| 160 |
+
No model license has been selected for v1.0. The training images are not distributed with the checkpoint.
|
| 161 |
+
|
| 162 |
+
## Citation
|
| 163 |
+
|
| 164 |
+
```bibtex
|
| 165 |
+
@misc{baragi2026animastyleembedding,
|
| 166 |
+
title = {Anima Style Embedding v1.0},
|
| 167 |
+
author = {{Baragi AI}},
|
| 168 |
+
year = {2026},
|
| 169 |
+
howpublished = {Hugging Face model repository},
|
| 170 |
+
url = {https://huggingface.co/Baragi-AI/Anima-Style-Embedding}
|
| 171 |
+
}
|
| 172 |
+
```
|
SHA256SUMS.json
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model.safetensors": "6cdf126152927f6e31dc856a8d10b8decee3bb20ce4c0ca449206db65d4633ec",
|
| 3 |
+
"config.json": "7323cbf6061896453a88cd0f6302831b96278a52eb8b0b3c1500d84552a1e68f"
|
| 4 |
+
}
|
assets/generalization_and_gallery_size.png
ADDED
|
Git LFS Details
|
assets/learned_vs_frozen_baseline.png
ADDED
|
Git LFS Details
|
assets/reference_count_curve.png
ADDED
|
Git LFS Details
|
assets/training_validation_curves.png
ADDED
|
Git LFS Details
|
config.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"model_type": "anima_style_embedding",
|
| 3 |
+
"version": "1.0",
|
| 4 |
+
"architecture": {
|
| 5 |
+
"width": 512,
|
| 6 |
+
"blocks": 4,
|
| 7 |
+
"heads": 8,
|
| 8 |
+
"embedding_dim": 512,
|
| 9 |
+
"dropout": 0.1,
|
| 10 |
+
"reference_grounding": true,
|
| 11 |
+
"functional_factors": true,
|
| 12 |
+
"reference_count": [
|
| 13 |
+
1,
|
| 14 |
+
8
|
| 15 |
+
],
|
| 16 |
+
"trainable_parameters": 17488353
|
| 17 |
+
},
|
| 18 |
+
"inputs": {
|
| 19 |
+
"siglip2_full": {
|
| 20 |
+
"shape": [
|
| 21 |
+
30,
|
| 22 |
+
1152
|
| 23 |
+
],
|
| 24 |
+
"dtype": "bfloat16"
|
| 25 |
+
},
|
| 26 |
+
"siglip2_face": {
|
| 27 |
+
"shape": [
|
| 28 |
+
30,
|
| 29 |
+
1152
|
| 30 |
+
],
|
| 31 |
+
"dtype": "bfloat16",
|
| 32 |
+
"optional": true
|
| 33 |
+
},
|
| 34 |
+
"anima": {
|
| 35 |
+
"shape": [
|
| 36 |
+
3,
|
| 37 |
+
4096
|
| 38 |
+
],
|
| 39 |
+
"dtype": "bfloat16"
|
| 40 |
+
}
|
| 41 |
+
},
|
| 42 |
+
"vision_backbone": {
|
| 43 |
+
"repo_id": "timm/vit_so400m_patch16_siglip_gap_512.v2_webli",
|
| 44 |
+
"image_size": 512,
|
| 45 |
+
"layer_fractions": [
|
| 46 |
+
0.25,
|
| 47 |
+
0.55,
|
| 48 |
+
1.0
|
| 49 |
+
],
|
| 50 |
+
"pool_sizes": [
|
| 51 |
+
2,
|
| 52 |
+
4,
|
| 53 |
+
2
|
| 54 |
+
]
|
| 55 |
+
},
|
| 56 |
+
"anima_features": {
|
| 57 |
+
"image_size": 768,
|
| 58 |
+
"blocks": [
|
| 59 |
+
8,
|
| 60 |
+
18,
|
| 61 |
+
26
|
| 62 |
+
],
|
| 63 |
+
"sigma": 0.1,
|
| 64 |
+
"noise_seed": 20260715
|
| 65 |
+
},
|
| 66 |
+
"training": {
|
| 67 |
+
"checkpoint_step": 4500,
|
| 68 |
+
"face_dropout": 0.3,
|
| 69 |
+
"query_count": 2,
|
| 70 |
+
"optimizer": "AdamW(fused)",
|
| 71 |
+
"scheduler": "cosine_with_linear_warmup",
|
| 72 |
+
"learning_rate": 0.0001,
|
| 73 |
+
"packed_manifest_sha256": "c1267b9fd45c6e0d222b91d6ae2291b36b763277cc39cbc32484874ffeae9b32"
|
| 74 |
+
}
|
| 75 |
+
}
|
metrics/model_card_metrics.json
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"selected_checkpoint": {
|
| 3 |
+
"checkpoint": "/workspace/runs/style_embedding_combined_lr1e4_clip10_5k/best.pt",
|
| 4 |
+
"checkpoint_sha256": "16345685b72c9bb018833ea9d42d18ebdaafa585b2a2eb136f267006c1de5663",
|
| 5 |
+
"step": 4500,
|
| 6 |
+
"validation_checkpoint_score": 0.6301507651805878
|
| 7 |
+
},
|
| 8 |
+
"validation_k5": {
|
| 9 |
+
"synthetic": {
|
| 10 |
+
"styles": 4500.0,
|
| 11 |
+
"queries": 22500.0,
|
| 12 |
+
"top1": 0.5625777840614319,
|
| 13 |
+
"top5": 0.7585333585739136,
|
| 14 |
+
"mrr": 0.6518997550010681,
|
| 15 |
+
"margin": -0.006614952813833952,
|
| 16 |
+
"positive_cosine": 0.7365614771842957,
|
| 17 |
+
"hardest_negative_cosine": 0.7431764006614685,
|
| 18 |
+
"verification_auroc": 0.5534452199935913,
|
| 19 |
+
"embedding_std": 0.04349411278963089,
|
| 20 |
+
"embedding_effective_rank": 24.163583755493164,
|
| 21 |
+
"seen_queries": 20000.0,
|
| 22 |
+
"seen_top1": 0.5681999921798706,
|
| 23 |
+
"seen_top5": 0.7637499570846558,
|
| 24 |
+
"seen_mrr": 0.6573799848556519,
|
| 25 |
+
"seen_margin": -0.004584707319736481,
|
| 26 |
+
"unseen_queries": 2500.0,
|
| 27 |
+
"unseen_top1": 0.5175999999046326,
|
| 28 |
+
"unseen_top5": 0.7167999744415283,
|
| 29 |
+
"unseen_mrr": 0.6080579161643982,
|
| 30 |
+
"unseen_margin": -0.02285691164433956,
|
| 31 |
+
"matched_queries": 4500.0,
|
| 32 |
+
"matched_top1": 0.48955556750297546,
|
| 33 |
+
"matched_top5": 0.6902222037315369,
|
| 34 |
+
"matched_mrr": 0.5840909481048584,
|
| 35 |
+
"matched_margin": -0.030851511284708977,
|
| 36 |
+
"cross_queries": 18000.0,
|
| 37 |
+
"cross_top1": 0.5808333158493042,
|
| 38 |
+
"cross_top5": 0.7756111025810242,
|
| 39 |
+
"cross_mrr": 0.6688519716262817,
|
| 40 |
+
"cross_margin": -0.0005558129050768912
|
| 41 |
+
},
|
| 42 |
+
"human": {
|
| 43 |
+
"styles": 4500.0,
|
| 44 |
+
"queries": 22500.0,
|
| 45 |
+
"top1": 0.6493777632713318,
|
| 46 |
+
"top5": 0.8219555616378784,
|
| 47 |
+
"mrr": 0.7280733585357666,
|
| 48 |
+
"margin": 0.022814957424998283,
|
| 49 |
+
"positive_cosine": 0.7811680436134338,
|
| 50 |
+
"hardest_negative_cosine": 0.7583531141281128,
|
| 51 |
+
"verification_auroc": 0.6369090676307678,
|
| 52 |
+
"embedding_std": 0.043804656714200974,
|
| 53 |
+
"embedding_effective_rank": 27.383806228637695,
|
| 54 |
+
"seen_queries": 20000.0,
|
| 55 |
+
"seen_top1": 0.660099983215332,
|
| 56 |
+
"seen_top5": 0.830549955368042,
|
| 57 |
+
"seen_mrr": 0.7378283143043518,
|
| 58 |
+
"seen_margin": 0.026178810745477676,
|
| 59 |
+
"unseen_queries": 2500.0,
|
| 60 |
+
"unseen_top1": 0.5636000037193298,
|
| 61 |
+
"unseen_top5": 0.7531999945640564,
|
| 62 |
+
"unseen_mrr": 0.6500336527824402,
|
| 63 |
+
"unseen_margin": -0.004095893818885088
|
| 64 |
+
}
|
| 65 |
+
},
|
| 66 |
+
"sealed_test_k5": {
|
| 67 |
+
"synthetic": {
|
| 68 |
+
"styles": 500.0,
|
| 69 |
+
"queries": 2500.0,
|
| 70 |
+
"top1": 0.7375999689102173,
|
| 71 |
+
"top5": 0.9031999707221985,
|
| 72 |
+
"mrr": 0.8114251494407654,
|
| 73 |
+
"margin": 0.06940444558858871,
|
| 74 |
+
"positive_cosine": 0.7258960008621216,
|
| 75 |
+
"hardest_negative_cosine": 0.6564915776252747,
|
| 76 |
+
"verification_auroc": 0.7113653421401978,
|
| 77 |
+
"embedding_std": 0.04344247281551361,
|
| 78 |
+
"embedding_effective_rank": 23.896039962768555,
|
| 79 |
+
"unseen_queries": 2500.0,
|
| 80 |
+
"unseen_top1": 0.7375999689102173,
|
| 81 |
+
"unseen_top5": 0.9031999707221985,
|
| 82 |
+
"unseen_mrr": 0.8114251494407654,
|
| 83 |
+
"unseen_margin": 0.06940444558858871,
|
| 84 |
+
"matched_queries": 500.0,
|
| 85 |
+
"matched_top1": 0.6600000262260437,
|
| 86 |
+
"matched_top5": 0.8520000576972961,
|
| 87 |
+
"matched_mrr": 0.748103678226471,
|
| 88 |
+
"matched_margin": 0.045967720448970795,
|
| 89 |
+
"cross_queries": 2000.0,
|
| 90 |
+
"cross_top1": 0.7570000290870667,
|
| 91 |
+
"cross_top5": 0.9160000681877136,
|
| 92 |
+
"cross_mrr": 0.8272556662559509,
|
| 93 |
+
"cross_margin": 0.0752636268734932
|
| 94 |
+
},
|
| 95 |
+
"human": {
|
| 96 |
+
"styles": 500.0,
|
| 97 |
+
"queries": 2500.0,
|
| 98 |
+
"top1": 0.761199951171875,
|
| 99 |
+
"top5": 0.9199999570846558,
|
| 100 |
+
"mrr": 0.830402135848999,
|
| 101 |
+
"margin": 0.08207859843969345,
|
| 102 |
+
"positive_cosine": 0.7568042874336243,
|
| 103 |
+
"hardest_negative_cosine": 0.6747256517410278,
|
| 104 |
+
"verification_auroc": 0.7453367114067078,
|
| 105 |
+
"embedding_std": 0.04376835376024246,
|
| 106 |
+
"embedding_effective_rank": 26.91031265258789,
|
| 107 |
+
"unseen_queries": 2500.0,
|
| 108 |
+
"unseen_top1": 0.761199951171875,
|
| 109 |
+
"unseen_top5": 0.9199999570846558,
|
| 110 |
+
"unseen_mrr": 0.830402135848999,
|
| 111 |
+
"unseen_margin": 0.08207859843969345
|
| 112 |
+
}
|
| 113 |
+
},
|
| 114 |
+
"frozen_full_face_validation_k5": {
|
| 115 |
+
"synthetic": {
|
| 116 |
+
"styles": 4500.0,
|
| 117 |
+
"queries": 22500.0,
|
| 118 |
+
"top1": 0.2617333233356476,
|
| 119 |
+
"top5": 0.3952000141143799,
|
| 120 |
+
"mrr": 0.3287946879863739,
|
| 121 |
+
"margin": -0.058847684413194656,
|
| 122 |
+
"positive_cosine": 0.3081073760986328,
|
| 123 |
+
"hardest_negative_cosine": 0.36695507168769836,
|
| 124 |
+
"verification_auroc": 0.3488680124282837,
|
| 125 |
+
"seen_queries": 20000.0,
|
| 126 |
+
"seen_top1": 0.2628999948501587,
|
| 127 |
+
"seen_top5": 0.3959999978542328,
|
| 128 |
+
"seen_mrr": 0.3298960030078888,
|
| 129 |
+
"seen_margin": -0.0586077980697155,
|
| 130 |
+
"unseen_queries": 2500.0,
|
| 131 |
+
"unseen_top1": 0.2523999810218811,
|
| 132 |
+
"unseen_top5": 0.3887999951839447,
|
| 133 |
+
"unseen_mrr": 0.31998398900032043,
|
| 134 |
+
"unseen_margin": -0.06076674535870552,
|
| 135 |
+
"matched_queries": 4500.0,
|
| 136 |
+
"matched_top1": 0.10533333569765091,
|
| 137 |
+
"matched_top5": 0.1851111203432083,
|
| 138 |
+
"matched_mrr": 0.14898858964443207,
|
| 139 |
+
"matched_margin": -0.11573364585638046,
|
| 140 |
+
"cross_queries": 18000.0,
|
| 141 |
+
"cross_top1": 0.3008333444595337,
|
| 142 |
+
"cross_top5": 0.4477222263813019,
|
| 143 |
+
"cross_mrr": 0.37374621629714966,
|
| 144 |
+
"cross_margin": -0.04462619498372078
|
| 145 |
+
},
|
| 146 |
+
"human": {
|
| 147 |
+
"styles": 4500.0,
|
| 148 |
+
"queries": 22500.0,
|
| 149 |
+
"top1": 0.43657779693603516,
|
| 150 |
+
"top5": 0.5786222219467163,
|
| 151 |
+
"mrr": 0.5056873559951782,
|
| 152 |
+
"margin": -0.029125619679689407,
|
| 153 |
+
"positive_cosine": 0.4710022509098053,
|
| 154 |
+
"hardest_negative_cosine": 0.5001279711723328,
|
| 155 |
+
"verification_auroc": 0.4406580626964569,
|
| 156 |
+
"seen_queries": 20000.0,
|
| 157 |
+
"seen_top1": 0.4320499897003174,
|
| 158 |
+
"seen_top5": 0.5762999653816223,
|
| 159 |
+
"seen_mrr": 0.5021449327468872,
|
| 160 |
+
"seen_margin": -0.030033092945814133,
|
| 161 |
+
"unseen_queries": 2500.0,
|
| 162 |
+
"unseen_top1": 0.47279998660087585,
|
| 163 |
+
"unseen_top5": 0.5971999764442444,
|
| 164 |
+
"unseen_mrr": 0.5340264439582825,
|
| 165 |
+
"unseen_margin": -0.021865803748369217
|
| 166 |
+
}
|
| 167 |
+
},
|
| 168 |
+
"protocol_note": "Synthetic K=5 uses the locked five-controlled support, one matched and four cross-content query protocol. Other K values use deterministic generic record ordering."
|
| 169 |
+
}
|
metrics/retrieval_metrics.csv
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
split,source,k,styles,queries,top1,top5,mrr,margin,seen_top1,seen_top5,seen_mrr,unseen_top1,unseen_top5,unseen_mrr,matched_mrr,cross_mrr,verification_auroc,embedding_effective_rank
|
| 2 |
+
validation,synthetic,1,4500.0,40500.0,0.25738272070884705,0.4447901248931885,0.3484785854816437,-0.13694550096988678,0.26072221994400024,0.448972225189209,0.35212650895118713,0.23066666722297668,0.4113333523273468,0.3192950487136841,,,0.2625024914741516,24.163583755493164
|
| 3 |
+
validation,synthetic,2,4500.0,36000.0,0.38269445300102234,0.5837222337722778,0.479046106338501,-0.0735325887799263,0.3878125250339508,0.5885000228881836,0.48388049006462097,0.34175002574920654,0.5455000400543213,0.4403711259365082,,,0.3855718970298767,24.163583755493164
|
| 4 |
+
validation,synthetic,4,4500.0,27000.0,0.4913703501224518,0.6868888735771179,0.5827372670173645,-0.032036565244197845,0.4964166581630707,0.6924583315849304,0.5878510475158691,0.45100000500679016,0.6423333287239075,0.5418276190757751,,,0.4890711009502411,24.163583755493164
|
| 5 |
+
validation,synthetic,5,4500.0,22500.0,0.5625777840614319,0.7585333585739136,0.6518997550010681,-0.006614952813833952,0.5681999921798706,0.7637499570846558,0.6573799848556519,0.5175999999046326,0.7167999744415283,0.6080579161643982,0.5840909481048584,0.6688519716262817,0.5534452199935913,24.163583755493164
|
| 6 |
+
validation,synthetic,8,4500.0,9000.0,0.5631111264228821,0.7501111030578613,0.6487501263618469,-0.006703122518956661,0.5692500472068787,0.7573750615119934,0.6548616290092468,0.5139999985694885,0.6920000314712524,0.5998580455780029,,,0.557915985584259,24.163583755493164
|
| 7 |
+
validation,human,1,4500.0,40500.0,0.37967902421951294,0.5846666693687439,0.47633036971092224,-0.07382111996412277,0.3872777819633484,0.5945833325386047,0.48492416739463806,0.31888890266418457,0.5053333640098572,0.40757980942726135,,,0.38891345262527466,27.383806228637695
|
| 8 |
+
validation,human,2,4500.0,36000.0,0.5184444785118103,0.7187777757644653,0.6118195652961731,-0.018171189352869987,0.5287187695503235,0.729593813419342,0.6219512224197388,0.4362500309944153,0.6322500109672546,0.5307666063308716,,,0.516968846321106,27.383806228637695
|
| 9 |
+
validation,human,4,4500.0,27000.0,0.6229629516601562,0.8089629411697388,0.7071906924247742,0.01628497801721096,0.6336249709129333,0.8175833225250244,0.7167206406593323,0.5376666784286499,0.7400000095367432,0.6309514045715332,,,0.6160270571708679,27.383806228637695
|
| 10 |
+
validation,human,5,4500.0,22500.0,0.6493777632713318,0.8219555616378784,0.7280733585357666,0.022814957424998283,0.660099983215332,0.830549955368042,0.7378283143043518,0.5636000037193298,0.7531999945640564,0.6500336527824402,,,0.6369090676307678,27.383806228637695
|
| 11 |
+
validation,human,8,4500.0,9000.0,0.6846666932106018,0.8516666889190674,0.7596060037612915,0.03352390229701996,0.6943750381469727,0.85875004529953,0.7680479884147644,0.6070000529289246,0.7950000166893005,0.6920705437660217,,,0.6696112155914307,27.383806228637695
|
| 12 |
+
test,synthetic,1,500.0,4500.0,0.41688889265060425,0.6495555639266968,0.5274384617805481,-0.07223178446292877,,,,0.41688889265060425,0.6495555639266968,0.5274384617805481,,,0.41443032026290894,23.896039962768555
|
| 13 |
+
test,synthetic,2,500.0,4000.0,0.5692500472068787,0.7830000519752502,0.6672611236572266,0.00026985956355929375,,,,0.5692500472068787,0.7830000519752502,0.6672611236572266,,,0.557541012763977,23.896039962768555
|
| 14 |
+
test,synthetic,4,500.0,3000.0,0.6786666512489319,0.8600000143051147,0.7601169943809509,0.04286628216505051,,,,0.6786666512489319,0.8600000143051147,0.7601169943809509,,,0.6542216539382935,23.896039962768555
|
| 15 |
+
test,synthetic,5,500.0,2500.0,0.7375999689102173,0.9031999707221985,0.8114251494407654,0.06940444558858871,,,,0.7375999689102173,0.9031999707221985,0.8114251494407654,0.748103678226471,0.8272556662559509,0.7113653421401978,23.896039962768555
|
| 16 |
+
test,synthetic,8,500.0,1000.0,0.7070000171661377,0.8790000677108765,0.7862902879714966,0.06344308704137802,,,,0.7070000171661377,0.8790000677108765,0.7862902879714966,,,0.7011929750442505,23.896039962768555
|
| 17 |
+
test,human,1,500.0,4500.0,0.5155555605888367,0.7431111335754395,0.6204044222831726,-0.0215375367552042,,,,0.5155555605888367,0.7431111335754395,0.6204044222831726,,,0.5082485675811768,26.91031265258789
|
| 18 |
+
test,human,2,500.0,4000.0,0.6565000414848328,0.8540000319480896,0.7454702258110046,0.03674145042896271,,,,0.6565000414848328,0.8540000319480896,0.7454702258110046,,,0.6430025100708008,26.91031265258789
|
| 19 |
+
test,human,4,500.0,3000.0,0.737666666507721,0.9136666655540466,0.8140823245048523,0.07469645887613297,,,,0.737666666507721,0.9136666655540466,0.8140823245048523,,,0.726514458656311,26.91031265258789
|
| 20 |
+
test,human,5,500.0,2500.0,0.761199951171875,0.9199999570846558,0.830402135848999,0.08207859843969345,,,,0.761199951171875,0.9199999570846558,0.830402135848999,,,0.7453367114067078,26.91031265258789
|
| 21 |
+
test,human,8,500.0,1000.0,0.7820000648498535,0.9250000715255737,0.8470030426979065,0.08853543549776077,,,,0.7820000648498535,0.9250000715255737,0.8470030426979065,,,0.7604439854621887,26.91031265258789
|
metrics/test_k_curve.json
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"synthetic": {
|
| 3 |
+
"k1": {
|
| 4 |
+
"styles": 500.0,
|
| 5 |
+
"queries": 4500.0,
|
| 6 |
+
"top1": 0.41688889265060425,
|
| 7 |
+
"top5": 0.6495555639266968,
|
| 8 |
+
"mrr": 0.5274384617805481,
|
| 9 |
+
"margin": -0.07223178446292877,
|
| 10 |
+
"positive_cosine": 0.5964593291282654,
|
| 11 |
+
"hardest_negative_cosine": 0.668691098690033,
|
| 12 |
+
"verification_auroc": 0.41443032026290894,
|
| 13 |
+
"embedding_std": 0.04344247281551361,
|
| 14 |
+
"embedding_effective_rank": 23.896039962768555,
|
| 15 |
+
"unseen_queries": 4500.0,
|
| 16 |
+
"unseen_top1": 0.41688889265060425,
|
| 17 |
+
"unseen_top5": 0.6495555639266968,
|
| 18 |
+
"unseen_mrr": 0.5274384617805481,
|
| 19 |
+
"unseen_margin": -0.07223178446292877
|
| 20 |
+
},
|
| 21 |
+
"k2": {
|
| 22 |
+
"styles": 500.0,
|
| 23 |
+
"queries": 4000.0,
|
| 24 |
+
"top1": 0.5692500472068787,
|
| 25 |
+
"top5": 0.7830000519752502,
|
| 26 |
+
"mrr": 0.6672611236572266,
|
| 27 |
+
"margin": 0.00026985956355929375,
|
| 28 |
+
"positive_cosine": 0.6695296764373779,
|
| 29 |
+
"hardest_negative_cosine": 0.6692599058151245,
|
| 30 |
+
"verification_auroc": 0.557541012763977,
|
| 31 |
+
"embedding_std": 0.04344247281551361,
|
| 32 |
+
"embedding_effective_rank": 23.896039962768555,
|
| 33 |
+
"unseen_queries": 4000.0,
|
| 34 |
+
"unseen_top1": 0.5692500472068787,
|
| 35 |
+
"unseen_top5": 0.7830000519752502,
|
| 36 |
+
"unseen_mrr": 0.6672611236572266,
|
| 37 |
+
"unseen_margin": 0.00026985956355929375
|
| 38 |
+
},
|
| 39 |
+
"k4": {
|
| 40 |
+
"styles": 500.0,
|
| 41 |
+
"queries": 3000.0,
|
| 42 |
+
"top1": 0.6786666512489319,
|
| 43 |
+
"top5": 0.8600000143051147,
|
| 44 |
+
"mrr": 0.7601169943809509,
|
| 45 |
+
"margin": 0.04286628216505051,
|
| 46 |
+
"positive_cosine": 0.7160320281982422,
|
| 47 |
+
"hardest_negative_cosine": 0.6731657981872559,
|
| 48 |
+
"verification_auroc": 0.6542216539382935,
|
| 49 |
+
"embedding_std": 0.04344247281551361,
|
| 50 |
+
"embedding_effective_rank": 23.896039962768555,
|
| 51 |
+
"unseen_queries": 3000.0,
|
| 52 |
+
"unseen_top1": 0.6786666512489319,
|
| 53 |
+
"unseen_top5": 0.8600000143051147,
|
| 54 |
+
"unseen_mrr": 0.7601169943809509,
|
| 55 |
+
"unseen_margin": 0.04286628216505051
|
| 56 |
+
},
|
| 57 |
+
"k5": {
|
| 58 |
+
"styles": 500.0,
|
| 59 |
+
"queries": 2500.0,
|
| 60 |
+
"top1": 0.7375999689102173,
|
| 61 |
+
"top5": 0.9031999707221985,
|
| 62 |
+
"mrr": 0.8114251494407654,
|
| 63 |
+
"margin": 0.06940444558858871,
|
| 64 |
+
"positive_cosine": 0.7258960008621216,
|
| 65 |
+
"hardest_negative_cosine": 0.6564915776252747,
|
| 66 |
+
"verification_auroc": 0.7113653421401978,
|
| 67 |
+
"embedding_std": 0.04344247281551361,
|
| 68 |
+
"embedding_effective_rank": 23.896039962768555,
|
| 69 |
+
"unseen_queries": 2500.0,
|
| 70 |
+
"unseen_top1": 0.7375999689102173,
|
| 71 |
+
"unseen_top5": 0.9031999707221985,
|
| 72 |
+
"unseen_mrr": 0.8114251494407654,
|
| 73 |
+
"unseen_margin": 0.06940444558858871,
|
| 74 |
+
"matched_queries": 500.0,
|
| 75 |
+
"matched_top1": 0.6600000262260437,
|
| 76 |
+
"matched_top5": 0.8520000576972961,
|
| 77 |
+
"matched_mrr": 0.748103678226471,
|
| 78 |
+
"matched_margin": 0.045967720448970795,
|
| 79 |
+
"cross_queries": 2000.0,
|
| 80 |
+
"cross_top1": 0.7570000290870667,
|
| 81 |
+
"cross_top5": 0.9160000681877136,
|
| 82 |
+
"cross_mrr": 0.8272556662559509,
|
| 83 |
+
"cross_margin": 0.0752636268734932
|
| 84 |
+
},
|
| 85 |
+
"k8": {
|
| 86 |
+
"styles": 500.0,
|
| 87 |
+
"queries": 1000.0,
|
| 88 |
+
"top1": 0.7070000171661377,
|
| 89 |
+
"top5": 0.8790000677108765,
|
| 90 |
+
"mrr": 0.7862902879714966,
|
| 91 |
+
"margin": 0.06344308704137802,
|
| 92 |
+
"positive_cosine": 0.739560604095459,
|
| 93 |
+
"hardest_negative_cosine": 0.676117479801178,
|
| 94 |
+
"verification_auroc": 0.7011929750442505,
|
| 95 |
+
"embedding_std": 0.04344247281551361,
|
| 96 |
+
"embedding_effective_rank": 23.896039962768555,
|
| 97 |
+
"unseen_queries": 1000.0,
|
| 98 |
+
"unseen_top1": 0.7070000171661377,
|
| 99 |
+
"unseen_top5": 0.8790000677108765,
|
| 100 |
+
"unseen_mrr": 0.7862902879714966,
|
| 101 |
+
"unseen_margin": 0.06344308704137802
|
| 102 |
+
}
|
| 103 |
+
},
|
| 104 |
+
"human": {
|
| 105 |
+
"k1": {
|
| 106 |
+
"styles": 500.0,
|
| 107 |
+
"queries": 4500.0,
|
| 108 |
+
"top1": 0.5155555605888367,
|
| 109 |
+
"top5": 0.7431111335754395,
|
| 110 |
+
"mrr": 0.6204044222831726,
|
| 111 |
+
"margin": -0.0215375367552042,
|
| 112 |
+
"positive_cosine": 0.6388872861862183,
|
| 113 |
+
"hardest_negative_cosine": 0.6604248285293579,
|
| 114 |
+
"verification_auroc": 0.5082485675811768,
|
| 115 |
+
"embedding_std": 0.04376835376024246,
|
| 116 |
+
"embedding_effective_rank": 26.91031265258789,
|
| 117 |
+
"unseen_queries": 4500.0,
|
| 118 |
+
"unseen_top1": 0.5155555605888367,
|
| 119 |
+
"unseen_top5": 0.7431111335754395,
|
| 120 |
+
"unseen_mrr": 0.6204044222831726,
|
| 121 |
+
"unseen_margin": -0.0215375367552042
|
| 122 |
+
},
|
| 123 |
+
"k2": {
|
| 124 |
+
"styles": 500.0,
|
| 125 |
+
"queries": 4000.0,
|
| 126 |
+
"top1": 0.6565000414848328,
|
| 127 |
+
"top5": 0.8540000319480896,
|
| 128 |
+
"mrr": 0.7454702258110046,
|
| 129 |
+
"margin": 0.03674145042896271,
|
| 130 |
+
"positive_cosine": 0.7047365307807922,
|
| 131 |
+
"hardest_negative_cosine": 0.6679950952529907,
|
| 132 |
+
"verification_auroc": 0.6430025100708008,
|
| 133 |
+
"embedding_std": 0.04376835376024246,
|
| 134 |
+
"embedding_effective_rank": 26.91031265258789,
|
| 135 |
+
"unseen_queries": 4000.0,
|
| 136 |
+
"unseen_top1": 0.6565000414848328,
|
| 137 |
+
"unseen_top5": 0.8540000319480896,
|
| 138 |
+
"unseen_mrr": 0.7454702258110046,
|
| 139 |
+
"unseen_margin": 0.03674145042896271
|
| 140 |
+
},
|
| 141 |
+
"k4": {
|
| 142 |
+
"styles": 500.0,
|
| 143 |
+
"queries": 3000.0,
|
| 144 |
+
"top1": 0.737666666507721,
|
| 145 |
+
"top5": 0.9136666655540466,
|
| 146 |
+
"mrr": 0.8140823245048523,
|
| 147 |
+
"margin": 0.07469645887613297,
|
| 148 |
+
"positive_cosine": 0.7484809756278992,
|
| 149 |
+
"hardest_negative_cosine": 0.6737845540046692,
|
| 150 |
+
"verification_auroc": 0.726514458656311,
|
| 151 |
+
"embedding_std": 0.04376835376024246,
|
| 152 |
+
"embedding_effective_rank": 26.91031265258789,
|
| 153 |
+
"unseen_queries": 3000.0,
|
| 154 |
+
"unseen_top1": 0.737666666507721,
|
| 155 |
+
"unseen_top5": 0.9136666655540466,
|
| 156 |
+
"unseen_mrr": 0.8140823245048523,
|
| 157 |
+
"unseen_margin": 0.07469645887613297
|
| 158 |
+
},
|
| 159 |
+
"k5": {
|
| 160 |
+
"styles": 500.0,
|
| 161 |
+
"queries": 2500.0,
|
| 162 |
+
"top1": 0.761199951171875,
|
| 163 |
+
"top5": 0.9199999570846558,
|
| 164 |
+
"mrr": 0.830402135848999,
|
| 165 |
+
"margin": 0.08207859843969345,
|
| 166 |
+
"positive_cosine": 0.7568042874336243,
|
| 167 |
+
"hardest_negative_cosine": 0.6747256517410278,
|
| 168 |
+
"verification_auroc": 0.7453367114067078,
|
| 169 |
+
"embedding_std": 0.04376835376024246,
|
| 170 |
+
"embedding_effective_rank": 26.91031265258789,
|
| 171 |
+
"unseen_queries": 2500.0,
|
| 172 |
+
"unseen_top1": 0.761199951171875,
|
| 173 |
+
"unseen_top5": 0.9199999570846558,
|
| 174 |
+
"unseen_mrr": 0.830402135848999,
|
| 175 |
+
"unseen_margin": 0.08207859843969345
|
| 176 |
+
},
|
| 177 |
+
"k8": {
|
| 178 |
+
"styles": 500.0,
|
| 179 |
+
"queries": 1000.0,
|
| 180 |
+
"top1": 0.7820000648498535,
|
| 181 |
+
"top5": 0.9250000715255737,
|
| 182 |
+
"mrr": 0.8470030426979065,
|
| 183 |
+
"margin": 0.08853543549776077,
|
| 184 |
+
"positive_cosine": 0.7681199312210083,
|
| 185 |
+
"hardest_negative_cosine": 0.6795844435691833,
|
| 186 |
+
"verification_auroc": 0.7604439854621887,
|
| 187 |
+
"embedding_std": 0.04376835376024246,
|
| 188 |
+
"embedding_effective_rank": 26.91031265258789,
|
| 189 |
+
"unseen_queries": 1000.0,
|
| 190 |
+
"unseen_top1": 0.7820000648498535,
|
| 191 |
+
"unseen_top5": 0.9250000715255737,
|
| 192 |
+
"unseen_mrr": 0.8470030426979065,
|
| 193 |
+
"unseen_margin": 0.08853543549776077
|
| 194 |
+
}
|
| 195 |
+
},
|
| 196 |
+
"checkpoint_score": 0.8209136426448822,
|
| 197 |
+
"checkpoint_config": {
|
| 198 |
+
"packed_manifest_sha256": "c1267b9fd45c6e0d222b91d6ae2291b36b763277cc39cbc32484874ffeae9b32",
|
| 199 |
+
"use_anima": true,
|
| 200 |
+
"face_dropout": 0.3,
|
| 201 |
+
"episode_pairs": 8,
|
| 202 |
+
"seed": 20260719
|
| 203 |
+
}
|
| 204 |
+
}
|
metrics/training_metrics.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
metrics/validation_k_curve.json
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"synthetic": {
|
| 3 |
+
"k1": {
|
| 4 |
+
"styles": 4500.0,
|
| 5 |
+
"queries": 40500.0,
|
| 6 |
+
"top1": 0.25738272070884705,
|
| 7 |
+
"top5": 0.4447901248931885,
|
| 8 |
+
"mrr": 0.3484785854816437,
|
| 9 |
+
"margin": -0.13694550096988678,
|
| 10 |
+
"positive_cosine": 0.6166356205940247,
|
| 11 |
+
"hardest_negative_cosine": 0.7535811066627502,
|
| 12 |
+
"verification_auroc": 0.2625024914741516,
|
| 13 |
+
"embedding_std": 0.04349411278963089,
|
| 14 |
+
"embedding_effective_rank": 24.163583755493164,
|
| 15 |
+
"seen_queries": 36000.0,
|
| 16 |
+
"seen_top1": 0.26072221994400024,
|
| 17 |
+
"seen_top5": 0.448972225189209,
|
| 18 |
+
"seen_mrr": 0.35212650895118713,
|
| 19 |
+
"seen_margin": -0.13477584719657898,
|
| 20 |
+
"unseen_queries": 4500.0,
|
| 21 |
+
"unseen_top1": 0.23066666722297668,
|
| 22 |
+
"unseen_top5": 0.4113333523273468,
|
| 23 |
+
"unseen_mrr": 0.3192950487136841,
|
| 24 |
+
"unseen_margin": -0.15430252254009247
|
| 25 |
+
},
|
| 26 |
+
"k2": {
|
| 27 |
+
"styles": 4500.0,
|
| 28 |
+
"queries": 36000.0,
|
| 29 |
+
"top1": 0.38269445300102234,
|
| 30 |
+
"top5": 0.5837222337722778,
|
| 31 |
+
"mrr": 0.479046106338501,
|
| 32 |
+
"margin": -0.0735325887799263,
|
| 33 |
+
"positive_cosine": 0.6810839176177979,
|
| 34 |
+
"hardest_negative_cosine": 0.7546165585517883,
|
| 35 |
+
"verification_auroc": 0.3855718970298767,
|
| 36 |
+
"embedding_std": 0.04349411278963089,
|
| 37 |
+
"embedding_effective_rank": 24.163583755493164,
|
| 38 |
+
"seen_queries": 32000.0,
|
| 39 |
+
"seen_top1": 0.3878125250339508,
|
| 40 |
+
"seen_top5": 0.5885000228881836,
|
| 41 |
+
"seen_mrr": 0.48388049006462097,
|
| 42 |
+
"seen_margin": -0.07155531644821167,
|
| 43 |
+
"unseen_queries": 4000.0,
|
| 44 |
+
"unseen_top1": 0.34175002574920654,
|
| 45 |
+
"unseen_top5": 0.5455000400543213,
|
| 46 |
+
"unseen_mrr": 0.4403711259365082,
|
| 47 |
+
"unseen_margin": -0.08935073763132095
|
| 48 |
+
},
|
| 49 |
+
"k4": {
|
| 50 |
+
"styles": 4500.0,
|
| 51 |
+
"queries": 27000.0,
|
| 52 |
+
"top1": 0.4913703501224518,
|
| 53 |
+
"top5": 0.6868888735771179,
|
| 54 |
+
"mrr": 0.5827372670173645,
|
| 55 |
+
"margin": -0.032036565244197845,
|
| 56 |
+
"positive_cosine": 0.7242447733879089,
|
| 57 |
+
"hardest_negative_cosine": 0.756281316280365,
|
| 58 |
+
"verification_auroc": 0.4890711009502411,
|
| 59 |
+
"embedding_std": 0.04349411278963089,
|
| 60 |
+
"embedding_effective_rank": 24.163583755493164,
|
| 61 |
+
"seen_queries": 24000.0,
|
| 62 |
+
"seen_top1": 0.4964166581630707,
|
| 63 |
+
"seen_top5": 0.6924583315849304,
|
| 64 |
+
"seen_mrr": 0.5878510475158691,
|
| 65 |
+
"seen_margin": -0.030110228806734085,
|
| 66 |
+
"unseen_queries": 3000.0,
|
| 67 |
+
"unseen_top1": 0.45100000500679016,
|
| 68 |
+
"unseen_top5": 0.6423333287239075,
|
| 69 |
+
"unseen_mrr": 0.5418276190757751,
|
| 70 |
+
"unseen_margin": -0.047447264194488525
|
| 71 |
+
},
|
| 72 |
+
"k5": {
|
| 73 |
+
"styles": 4500.0,
|
| 74 |
+
"queries": 22500.0,
|
| 75 |
+
"top1": 0.5625777840614319,
|
| 76 |
+
"top5": 0.7585333585739136,
|
| 77 |
+
"mrr": 0.6518997550010681,
|
| 78 |
+
"margin": -0.006614952813833952,
|
| 79 |
+
"positive_cosine": 0.7365614771842957,
|
| 80 |
+
"hardest_negative_cosine": 0.7431764006614685,
|
| 81 |
+
"verification_auroc": 0.5534452199935913,
|
| 82 |
+
"embedding_std": 0.04349411278963089,
|
| 83 |
+
"embedding_effective_rank": 24.163583755493164,
|
| 84 |
+
"seen_queries": 20000.0,
|
| 85 |
+
"seen_top1": 0.5681999921798706,
|
| 86 |
+
"seen_top5": 0.7637499570846558,
|
| 87 |
+
"seen_mrr": 0.6573799848556519,
|
| 88 |
+
"seen_margin": -0.004584707319736481,
|
| 89 |
+
"unseen_queries": 2500.0,
|
| 90 |
+
"unseen_top1": 0.5175999999046326,
|
| 91 |
+
"unseen_top5": 0.7167999744415283,
|
| 92 |
+
"unseen_mrr": 0.6080579161643982,
|
| 93 |
+
"unseen_margin": -0.02285691164433956,
|
| 94 |
+
"matched_queries": 4500.0,
|
| 95 |
+
"matched_top1": 0.48955556750297546,
|
| 96 |
+
"matched_top5": 0.6902222037315369,
|
| 97 |
+
"matched_mrr": 0.5840909481048584,
|
| 98 |
+
"matched_margin": -0.030851511284708977,
|
| 99 |
+
"cross_queries": 18000.0,
|
| 100 |
+
"cross_top1": 0.5808333158493042,
|
| 101 |
+
"cross_top5": 0.7756111025810242,
|
| 102 |
+
"cross_mrr": 0.6688519716262817,
|
| 103 |
+
"cross_margin": -0.0005558129050768912
|
| 104 |
+
},
|
| 105 |
+
"k8": {
|
| 106 |
+
"styles": 4500.0,
|
| 107 |
+
"queries": 9000.0,
|
| 108 |
+
"top1": 0.5631111264228821,
|
| 109 |
+
"top5": 0.7501111030578613,
|
| 110 |
+
"mrr": 0.6487501263618469,
|
| 111 |
+
"margin": -0.006703122518956661,
|
| 112 |
+
"positive_cosine": 0.7508071660995483,
|
| 113 |
+
"hardest_negative_cosine": 0.7575103044509888,
|
| 114 |
+
"verification_auroc": 0.557915985584259,
|
| 115 |
+
"embedding_std": 0.04349411278963089,
|
| 116 |
+
"embedding_effective_rank": 24.163583755493164,
|
| 117 |
+
"seen_queries": 8000.0,
|
| 118 |
+
"seen_top1": 0.5692500472068787,
|
| 119 |
+
"seen_top5": 0.7573750615119934,
|
| 120 |
+
"seen_mrr": 0.6548616290092468,
|
| 121 |
+
"seen_margin": -0.004510539583861828,
|
| 122 |
+
"unseen_queries": 1000.0,
|
| 123 |
+
"unseen_top1": 0.5139999985694885,
|
| 124 |
+
"unseen_top5": 0.6920000314712524,
|
| 125 |
+
"unseen_mrr": 0.5998580455780029,
|
| 126 |
+
"unseen_margin": -0.024243783205747604
|
| 127 |
+
}
|
| 128 |
+
},
|
| 129 |
+
"human": {
|
| 130 |
+
"k1": {
|
| 131 |
+
"styles": 4500.0,
|
| 132 |
+
"queries": 40500.0,
|
| 133 |
+
"top1": 0.37967902421951294,
|
| 134 |
+
"top5": 0.5846666693687439,
|
| 135 |
+
"mrr": 0.47633036971092224,
|
| 136 |
+
"margin": -0.07382111996412277,
|
| 137 |
+
"positive_cosine": 0.6724859476089478,
|
| 138 |
+
"hardest_negative_cosine": 0.7463070750236511,
|
| 139 |
+
"verification_auroc": 0.38891345262527466,
|
| 140 |
+
"embedding_std": 0.043804656714200974,
|
| 141 |
+
"embedding_effective_rank": 27.383806228637695,
|
| 142 |
+
"seen_queries": 36000.0,
|
| 143 |
+
"seen_top1": 0.3872777819633484,
|
| 144 |
+
"seen_top5": 0.5945833325386047,
|
| 145 |
+
"seen_mrr": 0.48492416739463806,
|
| 146 |
+
"seen_margin": -0.06964229047298431,
|
| 147 |
+
"unseen_queries": 4500.0,
|
| 148 |
+
"unseen_top1": 0.31888890266418457,
|
| 149 |
+
"unseen_top5": 0.5053333640098572,
|
| 150 |
+
"unseen_mrr": 0.40757980942726135,
|
| 151 |
+
"unseen_margin": -0.10725177824497223
|
| 152 |
+
},
|
| 153 |
+
"k2": {
|
| 154 |
+
"styles": 4500.0,
|
| 155 |
+
"queries": 36000.0,
|
| 156 |
+
"top1": 0.5184444785118103,
|
| 157 |
+
"top5": 0.7187777757644653,
|
| 158 |
+
"mrr": 0.6118195652961731,
|
| 159 |
+
"margin": -0.018171189352869987,
|
| 160 |
+
"positive_cosine": 0.7339839339256287,
|
| 161 |
+
"hardest_negative_cosine": 0.7521551847457886,
|
| 162 |
+
"verification_auroc": 0.516968846321106,
|
| 163 |
+
"embedding_std": 0.043804656714200974,
|
| 164 |
+
"embedding_effective_rank": 27.383806228637695,
|
| 165 |
+
"seen_queries": 32000.0,
|
| 166 |
+
"seen_top1": 0.5287187695503235,
|
| 167 |
+
"seen_top5": 0.729593813419342,
|
| 168 |
+
"seen_mrr": 0.6219512224197388,
|
| 169 |
+
"seen_margin": -0.014534689486026764,
|
| 170 |
+
"unseen_queries": 4000.0,
|
| 171 |
+
"unseen_top1": 0.4362500309944153,
|
| 172 |
+
"unseen_top5": 0.6322500109672546,
|
| 173 |
+
"unseen_mrr": 0.5307666063308716,
|
| 174 |
+
"unseen_margin": -0.04726320877671242
|
| 175 |
+
},
|
| 176 |
+
"k4": {
|
| 177 |
+
"styles": 4500.0,
|
| 178 |
+
"queries": 27000.0,
|
| 179 |
+
"top1": 0.6229629516601562,
|
| 180 |
+
"top5": 0.8089629411697388,
|
| 181 |
+
"mrr": 0.7071906924247742,
|
| 182 |
+
"margin": 0.01628497801721096,
|
| 183 |
+
"positive_cosine": 0.7733137607574463,
|
| 184 |
+
"hardest_negative_cosine": 0.7570288181304932,
|
| 185 |
+
"verification_auroc": 0.6160270571708679,
|
| 186 |
+
"embedding_std": 0.043804656714200974,
|
| 187 |
+
"embedding_effective_rank": 27.383806228637695,
|
| 188 |
+
"seen_queries": 24000.0,
|
| 189 |
+
"seen_top1": 0.6336249709129333,
|
| 190 |
+
"seen_top5": 0.8175833225250244,
|
| 191 |
+
"seen_mrr": 0.7167206406593323,
|
| 192 |
+
"seen_margin": 0.019602350890636444,
|
| 193 |
+
"unseen_queries": 3000.0,
|
| 194 |
+
"unseen_top1": 0.5376666784286499,
|
| 195 |
+
"unseen_top5": 0.7400000095367432,
|
| 196 |
+
"unseen_mrr": 0.6309514045715332,
|
| 197 |
+
"unseen_margin": -0.01025400310754776
|
| 198 |
+
},
|
| 199 |
+
"k5": {
|
| 200 |
+
"styles": 4500.0,
|
| 201 |
+
"queries": 22500.0,
|
| 202 |
+
"top1": 0.6493777632713318,
|
| 203 |
+
"top5": 0.8219555616378784,
|
| 204 |
+
"mrr": 0.7280733585357666,
|
| 205 |
+
"margin": 0.022814957424998283,
|
| 206 |
+
"positive_cosine": 0.7811680436134338,
|
| 207 |
+
"hardest_negative_cosine": 0.7583531141281128,
|
| 208 |
+
"verification_auroc": 0.6369090676307678,
|
| 209 |
+
"embedding_std": 0.043804656714200974,
|
| 210 |
+
"embedding_effective_rank": 27.383806228637695,
|
| 211 |
+
"seen_queries": 20000.0,
|
| 212 |
+
"seen_top1": 0.660099983215332,
|
| 213 |
+
"seen_top5": 0.830549955368042,
|
| 214 |
+
"seen_mrr": 0.7378283143043518,
|
| 215 |
+
"seen_margin": 0.026178810745477676,
|
| 216 |
+
"unseen_queries": 2500.0,
|
| 217 |
+
"unseen_top1": 0.5636000037193298,
|
| 218 |
+
"unseen_top5": 0.7531999945640564,
|
| 219 |
+
"unseen_mrr": 0.6500336527824402,
|
| 220 |
+
"unseen_margin": -0.004095893818885088
|
| 221 |
+
},
|
| 222 |
+
"k8": {
|
| 223 |
+
"styles": 4500.0,
|
| 224 |
+
"queries": 9000.0,
|
| 225 |
+
"top1": 0.6846666932106018,
|
| 226 |
+
"top5": 0.8516666889190674,
|
| 227 |
+
"mrr": 0.7596060037612915,
|
| 228 |
+
"margin": 0.03352390229701996,
|
| 229 |
+
"positive_cosine": 0.793936014175415,
|
| 230 |
+
"hardest_negative_cosine": 0.7604120373725891,
|
| 231 |
+
"verification_auroc": 0.6696112155914307,
|
| 232 |
+
"embedding_std": 0.043804656714200974,
|
| 233 |
+
"embedding_effective_rank": 27.383806228637695,
|
| 234 |
+
"seen_queries": 8000.0,
|
| 235 |
+
"seen_top1": 0.6943750381469727,
|
| 236 |
+
"seen_top5": 0.85875004529953,
|
| 237 |
+
"seen_mrr": 0.7680479884147644,
|
| 238 |
+
"seen_margin": 0.03656964749097824,
|
| 239 |
+
"unseen_queries": 1000.0,
|
| 240 |
+
"unseen_top1": 0.6070000529289246,
|
| 241 |
+
"unseen_top5": 0.7950000166893005,
|
| 242 |
+
"unseen_mrr": 0.6920705437660217,
|
| 243 |
+
"unseen_margin": 0.009157972410321236
|
| 244 |
+
}
|
| 245 |
+
},
|
| 246 |
+
"checkpoint_score": 0.6290457844734192,
|
| 247 |
+
"checkpoint_config": {
|
| 248 |
+
"packed_manifest_sha256": "c1267b9fd45c6e0d222b91d6ae2291b36b763277cc39cbc32484874ffeae9b32",
|
| 249 |
+
"use_anima": true,
|
| 250 |
+
"face_dropout": 0.3,
|
| 251 |
+
"episode_pairs": 8,
|
| 252 |
+
"seed": 20260719
|
| 253 |
+
}
|
| 254 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6cdf126152927f6e31dc856a8d10b8decee3bb20ce4c0ca449206db65d4633ec
|
| 3 |
+
size 69962484
|
modeling_anima_style_embedding.py
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import math
|
| 4 |
+
|
| 5 |
+
import torch
|
| 6 |
+
from torch import Tensor, nn
|
| 7 |
+
from torch.nn import functional as F
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def masked_mean_prototype(per_image: Tensor, mask: Tensor) -> Tensor:
|
| 11 |
+
if per_image.ndim != 3 or mask.shape != per_image.shape[:2]:
|
| 12 |
+
raise ValueError("expected per_image [batch,references,width] and matching mask")
|
| 13 |
+
mask = mask.to(device=per_image.device, dtype=torch.bool)
|
| 14 |
+
counts = mask.sum(dim=1)
|
| 15 |
+
if torch.any(counts < 1) or torch.any(counts > 8):
|
| 16 |
+
raise ValueError("each reference set must contain 1-8 images")
|
| 17 |
+
weights = mask.unsqueeze(-1).to(per_image.dtype)
|
| 18 |
+
mean = (per_image * weights).sum(dim=1) / counts.unsqueeze(-1)
|
| 19 |
+
return F.normalize(mean, dim=-1)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class StyleMixerBlock(nn.Module):
|
| 23 |
+
def __init__(self, width: int, heads: int, dropout: float = 0.0) -> None:
|
| 24 |
+
super().__init__()
|
| 25 |
+
self.query_norm = nn.LayerNorm(width)
|
| 26 |
+
self.token_norm = nn.LayerNorm(width)
|
| 27 |
+
self.attention = nn.MultiheadAttention(width, heads, batch_first=True)
|
| 28 |
+
self.attention_dropout = nn.Dropout(dropout)
|
| 29 |
+
self.output_norm = nn.LayerNorm(width)
|
| 30 |
+
self.mlp = nn.Sequential(
|
| 31 |
+
nn.Linear(width, 4 * width),
|
| 32 |
+
nn.GELU(),
|
| 33 |
+
nn.Dropout(dropout),
|
| 34 |
+
nn.Linear(4 * width, width),
|
| 35 |
+
nn.Dropout(dropout),
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
def forward(self, query: Tensor, tokens: Tensor, token_mask: Tensor) -> Tensor:
|
| 39 |
+
value, _ = self.attention(
|
| 40 |
+
self.query_norm(query),
|
| 41 |
+
self.token_norm(tokens),
|
| 42 |
+
self.token_norm(tokens),
|
| 43 |
+
key_padding_mask=~token_mask,
|
| 44 |
+
need_weights=False,
|
| 45 |
+
)
|
| 46 |
+
query = query + self.attention_dropout(value)
|
| 47 |
+
return query + self.mlp(self.output_norm(query))
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
class UnifiedStyleEncoder(nn.Module):
|
| 51 |
+
"""Encode cached full/face vision tokens and optional Anima descriptors."""
|
| 52 |
+
|
| 53 |
+
def __init__(
|
| 54 |
+
self,
|
| 55 |
+
*,
|
| 56 |
+
external_dim: int = 1152,
|
| 57 |
+
external_tokens: int = 30,
|
| 58 |
+
anima_dim: int = 4096,
|
| 59 |
+
anima_tokens: int = 3,
|
| 60 |
+
width: int = 384,
|
| 61 |
+
blocks: int = 2,
|
| 62 |
+
heads: int = 6,
|
| 63 |
+
embedding_dim: int = 512,
|
| 64 |
+
use_anima: bool = True,
|
| 65 |
+
dropout: float = 0.0,
|
| 66 |
+
reference_grounding: bool = False,
|
| 67 |
+
functional_factors: bool = False,
|
| 68 |
+
) -> None:
|
| 69 |
+
super().__init__()
|
| 70 |
+
if (
|
| 71 |
+
blocks < 1
|
| 72 |
+
or width % heads
|
| 73 |
+
or (reference_grounding and embedding_dim % heads)
|
| 74 |
+
or not 0.0 <= dropout < 1.0
|
| 75 |
+
):
|
| 76 |
+
raise ValueError("blocks must be positive and width must be divisible by heads")
|
| 77 |
+
if functional_factors and embedding_dim != 512:
|
| 78 |
+
raise ValueError("functional factorization currently requires a 512-D embedding")
|
| 79 |
+
self.external_tokens = external_tokens
|
| 80 |
+
self.anima_tokens = anima_tokens if use_anima else 0
|
| 81 |
+
self.external_projector = nn.Sequential(
|
| 82 |
+
nn.LayerNorm(external_dim),
|
| 83 |
+
nn.Linear(external_dim, width),
|
| 84 |
+
)
|
| 85 |
+
self.anima_projector = (
|
| 86 |
+
nn.Sequential(nn.LayerNorm(anima_dim), nn.Linear(anima_dim, width))
|
| 87 |
+
if use_anima
|
| 88 |
+
else None
|
| 89 |
+
)
|
| 90 |
+
self.full_positions = nn.Parameter(torch.randn(external_tokens, width) * 0.02)
|
| 91 |
+
self.face_positions = nn.Parameter(torch.randn(external_tokens, width) * 0.02)
|
| 92 |
+
self.anima_positions = (
|
| 93 |
+
nn.Parameter(torch.randn(anima_tokens, width) * 0.02) if use_anima else None
|
| 94 |
+
)
|
| 95 |
+
self.reference_grounding = reference_grounding
|
| 96 |
+
self.functional_factors = functional_factors
|
| 97 |
+
query_count = 5 if functional_factors else 1
|
| 98 |
+
self.style_query = nn.Parameter(torch.randn(1, query_count, width) * 0.02)
|
| 99 |
+
self.blocks = nn.ModuleList(
|
| 100 |
+
[StyleMixerBlock(width, heads, dropout) for _ in range(blocks)]
|
| 101 |
+
)
|
| 102 |
+
if functional_factors:
|
| 103 |
+
self.factor_output = nn.Sequential(nn.LayerNorm(width), nn.Linear(width, 96))
|
| 104 |
+
self.shared_output = nn.Sequential(nn.LayerNorm(width), nn.Linear(width, 128))
|
| 105 |
+
self.output = nn.Sequential(nn.LayerNorm(512), nn.Linear(512, embedding_dim))
|
| 106 |
+
self.factor_decoders = nn.ModuleList([nn.Linear(96, external_dim) for _ in range(4)])
|
| 107 |
+
else:
|
| 108 |
+
self.output = nn.Sequential(nn.LayerNorm(width), nn.Linear(width, embedding_dim))
|
| 109 |
+
if reference_grounding:
|
| 110 |
+
self.consensus_query = nn.Parameter(torch.randn(1, 1, embedding_dim) * 0.02)
|
| 111 |
+
self.consensus_attention = nn.MultiheadAttention(
|
| 112 |
+
embedding_dim, heads, batch_first=True, dropout=dropout
|
| 113 |
+
)
|
| 114 |
+
self.consensus_condition = nn.Linear(embedding_dim, width)
|
| 115 |
+
self.consensus_gamma = nn.Parameter(torch.tensor(-2.9444))
|
| 116 |
+
|
| 117 |
+
def _read_tokens(
|
| 118 |
+
self, tokens: Tensor, token_mask: Tensor, conditioning: Tensor | None = None
|
| 119 |
+
) -> tuple[Tensor, Tensor | None]:
|
| 120 |
+
query = self.style_query.expand(tokens.shape[0], -1, -1)
|
| 121 |
+
if conditioning is not None:
|
| 122 |
+
query = query + self.consensus_condition(conditioning)[:, None]
|
| 123 |
+
for block in self.blocks:
|
| 124 |
+
query = block(query, tokens, token_mask)
|
| 125 |
+
if self.functional_factors:
|
| 126 |
+
factors = F.normalize(self.factor_output(query[:, :4]), dim=-1)
|
| 127 |
+
shared = self.shared_output(query[:, 4])
|
| 128 |
+
embedding = self.output(torch.cat((factors.flatten(1), shared), dim=-1))
|
| 129 |
+
return F.normalize(embedding, dim=-1), factors
|
| 130 |
+
return F.normalize(self.output(query[:, 0]), dim=-1), None
|
| 131 |
+
|
| 132 |
+
def encode_images(
|
| 133 |
+
self,
|
| 134 |
+
full_features: Tensor,
|
| 135 |
+
*,
|
| 136 |
+
face_features: Tensor | None = None,
|
| 137 |
+
face_mask: Tensor | None = None,
|
| 138 |
+
anima_features: Tensor | None = None,
|
| 139 |
+
conditioning: Tensor | None = None,
|
| 140 |
+
) -> Tensor:
|
| 141 |
+
"""Encode independent images without padding them into reference sets."""
|
| 142 |
+
|
| 143 |
+
if full_features.ndim != 3 or full_features.shape[1] != self.external_tokens:
|
| 144 |
+
raise ValueError("full_features must have shape [images,external_tokens,width]")
|
| 145 |
+
images = full_features.shape[0]
|
| 146 |
+
full = self.external_projector(full_features) + self.full_positions
|
| 147 |
+
tokens = [full]
|
| 148 |
+
masks = [torch.ones(full.shape[:2], dtype=torch.bool, device=full.device)]
|
| 149 |
+
|
| 150 |
+
if face_features is not None:
|
| 151 |
+
if face_features.shape != full_features.shape:
|
| 152 |
+
raise ValueError("face_features must match full_features")
|
| 153 |
+
if face_mask is None or face_mask.shape != (images,):
|
| 154 |
+
raise ValueError("face_mask is required and must contain one value per image")
|
| 155 |
+
face = self.external_projector(face_features)
|
| 156 |
+
tokens.append(face + self.face_positions)
|
| 157 |
+
masks.append(face_mask[:, None].to(torch.bool).expand(-1, self.external_tokens))
|
| 158 |
+
|
| 159 |
+
if self.anima_projector is not None:
|
| 160 |
+
expected = (images, self.anima_tokens)
|
| 161 |
+
if anima_features is None or anima_features.shape[:2] != expected:
|
| 162 |
+
raise ValueError("anima_features are required by this encoder configuration")
|
| 163 |
+
anima = self.anima_projector(anima_features)
|
| 164 |
+
tokens.append(anima + self.anima_positions)
|
| 165 |
+
masks.append(torch.ones(anima.shape[:2], dtype=torch.bool, device=anima.device))
|
| 166 |
+
|
| 167 |
+
token_tensor = torch.cat(tokens, dim=1)
|
| 168 |
+
token_mask = torch.cat(masks, dim=1)
|
| 169 |
+
return self._read_tokens(token_tensor, token_mask, conditioning)[0]
|
| 170 |
+
|
| 171 |
+
def encode_images_with_factors(
|
| 172 |
+
self,
|
| 173 |
+
full_features: Tensor,
|
| 174 |
+
*,
|
| 175 |
+
face_features: Tensor | None = None,
|
| 176 |
+
face_mask: Tensor | None = None,
|
| 177 |
+
anima_features: Tensor | None = None,
|
| 178 |
+
conditioning: Tensor | None = None,
|
| 179 |
+
) -> tuple[Tensor, Tensor | None]:
|
| 180 |
+
if full_features.ndim != 3 or full_features.shape[1] != self.external_tokens:
|
| 181 |
+
raise ValueError("full_features must have shape [images,external_tokens,width]")
|
| 182 |
+
images = full_features.shape[0]
|
| 183 |
+
full = self.external_projector(full_features) + self.full_positions
|
| 184 |
+
tokens = [full]
|
| 185 |
+
masks = [torch.ones(full.shape[:2], dtype=torch.bool, device=full.device)]
|
| 186 |
+
if face_features is not None:
|
| 187 |
+
if face_features.shape != full_features.shape:
|
| 188 |
+
raise ValueError("face_features must match full_features")
|
| 189 |
+
if face_mask is None or face_mask.shape != (images,):
|
| 190 |
+
raise ValueError("face_mask is required and must contain one value per image")
|
| 191 |
+
tokens.append(self.external_projector(face_features) + self.face_positions)
|
| 192 |
+
masks.append(face_mask[:, None].to(torch.bool).expand(-1, self.external_tokens))
|
| 193 |
+
if self.anima_projector is not None:
|
| 194 |
+
if anima_features is None or anima_features.shape[:2] != (images, self.anima_tokens):
|
| 195 |
+
raise ValueError("anima_features are required by this encoder configuration")
|
| 196 |
+
tokens.append(self.anima_projector(anima_features) + self.anima_positions)
|
| 197 |
+
masks.append(torch.ones(anima_features.shape[:2], dtype=torch.bool, device=full.device))
|
| 198 |
+
return self._read_tokens(torch.cat(tokens, dim=1), torch.cat(masks, dim=1), conditioning)
|
| 199 |
+
|
| 200 |
+
def encode_reference_sets(
|
| 201 |
+
self,
|
| 202 |
+
full_features: Tensor,
|
| 203 |
+
reference_mask: Tensor,
|
| 204 |
+
*,
|
| 205 |
+
face_features: Tensor | None = None,
|
| 206 |
+
face_mask: Tensor | None = None,
|
| 207 |
+
anima_features: Tensor | None = None,
|
| 208 |
+
) -> tuple[Tensor, Tensor, Tensor | None]:
|
| 209 |
+
batch, references = full_features.shape[:2]
|
| 210 |
+
flat_face = None if face_features is None else face_features.flatten(0, 1)
|
| 211 |
+
flat_face_mask = None if face_mask is None else face_mask.flatten()
|
| 212 |
+
flat_anima = None if anima_features is None else anima_features.flatten(0, 1)
|
| 213 |
+
per_image, factors = self.encode_images_with_factors(
|
| 214 |
+
full_features.flatten(0, 1),
|
| 215 |
+
face_features=flat_face,
|
| 216 |
+
face_mask=flat_face_mask,
|
| 217 |
+
anima_features=flat_anima,
|
| 218 |
+
)
|
| 219 |
+
per_image = per_image.reshape(batch, references, -1)
|
| 220 |
+
factors = None if factors is None else factors.reshape(batch, references, 4, -1)
|
| 221 |
+
base = masked_mean_prototype(per_image, reference_mask)
|
| 222 |
+
if not self.reference_grounding:
|
| 223 |
+
return base, per_image, factors
|
| 224 |
+
consensus, _ = self.consensus_attention(
|
| 225 |
+
self.consensus_query.expand(batch, -1, -1),
|
| 226 |
+
per_image,
|
| 227 |
+
per_image,
|
| 228 |
+
key_padding_mask=~reference_mask,
|
| 229 |
+
need_weights=False,
|
| 230 |
+
)
|
| 231 |
+
consensus = F.normalize(consensus[:, 0], dim=-1)
|
| 232 |
+
reread, factors = self.encode_images_with_factors(
|
| 233 |
+
full_features.flatten(0, 1),
|
| 234 |
+
face_features=flat_face,
|
| 235 |
+
face_mask=flat_face_mask,
|
| 236 |
+
anima_features=flat_anima,
|
| 237 |
+
conditioning=consensus[:, None].expand(-1, references, -1).reshape(batch * references, -1),
|
| 238 |
+
)
|
| 239 |
+
reread = reread.reshape(batch, references, -1)
|
| 240 |
+
factors = None if factors is None else factors.reshape(batch, references, 4, -1)
|
| 241 |
+
agreement = F.cosine_similarity(reread, consensus[:, None], dim=-1)
|
| 242 |
+
centered = agreement - (
|
| 243 |
+
(agreement * reference_mask).sum(1, keepdim=True)
|
| 244 |
+
/ reference_mask.sum(1, keepdim=True).clamp_min(1)
|
| 245 |
+
)
|
| 246 |
+
weights = (1.0 + 0.25 * torch.tanh(4.0 * centered)) * reference_mask
|
| 247 |
+
grounded = F.normalize((reread * weights[..., None]).sum(1) / weights.sum(1, keepdim=True), dim=-1)
|
| 248 |
+
gamma = torch.sigmoid(self.consensus_gamma)
|
| 249 |
+
return F.normalize(base + gamma * (grounded - base), dim=-1), reread, factors
|
| 250 |
+
|
| 251 |
+
def functional_response_loss(self, factor_codes: Tensor, full_features: Tensor) -> Tensor:
|
| 252 |
+
"""Reconstruct artist response after removing a shared prompt/seed cell mean."""
|
| 253 |
+
if not self.functional_factors:
|
| 254 |
+
return full_features.new_zeros(())
|
| 255 |
+
groups = ((2, 3, 4, 5), (0, 6, 24), tuple(range(8, 24)), (1, 7, 25))
|
| 256 |
+
losses = []
|
| 257 |
+
for index, token_indices in enumerate(groups):
|
| 258 |
+
teacher = full_features[..., list(token_indices), :].float().mean(dim=-2)
|
| 259 |
+
teacher = F.normalize(teacher - teacher.mean(dim=1, keepdim=True), dim=-1)
|
| 260 |
+
prediction = F.normalize(self.factor_decoders[index](factor_codes[..., index, :]).float(), dim=-1)
|
| 261 |
+
losses.append((1.0 - F.cosine_similarity(prediction, teacher, dim=-1)).mean())
|
| 262 |
+
return torch.stack(losses).mean()
|
| 263 |
+
|
| 264 |
+
def forward(
|
| 265 |
+
self,
|
| 266 |
+
full_features: Tensor,
|
| 267 |
+
reference_mask: Tensor,
|
| 268 |
+
*,
|
| 269 |
+
face_features: Tensor | None = None,
|
| 270 |
+
face_mask: Tensor | None = None,
|
| 271 |
+
anima_features: Tensor | None = None,
|
| 272 |
+
) -> tuple[Tensor, Tensor]:
|
| 273 |
+
if full_features.ndim != 4 or full_features.shape[2] != self.external_tokens:
|
| 274 |
+
raise ValueError("full_features must have shape [batch,references,external_tokens,width]")
|
| 275 |
+
batch, references = full_features.shape[:2]
|
| 276 |
+
if reference_mask.shape != (batch, references):
|
| 277 |
+
raise ValueError("reference_mask shape does not match full_features")
|
| 278 |
+
|
| 279 |
+
prototype, per_image, _ = self.encode_reference_sets(
|
| 280 |
+
full_features,
|
| 281 |
+
reference_mask,
|
| 282 |
+
face_features=face_features,
|
| 283 |
+
face_mask=face_mask,
|
| 284 |
+
anima_features=anima_features,
|
| 285 |
+
)
|
| 286 |
+
return prototype, per_image
|
| 287 |
+
|
| 288 |
+
|
| 289 |
+
class AngularPrototypeLoss(nn.Module):
|
| 290 |
+
"""Episode prototype softmax with an optional ArcFace-style positive margin."""
|
| 291 |
+
|
| 292 |
+
def __init__(
|
| 293 |
+
self, initial_scale: float = 10.0, initial_bias: float | None = None
|
| 294 |
+
) -> None:
|
| 295 |
+
super().__init__()
|
| 296 |
+
if initial_scale <= 0:
|
| 297 |
+
raise ValueError("initial_scale must be positive")
|
| 298 |
+
self.raw_scale = nn.Parameter(torch.tensor(math.log(math.expm1(initial_scale))))
|
| 299 |
+
# initial_bias remains accepted for feasibility-script compatibility. A
|
| 300 |
+
# common softmax bias is a no-op and is not a trainable production parameter.
|
| 301 |
+
|
| 302 |
+
def forward(
|
| 303 |
+
self,
|
| 304 |
+
queries: Tensor,
|
| 305 |
+
prototypes: Tensor,
|
| 306 |
+
targets: Tensor,
|
| 307 |
+
*,
|
| 308 |
+
margin: float = 0.0,
|
| 309 |
+
) -> tuple[Tensor, Tensor]:
|
| 310 |
+
if queries.ndim < 2 or prototypes.ndim != queries.ndim:
|
| 311 |
+
raise ValueError("queries and prototypes must have matching [episode,...,width] ranks")
|
| 312 |
+
if queries.shape[:-2] != prototypes.shape[:-2] or queries.shape[-1] != prototypes.shape[-1]:
|
| 313 |
+
raise ValueError("queries and prototypes must have matching episode axes and widths")
|
| 314 |
+
if targets.shape != queries.shape[:-1]:
|
| 315 |
+
raise ValueError("targets must contain one class index per query")
|
| 316 |
+
# Autocast can round a near-perfect BF16 cosine to exactly one. ArcFace's
|
| 317 |
+
# sqrt(1-cos²) derivative is then singular, so margin math and CE stay FP32.
|
| 318 |
+
cosine = (
|
| 319 |
+
F.normalize(queries, dim=-1)
|
| 320 |
+
@ F.normalize(prototypes, dim=-1).transpose(-1, -2)
|
| 321 |
+
).float()
|
| 322 |
+
loss_cosine = cosine
|
| 323 |
+
if margin:
|
| 324 |
+
if not 0.0 <= margin < math.pi / 2:
|
| 325 |
+
raise ValueError("margin must be in [0, pi/2)")
|
| 326 |
+
positive = cosine.gather(-1, targets.unsqueeze(-1)).clamp(-1 + 1e-6, 1 - 1e-6)
|
| 327 |
+
positive_margin = positive * math.cos(margin) - torch.sqrt(1 - positive.square()) * math.sin(margin)
|
| 328 |
+
loss_cosine = cosine.scatter(-1, targets.unsqueeze(-1), positive_margin)
|
| 329 |
+
scale = F.softplus(self.raw_scale).clamp_max(100.0)
|
| 330 |
+
loss_logits = scale * loss_cosine
|
| 331 |
+
metric_logits = scale * cosine
|
| 332 |
+
return (
|
| 333 |
+
F.cross_entropy(loss_logits.flatten(0, -2), targets.flatten()),
|
| 334 |
+
metric_logits,
|
| 335 |
+
)
|
| 336 |
+
|
| 337 |
+
|
| 338 |
+
def subset_consistency_loss(first: Tensor, second: Tensor) -> Tensor:
|
| 339 |
+
if first.shape != second.shape or first.ndim != 2:
|
| 340 |
+
raise ValueError("subset prototypes must have equal [batch,width] shapes")
|
| 341 |
+
return (1.0 - F.cosine_similarity(first, second, dim=-1)).mean()
|
requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
torch>=2.4
|
| 2 |
+
safetensors>=0.4
|
| 3 |
+
huggingface_hub>=0.28
|