kem-gov commited on
Commit
3aea121
·
verified ·
1 Parent(s): 70ff189

Publish via hf-publish-experiment (f8c5cbf3c6afdead0b653403120b2b0621491e87)

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ 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
+ sample_input.jpg filter=lfs diff=lfs merge=lfs -text
37
+ vit_base_raspberry_executorch_optimized.pte filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: executorch
3
+ license: apache-2.0
4
+ base_model: google/vit-base-patch16-224
5
+ base_model_relation: quantized
6
+ tags:
7
+ - image-classification
8
+ - vit
9
+ - int8
10
+ - quantized
11
+ - xnnpack
12
+ - arm
13
+ - executorch
14
+ - edge-ai
15
+ - imagenet
16
+ pipeline_tag: image-classification
17
+ datasets:
18
+ - imagenet-1k
19
+ metrics:
20
+ - accuracy
21
+ model-index:
22
+ - name: vit-base-patch16-224-int8-xnnpack-executorch
23
+ results:
24
+ - task:
25
+ type: image-classification
26
+ name: Image Classification
27
+ dataset:
28
+ type: imagenet-1k
29
+ name: ImageNet-1K val
30
+ split: validation
31
+ args:
32
+ evaluation_samples: 50000
33
+ metrics:
34
+ - type: accuracy
35
+ value: 81.52
36
+ name: Top-1 Accuracy (ExecuTorch INT8)
37
+ - type: accuracy
38
+ value: 96.07
39
+ name: Top-5 Accuracy (ExecuTorch INT8)
40
+ ---
41
+
42
+ # ViT-Base-Patch16-224 INT8 (ExecuTorch + XNNPACK)
43
+
44
+ This is an INT8-quantized version of [google/vit-base-patch16-224](https://huggingface.co/google/vit-base-patch16-224) optimized for edge deployment on ARM devices using [ExecuTorch](https://github.com/pytorch/executorch) with the XNNPACK backend. The model was quantized using PT2E dynamic quantization and exported to the `.pte` format for efficient inference on ARM Cortex-A processors (Raspberry Pi, mobile ARM, embedded).
45
+
46
+ <!--
47
+ MAINTAINER WARNING — fp32 weights are NOT in git, and the publish workflow will DELETE them from HF.
48
+
49
+ The FP32 original .pte (330 MB) exceeds GitHub's 100 MB per-file limit, so it is gitignored and not
50
+ committed. It must be uploaded to the HF repo MANUALLY (interim stopgap — a permanent large-file
51
+ store is an open question; see FOLLOWUPS section 1).
52
+
53
+ CRITICAL: the publish workflow (.github/workflows/publish.yml) runs `hf upload --delete '*'`, which
54
+ deletes every file in the HF repo that is not in the local models/<model>/ upload set. Because the
55
+ fp32 .pte is gitignored it is NOT in that set, so re-running publish will DELETE a manually-uploaded
56
+ fp32 file. After any publish dispatch you must re-upload the fp32 weights by hand until a permanent
57
+ solution replaces this stopgap.
58
+ -->
59
+
60
+ ## Key Highlights
61
+
62
+ Compared to the FP32 baseline:
63
+
64
+ - **3.94x smaller** — 330.42 MB to 83.96 MB
65
+ - **2.26x faster** — 397.86 ms to 176.35 ms on Raspberry Pi
66
+ - **Minimal accuracy loss** — -0.008 pp Top-1 Accuracy
67
+
68
+ ## Model Details
69
+
70
+ ### Model Description
71
+
72
+ Quantized version of ViT-Base-Patch16-224, Google's Vision Transformer (ViT) base model trained on ImageNet-21k and fine-tuned on ImageNet-1k, optimized for efficient edge inference via INT8 dynamic quantization and the ExecuTorch runtime.
73
+
74
+ - **Developed by:** Google
75
+ - **Model type:** Image Classification
76
+ - **License:** Gemma
77
+ - **Base model:** [google/vit-base-patch16-224](https://huggingface.co/google/vit-base-patch16-224) — quantized, not finetuned
78
+
79
+ ### Model Sources
80
+
81
+ - **Repository:** https://huggingface.co/google/vit-base-patch16-224
82
+
83
+ ## How to Get Started with the Model
84
+
85
+ ### Install dependencies
86
+
87
+ ```bash
88
+ pip install executorch torch torchvision pillow numpy
89
+ ```
90
+
91
+ ### Download the model
92
+
93
+ ```python
94
+ from huggingface_hub import hf_hub_download
95
+
96
+ model_path = hf_hub_download(
97
+ repo_id="Arm/vit-base-int8-xnnpack-executorch",
98
+ filename="vit_base_raspberry_executorch_optimized.pte",
99
+ )
100
+ ```
101
+
102
+ ### Run inference
103
+
104
+ ```bash
105
+ python example.py
106
+ ```
107
+
108
+ Or use the core inference loop directly:
109
+
110
+ ```python
111
+ import torch
112
+ from executorch.runtime import Runtime
113
+ from PIL import Image
114
+ from torchvision import transforms
115
+
116
+ # Load model
117
+ runtime = Runtime.get()
118
+ program = runtime.load_program("vit_base_raspberry_executorch_optimized.pte")
119
+ method = program.load_method("forward")
120
+
121
+ # Preprocess (resize to 224x224, normalize to [-1, 1])
122
+ image = Image.open("input.jpg").convert("RGB")
123
+ transform = transforms.Compose([
124
+ transforms.Resize((224, 224)),
125
+ transforms.ToTensor(),
126
+ transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
127
+ ])
128
+ input_tensor = transform(image).unsqueeze(0) # [1, 3, 224, 224]
129
+
130
+ # Run inference
131
+ outputs = method.execute([input_tensor])
132
+
133
+ # outputs[0] shape: [1, 1000] — raw logits, one per ImageNet class
134
+ # Apply softmax for probabilities; see example.py for full top-k postprocessing
135
+ ```
136
+
137
+ ## Evaluation
138
+
139
+ ### Testing Data, Factors & Metrics
140
+
141
+ #### Testing Data
142
+
143
+ Evaluated on 50,000 images from ImageNet-1K val (validation split).
144
+
145
+ #### Metrics
146
+
147
+ - **Top-1 Accuracy** — the fraction of images where the highest-probability class matches the ground truth label
148
+ - **Top-5 Accuracy** — the fraction of images where the ground truth label appears in the five highest-probability predictions
149
+
150
+ ### Results
151
+
152
+ #### Accuracy
153
+
154
+ | Metric | FP32 (Original) | INT8 (Optimized) | Delta |
155
+ |:---|:---:|:---:|:---:|
156
+ | Top-1 Accuracy (PyTorch) | 81.52% | 81.52% | 0.00 pp |
157
+ | Top-1 Accuracy (ExecuTorch) | 81.52% | 81.52% | -0.008 pp |
158
+ | Top-5 Accuracy (ExecuTorch) | 96.06% | 96.07% | +0.008 pp |
159
+
160
+ #### Efficiency
161
+
162
+ | Metric | FP32 (Original) | INT8 (Optimized) | Improvement |
163
+ |:---|:---:|:---:|:---:|
164
+ | Model Size (.pte) | 330.42 MB | 83.96 MB | **3.94x smaller** |
165
+ | Raspberry Pi Latency | 397.86 ms | 176.35 ms | **2.26x faster** |
166
+ | Raspberry Pi Peak Memory (USS) | 386.61 MB | 112.73 MB | **3.43x less** |
167
+ | Raspberry Pi Median Memory (USS) | 386.56 MB | 109.70 MB | **3.52x less** |
168
+
169
+ ## Technical Specifications
170
+
171
+ ### Objective
172
+
173
+ 1000-class image classification on ImageNet using a Vision Transformer (ViT) architecture with 16x16 patch tokens.
174
+
175
+ ### Quantization
176
+
177
+ - **Method**: PT2E Dynamic Quantization via XNNPACKQuantizer
178
+ - **Precision**: INT8 symmetric, per-channel weights
179
+ - **Backend**: XNNPACK
180
+ - **Layers kept in FP32**: None (uniform quantization — all layers quantized)
181
+
182
+ ### Export Pipeline
183
+
184
+ 1. Load pretrained FP32 model from HuggingFace (`google/vit-base-patch16-224`)
185
+ 2. Wrap model to return a single logits tensor (strips HuggingFace output dataclass)
186
+ 3. Capture model graph via `torch.export`
187
+ 4. Insert dynamic quantization observers (XNNPACKQuantizer, per-op mode)
188
+ 5. Convert observers to Q/DQ pairs
189
+ 6. Export to ExecuTorch `.pte` with XNNPACK backend (per-op partitioner to handle ViT attention graph topology)
190
+
191
+ ### Preprocessing
192
+
193
+ | Property | Value |
194
+ |---|---|
195
+ | Input shape | `[1, 3, 224, 224]` (BCHW) |
196
+ | Data type | float32 |
197
+ | Value range | [0.0, 1.0] before normalization |
198
+ | Color space | RGB |
199
+
200
+ **Steps**:
201
+ 1. Resize image to 224x224 (bilinear interpolation)
202
+ 2. Convert to tensor (`ToTensor()`: [0–255] uint8 → [0, 1] float32)
203
+ 3. Normalize: subtract 0.5 and divide by 0.5 per channel → output range [-1, 1]
204
+
205
+ **Normalization**: mean `[0.5, 0.5, 0.5]`, std `[0.5, 0.5, 0.5]` (standard ViT normalization from HuggingFace processor).
206
+
207
+ ### Postprocessing
208
+
209
+ | Property | Value |
210
+ |---|---|
211
+ | Output shape | `[1, 1000]` |
212
+ | Output format | Raw class logits (unnormalized), one score per ImageNet class |
213
+
214
+ **Steps**:
215
+ 1. Apply softmax over the 1000 class dimension to obtain probabilities
216
+ 2. Take `topk(5)` to retrieve the five highest-probability class indices and scores
217
+ 3. Map class indices to human-readable labels using the ImageNet class list
218
+
219
+ ## Known Limitations
220
+
221
+ - Evaluated on the full 50,000-image ImageNet-1K validation set
222
+ - Fixed input size of 224x224 — images are resized without preserving aspect ratio
223
+ - Optimized for single-batch inference (batch size = 1); multi-batch export is not supported in this configuration
benchmarks/README.md ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Benchmarks
2
+
3
+ Machine-readable measurement records for this model, conforming to
4
+ [`mech-model-schemas`](https://github.com/Arm-Debug/mech-model-schemas)
5
+ v1.0.0 (`task: vision-classification`).
6
+
7
+ These complement — they don't replace — the eval block in the model
8
+ card. The card carries the headline numbers in human-readable form;
9
+ these YAMLs carry the same data with full context (target hardware,
10
+ runtime config, dataset slice, benchmark parameters) so downstream
11
+ tooling can ingest them programmatically.
12
+
13
+ ## Files
14
+
15
+ - `vit-base-raspberrypi5-int8.yaml` — INT8 measurements on
16
+ Raspberry Pi 5 via ExecuTorch + XNNPACK + KleidiAI.
17
+ - `vit-base-raspberrypi5-fp32.yaml` — FP32 baseline on the same
18
+ hardware/runtime, for comparison.
19
+
20
+ ## Reading these
21
+
22
+ Each record has three top-level sections:
23
+
24
+ - `context.{model,target,runtime,dataset,benchmark}` — everything
25
+ needed to reproduce the measurement.
26
+ - `performance` — latency (p50/p90), memory (peak/average), cold
27
+ start, FPS, delegation %.
28
+ - `accuracy` — Top-1 / Top-5 percentages.
29
+
30
+ The two records share `context.{target,runtime,dataset,benchmark}`;
31
+ the disambiguator is `weight_dtype` (and, once published under an
32
+ `Arm/*` slug, `model.id`).
33
+
34
+ ## Notes specific to this model
35
+
36
+ - **Dynamic quantization** (`quantization.mode: dynamic`, PTQ-dynamic) —
37
+ unlike the static-PTQ CNNs. Activations are quantized at runtime.
38
+ - **Low XNNPACK delegation (77.18%)** — operator coverage is only ~16%
39
+ for ViT's attention/layernorm ops; most of the speedup comes from the
40
+ delegated MatMuls. The 2.26× speedup is modest *because* the transformer
41
+ is largely non-delegated on CPU.
42
+ - **Big and slow on Pi** — 175ms p50 / 5.7 fps int8. This is a base-size
43
+ transformer; it runs, but it's not a real-time edge model on a Pi 5.
44
+ - Accuracy values are the **ExecuTorch-measured** figures from
45
+ `report.json` (int8 Top-1 81.516 / Top-5 96.072; fp32 81.524 / 96.064) —
46
+ the int8 accuracy loss is negligible (−0.008pp Top-1), characteristic of
47
+ dynamic quant on a transformer.
48
+
49
+ ## Provenance
50
+
51
+ Source: Marvik delivery package `vit_base_raspberry_executorch.zip`
52
+ (`report.json`, `metadata.yaml`, `huggingface/README.md`). The INT8
53
+ record maps from the delivered `metadata.yaml`; the FP32 baseline is
54
+ hand-reconstructed from `report.json` `original` fields (the pipeline
55
+ only emits the optimised metadata).
benchmarks/vit-base-raspberrypi5-fp32.yaml ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # FP32 baseline measurement record — ViT-Base-Patch16-224 on Raspberry Pi 5 via ExecuTorch.
2
+ # Pairs with `vit-base-raspberrypi5-int8.yaml` to demonstrate the
3
+ # baseline-comparison join.
4
+ #
5
+ # Source: Marvik delivery package `vit_base_raspberry_executorch.zip`,
6
+ # `report.json` `original` fields (the un-quantised baseline measured under
7
+ # identical target / runtime / dataset / benchmark conditions to the optimised
8
+ # record).
9
+ #
10
+ # Same target / runtime / dataset / benchmark as the INT8 record — the
11
+ # disambiguator is `weight_dtype` (and, once published, `model.id`).
12
+ #
13
+ # Hand-curated rather than redelivered: Marvik's pipeline only emits the
14
+ # optimised metadata.yaml, so this baseline is reconstructed from report.json.
15
+ #
16
+ # Outstanding unknowns (not surfaced by the pipeline yet):
17
+ # - context.runtime.config.n_threads
18
+ # - performance.end_to_end_latency_ms.p99
19
+
20
+ version: 1.0.0
21
+ task: vision-classification
22
+ created_at: '2026-05-07T15:58:46Z'
23
+ context:
24
+ model:
25
+ id: google/vit-base-patch16-224
26
+ base_model_id: google/vit-base-patch16-224
27
+ profile: Experimental
28
+ weight_dtype: fp32
29
+ model_size_mb: 330.423
30
+ format: pte
31
+ target:
32
+ name: Raspberry Pi 5
33
+ hardware_class: Edge Linux
34
+ cpu_architecture: arm64
35
+ cpu_model: Cortex-A76
36
+ cpu_core_count: 4
37
+ cpu_clock_ghz: 2.4
38
+ system_memory_gb: 8
39
+ os: linux
40
+ os_version: Raspberry Pi OS Bookworm
41
+ runtime:
42
+ name: executorch
43
+ execution_backend: cpu
44
+ version: 1.1.0
45
+ config:
46
+ optimisations:
47
+ - XNNPACK
48
+ - KleidiAI
49
+ dataset:
50
+ name: ImageNet-1k
51
+ slice: val
52
+ sample_count: 50000
53
+ reference_url: https://www.image-net.org/
54
+ benchmark:
55
+ batch_size: 1
56
+ input_resolution: 224x224
57
+ num_runs: 10
58
+ warmup_runs: 10
59
+ performance:
60
+ end_to_end_latency_ms:
61
+ p50: 397.621
62
+ p90: 398.733
63
+ peak_memory_mb: 386.609
64
+ average_memory_mb: 386.563
65
+ cold_start_time_ms: 272.856
66
+ accuracy:
67
+ top_1_accuracy_pct: 81.524
68
+ top_5_accuracy_pct: 96.064
benchmarks/vit-base-raspberrypi5-int8.yaml ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: 1.0.0
2
+ task: vision-classification
3
+ created_at: '2026-05-07T15:58:46Z'
4
+ context:
5
+ model:
6
+ id: google/vit-base-patch16-224
7
+ base_model_id: google/vit-base-patch16-224
8
+ weight_dtype: int8
9
+ profile: Arm-Optimized
10
+ quantization:
11
+ method: PTQ-dynamic
12
+ weight_bits: 8
13
+ activation_bits: 8
14
+ symmetric: true
15
+ mode: dynamic
16
+ weight_granularity: per-channel
17
+ model_size_mb: 83.963
18
+ format: pte
19
+ target:
20
+ name: Raspberry Pi 5
21
+ hardware_class: Edge Linux
22
+ cpu_architecture: arm64
23
+ cpu_model: Cortex-A76
24
+ cpu_core_count: 4
25
+ cpu_clock_ghz: 2.4
26
+ system_memory_gb: 8
27
+ os: linux
28
+ os_version: Raspberry Pi OS Bookworm
29
+ runtime:
30
+ name: executorch
31
+ execution_backend: cpu
32
+ version: 1.1.0
33
+ config:
34
+ optimisations:
35
+ - XNNPACK
36
+ - KleidiAI
37
+ dataset:
38
+ name: ImageNet-1k
39
+ slice: val
40
+ sample_count: 50000
41
+ reference_url: https://www.image-net.org/
42
+ benchmark:
43
+ batch_size: 1
44
+ input_resolution: 224x224
45
+ num_runs: 10
46
+ warmup_runs: 10
47
+ performance:
48
+ end_to_end_latency_ms:
49
+ p50: 175.448
50
+ p90: 178.154
51
+ peak_memory_mb: 112.73
52
+ average_memory_mb: 109.70
53
+ delegation_pct: 77.18
54
+ cold_start_time_ms: 250.304
55
+ frames_per_second: 5.7
56
+ accuracy:
57
+ top_1_accuracy_pct: 81.516
58
+ top_5_accuracy_pct: 96.072
config.yaml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ input:
2
+ shape: [1, 3, 224, 224]
3
+ dtype: float32
4
+ range: [0.0, 1.0]
5
+ preprocessing:
6
+ - resize: [224, 224]
7
+ - to_tensor
8
+ - normalize:
9
+ mean: [0.5, 0.5, 0.5]
10
+ std: [0.5, 0.5, 0.5]
11
+
12
+ output:
13
+ shape: [1, 1000]
14
+ format: "Raw class logits (unnormalized), one score per ImageNet class"
15
+ postprocessing:
16
+ softmax: true
17
+ top_k: 5
example.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Minimal inference example for ViT-Base-Patch16-224 INT8 using ExecuTorch.
2
+
3
+ Loads a quantized .pte model and runs image classification on a single image.
4
+ Requires: executorch, torch, torchvision, pillow, numpy, json
5
+ """
6
+
7
+ import json
8
+ from pathlib import Path
9
+
10
+ import torch
11
+ from executorch.runtime import Runtime
12
+ from PIL import Image, ImageDraw, ImageFont
13
+ from torchvision import transforms
14
+
15
+
16
+ # ── Configuration ──────────────────────────────────────────────────────────────
17
+ MODEL_PATH = "vit_base_raspberry_executorch_optimized.pte"
18
+ IMAGE_PATH = "sample_input.jpg"
19
+ INPUT_SIZE = (224, 224) # Height, Width expected by the model
20
+ TOP_K = 5 # Number of top predictions to return
21
+
22
+ # Normalization constants used by the google/vit-base-patch16-224 processor
23
+ VIT_MEAN = [0.5, 0.5, 0.5]
24
+ VIT_STD = [0.5, 0.5, 0.5]
25
+
26
+ # Labels file (sibling to this script)
27
+ LABELS_PATH = Path(__file__).parent / "imagenet_classes.json"
28
+
29
+
30
+ def load_labels() -> dict:
31
+ """Load ImageNet class labels from sibling JSON file."""
32
+ with open(LABELS_PATH) as f:
33
+ return json.load(f)
34
+
35
+
36
+ def load_model(pte_path: str):
37
+ """Load ExecuTorch .pte model and return the forward method.
38
+
39
+ Load the method once and reuse it — do not reload per call.
40
+ """
41
+ runtime = Runtime.get()
42
+ program = runtime.load_program(pte_path)
43
+ return program.load_method("forward")
44
+
45
+
46
+ def preprocess(image_path: str) -> torch.Tensor:
47
+ """Load and preprocess image for ViT-Base model input.
48
+
49
+ Pipeline: Resize(224, 224) -> ToTensor -> Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
50
+ Input values are in [0, 1] after ToTensor, then normalized to [-1, 1] range.
51
+ """
52
+ image = Image.open(image_path).convert("RGB")
53
+
54
+ transform = transforms.Compose(
55
+ [
56
+ transforms.Resize(INPUT_SIZE),
57
+ transforms.ToTensor(),
58
+ transforms.Normalize(mean=VIT_MEAN, std=VIT_STD),
59
+ ]
60
+ )
61
+
62
+ tensor = transform(image)
63
+ # Add batch dimension: [C, H, W] -> [1, C, H, W]
64
+ return tensor.unsqueeze(0)
65
+
66
+
67
+ def run_inference(method, input_tensor: torch.Tensor) -> torch.Tensor:
68
+ """Run forward pass and return raw logits tensor [1, 1000]."""
69
+ outputs = method.execute([input_tensor])
70
+ return outputs[0]
71
+
72
+
73
+ def postprocess(raw_output: torch.Tensor, labels: dict) -> list[dict]:
74
+ """Decode raw logits into top-k class predictions.
75
+
76
+ Applies softmax to convert logits to probabilities, then returns
77
+ the top-k predictions with class names and scores.
78
+ """
79
+ logits = raw_output
80
+ if logits.dim() == 1:
81
+ logits = logits.unsqueeze(0)
82
+
83
+ # Softmax to get probabilities
84
+ probabilities = torch.softmax(logits, dim=-1)
85
+
86
+ # Top-k predictions
87
+ k = min(TOP_K, probabilities.shape[-1])
88
+ top_scores, top_indices = probabilities.topk(k, dim=-1)
89
+
90
+ results = []
91
+ for score, idx in zip(top_scores[0].tolist(), top_indices[0].tolist(), strict=False):
92
+ label = labels.get(str(idx), f"class_{idx}")
93
+ results.append(
94
+ {"class_index": idx, "class": label, "probability": round(score, 6)}
95
+ )
96
+
97
+ return results
98
+
99
+
100
+ def save_results(results: list[dict]) -> None:
101
+ """Save top-k predictions to predictions.json in the script's directory."""
102
+ output_path = Path(__file__).parent / "predictions.json"
103
+ with open(output_path, "w") as f:
104
+ json.dump(results, f, indent=2)
105
+ print(f"Predictions saved to: {output_path}")
106
+
107
+
108
+ def _load_fonts() -> tuple[ImageFont.FreeTypeFont, ImageFont.FreeTypeFont]:
109
+ """Load DejaVuSans regular and bold fonts, falling back to the built-in bitmap font."""
110
+ font_dir = Path("/usr/share/fonts/truetype/dejavu")
111
+ try:
112
+ regular = ImageFont.truetype(str(font_dir / "DejaVuSans.ttf"), 14)
113
+ bold = ImageFont.truetype(str(font_dir / "DejaVuSans-Bold.ttf"), 15)
114
+ except OSError:
115
+ regular = ImageFont.load_default()
116
+ bold = regular
117
+ return regular, bold
118
+
119
+
120
+ def save_output_image(image_path: str, results: list[dict]) -> None:
121
+ """Render the input image alongside its top-k predictions and save as sample_output.jpg.
122
+
123
+ Layout (700 × 330 px):
124
+ ┌────────────┬──────────────────────────┐
125
+ │ input img │ Top-5 Predictions panel │
126
+ │ 280 × 280 │ (label + probability │
127
+ │ │ bar for each rank) │
128
+ └────────────┴──────────────────────────┘
129
+ """
130
+ # ── Layout constants ───────────────────────────────────────────────────────
131
+ MARGIN = 20
132
+ IMG_SZ = 280
133
+ PANEL_W = 360
134
+ CANVAS_W = MARGIN + IMG_SZ + MARGIN + PANEL_W + MARGIN # 700
135
+ CANVAS_H = MARGIN + IMG_SZ + MARGIN # 320
136
+ TITLE_H = 28
137
+ ROW_H = (IMG_SZ - TITLE_H - 8) // TOP_K # ≈ 44 px per row
138
+
139
+ # Palette
140
+ BG_COLOR = "#f5f5f5"
141
+ PANEL_BG = "#ffffff"
142
+ TOP1_BG = "#e3f2fd"
143
+ BAR_TOP1 = "#1565c0"
144
+ BAR_REST = "#90caf9"
145
+ TEXT_DARK = "#212121"
146
+ TEXT_GRAY = "#616161"
147
+ BORDER = "#bdbdbd"
148
+
149
+ font, font_bold = _load_fonts()
150
+
151
+ # ── Canvas ─────────────────────────────────────────────────────────────────
152
+ canvas = Image.new("RGB", (CANVAS_W, CANVAS_H), BG_COLOR)
153
+ draw = ImageDraw.Draw(canvas)
154
+
155
+ # ── Left panel: original image ─────────────────────────────────────────────
156
+ orig = Image.open(image_path).convert("RGB").resize((IMG_SZ, IMG_SZ), Image.LANCZOS)
157
+ canvas.paste(orig, (MARGIN, MARGIN))
158
+ draw.rectangle(
159
+ [MARGIN, MARGIN, MARGIN + IMG_SZ - 1, MARGIN + IMG_SZ - 1],
160
+ outline=BORDER,
161
+ width=1,
162
+ )
163
+
164
+ # ── Right panel: predictions ───────────────────────────────────────────────
165
+ px = MARGIN + IMG_SZ + MARGIN
166
+ py = MARGIN
167
+ draw.rectangle([px, py, px + PANEL_W, py + IMG_SZ], fill=PANEL_BG, outline=BORDER, width=1)
168
+
169
+ # Panel title
170
+ draw.text((px + 10, py + 6), "Top-5 Predictions", font=font_bold, fill=TEXT_DARK)
171
+ draw.line([px + 1, py + TITLE_H, px + PANEL_W - 1, py + TITLE_H], fill=BORDER, width=1)
172
+
173
+ max_prob = results[0]["probability"] if results else 1.0
174
+ BAR_MAX_W = PANEL_W - 24 # usable bar width
175
+
176
+ for rank, pred in enumerate(results):
177
+ ry = py + TITLE_H + 8 + rank * ROW_H
178
+
179
+ # Highlight top-1 row
180
+ if rank == 0:
181
+ draw.rectangle([px + 2, ry, px + PANEL_W - 2, ry + ROW_H - 2], fill=TOP1_BG)
182
+
183
+ # Rank badge
184
+ badge_text = f"#{rank + 1}"
185
+ draw.text((px + 8, ry + 4), badge_text, font=font_bold, fill=BAR_TOP1 if rank == 0 else TEXT_GRAY)
186
+
187
+ # Class name (truncated to prevent overflow)
188
+ label = pred["class"]
189
+ max_chars = 32
190
+ if len(label) > max_chars:
191
+ label = label[:max_chars - 1] + "…"
192
+ draw.text((px + 36, ry + 4), label, font=font, fill=TEXT_DARK)
193
+
194
+ # Probability bar
195
+ bar_w = max(4, int((pred["probability"] / max_prob) * BAR_MAX_W))
196
+ bar_y = ry + ROW_H - 14
197
+ bar_color = BAR_TOP1 if rank == 0 else BAR_REST
198
+ draw.rectangle([px + 8, bar_y, px + 8 + bar_w, bar_y + 8], fill=bar_color)
199
+
200
+ # Percentage label at right end
201
+ pct_text = f"{pred['probability'] * 100:.2f}%"
202
+ draw.text((px + PANEL_W - 56, ry + 4), pct_text, font=font, fill=TEXT_GRAY)
203
+
204
+ # ── Save ───────────────────────────────────────────────────────────────────
205
+ output_path = Path(__file__).parent / "sample_output.jpg"
206
+ canvas.save(str(output_path), quality=95)
207
+ print(f"Output image saved to: {output_path}")
208
+
209
+
210
+ def main() -> None:
211
+ # Resolve paths relative to script location
212
+ script_dir = Path(__file__).parent
213
+ model_path = str(script_dir / MODEL_PATH)
214
+ image_path = str(script_dir / IMAGE_PATH)
215
+
216
+ # Load class labels
217
+ labels = load_labels()
218
+
219
+ # Load model
220
+ print(f"Loading model: {model_path}")
221
+ method = load_model(model_path)
222
+
223
+ # Preprocess input image
224
+ print(f"Preprocessing image: {image_path}")
225
+ input_tensor = preprocess(image_path)
226
+ print(f"Input tensor shape: {input_tensor.shape}")
227
+
228
+ # Run inference
229
+ print("Running inference...")
230
+ raw_output = run_inference(method, input_tensor)
231
+ print(f"Output tensor shape: {raw_output.shape}")
232
+
233
+ # Postprocess outputs
234
+ results = postprocess(raw_output, labels)
235
+
236
+ # Print top-k predictions
237
+ print(f"\nTop-{TOP_K} predictions:")
238
+ for i, pred in enumerate(results, 1):
239
+ print(
240
+ f" {i}. {pred['class']} — {pred['probability']:.4f} ({pred['probability'] * 100:.2f}%)"
241
+ )
242
+
243
+ # Save results and visualization
244
+ save_results(results)
245
+ save_output_image(image_path, results)
246
+
247
+
248
+ if __name__ == "__main__":
249
+ main()
imagenet_classes.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"0": "tench, Tinca tinca", "1": "goldfish, Carassius auratus", "2": "great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias", "3": "tiger shark, Galeocerdo cuvieri", "4": "hammerhead, hammerhead shark", "5": "electric ray, crampfish, numbfish, torpedo", "6": "stingray", "7": "cock", "8": "hen", "9": "ostrich, Struthio camelus", "10": "brambling, Fringilla montifringilla", "11": "goldfinch, Carduelis carduelis", "12": "house finch, linnet, Carpodacus mexicanus", "13": "junco, snowbird", "14": "indigo bunting, indigo finch, indigo bird, Passerina cyanea", "15": "robin, American robin, Turdus migratorius", "16": "bulbul", "17": "jay", "18": "magpie", "19": "chickadee", "20": "water ouzel, dipper", "21": "kite", "22": "bald eagle, American eagle, Haliaeetus leucocephalus", "23": "vulture", "24": "great grey owl, great gray owl, Strix nebulosa", "25": "European fire salamander, Salamandra salamandra", "26": "common newt, Triturus vulgaris", "27": "eft", "28": "spotted salamander, Ambystoma maculatum", "29": "axolotl, mud puppy, Ambystoma mexicanum", "30": "bullfrog, Rana catesbeiana", "31": "tree frog, tree-frog", "32": "tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui", "33": "loggerhead, loggerhead turtle, Caretta caretta", "34": "leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea", "35": "mud turtle", "36": "terrapin", "37": "box turtle, box tortoise", "38": "banded gecko", "39": "common iguana, iguana, Iguana iguana", "40": "American chameleon, anole, Anolis carolinensis", "41": "whiptail, whiptail lizard", "42": "agama", "43": "frilled lizard, Chlamydosaurus kingi", "44": "alligator lizard", "45": "Gila monster, Heloderma suspectum", "46": "green lizard, Lacerta viridis", "47": "African chameleon, Chamaeleo chamaeleon", "48": "Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis", "49": "African crocodile, Nile crocodile, Crocodylus niloticus", "50": "American alligator, Alligator mississipiensis", "51": "triceratops", "52": "thunder snake, worm snake, Carphophis amoenus", "53": "ringneck snake, ring-necked snake, ring snake", "54": "hognose snake, puff adder, sand viper", "55": "green snake, grass snake", "56": "king snake, kingsnake", "57": "garter snake, grass snake", "58": "water snake", "59": "vine snake", "60": "night snake, Hypsiglena torquata", "61": "boa constrictor, Constrictor constrictor", "62": "rock python, rock snake, Python sebae", "63": "Indian cobra, Naja naja", "64": "green mamba", "65": "sea snake", "66": "horned viper, cerastes, sand viper, horned asp, Cerastes cornutus", "67": "diamondback, diamondback rattlesnake, Crotalus adamanteus", "68": "sidewinder, horned rattlesnake, Crotalus cerastes", "69": "trilobite", "70": "harvestman, daddy longlegs, Phalangium opilio", "71": "scorpion", "72": "black and gold garden spider, Argiope aurantia", "73": "barn spider, Araneus cavaticus", "74": "garden spider, Aranea diademata", "75": "black widow, Latrodectus mactans", "76": "tarantula", "77": "wolf spider, hunting spider", "78": "tick", "79": "centipede", "80": "black grouse", "81": "ptarmigan", "82": "ruffed grouse, partridge, Bonasa umbellus", "83": "prairie chicken, prairie grouse, prairie fowl", "84": "peacock", "85": "quail", "86": "partridge", "87": "African grey, African gray, Psittacus erithacus", "88": "macaw", "89": "sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita", "90": "lorikeet", "91": "coucal", "92": "bee eater", "93": "hornbill", "94": "hummingbird", "95": "jacamar", "96": "toucan", "97": "drake", "98": "red-breasted merganser, Mergus serrator", "99": "goose", "100": "black swan, Cygnus atratus", "101": "tusker", "102": "echidna, spiny anteater, anteater", "103": "platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus", "104": "wallaby, brush kangaroo", "105": "koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus", "106": "wombat", "107": "jellyfish", "108": "sea anemone, anemone", "109": "brain coral", "110": "flatworm, platyhelminth", "111": "nematode, nematode worm, roundworm", "112": "conch", "113": "snail", "114": "slug", "115": "sea slug, nudibranch", "116": "chiton, coat-of-mail shell, sea cradle, polyplacophore", "117": "chambered nautilus, pearly nautilus, nautilus", "118": "Dungeness crab, Cancer magister", "119": "rock crab, Cancer irroratus", "120": "fiddler crab", "121": "king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica", "122": "American lobster, Northern lobster, Maine lobster, Homarus americanus", "123": "spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish", "124": "crayfish, crawfish, crawdad, crawdaddy", "125": "hermit crab", "126": "isopod", "127": "white stork, Ciconia ciconia", "128": "black stork, Ciconia nigra", "129": "spoonbill", "130": "flamingo", "131": "little blue heron, Egretta caerulea", "132": "American egret, great white heron, Egretta albus", "133": "bittern", "134": "crane", "135": "limpkin, Aramus pictus", "136": "European gallinule, Porphyrio porphyrio", "137": "American coot, marsh hen, mud hen, water hen, Fulica americana", "138": "bustard", "139": "ruddy turnstone, Arenaria interpres", "140": "red-backed sandpiper, dunlin, Erolia alpina", "141": "redshank, Tringa totanus", "142": "dowitcher", "143": "oystercatcher, oyster catcher", "144": "pelican", "145": "king penguin, Aptenodytes patagonica", "146": "albatross, mollymawk", "147": "grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus", "148": "killer whale, killer, orca, grampus, sea wolf, Orcinus orca", "149": "dugong, Dugong dugon", "150": "sea lion", "151": "Chihuahua", "152": "Japanese spaniel", "153": "Maltese dog, Maltese terrier, Maltese", "154": "Pekinese, Pekingese, Peke", "155": "Shih-Tzu", "156": "Blenheim spaniel", "157": "papillon", "158": "toy terrier", "159": "Rhodesian ridgeback", "160": "Afghan hound, Afghan", "161": "basset, basset hound", "162": "beagle", "163": "bloodhound, sleuthhound", "164": "bluetick", "165": "black-and-tan coonhound", "166": "Walker hound, Walker foxhound", "167": "English foxhound", "168": "redbone", "169": "borzoi, Russian wolfhound", "170": "Irish wolfhound", "171": "Italian greyhound", "172": "whippet", "173": "Ibizan hound, Ibizan Podenco", "174": "Norwegian elkhound, elkhound", "175": "otterhound, otter hound", "176": "Saluki, gazelle hound", "177": "Scottish deerhound, deerhound", "178": "Weimaraner", "179": "Staffordshire bullterrier, Staffordshire bull terrier", "180": "American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier", "181": "Bedlington terrier", "182": "Border terrier", "183": "Kerry blue terrier", "184": "Irish terrier", "185": "Norfolk terrier", "186": "Norwich terrier", "187": "Yorkshire terrier", "188": "wire-haired fox terrier", "189": "Lakeland terrier", "190": "Sealyham terrier, Sealyham", "191": "Airedale, Airedale terrier", "192": "cairn, cairn terrier", "193": "Australian terrier", "194": "Dandie Dinmont, Dandie Dinmont terrier", "195": "Boston bull, Boston terrier", "196": "miniature schnauzer", "197": "giant schnauzer", "198": "standard schnauzer", "199": "Scotch terrier, Scottish terrier, Scottie", "200": "Tibetan terrier, chrysanthemum dog", "201": "silky terrier, Sydney silky", "202": "soft-coated wheaten terrier", "203": "West Highland white terrier", "204": "Lhasa, Lhasa apso", "205": "flat-coated retriever", "206": "curly-coated retriever", "207": "golden retriever", "208": "Labrador retriever", "209": "Chesapeake Bay retriever", "210": "German short-haired pointer", "211": "vizsla, Hungarian pointer", "212": "English setter", "213": "Irish setter, red setter", "214": "Gordon setter", "215": "Brittany spaniel", "216": "clumber, clumber spaniel", "217": "English springer, English springer spaniel", "218": "Welsh springer spaniel", "219": "cocker spaniel, English cocker spaniel, cocker", "220": "Sussex spaniel", "221": "Irish water spaniel", "222": "kuvasz", "223": "schipperke", "224": "groenendael", "225": "malinois", "226": "briard", "227": "kelpie", "228": "komondor", "229": "Old English sheepdog, bobtail", "230": "Shetland sheepdog, Shetland sheep dog, Shetland", "231": "collie", "232": "Border collie", "233": "Bouvier des Flandres, Bouviers des Flandres", "234": "Rottweiler", "235": "German shepherd, German shepherd dog, German police dog, alsatian", "236": "Doberman, Doberman pinscher", "237": "miniature pinscher", "238": "Greater Swiss Mountain dog", "239": "Bernese mountain dog", "240": "Appenzeller", "241": "EntleBucher", "242": "boxer", "243": "bull mastiff", "244": "Tibetan mastiff", "245": "French bulldog", "246": "Great Dane", "247": "Saint Bernard, St Bernard", "248": "Eskimo dog, husky", "249": "malamute, malemute, Alaskan malamute", "250": "Siberian husky", "251": "dalmatian, coach dog, carriage dog", "252": "affenpinscher, monkey pinscher, monkey dog", "253": "basenji", "254": "pug, pug-dog", "255": "Leonberg", "256": "Newfoundland, Newfoundland dog", "257": "Great Pyrenees", "258": "Samoyed, Samoyede", "259": "Pomeranian", "260": "chow, chow chow", "261": "keeshond", "262": "Brabancon griffon", "263": "Pembroke, Pembroke Welsh corgi", "264": "Cardigan, Cardigan Welsh corgi", "265": "toy poodle", "266": "miniature poodle", "267": "standard poodle", "268": "Mexican hairless", "269": "timber wolf, grey wolf, gray wolf, Canis lupus", "270": "white wolf, Arctic wolf, Canis lupus tundrarum", "271": "red wolf, maned wolf, Canis rufus, Canis niger", "272": "coyote, prairie wolf, brush wolf, Canis latrans", "273": "dingo, warrigal, warragal, Canis dingo", "274": "dhole, Cuon alpinus", "275": "African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus", "276": "hyena, hyaena", "277": "red fox, Vulpes vulpes", "278": "kit fox, Vulpes macrotis", "279": "Arctic fox, white fox, Alopex lagopus", "280": "grey fox, gray fox, Urocyon cinereoargenteus", "281": "tabby, tabby cat", "282": "tiger cat", "283": "Persian cat", "284": "Siamese cat, Siamese", "285": "Egyptian cat", "286": "cougar, puma, catamount, mountain lion, painter, panther, Felis concolor", "287": "lynx, catamount", "288": "leopard, Panthera pardus", "289": "snow leopard, ounce, Panthera uncia", "290": "jaguar, panther, Panthera onca, Felis onca", "291": "lion, king of beasts, Panthera leo", "292": "tiger, Panthera tigris", "293": "cheetah, chetah, Acinonyx jubatus", "294": "brown bear, bruin, Ursus arctos", "295": "American black bear, black bear, Ursus americanus, Euarctos americanus", "296": "ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus", "297": "sloth bear, Melursus ursinus, Ursus ursinus", "298": "mongoose", "299": "meerkat, mierkat", "300": "tiger beetle", "301": "ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle", "302": "ground beetle, carabid beetle", "303": "long-horned beetle, longicorn, longicorn beetle", "304": "leaf beetle, chrysomelid", "305": "dung beetle", "306": "rhinoceros beetle", "307": "weevil", "308": "fly", "309": "bee", "310": "ant, emmet, pismire", "311": "grasshopper, hopper", "312": "cricket", "313": "walking stick, walkingstick, stick insect", "314": "cockroach, roach", "315": "mantis, mantid", "316": "cicada, cicala", "317": "leafhopper", "318": "lacewing, lacewing fly", "319": "dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk", "320": "damselfly", "321": "admiral", "322": "ringlet, ringlet butterfly", "323": "monarch, monarch butterfly, milkweed butterfly, Danaus plexippus", "324": "cabbage butterfly", "325": "sulphur butterfly, sulfur butterfly", "326": "lycaenid, lycaenid butterfly", "327": "starfish, sea star", "328": "sea urchin", "329": "sea cucumber, holothurian", "330": "wood rabbit, cottontail, cottontail rabbit", "331": "hare", "332": "Angora, Angora rabbit", "333": "hamster", "334": "porcupine, hedgehog", "335": "fox squirrel, eastern fox squirrel, Sciurus niger", "336": "marmot", "337": "beaver", "338": "guinea pig, Cavia cobaya", "339": "sorrel", "340": "zebra", "341": "hog, pig, grunter, squealer, Sus scrofa", "342": "wild boar, boar, Sus scrofa", "343": "warthog", "344": "hippopotamus, hippo, river horse, Hippopotamus amphibius", "345": "ox", "346": "water buffalo, water ox, Asiatic buffalo, Bubalus bubalis", "347": "bison", "348": "ram, tup", "349": "bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis", "350": "ibex, Capra ibex", "351": "hartebeest", "352": "impala, Aepyceros melampus", "353": "gazelle", "354": "Arabian camel, dromedary, Camelus dromedarius", "355": "llama", "356": "weasel", "357": "mink", "358": "polecat, fitch, foulmart, foumart, Mustela putorius", "359": "black-footed ferret, ferret, Mustela nigripes", "360": "otter", "361": "skunk, polecat, wood pussy", "362": "badger", "363": "armadillo", "364": "three-toed sloth, ai, Bradypus tridactylus", "365": "orangutan, orang, orangutang, Pongo pygmaeus", "366": "gorilla, Gorilla gorilla", "367": "chimpanzee, chimp, Pan troglodytes", "368": "gibbon, Hylobates lar", "369": "siamang, Hylobates syndactylus, Symphalangus syndactylus", "370": "guenon, guenon monkey", "371": "patas, hussar monkey, Erythrocebus patas", "372": "baboon", "373": "macaque", "374": "langur", "375": "colobus, colobus monkey", "376": "proboscis monkey, Nasalis larvatus", "377": "marmoset", "378": "capuchin, ringtail, Cebus capucinus", "379": "howler monkey, howler", "380": "titi, titi monkey", "381": "spider monkey, Ateles geoffroyi", "382": "squirrel monkey, Saimiri sciureus", "383": "Madagascar cat, ring-tailed lemur, Lemur catta", "384": "indri, indris, Indri indri, Indri brevicaudatus", "385": "Indian elephant, Elephas maximus", "386": "African elephant, Loxodonta africana", "387": "lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens", "388": "giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca", "389": "barracouta, snoek", "390": "eel", "391": "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch", "392": "rock beauty, Holocanthus tricolor", "393": "anemone fish", "394": "sturgeon", "395": "gar, garfish, garpike, billfish, Lepisosteus osseus", "396": "lionfish", "397": "puffer, pufferfish, blowfish, globefish", "398": "abacus", "399": "abaya", "400": "academic gown, academic robe, judge's robe", "401": "accordion, piano accordion, squeeze box", "402": "acoustic guitar", "403": "aircraft carrier, carrier, flattop, attack aircraft carrier", "404": "airliner", "405": "airship, dirigible", "406": "altar", "407": "ambulance", "408": "amphibian, amphibious vehicle", "409": "analog clock", "410": "apiary, bee house", "411": "apron", "412": "ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin", "413": "assault rifle, assault gun", "414": "backpack, back pack, knapsack, packsack, rucksack, haversack", "415": "bakery, bakeshop, bakehouse", "416": "balance beam, beam", "417": "balloon", "418": "ballpoint, ballpoint pen, ballpen, Biro", "419": "Band Aid", "420": "banjo", "421": "bannister, banister, balustrade, balusters, handrail", "422": "barbell", "423": "barber chair", "424": "barbershop", "425": "barn", "426": "barometer", "427": "barrel, cask", "428": "barrow, garden cart, lawn cart, wheelbarrow", "429": "baseball", "430": "basketball", "431": "bassinet", "432": "bassoon", "433": "bathing cap, swimming cap", "434": "bath towel", "435": "bathtub, bathing tub, bath, tub", "436": "beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon", "437": "beacon, lighthouse, beacon light, pharos", "438": "beaker", "439": "bearskin, busby, shako", "440": "beer bottle", "441": "beer glass", "442": "bell cote, bell cot", "443": "bib", "444": "bicycle-built-for-two, tandem bicycle, tandem", "445": "bikini, two-piece", "446": "binder, ring-binder", "447": "binoculars, field glasses, opera glasses", "448": "birdhouse", "449": "boathouse", "450": "bobsled, bobsleigh, bob", "451": "bolo tie, bolo, bola tie, bola", "452": "bonnet, poke bonnet", "453": "bookcase", "454": "bookshop, bookstore, bookstall", "455": "bottlecap", "456": "bow", "457": "bow tie, bow-tie, bowtie", "458": "brass, memorial tablet, plaque", "459": "brassiere, bra, bandeau", "460": "breakwater, groin, groyne, mole, bulwark, seawall, jetty", "461": "breastplate, aegis, egis", "462": "broom", "463": "bucket, pail", "464": "buckle", "465": "bulletproof vest", "466": "bullet train, bullet", "467": "butcher shop, meat market", "468": "cab, hack, taxi, taxicab", "469": "caldron, cauldron", "470": "candle, taper, wax light", "471": "cannon", "472": "canoe", "473": "can opener, tin opener", "474": "cardigan", "475": "car mirror", "476": "carousel, carrousel, merry-go-round, roundabout, whirligig", "477": "carpenter's kit, tool kit", "478": "carton", "479": "car wheel", "480": "cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM", "481": "cassette", "482": "cassette player", "483": "castle", "484": "catamaran", "485": "CD player", "486": "cello, violoncello", "487": "cellular telephone, cellular phone, cellphone, cell, mobile phone", "488": "chain", "489": "chainlink fence", "490": "chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour", "491": "chain saw, chainsaw", "492": "chest", "493": "chiffonier, commode", "494": "chime, bell, gong", "495": "china cabinet, china closet", "496": "Christmas stocking", "497": "church, church building", "498": "cinema, movie theater, movie theatre, movie house, picture palace", "499": "cleaver, meat cleaver, chopper", "500": "cliff dwelling", "501": "cloak", "502": "clog, geta, patten, sabot", "503": "cocktail shaker", "504": "coffee mug", "505": "coffeepot", "506": "coil, spiral, volute, whorl, helix", "507": "combination lock", "508": "computer keyboard, keypad", "509": "confectionery, confectionary, candy store", "510": "container ship, containership, container vessel", "511": "convertible", "512": "corkscrew, bottle screw", "513": "cornet, horn, trumpet, trump", "514": "cowboy boot", "515": "cowboy hat, ten-gallon hat", "516": "cradle", "517": "crane", "518": "crash helmet", "519": "crate", "520": "crib, cot", "521": "Crock Pot", "522": "croquet ball", "523": "crutch", "524": "cuirass", "525": "dam, dike, dyke", "526": "desk", "527": "desktop computer", "528": "dial telephone, dial phone", "529": "diaper, nappy, napkin", "530": "digital clock", "531": "digital watch", "532": "dining table, board", "533": "dishrag, dishcloth", "534": "dishwasher, dish washer, dishwashing machine", "535": "disk brake, disc brake", "536": "dock, dockage, docking facility", "537": "dogsled, dog sled, dog sleigh", "538": "dome", "539": "doormat, welcome mat", "540": "drilling platform, offshore rig", "541": "drum, membranophone, tympan", "542": "drumstick", "543": "dumbbell", "544": "Dutch oven", "545": "electric fan, blower", "546": "electric guitar", "547": "electric locomotive", "548": "entertainment center", "549": "envelope", "550": "espresso maker", "551": "face powder", "552": "feather boa, boa", "553": "file, file cabinet, filing cabinet", "554": "fireboat", "555": "fire engine, fire truck", "556": "fire screen, fireguard", "557": "flagpole, flagstaff", "558": "flute, transverse flute", "559": "folding chair", "560": "football helmet", "561": "forklift", "562": "fountain", "563": "fountain pen", "564": "four-poster", "565": "freight car", "566": "French horn, horn", "567": "frying pan, frypan, skillet", "568": "fur coat", "569": "garbage truck, dustcart", "570": "gasmask, respirator, gas helmet", "571": "gas pump, gasoline pump, petrol pump, island dispenser", "572": "goblet", "573": "go-kart", "574": "golf ball", "575": "golfcart, golf cart", "576": "gondola", "577": "gong, tam-tam", "578": "gown", "579": "grand piano, grand", "580": "greenhouse, nursery, glasshouse", "581": "grille, radiator grille", "582": "grocery store, grocery, food market, market", "583": "guillotine", "584": "hair slide", "585": "hair spray", "586": "half track", "587": "hammer", "588": "hamper", "589": "hand blower, blow dryer, blow drier, hair dryer, hair drier", "590": "hand-held computer, hand-held microcomputer", "591": "handkerchief, hankie, hanky, hankey", "592": "hard disc, hard disk, fixed disk", "593": "harmonica, mouth organ, harp, mouth harp", "594": "harp", "595": "harvester, reaper", "596": "hatchet", "597": "holster", "598": "home theater, home theatre", "599": "honeycomb", "600": "hook, claw", "601": "hoopskirt, crinoline", "602": "horizontal bar, high bar", "603": "horse cart, horse-cart", "604": "hourglass", "605": "iPod", "606": "iron, smoothing iron", "607": "jack-o'-lantern", "608": "jean, blue jean, denim", "609": "jeep, landrover", "610": "jersey, T-shirt, tee shirt", "611": "jigsaw puzzle", "612": "jinrikisha, ricksha, rickshaw", "613": "joystick", "614": "kimono", "615": "knee pad", "616": "knot", "617": "lab coat, laboratory coat", "618": "ladle", "619": "lampshade, lamp shade", "620": "laptop, laptop computer", "621": "lawn mower, mower", "622": "lens cap, lens cover", "623": "letter opener, paper knife, paperknife", "624": "library", "625": "lifeboat", "626": "lighter, light, igniter, ignitor", "627": "limousine, limo", "628": "liner, ocean liner", "629": "lipstick, lip rouge", "630": "Loafer", "631": "lotion", "632": "loudspeaker, speaker, speaker unit, loudspeaker system, speaker system", "633": "loupe, jeweler's loupe", "634": "lumbermill, sawmill", "635": "magnetic compass", "636": "mailbag, postbag", "637": "mailbox, letter box", "638": "maillot", "639": "maillot, tank suit", "640": "manhole cover", "641": "maraca", "642": "marimba, xylophone", "643": "mask", "644": "matchstick", "645": "maypole", "646": "maze, labyrinth", "647": "measuring cup", "648": "medicine chest, medicine cabinet", "649": "megalith, megalithic structure", "650": "microphone, mike", "651": "microwave, microwave oven", "652": "military uniform", "653": "milk can", "654": "minibus", "655": "miniskirt, mini", "656": "minivan", "657": "missile", "658": "mitten", "659": "mixing bowl", "660": "mobile home, manufactured home", "661": "Model T", "662": "modem", "663": "monastery", "664": "monitor", "665": "moped", "666": "mortar", "667": "mortarboard", "668": "mosque", "669": "mosquito net", "670": "motor scooter, scooter", "671": "mountain bike, all-terrain bike, off-roader", "672": "mountain tent", "673": "mouse, computer mouse", "674": "mousetrap", "675": "moving van", "676": "muzzle", "677": "nail", "678": "neck brace", "679": "necklace", "680": "nipple", "681": "notebook, notebook computer", "682": "obelisk", "683": "oboe, hautboy, hautbois", "684": "ocarina, sweet potato", "685": "odometer, hodometer, mileometer, milometer", "686": "oil filter", "687": "organ, pipe organ", "688": "oscilloscope, scope, cathode-ray oscilloscope, CRO", "689": "overskirt", "690": "oxcart", "691": "oxygen mask", "692": "packet", "693": "paddle, boat paddle", "694": "paddlewheel, paddle wheel", "695": "padlock", "696": "paintbrush", "697": "pajama, pyjama, pj's, jammies", "698": "palace", "699": "panpipe, pandean pipe, syrinx", "700": "paper towel", "701": "parachute, chute", "702": "parallel bars, bars", "703": "park bench", "704": "parking meter", "705": "passenger car, coach, carriage", "706": "patio, terrace", "707": "pay-phone, pay-station", "708": "pedestal, plinth, footstall", "709": "pencil box, pencil case", "710": "pencil sharpener", "711": "perfume, essence", "712": "Petri dish", "713": "photocopier", "714": "pick, plectrum, plectron", "715": "pickelhaube", "716": "picket fence, paling", "717": "pickup, pickup truck", "718": "pier", "719": "piggy bank, penny bank", "720": "pill bottle", "721": "pillow", "722": "ping-pong ball", "723": "pinwheel", "724": "pirate, pirate ship", "725": "pitcher, ewer", "726": "plane, carpenter's plane, woodworking plane", "727": "planetarium", "728": "plastic bag", "729": "plate rack", "730": "plow, plough", "731": "plunger, plumber's helper", "732": "Polaroid camera, Polaroid Land camera", "733": "pole", "734": "police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria", "735": "poncho", "736": "pool table, billiard table, snooker table", "737": "pop bottle, soda bottle", "738": "pot, flowerpot", "739": "potter's wheel", "740": "power drill", "741": "prayer rug, prayer mat", "742": "printer", "743": "prison, prison house", "744": "projectile, missile", "745": "projector", "746": "puck, hockey puck", "747": "punching bag, punch bag, punching ball, punchball", "748": "purse", "749": "quill, quill pen", "750": "quilt, comforter, comfort, puff", "751": "racer, race car, racing car", "752": "racket, racquet", "753": "radiator", "754": "radio, wireless", "755": "radio telescope, radio reflector", "756": "rain barrel", "757": "recreational vehicle, RV, R.V.", "758": "reel", "759": "reflex camera", "760": "refrigerator, icebox", "761": "remote control, remote", "762": "restaurant, eating house, eating place, eatery", "763": "revolver, six-gun, six-shooter", "764": "rifle", "765": "rocking chair, rocker", "766": "rotisserie", "767": "rubber eraser, rubber, pencil eraser", "768": "rugby ball", "769": "rule, ruler", "770": "running shoe", "771": "safe", "772": "safety pin", "773": "saltshaker, salt shaker", "774": "sandal", "775": "sarong", "776": "sax, saxophone", "777": "scabbard", "778": "scale, weighing machine", "779": "school bus", "780": "schooner", "781": "scoreboard", "782": "screen, CRT screen", "783": "screw", "784": "screwdriver", "785": "seat belt, seatbelt", "786": "sewing machine", "787": "shield, buckler", "788": "shoe shop, shoe-shop, shoe store", "789": "shoji", "790": "shopping basket", "791": "shopping cart", "792": "shovel", "793": "shower cap", "794": "shower curtain", "795": "ski", "796": "ski mask", "797": "sleeping bag", "798": "slide rule, slipstick", "799": "sliding door", "800": "slot, one-armed bandit", "801": "snorkel", "802": "snowmobile", "803": "snowplow, snowplough", "804": "soap dispenser", "805": "soccer ball", "806": "sock", "807": "solar dish, solar collector, solar furnace", "808": "sombrero", "809": "soup bowl", "810": "space bar", "811": "space heater", "812": "space shuttle", "813": "spatula", "814": "speedboat", "815": "spider web, spider's web", "816": "spindle", "817": "sports car, sport car", "818": "spotlight, spot", "819": "stage", "820": "steam locomotive", "821": "steel arch bridge", "822": "steel drum", "823": "stethoscope", "824": "stole", "825": "stone wall", "826": "stopwatch, stop watch", "827": "stove", "828": "strainer", "829": "streetcar, tram, tramcar, trolley, trolley car", "830": "stretcher", "831": "studio couch, day bed", "832": "stupa, tope", "833": "submarine, pigboat, sub, U-boat", "834": "suit, suit of clothes", "835": "sundial", "836": "sunglass", "837": "sunglasses, dark glasses, shades", "838": "sunscreen, sunblock, sun blocker", "839": "suspension bridge", "840": "swab, swob, mop", "841": "sweatshirt", "842": "swimming trunks, bathing trunks", "843": "swing", "844": "switch, electric switch, electrical switch", "845": "syringe", "846": "table lamp", "847": "tank, army tank, armored combat vehicle, armoured combat vehicle", "848": "tape player", "849": "teapot", "850": "teddy, teddy bear", "851": "television, television system", "852": "tennis ball", "853": "thatch, thatched roof", "854": "theater curtain, theatre curtain", "855": "thimble", "856": "thresher, thrasher, threshing machine", "857": "throne", "858": "tile roof", "859": "toaster", "860": "tobacco shop, tobacconist shop, tobacconist", "861": "toilet seat", "862": "torch", "863": "totem pole", "864": "tow truck, tow car, wrecker", "865": "toyshop", "866": "tractor", "867": "trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi", "868": "tray", "869": "trench coat", "870": "tricycle, trike, velocipede", "871": "trimaran", "872": "tripod", "873": "triumphal arch", "874": "trolleybus, trolley coach, trackless trolley", "875": "trombone", "876": "tub, vat", "877": "turnstile", "878": "typewriter keyboard", "879": "umbrella", "880": "unicycle, monocycle", "881": "upright, upright piano", "882": "vacuum, vacuum cleaner", "883": "vase", "884": "vault", "885": "velvet", "886": "vending machine", "887": "vestment", "888": "viaduct", "889": "violin, fiddle", "890": "volleyball", "891": "waffle iron", "892": "wall clock", "893": "wallet, billfold, notecase, pocketbook", "894": "wardrobe, closet, press", "895": "warplane, military plane", "896": "washbasin, handbasin, washbowl, lavabo, wash-hand basin", "897": "washer, automatic washer, washing machine", "898": "water bottle", "899": "water jug", "900": "water tower", "901": "whiskey jug", "902": "whistle", "903": "wig", "904": "window screen", "905": "window shade", "906": "Windsor tie", "907": "wine bottle", "908": "wing", "909": "wok", "910": "wooden spoon", "911": "wool, woolen, woollen", "912": "worm fence, snake fence, snake-rail fence, Virginia fence", "913": "wreck", "914": "yawl", "915": "yurt", "916": "web site, website, internet site, site", "917": "comic book", "918": "crossword puzzle, crossword", "919": "street sign", "920": "traffic light, traffic signal, stoplight", "921": "book jacket, dust cover, dust jacket, dust wrapper", "922": "menu", "923": "plate", "924": "guacamole", "925": "consomme", "926": "hot pot, hotpot", "927": "trifle", "928": "ice cream, icecream", "929": "ice lolly, lolly, lollipop, popsicle", "930": "French loaf", "931": "bagel, beigel", "932": "pretzel", "933": "cheeseburger", "934": "hotdog, hot dog, red hot", "935": "mashed potato", "936": "head cabbage", "937": "broccoli", "938": "cauliflower", "939": "zucchini, courgette", "940": "spaghetti squash", "941": "acorn squash", "942": "butternut squash", "943": "cucumber, cuke", "944": "artichoke, globe artichoke", "945": "bell pepper", "946": "cardoon", "947": "mushroom", "948": "Granny Smith", "949": "strawberry", "950": "orange", "951": "lemon", "952": "fig", "953": "pineapple, ananas", "954": "banana", "955": "jackfruit, jak, jack", "956": "custard apple", "957": "pomegranate", "958": "hay", "959": "carbonara", "960": "chocolate sauce, chocolate syrup", "961": "dough", "962": "meat loaf, meatloaf", "963": "pizza, pizza pie", "964": "potpie", "965": "burrito", "966": "red wine", "967": "espresso", "968": "cup", "969": "eggnog", "970": "alp", "971": "bubble", "972": "cliff, drop, drop-off", "973": "coral reef", "974": "geyser", "975": "lakeside, lakeshore", "976": "promontory, headland, head, foreland", "977": "sandbar, sand bar", "978": "seashore, coast, seacoast, sea-coast", "979": "valley, vale", "980": "volcano", "981": "ballplayer, baseball player", "982": "groom, bridegroom", "983": "scuba diver", "984": "rapeseed", "985": "daisy", "986": "yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum", "987": "corn", "988": "acorn", "989": "hip, rose hip, rosehip", "990": "buckeye, horse chestnut, conker", "991": "coral fungus", "992": "agaric", "993": "gyromitra", "994": "stinkhorn, carrion fungus", "995": "earthstar", "996": "hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa", "997": "bolete", "998": "ear, spike, capitulum", "999": "toilet tissue, toilet paper, bathroom tissue"}
metadata.yaml ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Metadata generated by ARM Model Optimization Pipeline
2
+ version: 1.0.0
3
+ task: vision-classification
4
+ created_at: '2026-05-07T15:58:46Z'
5
+ context:
6
+ model:
7
+ id: google/vit-base-patch16-224
8
+ base_model_id: google/vit-base-patch16-224
9
+ profile: Arm-Optimized
10
+ weight_dtype: int8
11
+ quantization:
12
+ method: PTQ-dynamic
13
+ weight_bits: 8
14
+ activation_bits: 8
15
+ symmetric: true
16
+ mode: dynamic
17
+ weight_granularity: per-channel
18
+ model_size_mb: 83.963
19
+ format: pte
20
+ target:
21
+ name: Raspberry Pi 5
22
+ hardware_class: Edge Linux
23
+ cpu_architecture: arm64
24
+ cpu_model: Cortex-A76
25
+ cpu_core_count: 4
26
+ cpu_clock_ghz: 2.4
27
+ system_memory_gb: 8
28
+ os: linux
29
+ os_version: Raspberry Pi OS Bookworm
30
+ runtime:
31
+ name: executorch
32
+ execution_backend: cpu
33
+ optimisations:
34
+ - XNNPACK
35
+ - KleidiAI
36
+ version: 1.1.0
37
+ dataset:
38
+ name: ImageNet-1k
39
+ sample_count: 50000
40
+ reference_url: https://www.image-net.org/
41
+ slice: val
42
+ benchmark:
43
+ batch_size: 1
44
+ input_resolution: 224x224
45
+ num_runs: 10
46
+ warmup_runs: 10
47
+ performance:
48
+ end_to_end_latency_ms:
49
+ p50: 175.448
50
+ p90: 178.154
51
+ peak_memory_mb: 112.73
52
+ average_memory_mb: 109.7
53
+ frames_per_second: 5.7
54
+ delegation_pct: 77.18
55
+ cold_start_time_ms: 250.304
56
+ accuracy:
57
+ top_1_accuracy_pct: 81.52
58
+ top_5_accuracy_pct: 96.07
predictions.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "class_index": 0,
4
+ "class": "tench, Tinca tinca",
5
+ "probability": 0.817532
6
+ },
7
+ {
8
+ "class_index": 394,
9
+ "class": "sturgeon",
10
+ "probability": 0.129254
11
+ },
12
+ {
13
+ "class_index": 389,
14
+ "class": "barracouta, snoek",
15
+ "probability": 0.028204
16
+ },
17
+ {
18
+ "class_index": 391,
19
+ "class": "coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch",
20
+ "probability": 0.008734
21
+ },
22
+ {
23
+ "class_index": 390,
24
+ "class": "eel",
25
+ "probability": 0.003064
26
+ }
27
+ ]
sample_input.jpg ADDED

Git LFS Details

  • SHA256: 6c4f5d07f81ae2fb4345ad63195f97a8dbdb4b1f8ca93b210941e71dea8844b6
  • Pointer size: 131 Bytes
  • Size of remote file: 223 kB
vit_base_raspberry_executorch_optimized.pte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:de0010ebee1eb55630996ac853581aa70785fe03f124bd0ea249e02ccbbc530b
3
+ size 88041760