File size: 39,010 Bytes
ff820d7 fe905c2 ff820d7 fe905c2 369c342 fe905c2 369c342 862620a fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 862620a fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 862620a fe905c2 369c342 fe905c2 862620a fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 862620a fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 369c342 fe905c2 ff820d7 369c342 ff820d7 369c342 862620a ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 862620a ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 862620a ff820d7 369c342 ff820d7 862620a ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 862620a ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 369c342 ff820d7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 | ---
language:
- en
- it
tags:
- pytorch
- outfit-transformer
- fashion
- compatibility-prediction
- complementary-item-retrieval
- embeddings
---
> [!NOTE]
> This README is available in English below and in [Italian / italiano](#versione-italiana).
> La [versione italiana](#versione-italiana) si trova nella seconda parte del documento.
> [!IMPORTANT]
> These weights were trained and used with my **OutfitTransformer** model, available in the [FlorindoDev/OutfitTransformer](https://github.com/FlorindoDev/OutfitTransformer) repository. To use them, refer to that project's code, architecture, and instructions.
# OutfitTransformer: Weights and precomputed embeddings
This repository contains checkpoints trained with my implementation of
OutfitTransformer and **precomputed embeddings** for the project's training
and evaluation workflows.
The source code, model configuration, and usage instructions are available on
[GitHub](https://github.com/FlorindoDev/OutfitTransformer).
It includes **cp_precomputed-flashionclip** (Compatibility Prediction) and
**cir_precomputed-flashionclip** (Complementary Item Retrieval) checkpoints for
both Polyvore subsets, `nondisjoint` and `disjoint`. FashionCLIP embeddings
are available for both subsets, with Marqo FashionSigLIP embeddings also
included for `nondisjoint`. Each cache has train, validation, and test splits.
## Results
Results on Polyvore, split `test`, with precomputed embeddings, grouped by
`nondisjoint` and `disjoint` subsets. Metrics use a 0β1 scale, rounded to four
decimal places.
### Nondisjoint
| Metric / run detail | CP |
|---|---:|
| Checkpoint epoch | 76 |
| Evaluated examples | 20000 |
| Accuracy | 0.8478 |
| Precision | 0.9489 |
| Recall | 0.7352 |
| F1 | 0.8285 |
| ROC AUC | 0.9513 |
| Metric / run detail | CIR FITB |
|---|---:|
| Checkpoint epoch | 19 |
| Evaluated examples | 10000 |
| FITB accuracy | 0.6807 |
| MRR | 0.8169 |
| Recall@2 | 0.8782 |
CIR tests were run without `category_emb`.
### Disjoint
| Metric / run detail | CP |
|---|---:|
| Checkpoint epoch | 76 |
| Evaluated examples | 30290 |
| Accuracy | 0.6904 |
| Precision | 0.9816 |
| Recall | 0.3880 |
| F1 | 0.5561 |
| ROC AUC | 0.9202 |
| Metric / run detail | CIR FITB |
|---|---:|
| Checkpoint epoch | 22 |
| Evaluated examples | 15145 |
| FITB accuracy | 0.6640 |
| MRR | 0.8063 |
| Recall@2 | 0.8664 |
CIR tests were run without `category_emb`.
## Contents and organization
Artifacts are organized as follows. Each run contains `best.pt`, `config.json`,
individual epoch checkpoints in `epochs/`, and plots in `plots/`.
```text
.
βββ README.md
βββ .gitattributes
βββ checkpoints/
β βββ nondisjoint/
β β βββ cp_precomputed-flashionclip/
β β βββ cir_precomputed-flashionclip/
β βββ disjoint/
β βββ cp_precomputed-flashionclip/
β βββ cir_precomputed-flashionclip/
βββ precomputed_embeddings/
βββ fashionCLIP/
β βββ nondisjoint/
β β βββ train/
β β βββ validation/
β β βββ test/
β βββ disjoint/
β βββ train/
β βββ validation/
β βββ test/
βββ fashionSigLIP/
βββ nondisjoint/
βββ train/
βββ validation/
βββ test/
```
## Parameters and hyperparameters of the published runs
Values come from the four saved configurations, checked against `run_config`
in their respective `best.pt` files. Progress and validation metrics come from
the local checkpoints; test results are listed separately above. Shared tables
apply to both subsets unless stated otherwise. `null` indicates an unset value;
**not recorded** indicates a field absent from the saved configuration.
| Subset | CP | CIR |
| --- | --- | --- |
| `nondisjoint` | [config.json](checkpoints/nondisjoint/cp_precomputed-flashionclip/config.json) | [config.json](checkpoints/nondisjoint/cir_precomputed-flashionclip/config.json) |
| `disjoint` | [config.json](checkpoints/disjoint/cp_precomputed-flashionclip/config.json) | [config.json](checkpoints/disjoint/cir_precomputed-flashionclip/config.json) |
### Checkpoints and recorded progress
#### Nondisjoint
| Parameter | CP | CIR |
| --- | --- | --- |
| Run folder | `checkpoints/nondisjoint/cp_precomputed-flashionclip/` | `checkpoints/nondisjoint/cir_precomputed-flashionclip/` |
| Checkpoint format version (`checkpoint_schema_version`) | `2` | `1` |
| Configured maximum epochs (`training.epochs`) | `200` | `200` |
| Available epoch checkpoints | `77` (`1β77`) | `24` (`1β24`) |
| Latest available checkpoint | `epochs/cp_epoch_077.pt` | `epochs/cir_epoch_024.pt` |
| Epoch of `best.pt` | `76` | `19` |
| Selection metric (`training.best_metric`) | `val_auc` | `val_fitb_accuracy` |
| Validation metric in the best checkpoint | `0.95184712` | `0.6830` |
| Training examples in the best epoch | `106612` | `53248` |
| Validation examples in the best epoch | `10000` | `5000` |
#### Disjoint
| Parameter | CP | CIR |
| --- | --- | --- |
| Run folder | `checkpoints/disjoint/cp_precomputed-flashionclip/` | `checkpoints/disjoint/cir_precomputed-flashionclip/` |
| Checkpoint format version (`checkpoint_schema_version`) | `2` | `1` |
| Configured maximum epochs (`training.epochs`) | `200` | `200` |
| Available epoch checkpoints | `27` (`50β76`) | `22` (`1β22`) |
| Latest available checkpoint | `epochs/cp_epoch_076.pt` | `epochs/cir_epoch_022.pt` |
| Epoch of `best.pt` | `76` | `22` |
| Selection metric (`training.best_metric`) | `val_auc` | `val_fitb_accuracy` |
| Validation metric in the best checkpoint | `0.93390839` | `0.6723` |
| Training examples in the best epoch | `33990` | `16960` |
| Validation examples in the best epoch | `6000` | `3000` |
Selection metrics are maximized. The 200 epochs and total optimizer steps
describe the configured plan; available files document only the epochs
listed in the tables.
### Dataset and features
The values apply to all four runs; each run uses its own subset.
| Parameter | Recorded value |
| --- | --- |
| Dataset (`dataset.name`) | `polyvore` |
| Dataset identifier (`dataset.id`) | `mvasil/polyvore-outfits` |
| Subset (`dataset.subset`) | `nondisjoint` / `disjoint` |
| Dataset directory during training (`dataset.dataset_root`) | `datasets/polyvore-outfits` |
| Custom dataset cache (`dataset.cache_dir`) | `null` |
| Embedding directory during training (`dataset.embedding_root`) | `precomputed_embeddings/patrickjohncyh-fashion-clip` |
| Feature mode (`dataset.feature_mode`, `features.mode`) | `precomputed` |
| Use of precomputed embeddings (`features.precomputed`) | `true` |
| Encoder in the configuration (`features.encoder`) | `from_embedding_manifest` |
| Encoder identified in the manifests | `patrickjohncyh/fashion-clip` |
| Trainable features (`features.trainable`) | `false`: the encoders are not trained in these runs |
The recorded embedding path is the one used during training. Current caches
are stored under `precomputed_embeddings/fashionCLIP/<subset>/<split>/`.
Set `--embedding-root <download-dir>/precomputed_embeddings/fashionCLIP` when
using the downloaded repository; the loader selects the subset and split.
### Architecture
For CP, Transformer keys are under `model`; for CIR, they are under
`model.transformer`. The total input dimension is derived by concatenating
the two modalities.
| Parameter | cp_precomputed-flashionclip | cir_precomputed-flashionclip |
| --- | --- | --- |
| Dimension per modality (`modality_embedding_dim`) | `512` | `512` |
| Total input / Transformer dimension | `1024 = 512 + 512` | `1024 = 512 + 512` |
| Number of layers (`layers`) | `6` | `6` |
| Attention heads (`attention_heads`) | `16` | `16` |
| Feed-forward dimension (`feedforward_dim`) | `2024` | `2024` |
| Activation (`activation`) | `mish` | `mish` |
| Dropout (`dropout`) | `0.3` | `0.3` |
| Pre-norm (`norm_first`) | `true` | `true` |
| LayerNorm epsilon (`layer_norm_epsilon`) | `1e-5` | `1e-5` |
| L2 normalization epsilon (`normalization_epsilon`) | `1e-12` | `1e-12` |
| Embedding initialization standard deviation (`embedding_initialization_std`) | `0.02` | `0.02` |
| Maximum number of items (`max_items`) | `16` | `16` |
| Additional final LayerNorm, verified in the weights | Absent: no `cp.encoder.norm.*` keys | Absent: no `cir.encoder.norm.*` keys |
| Retrieval embedding dimension (`model.cir.embedding_dim`) | Not applicable | `128` |
| L2 normalization of final retrieval embeddings (`model.cir.normalize_embeddings`) | Not applicable | `false` |
| Category embedding (`model.use_category_embedding`) | Not applicable | `false` |
### Training and loss function
| Parameter | cp_precomputed-flashionclip | cir_precomputed-flashionclip |
| --- | --- | --- |
| Microbatch (`training.batch_size` / `training.batch_size_per_process`) | `512` outfits | `64` outfits per process |
| Gradient accumulation (`training.gradient_accumulation_steps`) | `4` microbatches | `4` microbatches |
| Effective batch size (`training.effective_batch_size` / `training.effective_batch_size_global`) | `2048` | `256` global |
| Effective batch size per process (`training.effective_batch_size_per_process`) | Not recorded separately | `256` |
| Optimizer (`training.optimizer`) | `AdamW` | `AdamW` |
| Configured / maximum learning rate (`training.learning_rate`) | `2e-5` | `2e-5` |
| Weight decay (`training.weight_decay`) | `0.01` | `0.01` |
| Gradient clipping, maximum norm (`training.max_grad_norm`) | `1.0` | `1.0` |
| Seed (`training.seed`) | `42` | `42` |
| Loss (`training.loss`) | `FocalLoss` | `InBatchTripletMarginLoss` |
| Loss reduction (`training.focal_reduction` / `training.loss_reduction`, `model.cir.loss_reduction`) | `mean` | `mean` |
| Focal alpha (`training.focal_alpha`) | `0.5` | Not applicable |
| Focal gamma (`training.focal_gamma`) | `2.0` | Not applicable |
| Triplet margin (`training.triplet_margin`, `model.cir.triplet_margin`) | Not applicable | `2.0` |
| Negative sampling (`training.negative_sampling`) | Not applicable | `in_batch` |
| Target sampling (`training.target_sampling`) | Not applicable | `random_item_per_outfit_access` |
| Early stopping patience (`training.early_stopping_patience`) | `null`: disabled | `null`: disabled |
| Minimum improvement (`training.early_stopping_min_delta`) | `0.0` | `0.0` |
| Resume weights (`training.resume_weights`) | `null` | `null` |
| Initialization from CP (`training.pretrained_cp_weights`) | Not applicable | Subset-specific paths below |
| Optimizer steps per epoch (`training.optimizer_steps_per_epoch`) | nondisjoint: `53`; disjoint: `17` | nondisjoint: `208`; disjoint: `67` |
| Total planned optimizer steps (`training.total_optimizer_steps`) | nondisjoint: `10600`; disjoint: `3400` | nondisjoint: `41600`; disjoint: `13400` |
For CIR, the target is an item chosen at random on every access to an outfit.
As described in the training README, the loss selects the hardest negative
among the positives from the other rows in the same microbatch: accumulating
up to 256 examples does not expand the negative pool of the 64-example microbatch.
CIR configurations record these CP initialization paths:
- `nondisjoint`: `checkpoints/nondisjoint/cp_precomputed/best.pt`.
- `disjoint`: `checkpoints/disjoint/cp_fashionclip/best.pt`.
These paths describe the training layout; update them to the corresponding
local CP checkpoint when reproducing a run.
### Scheduler
All fields in this table are saved under `training.scheduler` and have the same
values in all four runs.
| Parameter | Value |
| --- | --- |
| Scheduler (`name`) | `OneCycleLR` |
| Update frequency (`step`) | `optimizer_step`: after each optimizer update |
| Maximum learning rate (`max_lr`) | `2e-5` |
| Initial fraction of the cycle (`pct_start`) | `0.3` |
| Annealing strategy (`anneal_strategy`) | `cos` |
| Initial LR factor (`div_factor`) | `25.0` |
| Minimum LR factor (`final_div_factor`) | `10000.0` |
### Runtime
| Parameter | cp_precomputed-flashionclip | cir_precomputed-flashionclip |
| --- | --- | --- |
| Requested device (`runtime.requested_device`) | `auto` | `auto` |
| Resolved device (`runtime.resolved_device`) | `cuda` | `cuda` |
| DataLoader workers (`runtime.num_workers`) | `0` | `0` |
| Pinned memory (`runtime.pin_memory`) | `false` | `false` |
| Logging frequency (`runtime.log_every`) | Every `10` microbatches | Every `10` microbatches |
| Distributed training (`runtime.ddp`) | Not recorded | `false` |
| Number of processes (`runtime.world_size`) | Not recorded | `1` |
| Distributed backend (`runtime.distributed_backend`) | Not recorded | `null` |
| Mixed precision (`runtime.mixed_precision`) | Not recorded | `false` |
The tables cover the fields present in the four `config.json` files. Implicit
settings that were not serialized, such as AdamW betas and epsilon, and details
such as the GPU model and software versions are not documented by the inspected
artifacts.
## Checkpoints
Weights are saved in **PyTorch `.pt` format**. In the project's current format,
each checkpoint contains `model_state_dict`, `run_config`, the epoch number,
metrics, training history, and best-model selection information. `config.json`
stores a readable version of the experiment configuration.
`best.pt` is the checkpoint selected during training according to the configured
metric. Files in `epochs/`, when available, allow other epochs from the run to
be used. Current checkpoints do not include optimizer or scheduler state:
resuming in this project initializes a new run from the saved weights.
To load a checkpoint, use the loaders and commands from the source repository
with the configuration and architecture version used during training. It is
also useful to record the Git commit of the code used for each experiment.
The four checkpoints have no additional final Transformer LayerNorm
(`cp.encoder.norm.*` or `cir.encoder.norm.*`). Initialization of CIR from CP
is described in the
[CIR README](https://github.com/FlorindoDev/OutfitTransformer/blob/main/training/CIR/README.md).
Uploading to the Hub preserves the project's format; it does not automatically
add support for `transformers.AutoModel.from_pretrained()`.
## Precomputed embeddings
Embeddings are numerical representations of items, generated using the
[project's precomputation procedure](https://github.com/FlorindoDev/OutfitTransformer/blob/main/scripts/README.md).
They can be reused in workflows that support precomputed features, avoiding
the need to run the encoders again for each item.
Each cache includes **`manifest.json` and all `shard-*.pt` files listed in the
manifest**, kept in the same folder. Shards contain `schema_version`, the
`item_ids` identifiers, and the `embeddings` tensor; the manifest describes
the encoder, dataset, subset, split, dimensions, precision, fingerprint, and shards.
Each embedding concatenates image and text representations, each normalized
separately with L2 normalization. FashionCLIP produces 1024 components
(512 visual + 512 textual); Marqo FashionSigLIP produces 1536 (768 + 768).
The published checkpoints use FashionCLIP. FashionSigLIP caches require
models configured for their 1536-dimensional inputs.
### Parameters of the published caches
| Parameter | FashionCLIP | Marqo FashionSigLIP |
| --- | --- | --- |
| Format version (`schema_version`) | `2` | `2` |
| Dataset | `mvasil/polyvore-outfits` | `mvasil/polyvore-outfits` |
| Available subsets | `nondisjoint`, `disjoint` | `nondisjoint` |
| Encoder model (`encoder.model_name`) | `patrickjohncyh/fashion-clip` | `Marqo/marqo-fashionSigLIP` |
| Visual encoder (`encoder.visual_encoder`) | `FashionCLIPVisualEncoder` | `MarqoFashionSigLIPVisualEncoder` |
| Text encoder (`encoder.text_encoder`) | `FashionCLIPTextEncoder` | `MarqoFashionSigLIPTextEncoder` |
| Dimension per modality (`encoder.modality_dim`) | `512` | `768` |
| Final dimension (`embedding_dim`) | `1024` | `1536` |
| Aggregation (`encoder.aggregation`) | `concat_visual_then_text` | `concat_visual_then_text` |
| Normalization (`encoder.normalization`) | `l2_per_modality` | `l2_per_modality` |
| Saved precision (`dtype`) | `float32` | `float32` |
| Item count limit (`limit`) | `null` | `null` |
| Visual / text encoder commit | `null` / `null` | `c56244cc94f92419e8369fa71efdaf403b124ce8` / `c56244cc94f92419e8369fa71efdaf403b124ce8` |
#### fashionCLIP / nondisjoint
| Split | Items (`count`) | Shards | Manifest |
| --- | --- | --- | --- |
| Train | `204679` | `21` | [train/manifest.json](precomputed_embeddings/fashionCLIP/nondisjoint/train/manifest.json) |
| Validation | `25132` | `3` | [validation/manifest.json](precomputed_embeddings/fashionCLIP/nondisjoint/validation/manifest.json) |
| Test | `47854` | `5` | [test/manifest.json](precomputed_embeddings/fashionCLIP/nondisjoint/test/manifest.json) |
#### fashionCLIP / disjoint
| Split | Items (`count`) | Shards | Manifest |
| --- | --- | --- | --- |
| Train | `71967` | `8` | [train/manifest.json](precomputed_embeddings/fashionCLIP/disjoint/train/manifest.json) |
| Validation | `14657` | `2` | [validation/manifest.json](precomputed_embeddings/fashionCLIP/disjoint/validation/manifest.json) |
| Test | `70035` | `8` | [test/manifest.json](precomputed_embeddings/fashionCLIP/disjoint/test/manifest.json) |
#### fashionSigLIP / nondisjoint
| Split | Items (`count`) | Shards | Manifest |
| --- | --- | --- | --- |
| Train | `204679` | `21` | [train/manifest.json](precomputed_embeddings/fashionSigLIP/nondisjoint/train/manifest.json) |
| Validation | `25132` | `3` | [validation/manifest.json](precomputed_embeddings/fashionSigLIP/nondisjoint/validation/manifest.json) |
| Test | `47854` | `5` | [test/manifest.json](precomputed_embeddings/fashionSigLIP/nondisjoint/test/manifest.json) |
Shards contain at most 10000 items each; the last shard may be smaller.
Counts refer to items with embeddings.
FashionCLIP disjoint manifests and nondisjoint train/validation share the
`model_fingerprint`
`dfcff17f9fb9335b22792d610cb7e4ba8cd73afa2954b725aa5e2d993bc10c27`.
FashionCLIP nondisjoint test instead records
`b00590d05bc4af1a3a5316ecb65dabea7315fa93adf0dcbdbec0b8399ec1e788`.
All three FashionSigLIP caches share
`333a9948b0d676879fbac0938f4f8654eae108dbc00cfbf3f59552c051ac8802`.
Matching encoder names and dimensions do not establish identical
precomputation configurations when fingerprints differ.
Use `--embedding-root <download-dir>/precomputed_embeddings/fashionCLIP` or
`--embedding-root <download-dir>/precomputed_embeddings/fashionSigLIP`, according
to the model. The loader reads `<embedding-root>/<subset>/<split>/`.
Use caches matching the checkpoint, dataset, subset, and split; train and
validation must have matching fingerprints. The data needed to construct
outfits, labels, and queries are still those required by the project.
## References
- [OutfitTransformer source code](https://github.com/FlorindoDev/OutfitTransformer)
- [CP training](https://github.com/FlorindoDev/OutfitTransformer/blob/main/training/CP/README.md)
- [CIR training](https://github.com/FlorindoDev/OutfitTransformer/blob/main/training/CIR/README.md)
- [Embedding precomputation](https://github.com/FlorindoDev/OutfitTransformer/blob/main/scripts/README.md)
---
<a id="versione-italiana"></a>
> [!IMPORTANT]
> Questi sono pesi allenati e utilizzati con il mio modello **OutfitTransformer**, disponibile nella repository [FlorindoDev/OutfitTransformer](https://github.com/FlorindoDev/OutfitTransformer). Per utilizzarli, fai riferimento al codice, all'architettura e alle istruzioni di quel progetto.
# OutfitTransformer: Pesi ed embedding precomputati
Questa repository raccoglie i checkpoint allenati con la mia implementazione di
OutfitTransformer e gli **embedding precomputati** utilizzabili nei flussi di
training e valutazione del progetto.
Il codice sorgente, la configurazione del modello e le istruzioni di utilizzo sono
disponibili su [GitHub](https://github.com/FlorindoDev/OutfitTransformer).
Sono inclusi i checkpoint **cp_precomputed-flashionclip** (Compatibility Prediction)
e **cir_precomputed-flashionclip** (Complementary Item Retrieval) per entrambi
i subset Polyvore, `nondisjoint` e `disjoint`. Gli embedding FashionCLIP sono
disponibili per entrambi i subset; sono inclusi anche gli embedding Marqo
FashionSigLIP per `nondisjoint`. Ogni cache contiene train, validation e test.
## Risultati
Risultati su Polyvore, split `test`, con embedding precomputati, suddivisi per
subset `nondisjoint` e `disjoint`. Metriche su scala 0β1, arrotondate a quattro
cifre decimali.
### Nondisjoint
| Metrica / dettaglio esecuzione | CP |
|---|---:|
| Epoca del checkpoint | 76 |
| Esempi valutati | 20000 |
| Accuracy | 0.8478 |
| Precision | 0.9489 |
| Recall | 0.7352 |
| F1 | 0.8285 |
| ROC AUC | 0.9513 |
| Metrica / dettaglio esecuzione | CIR FITB |
|---|---:|
| Epoca del checkpoint | 19 |
| Esempi valutati | 10000 |
| FITB accuracy | 0.6807 |
| MRR | 0.8169 |
| Recall@2 | 0.8782 |
I test CIR sono stati eseguiti senza `category_emb`.
### Disjoint
| Metrica / dettaglio esecuzione | CP |
|---|---:|
| Epoca del checkpoint | 76 |
| Esempi valutati | 30290 |
| Accuracy | 0.6904 |
| Precision | 0.9816 |
| Recall | 0.3880 |
| F1 | 0.5561 |
| ROC AUC | 0.9202 |
| Metrica / dettaglio esecuzione | CIR FITB |
|---|---:|
| Epoca del checkpoint | 22 |
| Esempi valutati | 15145 |
| FITB accuracy | 0.6640 |
| MRR | 0.8063 |
| Recall@2 | 0.8664 |
I test CIR sono stati eseguiti senza `category_emb`.
## Contenuto e organizzazione
Gli artefatti sono organizzati come segue. Ogni run contiene `best.pt`,
`config.json`, i checkpoint delle singole epoche in `epochs/` e i grafici in
`plots/`.
```text
.
βββ README.md
βββ .gitattributes
βββ checkpoints/
β βββ nondisjoint/
β β βββ cp_precomputed-flashionclip/
β β βββ cir_precomputed-flashionclip/
β βββ disjoint/
β βββ cp_precomputed-flashionclip/
β βββ cir_precomputed-flashionclip/
βββ precomputed_embeddings/
βββ fashionCLIP/
β βββ nondisjoint/
β β βββ train/
β β βββ validation/
β β βββ test/
β βββ disjoint/
β βββ train/
β βββ validation/
β βββ test/
βββ fashionSigLIP/
βββ nondisjoint/
βββ train/
βββ validation/
βββ test/
```
## Parametri e iperparametri dei run pubblicati
I valori provengono dalle quattro configurazioni salvate, verificate con
`run_config` nei rispettivi `best.pt`. Avanzamento e metriche di validation
provengono dai checkpoint locali; i risultati di test sono riportati sopra.
Le tabelle comuni valgono per entrambi i subset salvo indicazione diversa.
`null` indica un valore non impostato; **non registrato** indica un campo
assente dalla configurazione salvata.
| Subset | CP | CIR |
| --- | --- | --- |
| `nondisjoint` | [config.json](checkpoints/nondisjoint/cp_precomputed-flashionclip/config.json) | [config.json](checkpoints/nondisjoint/cir_precomputed-flashionclip/config.json) |
| `disjoint` | [config.json](checkpoints/disjoint/cp_precomputed-flashionclip/config.json) | [config.json](checkpoints/disjoint/cir_precomputed-flashionclip/config.json) |
### Checkpoint e avanzamento registrato
#### Nondisjoint
| Parametro | CP | CIR |
| --- | --- | --- |
| Cartella del run | `checkpoints/nondisjoint/cp_precomputed-flashionclip/` | `checkpoints/nondisjoint/cir_precomputed-flashionclip/` |
| Versione del formato checkpoint (`checkpoint_schema_version`) | `2` | `1` |
| Epoche massime configurate (`training.epochs`) | `200` | `200` |
| Checkpoint di epoca disponibili | `77` (`1β77`) | `24` (`1β24`) |
| Ultimo checkpoint disponibile | `epochs/cp_epoch_077.pt` | `epochs/cir_epoch_024.pt` |
| Epoca di `best.pt` | `76` | `19` |
| Metrica di selezione (`training.best_metric`) | `val_auc` | `val_fitb_accuracy` |
| Metrica di validation nel best | `0.95184712` | `0.6830` |
| Esempi train nell'epoca del best | `106612` | `53248` |
| Esempi validation nell'epoca del best | `10000` | `5000` |
#### Disjoint
| Parametro | CP | CIR |
| --- | --- | --- |
| Cartella del run | `checkpoints/disjoint/cp_precomputed-flashionclip/` | `checkpoints/disjoint/cir_precomputed-flashionclip/` |
| Versione del formato checkpoint (`checkpoint_schema_version`) | `2` | `1` |
| Epoche massime configurate (`training.epochs`) | `200` | `200` |
| Checkpoint di epoca disponibili | `27` (`50β76`) | `22` (`1β22`) |
| Ultimo checkpoint disponibile | `epochs/cp_epoch_076.pt` | `epochs/cir_epoch_022.pt` |
| Epoca di `best.pt` | `76` | `22` |
| Metrica di selezione (`training.best_metric`) | `val_auc` | `val_fitb_accuracy` |
| Metrica di validation nel best | `0.93390839` | `0.6723` |
| Esempi train nell'epoca del best | `33990` | `16960` |
| Esempi validation nell'epoca del best | `6000` | `3000` |
Le metriche di selezione sono da massimizzare. Le 200 epoche e gli optimizer
step totali descrivono il piano configurato; i file disponibili documentano
soltanto le epoche indicate in tabella.
### Dataset e feature
I valori valgono per tutti e quattro i run; ogni run usa il proprio subset.
| Parametro | Valore registrato |
| --- | --- |
| Dataset (`dataset.name`) | `polyvore` |
| Identificativo dataset (`dataset.id`) | `mvasil/polyvore-outfits` |
| Subset (`dataset.subset`) | `nondisjoint` / `disjoint` |
| Directory dataset nel training (`dataset.dataset_root`) | `datasets/polyvore-outfits` |
| Cache dataset personalizzata (`dataset.cache_dir`) | `null` |
| Directory embedding nel training (`dataset.embedding_root`) | `precomputed_embeddings/patrickjohncyh-fashion-clip` |
| ModalitΓ feature (`dataset.feature_mode`, `features.mode`) | `precomputed` |
| Uso di embedding precomputati (`features.precomputed`) | `true` |
| Encoder nella configurazione (`features.encoder`) | `from_embedding_manifest` |
| Encoder identificato nei manifest | `patrickjohncyh/fashion-clip` |
| Feature allenabili (`features.trainable`) | `false`: gli encoder non vengono allenati in questi run |
Il percorso registrato Γ¨ quello usato durante il training. Le cache attuali
si trovano in `precomputed_embeddings/fashionCLIP/<subset>/<split>/`.
Usa `--embedding-root <download-dir>/precomputed_embeddings/fashionCLIP` con la
repository scaricata; il loader seleziona il subset e lo split.
### Architettura
Per CP le chiavi del Transformer sono in `model`; per CIR sono in
`model.transformer`. La dimensione totale di input Γ¨ derivata dalla
concatenazione delle due modalitΓ .
| Parametro | cp_precomputed-flashionclip | cir_precomputed-flashionclip |
| --- | --- | --- |
| Dimensione per modalitΓ (`modality_embedding_dim`) | `512` | `512` |
| Dimensione totale di input / Transformer | `1024 = 512 + 512` | `1024 = 512 + 512` |
| Numero di layer (`layers`) | `6` | `6` |
| Teste di attenzione (`attention_heads`) | `16` | `16` |
| Dimensione feed-forward (`feedforward_dim`) | `2024` | `2024` |
| Attivazione (`activation`) | `mish` | `mish` |
| Dropout (`dropout`) | `0.3` | `0.3` |
| Pre-norm (`norm_first`) | `true` | `true` |
| Epsilon LayerNorm (`layer_norm_epsilon`) | `1e-5` | `1e-5` |
| Epsilon normalizzazione L2 (`normalization_epsilon`) | `1e-12` | `1e-12` |
| Deviazione standard inizializzazione embedding (`embedding_initialization_std`) | `0.02` | `0.02` |
| Numero massimo di item (`max_items`) | `16` | `16` |
| LayerNorm finale aggiuntiva, verificata nei pesi | Assente: nessuna chiave `cp.encoder.norm.*` | Assente: nessuna chiave `cir.encoder.norm.*` |
| Dimensione embedding di retrieval (`model.cir.embedding_dim`) | Non applicabile | `128` |
| Normalizzazione L2 degli embedding finali di retrieval (`model.cir.normalize_embeddings`) | Non applicabile | `false` |
| Embedding di categoria (`model.use_category_embedding`) | Non applicabile | `false` |
### Training e funzione di loss
| Parametro | cp_precomputed-flashionclip | cir_precomputed-flashionclip |
| --- | --- | --- |
| Microbatch (`training.batch_size` / `training.batch_size_per_process`) | `512` outfit | `64` outfit per processo |
| Accumulo gradienti (`training.gradient_accumulation_steps`) | `4` microbatch | `4` microbatch |
| Batch effettivo (`training.effective_batch_size` / `training.effective_batch_size_global`) | `2048` | `256` globale |
| Batch effettivo per processo (`training.effective_batch_size_per_process`) | Non registrato separatamente | `256` |
| Ottimizzatore (`training.optimizer`) | `AdamW` | `AdamW` |
| Learning rate configurato / massimo (`training.learning_rate`) | `2e-5` | `2e-5` |
| Weight decay (`training.weight_decay`) | `0.01` | `0.01` |
| Gradient clipping, norma massima (`training.max_grad_norm`) | `1.0` | `1.0` |
| Seed (`training.seed`) | `42` | `42` |
| Loss (`training.loss`) | `FocalLoss` | `InBatchTripletMarginLoss` |
| Riduzione della loss (`training.focal_reduction` / `training.loss_reduction`, `model.cir.loss_reduction`) | `mean` | `mean` |
| Focal alpha (`training.focal_alpha`) | `0.5` | Non applicabile |
| Focal gamma (`training.focal_gamma`) | `2.0` | Non applicabile |
| Margine triplet (`training.triplet_margin`, `model.cir.triplet_margin`) | Non applicabile | `2.0` |
| Campionamento negativi (`training.negative_sampling`) | Non applicabile | `in_batch` |
| Campionamento target (`training.target_sampling`) | Non applicabile | `random_item_per_outfit_access` |
| Early stopping, patience (`training.early_stopping_patience`) | `null`: disabilitato | `null`: disabilitato |
| Miglioramento minimo (`training.early_stopping_min_delta`) | `0.0` | `0.0` |
| Pesi per resume (`training.resume_weights`) | `null` | `null` |
| Inizializzazione da CP (`training.pretrained_cp_weights`) | Non applicabile | Percorsi per subset riportati sotto |
| Optimizer step per epoca (`training.optimizer_steps_per_epoch`) | nondisjoint: `53`; disjoint: `17` | nondisjoint: `208`; disjoint: `67` |
| Optimizer step totali pianificati (`training.total_optimizer_steps`) | nondisjoint: `10600`; disjoint: `3400` | nondisjoint: `41600`; disjoint: `13400` |
Per CIR il target Γ¨ un item scelto casualmente a ogni accesso all'outfit. Come
descritto nel README del training, la loss seleziona il negativo piΓΉ difficile
tra i positivi delle altre righe dello stesso microbatch: l'accumulo fino a 256
esempi non amplia il gruppo di negativi del microbatch da 64.
Le configurazioni CIR registrano questi percorsi di inizializzazione da CP:
- `nondisjoint`: `checkpoints/nondisjoint/cp_precomputed/best.pt`.
- `disjoint`: `checkpoints/disjoint/cp_fashionclip/best.pt`.
Questi percorsi descrivono il layout del training; aggiornali al checkpoint CP
locale corrispondente quando riproduci un run.
### Scheduler
Tutti i campi di questa tabella sono salvati in `training.scheduler` e hanno lo
stesso valore nei quattro run.
| Parametro | Valore |
| --- | --- |
| Scheduler (`name`) | `OneCycleLR` |
| Frequenza di aggiornamento (`step`) | `optimizer_step`: dopo ogni aggiornamento dell'ottimizzatore |
| Learning rate massimo (`max_lr`) | `2e-5` |
| Frazione iniziale del ciclo (`pct_start`) | `0.3` |
| Strategia di annealing (`anneal_strategy`) | `cos` |
| Fattore LR iniziale (`div_factor`) | `25.0` |
| Fattore LR minimo (`final_div_factor`) | `10000.0` |
### Runtime
| Parametro | cp_precomputed-flashionclip | cir_precomputed-flashionclip |
| --- | --- | --- |
| Dispositivo richiesto (`runtime.requested_device`) | `auto` | `auto` |
| Dispositivo risolto (`runtime.resolved_device`) | `cuda` | `cuda` |
| Worker del DataLoader (`runtime.num_workers`) | `0` | `0` |
| Pinned memory (`runtime.pin_memory`) | `false` | `false` |
| Frequenza log (`runtime.log_every`) | Ogni `10` microbatch | Ogni `10` microbatch |
| Training distribuito (`runtime.ddp`) | Non registrato | `false` |
| Numero processi (`runtime.world_size`) | Non registrato | `1` |
| Backend distribuito (`runtime.distributed_backend`) | Non registrato | `null` |
| Mixed precision (`runtime.mixed_precision`) | Non registrata | `false` |
Le tabelle coprono i campi presenti nei quattro `config.json`. Impostazioni
implicite non serializzate, come i beta e l'epsilon di AdamW, e dettagli quali
modello di GPU e versioni software non sono documentati dagli artefatti letti.
## Checkpoint
I pesi sono salvati in formato **PyTorch `.pt`**. Nel formato attuale del progetto,
ogni checkpoint contiene `model_state_dict`, `run_config`, il numero dell'epoca,
le metriche, la cronologia del training e le informazioni sulla selezione del
modello migliore. `config.json` conserva una versione leggibile della
configurazione dell'esperimento.
`best.pt` Γ¨ il checkpoint selezionato dal training secondo la metrica configurata.
Gli eventuali file in `epochs/` permettono di utilizzare altre epoche del run.
I checkpoint attuali non includono lo stato di optimizer e scheduler: il resume
del progetto inizializza un nuovo run a partire dai pesi salvati.
Per caricare un checkpoint, usa i loader e i comandi della repository sorgente,
con la configurazione e la versione dell'architettura usate durante il training.
Per ciascun esperimento Γ¨ utile riportare anche il commit Git del codice usato.
I quattro checkpoint non contengono una LayerNorm finale aggiuntiva del
Transformer (`cp.encoder.norm.*` o `cir.encoder.norm.*`). L'inizializzazione
di CIR da CP Γ¨ descritta nel
[README CIR](https://github.com/FlorindoDev/OutfitTransformer/blob/main/training/CIR/README.md).
Il caricamento sul Hub conserva il formato del progetto; non aggiunge
automaticamente il supporto a `transformers.AutoModel.from_pretrained()`.
## Embedding precomputati
Gli embedding sono rappresentazioni numeriche degli articoli, generate con la
[procedura di precomputazione del progetto](https://github.com/FlorindoDev/OutfitTransformer/blob/main/scripts/README.md).
Possono essere riutilizzati nei flussi che supportano feature precomputate,
evitando di eseguire nuovamente gli encoder per ogni articolo.
Ogni cache comprende **`manifest.json` e tutti gli `shard-*.pt` elencati nel
manifest**, mantenuti nella stessa cartella. Gli shard contengono `schema_version`,
gli identificativi `item_ids` e il tensore `embeddings`; il manifest descrive
encoder, dataset, subset, split, dimensioni, precisione, fingerprint e shard.
Ogni embedding concatena le rappresentazioni di immagine e testo, normalizzate
L2 separatamente. FashionCLIP produce 1024 componenti (512 visuali + 512
testuali); Marqo FashionSigLIP ne produce 1536 (768 + 768). I checkpoint
pubblicati usano FashionCLIP. Le cache FashionSigLIP richiedono modelli
configurati per input di dimensione 1536.
### Parametri delle cache pubblicate
| Parametro | FashionCLIP | Marqo FashionSigLIP |
| --- | --- | --- |
| Versione del formato (`schema_version`) | `2` | `2` |
| Dataset | `mvasil/polyvore-outfits` | `mvasil/polyvore-outfits` |
| Subset disponibili | `nondisjoint`, `disjoint` | `nondisjoint` |
| Modello encoder (`encoder.model_name`) | `patrickjohncyh/fashion-clip` | `Marqo/marqo-fashionSigLIP` |
| Encoder visuale (`encoder.visual_encoder`) | `FashionCLIPVisualEncoder` | `MarqoFashionSigLIPVisualEncoder` |
| Encoder testuale (`encoder.text_encoder`) | `FashionCLIPTextEncoder` | `MarqoFashionSigLIPTextEncoder` |
| Dimensione per modalitΓ (`encoder.modality_dim`) | `512` | `768` |
| Dimensione finale (`embedding_dim`) | `1024` | `1536` |
| Aggregazione (`encoder.aggregation`) | `concat_visual_then_text` | `concat_visual_then_text` |
| Normalizzazione (`encoder.normalization`) | `l2_per_modality` | `l2_per_modality` |
| Precisione salvata (`dtype`) | `float32` | `float32` |
| Limite al numero di articoli (`limit`) | `null` | `null` |
| Commit encoder visuale / testuale | `null` / `null` | `c56244cc94f92419e8369fa71efdaf403b124ce8` / `c56244cc94f92419e8369fa71efdaf403b124ce8` |
#### fashionCLIP / nondisjoint
| Split | Articoli (`count`) | Shard | Manifest |
| --- | --- | --- | --- |
| Train | `204679` | `21` | [train/manifest.json](precomputed_embeddings/fashionCLIP/nondisjoint/train/manifest.json) |
| Validation | `25132` | `3` | [validation/manifest.json](precomputed_embeddings/fashionCLIP/nondisjoint/validation/manifest.json) |
| Test | `47854` | `5` | [test/manifest.json](precomputed_embeddings/fashionCLIP/nondisjoint/test/manifest.json) |
#### fashionCLIP / disjoint
| Split | Articoli (`count`) | Shard | Manifest |
| --- | --- | --- | --- |
| Train | `71967` | `8` | [train/manifest.json](precomputed_embeddings/fashionCLIP/disjoint/train/manifest.json) |
| Validation | `14657` | `2` | [validation/manifest.json](precomputed_embeddings/fashionCLIP/disjoint/validation/manifest.json) |
| Test | `70035` | `8` | [test/manifest.json](precomputed_embeddings/fashionCLIP/disjoint/test/manifest.json) |
#### fashionSigLIP / nondisjoint
| Split | Articoli (`count`) | Shard | Manifest |
| --- | --- | --- | --- |
| Train | `204679` | `21` | [train/manifest.json](precomputed_embeddings/fashionSigLIP/nondisjoint/train/manifest.json) |
| Validation | `25132` | `3` | [validation/manifest.json](precomputed_embeddings/fashionSigLIP/nondisjoint/validation/manifest.json) |
| Test | `47854` | `5` | [test/manifest.json](precomputed_embeddings/fashionSigLIP/nondisjoint/test/manifest.json) |
Gli shard contengono al massimo 10000 articoli ciascuno; lβultimo shard puΓ²
essere piΓΉ piccolo. I conteggi indicano articoli con embedding.
I manifest FashionCLIP disjoint e quelli nondisjoint train/validation condividono
il `model_fingerprint`
`dfcff17f9fb9335b22792d610cb7e4ba8cd73afa2954b725aa5e2d993bc10c27`.
FashionCLIP nondisjoint test registra invece
`b00590d05bc4af1a3a5316ecb65dabea7315fa93adf0dcbdbec0b8399ec1e788`.
Le tre cache FashionSigLIP condividono
`333a9948b0d676879fbac0938f4f8654eae108dbc00cfbf3f59552c051ac8802`.
Nome encoder e dimensioni uguali non attestano una configurazione identica
quando i fingerprint differiscono.
Usa `--embedding-root <download-dir>/precomputed_embeddings/fashionCLIP` oppure
`--embedding-root <download-dir>/precomputed_embeddings/fashionSigLIP`, secondo
il modello. Il loader legge `<embedding-root>/<subset>/<split>/`.
Usa cache coerenti con checkpoint, dataset, subset e split; train e validation
devono avere fingerprint corrispondenti. I dati per costruire outfit,
etichette e query restano quelli richiesti dal progetto.
## Riferimenti
- [Codice sorgente OutfitTransformer](https://github.com/FlorindoDev/OutfitTransformer)
- [Training CP](https://github.com/FlorindoDev/OutfitTransformer/blob/main/training/CP/README.md)
- [Training CIR](https://github.com/FlorindoDev/OutfitTransformer/blob/main/training/CIR/README.md)
- [Precomputazione degli embedding](https://github.com/FlorindoDev/OutfitTransformer/blob/main/scripts/README.md)
|