torstendittmann commited on
Commit
66d104d
·
verified ·
1 Parent(s): f02f671

Publish FocalNet ONNX and PyTorch checkpoints

Browse files
README.md CHANGED
@@ -1,3 +1,130 @@
1
  ---
2
  license: mit
 
 
 
 
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  license: mit
3
+ library_name: onnxruntime
4
+ pipeline_tag: image-to-image
5
+ tags:
6
+ - onnx
7
+ - computer-vision
8
+ - image-cropping
9
+ - saliency
10
+ base_model: timm/repvit_m0_9
11
  ---
12
+
13
+ # FocalNet
14
+
15
+ Appwrite FocalNet is a compact vision model for content-aware image cropping. It
16
+ predicts a 64×64 importance map, then ranks crop candidates with a small
17
+ composition head trained on human preferences.
18
+
19
+ This is **not** Microsoft FocalNet (the hierarchical attention backbone in
20
+ `timm`). Training code lives in [appwrite/focalnet](https://github.com/appwrite/focalnet).
21
+
22
+ The reference RepViT-M0.9 ranker has 4.76 million parameters. The published
23
+ `focalnet-human.onnx` artifact is 19.45 MiB in FP32.
24
+
25
+ ## Files
26
+
27
+ | File | Role | SHA-256 |
28
+ | --- | --- | --- |
29
+ | `focalnet-human.onnx` | Importance map + crop ranking (format v2) | `59164c601c98cea3f62b25166710831dac63e1a872fc64767c65316ad5385439` |
30
+ | `focalnet.onnx` | Importance map only (format v1) | `87becceb269a2973c359df789783be49a9f840f47170a015d3776d7c4145a2ce` |
31
+ | `focalnet-human.pt` | PyTorch ranking checkpoint | `82c4d695310c220e5f3bcfbf5e64d315a5e826cfd77e945e61e032460014480a` |
32
+ | `focalnet.pt` | PyTorch importance checkpoint | `d1942f0652f8ea85f75ffc0cb1bf40d7e70b38e7ad102ab0e6df5c2e07ce52cf` |
33
+
34
+ JSON sidecars next to the ONNX files record the preprocessing contract, parameter
35
+ counts, and export verification.
36
+
37
+ Use `focalnet-human.onnx` for inference. The PyTorch files are for continued
38
+ training, not for the ONNX Runtime path.
39
+
40
+ ## Usage
41
+
42
+ Download the ranking model and crop a photo:
43
+
44
+ ```sh
45
+ hf download appwrite/focalnet focalnet-human.onnx --local-dir artifacts
46
+ uv run focalnet predict-human artifacts/focalnet-human.onnx photo.jpg \
47
+ --aspect-ratio 16:9
48
+ ```
49
+
50
+ From Python:
51
+
52
+ ```python
53
+ from huggingface_hub import hf_hub_download
54
+ from focalnet.human_runtime import HumanCropPredictor
55
+
56
+ path = hf_hub_download("appwrite/focalnet", "focalnet-human.onnx")
57
+ crop = HumanCropPredictor(path).predict("photo.jpg", aspect_ratio=16 / 9)
58
+ ```
59
+
60
+ Importance-only inference:
61
+
62
+ ```sh
63
+ hf download appwrite/focalnet focalnet.onnx --local-dir artifacts
64
+ uv run focalnet predict artifacts/focalnet.onnx photo.jpg --aspect-ratio 16:9
65
+ ```
66
+
67
+ `predict-human` generates up to 125 crops across five positions and five zoom
68
+ levels, scores a padded maximum of 128 candidates in one ONNX call, and selects
69
+ the highest preference score among crops whose retained importance is within
70
+ 0.05 of the best candidate. The returned human score is a relative logit.
71
+ Compare it only among crops for the same image.
72
+
73
+ ## ONNX contract
74
+
75
+ | Field | Contract |
76
+ | --- | --- |
77
+ | Image input | `image`, float32 `[1,3,256,256]`, RGB NCHW |
78
+ | Normalization | `(pixel/255 - [0.485,0.456,0.406]) / [0.229,0.224,0.225]` |
79
+ | Resize | Apply EXIF orientation, then aspect-fit with bilinear interpolation |
80
+ | Alpha and padding | Composite alpha on black; normalized padding values are zero |
81
+ | Importance output | `importance`, float32 `[1,1,64,64]`, sigmoid applied |
82
+ | Ranking inputs | `boxes` `[1,128,4]` and letterbox `content` `[1,4]` |
83
+ | Ranking output | `crop_scores`, float32 `[1,128]` |
84
+
85
+ ## Results
86
+
87
+ The importance model was trained on 500,000 teacher-labeled Open Images V7
88
+ samples (RepViT-M0.9 encoder, 48-channel decoder, 10 epochs, best epoch 7).
89
+ Teacher agreement on the group-disjoint 10,000-image validation split:
90
+
91
+ | Metric | Result |
92
+ | --- | ---: |
93
+ | Map MAE | 0.09975 |
94
+ | Normalized centroid error | 0.06430 |
95
+ | 1:1 teacher importance retained | 91.09% |
96
+ | 16:9 teacher importance retained | 90.86% |
97
+ | 4:5 teacher importance retained | 85.56% |
98
+
99
+ The ranking head (7,069 parameters) was pretrained on CPC and fine-tuned on
100
+ GAICD. The importance network stays frozen. On GAICD's 500-image test split:
101
+
102
+ | Metric | GAICD only | CPC → GAICD |
103
+ | --- | ---: | ---: |
104
+ | Spearman correlation | 0.75696 | **0.76450** |
105
+ | Pearson correlation | 0.78211 | **0.79192** |
106
+ | Top-5 accuracy | 42.48% | **43.70%** |
107
+ | Top-10 accuracy | 64.45% | **64.54%** |
108
+ | Pairwise accuracy | 86.00% | **86.44%** |
109
+
110
+ The GAICD test split was inspected during several development iterations. Treat
111
+ these figures as engineering benchmarks, not an untouched final test. INT8
112
+ post-training quantization did not pass the crop-quality gate; FP32 is the
113
+ published artifact.
114
+
115
+ ## Training data
116
+
117
+ - Open Images V7 (teacher-labeled importance maps from U²-Net + YuNet)
118
+ - [Comparative Photo Composition (CPC)](https://www3.cs.stonybrook.edu/~cvl/projects/wei2018goods/VPN_CVPR2018s.html)
119
+ - [GAICD](https://github.com/HuiZeng/Grid-Anchor-based-Image-Cropping-Pytorch)
120
+
121
+ The reviewed CPC and GAICD archives do not state explicit image or annotation
122
+ licenses. This checkpoint is published under MIT for the model files; that
123
+ license does not grant rights to the third-party datasets or teacher weights
124
+ used during training.
125
+
126
+ ## License
127
+
128
+ Model files are available under the [MIT License](https://github.com/appwrite/focalnet/blob/main/LICENSE),
129
+ the same license as the training code. Review dataset and teacher-model terms
130
+ before redistribution of derived artifacts.
focalnet-human.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:59164c601c98cea3f62b25166710831dac63e1a872fc64767c65316ad5385439
3
+ size 20398992
focalnet-human.onnx.json ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 2,
3
+ "task": "human-crop-ranking",
4
+ "input": {
5
+ "image": [
6
+ 1,
7
+ 3,
8
+ 256,
9
+ 256
10
+ ],
11
+ "boxes": [
12
+ 1,
13
+ 128,
14
+ 4
15
+ ],
16
+ "content": [
17
+ 1,
18
+ 4
19
+ ],
20
+ "box_coordinates": "normalized oriented source image",
21
+ "content_coordinates": "normalized letterboxed model input",
22
+ "channels": "RGB",
23
+ "mean": [
24
+ 0.48500001430511475,
25
+ 0.4560000002384186,
26
+ 0.4059999883174896
27
+ ],
28
+ "std": [
29
+ 0.2290000021457672,
30
+ 0.2240000069141388,
31
+ 0.22499999403953552
32
+ ],
33
+ "resize": "bilinear-letterbox"
34
+ },
35
+ "output": {
36
+ "importance": {
37
+ "shape": [
38
+ 1,
39
+ 1,
40
+ 64,
41
+ 64
42
+ ],
43
+ "activation": "sigmoid already applied"
44
+ },
45
+ "crop_scores": {
46
+ "shape": [
47
+ 1,
48
+ 128
49
+ ],
50
+ "semantics": "relative human-preference logits; compare only within one image"
51
+ }
52
+ },
53
+ "model_config": {
54
+ "backbone": "repvit_m0_9",
55
+ "decoder_channels": 48
56
+ },
57
+ "rank_config": {
58
+ "feature_channels": 16,
59
+ "hidden_channels": 64
60
+ },
61
+ "parameters": 4757694,
62
+ "ranking_parameters": 7069,
63
+ "trained_epochs": 28,
64
+ "checkpoint_sha256": "82c4d695310c220e5f3bcfbf5e64d315a5e826cfd77e945e61e032460014480a",
65
+ "base_checkpoint_sha256": "d1942f0652f8ea85f75ffc0cb1bf40d7e70b38e7ad102ab0e6df5c2e07ce52cf",
66
+ "initialize_checkpoint_sha256": "16cf17814cbeec88180d158fd6ba018355e6ca80aecc7f861d7325e295b9c91b",
67
+ "dataset_name": "GAICD journal version",
68
+ "dataset_fingerprint": "b99bffff76228cb2d89077a772586b9874d3879e0b4e90a323e65e719e3197a8",
69
+ "candidate_policy": {
70
+ "positions": 5,
71
+ "scales": [
72
+ 1.0,
73
+ 0.9,
74
+ 0.8,
75
+ 0.7,
76
+ 0.65
77
+ ],
78
+ "retention_tolerance": 0.05
79
+ },
80
+ "onnxruntime_verification": {
81
+ "provider": "CPUExecutionProvider",
82
+ "graph_optimization": "ORT_DISABLE_ALL",
83
+ "atol": 0.05,
84
+ "rtol": 0.001
85
+ },
86
+ "export_max_abs_error": 0.004714310169219971
87
+ }
focalnet-human.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:82c4d695310c220e5f3bcfbf5e64d315a5e826cfd77e945e61e032460014480a
3
+ size 19596175
focalnet.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:87becceb269a2973c359df789783be49a9f840f47170a015d3776d7c4145a2ce
3
+ size 20184361
focalnet.onnx.json ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "format_version": 1,
3
+ "input": {
4
+ "name": "image",
5
+ "shape": [
6
+ 1,
7
+ 3,
8
+ 256,
9
+ 256
10
+ ],
11
+ "dtype": "float32",
12
+ "channels": "RGB",
13
+ "mean": [
14
+ 0.48500001430511475,
15
+ 0.4560000002384186,
16
+ 0.4059999883174896
17
+ ],
18
+ "std": [
19
+ 0.2290000021457672,
20
+ 0.2240000069141388,
21
+ 0.22499999403953552
22
+ ],
23
+ "resize": "bilinear-letterbox",
24
+ "padding": 0,
25
+ "orientation": "apply EXIF before resizing",
26
+ "alpha": "composite on black"
27
+ },
28
+ "output": {
29
+ "name": "importance",
30
+ "shape": [
31
+ 1,
32
+ 1,
33
+ 64,
34
+ 64
35
+ ],
36
+ "activation": "sigmoid already applied",
37
+ "coordinates": "letterboxed-input"
38
+ },
39
+ "model_config": {
40
+ "backbone": "repvit_m0_9",
41
+ "decoder_channels": 48
42
+ },
43
+ "parameters": 4750625,
44
+ "trained_epochs": 7,
45
+ "reparameterized": false,
46
+ "fusion_max_abs_error": 0.014633774757385254,
47
+ "checkpoint_sha256": "d1942f0652f8ea85f75ffc0cb1bf40d7e70b38e7ad102ab0e6df5c2e07ce52cf",
48
+ "manifest_sha256": {
49
+ "train": "61097ffbf1e03103162dc3b13829feab33aab3927e8b8085f57b304e9a810b56",
50
+ "validation": "1048db2654c8e533875e624a5cc37488b8efd46bf6e1fddb18ca67cebb281063"
51
+ },
52
+ "onnxruntime_verification": {
53
+ "provider": "CPUExecutionProvider",
54
+ "graph_optimization": "ORT_DISABLE_ALL",
55
+ "atol": 0.05,
56
+ "rtol": 0.001
57
+ },
58
+ "confidence": "No calibrated confidence head; importance_peak is an activation statistic.",
59
+ "export_max_abs_error": 0.005077719688415527
60
+ }
focalnet.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d1942f0652f8ea85f75ffc0cb1bf40d7e70b38e7ad102ab0e6df5c2e07ce52cf
3
+ size 57821822