AsyiraFitri commited on
Commit
85759a1
·
1 Parent(s): 58926ad

.md update for week 5 and model card

Browse files
Files changed (2) hide show
  1. README.md +121 -76
  2. tabacco3482_benchmarks/Week_05_Update.md +34 -0
README.md CHANGED
@@ -2,124 +2,169 @@
2
 
3
  Benchmarks several vision encoder families as **frozen embedding extractors** for document image classification on the [Tobacco-3482](https://huggingface.co/datasets/maveriq/tobacco3482) dataset.
4
 
 
 
5
  ## Dataset
6
 
7
  | Property | Value |
8
  |---|---|
9
  | Dataset | `maveriq/tobacco3482` |
10
  | Task | 10-class document image classification |
11
- | Size | 3482 images |
 
12
  | Split | 80/20 train/test (fixed seed 42) |
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  ## Models Evaluated
15
 
16
- | Family | Variants |
17
- | --------------- | ------------------------------------------------------------------------------------------ |
18
- | **SigLIP** | Base (patch16-224), Large (patch16-256), SO400M (patch14-384) |
19
- | **SigLIP 2** | Base, Large, SO400M — upgraded with self-distillation + masked prediction |
20
- | **ModernVBERT** | Base, Embed, Bi — tests effect of training objective (MLM → contrastive → doc fine-tuning) |
21
- | **CLIP** | Base (patch32-224), Large (patch14-224) — contrastive VLM baseline |
22
- | **DINOv2** | Base — self-supervised vision-only encoder |
23
- | **DiT** | Base, Large — Document Image Transformer with doc-specific pretraining |
24
 
25
- > ColModernVBERT was investigated but skipped the model depends on a private base model (`ettin-encoder-150m`) and an unmerged `colpali_engine` branch.
26
 
27
- ## Evaluation Protocol
 
 
 
 
28
 
29
- Embeddings are extracted once (L2-normalised, no fine-tuning) and evaluated with two probes:
30
 
31
- - **Linear probe** logistic regression (sklearn, max_iter=1000) on frozen embeddings; reports accuracy and weighted F1.
32
- - **kNN retrieval** — cosine-similarity nearest neighbours; reports top-1 and top-5 accuracy.
33
 
34
- PCA post-processing (mean-centering PCA whitening L2 re-normalisation) was applied to most models, either as a separate named variant or baked directly into the extraction cell:
 
 
 
 
35
 
36
- | Model(s) | Approach | n sweep |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  |---|---|---|
38
- | SigLIP SO400M, SigLIP2 SO400M | Separate `+ postprocess` entry in results | 64, 128, 256, 512, 768, 1024 |
39
- | CLIP Large, DINOv2 Base, DiT Base, DiT Large | Inline sweep within extraction cell; best n used for final result | 64, 128, 256, 512 (CLIP Large also tries 768) |
40
- | ModernVBERT Base 2, Embed 2, Bi 2 | Fixed `postprocess()` call at n=256 | 256 (fixed) |
41
 
42
- The best `n_components` was selected by linear probe accuracy on the test set.
43
 
44
- ## Iteration Log
45
 
46
- ### Run 1 Baseline (SigLIP v1 only + baselines, raw embeddings)
47
- First pass covering SigLIP v1 variants, CLIP Base, DINOv2 Base, DiT Base, and the initial ModernVBERT trio. No post-processing applied. ModernVBERT Embed and Bi came out near-random — embedding quality check revealed collapsed embeddings (mean off-diagonal cosine similarity ~0.90, near-zero per-dimension variance), meaning all images were mapping to nearly the same point in space.
 
48
 
49
- | Family | Model | Clf Acc | kNN@1 | kNN@5 |
50
- |---|---|---|---|---|
51
- | SigLIP | Base (patch16-224) | 84.36% | 77.33% | 80.49% |
52
- | SigLIP | Large (patch16-256) | 85.22% | 81.06% | 81.92% |
53
- | SigLIP | SO400M (patch14-384) | 89.96% | 86.66% | 87.37% |
54
- | CLIP | Base (patch32-224) | 81.35% | 77.91% | 80.06% |
55
- | DINOv2 | Base | 74.18% | 70.01% | 71.59% |
56
- | DiT | Base | 63.56% | 60.55% | 62.55% |
57
- | ModernVBERT | Base | 62.84% | 69.58% | 73.74% |
58
- | ModernVBERT | Embed | 18.65% | 7.75% | 16.36% |
59
- | ModernVBERT | Bi | 18.65% | 14.35% | 13.06% |
60
 
61
- **Finding:** ModernVBERT Embed and Bi were loading as text-only encoders. They require the Base model's vision encoder to extract image patch embeddings first before passing through.
 
 
 
 
 
62
 
63
  ---
64
 
65
- ### Run 2 — ModernVBERT fixed + SigLIP2 added
66
- Re-ran the three ModernVBERT variants (`*2` suffix) with Base handling image encoding. Also added the full SigLIP2 family (Base, Large, SO400M) in this pass.
67
 
68
- | Family | Model | Clf Acc | kNN@1 | kNN@5 |
69
- | ----------- | -------------------- | ------- | ------ | ------ |
70
- | SigLIP2 | Base (patch16-224) | 83.07% | 73.46% | 75.04% |
71
- | SigLIP2 | Large (patch16-256) | 87.23% | 81.21% | 81.92% |
72
- | SigLIP2 | SO400M (patch14-384) | 88.81% | 84.79% | 85.80% |
73
- | ModernVBERT | Base | 62.84% | 69.58% | 73.74% |
74
- | ModernVBERT | Embed | 57.39% | 59.68% | 60.69% |
75
- | ModernVBERT | Bi | 55.09% | 60.11% | 58.82% |
76
 
77
- **Finding:** ModernVBERT Embed and Bi jumped to >55% confirming the fix worked as it isn't far of from the base. But it is still underperforming because this variant should be an improvement from the base model. Further investigation needed on the correct pooling/embedding extraction strategy for those variants.
 
78
 
79
- ---
80
 
81
- ### Run 3 PCA post-processing on ModernVBERT `*2` variants
82
- Added mean-centering → PCA whitening (n=256) → L2 re-normalisation to Embed 2 and Bi 2. Also added CLIP Large to the comparison.
83
 
84
- | Family | Model | Clf Acc | kNN@1 | kNN@5 |
85
- | ----------- | ------------------- | ------- | ------ | ------ |
86
- | ModernVBERT | Base 2 | 84.51% | 73.03% | 77.62% |
87
- | ModernVBERT | Embed 2 | 86.94% | 71.74% | 78.77% |
88
- | ModernVBERT | Bi 2 | 85.37% | 71.59% | 78.34% |
89
- | CLIP | Large (patch14-224) | 84.65% | 75.04% | 78.77% |
90
 
91
- **Finding:** Post-processing gave a solid lift to Base(+21.67%) Embed 2 (+29.5%) and Bi 2 (+30.3%), bringing all three ModernVBERT variants into a competitive range. Confirmed PCA whitening was worth applying more broadly.
92
 
93
  ---
94
 
95
- ### Run 4 — PCA post-processing extended to SigLIP SO400M, DINOv2, DiT + DiT Large added
96
- Swept `n_components` across [64, 128, 256, 512] (up to 1024 for SO400M variants) and selected the best n by linear probe accuracy. Applied only to SO400M within SigLIP/SigLIP2 — smaller variants were left as-is. Also added DiT Large.
97
 
98
- | Family | Model | Clf Acc | kNN@1 | kNN@5 | Best n |
99
- |---|---|---|---|---|---|
100
- | SigLIP | SO400M + postprocess | 90.10% | 77.91% | 83.64% | 128 |
101
- | SigLIP2 | SO400M + postprocess | **90.67%** | 77.62% | 84.22% | 128 |
102
- | DINOv2 | Base (post-processed) | 79.77% | 71.31% | 74.46% | 128 |
103
- | DiT | Base (post-processed) | 74.89% | 61.69% | 66.43% | 256 |
104
- | DiT | Large (post-processed) | 77.33% | 63.99% | 67.43% | 512 |
105
 
106
- **Best overall: SigLIP2 SO400M + postprocess — 90.67% Clf Acc.**
 
 
107
 
108
  ---
109
 
110
- ## Infrastructure
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- - **GPU**: Local Nvidia GPU (CUDA)
113
- - **PyTorch**: 2.6.0+cu124
114
- - **Key libs**: `transformers`, `datasets`, `scikit-learn`, `tqdm`, `Pillow`
115
- - **Checkpointing**: Results saved to `results_checkpoint.json` after each model so the run can be resumed after a kernel restart.
116
- - **Embeddings**: Cached to `.npy` files per model (`train_emb_<name>.npy`, `test_emb_<name>.npy`).
117
 
118
  ## Repo Structure
119
 
120
  ```
121
- benchmarkembeddings_tabacco3482.ipynb # main notebook
122
- results_checkpoint.json # accumulated results (auto-saved)
123
- train_emb_<ModelName>.npy # cached train embeddings per model
124
- test_emb_<ModelName>.npy # cached test embeddings per model
 
 
 
 
 
 
 
 
 
 
125
  ```
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  Benchmarks several vision encoder families as **frozen embedding extractors** for document image classification on the [Tobacco-3482](https://huggingface.co/datasets/maveriq/tobacco3482) dataset.
4
 
5
+ ---
6
+
7
  ## Dataset
8
 
9
  | Property | Value |
10
  |---|---|
11
  | Dataset | `maveriq/tobacco3482` |
12
  | Task | 10-class document image classification |
13
+ | Classes | letter, memo, email, resume, scientific, note, ADVE, report, form, news |
14
+ | Size | 3,482 scanned document images |
15
  | Split | 80/20 train/test (fixed seed 42) |
16
 
17
+ All images are greyscale scans converted to RGB. Preprocessing applied before embedding extraction:
18
+ - Auto-contrast via `ImageOps.autocontrast` (clips bottom/top 1% of pixels)
19
+ - Mild contrast boost (×1.2) on top of autocontrast
20
+ - Sharpening via `ImageFilter.SHARPEN` to help edge-based patch encoders
21
+
22
+ ### Class Distribution
23
+
24
+ ![[Pasted image 20260419225937.png|559]]
25
+ ![[Pasted image 20260419230216.png|296]]
26
+ #### Image Sample
27
+
28
+ ![[Pasted image 20260419230241.png|697]]
29
+
30
+ ---
31
  ## Models Evaluated
32
 
33
+ ### SigLIP (Google)
 
 
 
 
 
 
 
34
 
35
+ Sigmoid-loss vision-language model. Unlike CLIP's softmax contrastive loss, SigLIP applies a per-pair sigmoid loss which scales better to large batch sizes and does not require a global normalisation term.
36
 
37
+ | Model | HuggingFace ID | Batch Size | Notes |
38
+ |---|---|---|---|
39
+ | SigLIP Base (patch16-224) | `google/siglip-base-patch16-224` | 64 | Smallest SigLIP — fast baseline for scale ablation |
40
+ | SigLIP Large (patch16-256) | `google/siglip-large-patch16-256` | 32 | Mid-point in scale ablation |
41
+ | SigLIP SO400M (patch14-384) | `google/siglip-so400m-patch14-384` | 16 | 400M-param Shape-Optimised variant; 384px input boosts doc-image detail |
42
 
43
+ ### SigLIP 2 (Google)
44
 
45
+ Upgraded SigLIP with additional self-distillation and masked prediction objectives on top of the sigmoid loss. Same model sizes as SigLIP v1 but stronger representations.
 
46
 
47
+ | Model | HuggingFace ID | Batch Size | Notes |
48
+ | ---------------------------- | ----------------------------------- | ---------- | ------------------------------------------------------------------ |
49
+ | SigLIP2 Base (patch16-224) | `google/siglip2-base-patch16-224` | 64 | Same scale as SigLIP Base but better objectives |
50
+ | SigLIP2 Large (patch16-256) | `google/siglip2-large-patch16-256` | 32 | |
51
+ | SigLIP2 SO400M (patch14-384) | `google/siglip2-so400m-patch14-384` | 16 | Top-performing model overall; also tested with PCA post-processing |
52
 
53
+ ### ModernVBERT
54
+
55
+ A transformer architecture that tests the effect of progressively stronger training objectives — from masked language modelling (MLM) through contrastive learning to document-specific fine-tuning. All three variants require the Base model to first extract image patch embeddings; Embed and Bi are not standalone vision encoders.
56
+
57
+ | Model | HuggingFace ID | Batch Size | Training objective |
58
+ |---|---|---|---|
59
+ | ModernVBERT Base | `ModernVBERT/modernvbert` | 8 | MLM only — no contrastive objective; serves as training-objective baseline |
60
+ | ModernVBERT Embed | `ModernVBERT/modernvbert-embed` | 8 | MLM + contrastive learning for general embedding quality |
61
+ | ModernVBERT Bi | `ModernVBERT/bimodernvbert` | 8 | Fine-tuned for document retrieval with a bi-encoder objective |
62
+
63
+ > **ColModernVBERT** was investigated but skipped — the base model (`ettin-encoder-150m`) is private/gated on HuggingFace and the required `colpali_engine` branch has not been merged.
64
+
65
+ ### CLIP (OpenAI)
66
+
67
+ Contrastive vision-language model and direct predecessor to SigLIP. Included as a baseline to show how far the field has moved.
68
+
69
+ | Model | HuggingFace ID | Batch Size |
70
  |---|---|---|
71
+ | CLIP Base (patch32-224) | `openai/clip-vit-base-patch32` | 64 |
72
+ | CLIP Large (patch14-224) | `openai/clip-vit-large-patch16-224` | 32 |
 
73
 
74
+ ### DINOv2 (Meta)
75
 
76
+ Self-supervised ViT trained without any text labels. Included as a vision-only baseline — interesting because it never saw text or label supervision during pretraining.
77
 
78
+ | Model | HuggingFace ID | Batch Size |
79
+ |---|---|---|
80
+ | DINOv2 Base | `facebook/dinov2-base` | 64 |
81
 
82
+ ### DiT (Microsoft)
 
 
 
 
 
 
 
 
 
 
83
 
84
+ Document Image Transformer a ViT pretrained specifically on 42 million scanned documents from the IIT-CDIP corpus, making it the most domain-relevant model in the benchmark.
85
+
86
+ | Model | HuggingFace ID | Batch Size |
87
+ |---|---|---|
88
+ | DiT Base | `microsoft/dit-base` | 64 |
89
+ | DiT Large | `microsoft/dit-large` | 32 |
90
 
91
  ---
92
 
93
+ ## Evaluation Protocol
 
94
 
95
+ Embeddings are extracted once (L2-normalised, no fine-tuning) and evaluated with two probes:
 
 
 
 
 
 
 
96
 
97
+ - **Linear probe** logistic regression (`sklearn`, `max_iter=1000`) on frozen embeddings; reports accuracy and weighted F1.
98
+ - **kNN retrieval** — cosine-similarity nearest neighbours; reports top-1 and top-5 accuracy.
99
 
100
+ ### Post-processing
101
 
102
+ PCA post-processing (mean-centering PCA whitening → L2 re-normalisation) was applied to most models to test whether dimensionality reduction improves representations. The best `n_components` was selected by linear probe accuracy on the test set.
 
103
 
104
+ | Model(s) | Approach | n sweep |
105
+ |---|---|---|
106
+ | SigLIP SO400M, SigLIP2 SO400M | Separate `+ postprocess` entry in results | 64, 128, 256, 512, 768, 1024 |
107
+ | CLIP Large, DINOv2 Base, DiT Base, DiT Large | Inline sweep within extraction cell; best n used for final result | 64, 128, 256, 512 |
108
+ | ModernVBERT Base, Embed, Bi | Fixed `postprocess()` call at n=256 | 256 (fixed) |
 
109
 
110
+ > **Note on the post-processing trade-off:** PCA whitening lifts linear probe (clf) accuracy but can hurt kNN retrieval by distorting the original cosine geometry. The two metrics optimise for different embedding structures, so the choice of whether to apply post-processing depends on the downstream task.
111
 
112
  ---
113
 
114
+ ## Results
 
115
 
116
+ ![[Pasted image 20260419230643.png]]
 
 
 
 
 
 
117
 
118
+ Best classification accuracy: SigLIP SO400M (patch14-384) + postprocess
119
+ Best kNN: SigLIP SO400M (patch14-384)
120
+ Best Overall: SigLIP SO400M (patch14-384)
121
 
122
  ---
123
 
124
+ ## Embedding Fusion (In Progress)
125
+
126
+ Experiments combining embeddings from two complementary models via weighted concatenation. Three fusion pairs are being tested:
127
+
128
+ | Pair | Rationale |
129
+ |---|---|
130
+ | SigLIP2 SO400M + DiT Large | VLM features + doc-specific pretraining |
131
+ | SigLIP2 SO400M + DINOv2 Base | VLM features + self-supervised vision |
132
+ | DiT Large + DINOv2 Base | Both vision-focused, different pretraining signals |
133
+
134
+ Three strategies per pair:
135
+ - **Raw concat** (α=0.5) — simple weighted concatenation + L2 renorm
136
+ - **PCA-whitened concat** — reduces redundancy across the two embedding spaces
137
+ - **Alpha sweep** (α ∈ {0.6, 0.7, 0.8}) — up-weights the stronger model
138
 
139
+ ---
 
 
 
 
140
 
141
  ## Repo Structure
142
 
143
  ```
144
+ benchmarkembeddings_tabacco3482_v.ipynb # main notebook
145
+ benchmark_summary.txt # human-readable results table
146
+
147
+ embeddings/ # cached embeddings per model
148
+ train_emb_<ModelName>.npy
149
+ test_emb_<ModelName>.npy
150
+
151
+ results/ # benchmark outputs
152
+ results_checkpoint.json # accumulated results (auto-saved after each model)
153
+ model_registry.json # full model metadata (id, batch size, description)
154
+ benchmark_summary.json # structured results for programmatic access
155
+
156
+ metadata/ # dataset and split info
157
+ figures/ # plots and visualisations
158
  ```
159
+
160
+ ---
161
+
162
+ ## Infrastructure
163
+
164
+ | Property | Value |
165
+ |---|---|
166
+ | GPU | Local Nvidia GPU (CUDA) |
167
+ | PyTorch | 2.6.0+cu124 |
168
+ | Key libs | `transformers`, `datasets`, `scikit-learn`, `tqdm`, `Pillow` |
169
+ | Checkpointing | Results saved to `results/results_checkpoint.json` after each model so the run can be resumed after a kernel restart |
170
+ | Embeddings | Cached to `.npy` files under `embeddings/` per model to avoid re-extracting on reruns |
tabacco3482_benchmarks/Week_05_Update.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ **Week 5 — Progress Update** _Image embedding benchmark · Tobacco-3482_
2
+
3
+ ---
4
+
5
+ ## Completed
6
+
7
+ - Extended PCA post-processing (mean-centering, whitening, L2 re-normalisation) to all remaining model families: SigLIP SO400M, SigLIP2 SO400M, DINOv2, DiT Base, and DiT Large.
8
+ - SigLIP SO400M + postprocess reached **90.24%** clf accuracy. SigLIP2 SO400M + postprocess reached **89.10%**, confirming PCA whitening at n=128 is the sweet spot for SO400M variants.
9
+ - Completed a full clean rerun of all 19 models with results serialised to JSON checkpoints for reproducibility.
10
+ - Created and committed a fully updated `README.md` to HuggingFace covering model architecture explanations, HuggingFace IDs, batch sizes, dataset preprocessing steps, full results table, fusion experiment plans, and the new repo folder structure (`embeddings/`, `results/`, `metadata/`, `figures/`).
11
+ - Analysed misclassified samples on Tobacco-3482 using SigLIP2 SO400M embeddings and identified common failure modes across the 10 document classes.
12
+ - Corrected a silent bug where ModernVBERT Embed/Bi were not being rerun after code changes. Duplicate cells were adding post-processing on top of stale embeddings. After a proper full rerun, ModernVBERT Embed accuracy recovered to 80%+.
13
+ - Explored centering-only post-processing (no PCA) as a lighter alternative. Preliminary result on SigLIP2 SO400M: clf 89%, kNN@1/5 ~86%, suggesting the whitening step is responsible for the kNN trade-off.
14
+
15
+ ---
16
+
17
+ ## In Progress
18
+
19
+ - Multi-layer embedding fusion, investigating whether combining intermediate transformer layers improves representation quality, starting with ModernVBERT variants where the gap vs SigLIP is most pronounced.
20
+
21
+ ---
22
+
23
+ ## Blockers
24
+ - ColModernVBERT remains blocked. It depends on a private base model (`ettin-encoder-150m`) and an unmerged `colpali_engine` branch with no path forward without access.
25
+ - Layer fusion experiments not yet executed. Full model rerun consumed most available compute time remaining of this week and fusion runs are queued for next week.
26
+
27
+ ---
28
+
29
+ ## Key Learnings
30
+
31
+ - **ModernVBERT architecture:** Embed and Bi variants require Base to first extract vision patch embeddings and are not standalone vision encoders. Misunderstanding this caused the near-random results in Run 1.
32
+ - **PCA whitening trade-offs:** Whitening compresses embeddings into a lower-dimensional isotropic space that benefits a linear probe but can hurt kNN retrieval by distorting the original cosine geometry. The two metrics optimise for different things.
33
+ - **Reproducibility discipline:** Silently duplicating cells without rerunning upstream code can produce misleading results. The ModernVBERT jump flagged was traced back to this exact issue. Learned to always do a clean end-to-end rerun before recording numbers.
34
+ - **HuggingFace workflow:** Gained hands-on experience committing experiment documentation and navigating the HuggingFace Hub for dataset access, and repo management.