Dralkh commited on
Commit
b77d257
·
verified ·
1 Parent(s): c043832

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +34 -55
README.md CHANGED
@@ -1,75 +1,54 @@
1
- ---
2
- language: en
3
- license: apache-2.0
4
- tags:
5
- - nutrition
6
- - calorie-estimation
7
- - food
8
- - computer-vision
9
- - regression
10
- - siglip
11
- datasets:
12
- - pinkieseb/nutrition_dataset
13
- - aryachakraborty/Food_Calorie_Dataset
14
- metrics:
15
- - mae
16
- - rmse
17
- model-index:
18
- - name: CalorieK
19
- results:
20
- - task:
21
- type: image-regression
22
- dataset:
23
- name: Nutrition5k (locked test)
24
- type: Nutrition5k
25
- metrics:
26
- - type: mae
27
- value: 86.2
28
- name: Calorie MAE (kcal)
29
- ---
30
-
31
  # CalorieK — food-photo calorie & macro estimation
32
 
33
  A single RGB food photo in, five numbers out: **calories (kcal), mass (g), protein (g), carbohydrate (g), fat (g)**.
34
  CalorieK is a SigLIP2-base vision tower with a small regression head, fine-tuned end-to-end and evaluated
35
  under a strict, leakage-audited Nutrition5k protocol.
36
 
37
- ## Headline result locked Nutrition5k test set (608 dishes, official test split, never seen)
 
 
38
 
39
- | Metric | CalorieK | CalorieCLIP (same 608 dishes) |
40
  | --- | --- | --- |
41
- | Calorie MAE | **86.2 kcal** (95% CI 53.5–132.3) | 155.7 kcal |
42
- | Median absolute error | **30.1 kcal** | 106.3 kcal |
43
- | Within ±50 kcal | **64.8%** | 20.2% |
44
- | Within ±100 kcal | **84.0%** | 47.0% |
45
- | Bias | **−49.5 kcal** | +67.5 kcal |
46
- | Invalid predictions | 0 / 608 | 0 / 608 |
47
 
48
- CalorieK roughly halves CalorieCLIP's calorie MAE (86 vs 156 kcal) and nearly doubles its within-±100
49
- hit rate on the same 608 dishes. Every test image is a deterministic central frame from the official
50
- Nutrition5k camera-A side-angle video of an official _test-split_ dish — selected by dish ID, never by
51
- image quality. Evaluation is dish-level (`physical_meal_id`).
52
 
53
- ### Macronutrient accuracy (same 608 dishes)
 
 
 
 
 
54
 
55
  | Task | MAE | PMAE |
56
  | --- | --- | --- |
57
- | Mass | 68.2 g | 34.7% |
58
- | Protein | 6.4 g | 38.1% |
59
- | Carbohydrate | 7.9 g | 40.6% |
60
- | Fat | 7.7 g | 54.5% |
61
 
62
- ## Comparison with open VLMs (paired 304-dish subset, seed 17)
63
 
64
  Each model answered the same calorie question on the same dishes, scored against the official
65
  Nutrition5k calorie labels.
66
 
 
 
67
  | Model | Params | MAE (kcal) | Median AE | Within ±100 kcal | Bias |
68
  | --- | --- | --- | --- | --- | --- |
69
- | **CalorieK (ours)** | 93.7M | **84.5** | **28.0** | **82.2%** | −46.2 |
70
- | Qwen3.5-9B (Q8_0)‡ | 9B | 112.4 | 56.8 | 68.4% | −44.0 |
71
- | CalorieCLIP (public) | 151M | 155.9 | 106.4 | 46.7% | +71.0 |
72
- | MiniMax M3 (reasoning)§ | 428B (MoE) | 160.0 | 95.7 | 52.6% | +53.6 |
73
 
74
  ‡ Qwen3.5-9B: 8-bit GGUF (Q8_0) via llama.cpp, 4k context, thinking off.
75
  § MiniMax M3: hosted reasoning model, chain-of-thought enabled — extensive per-dish reasoning did not
@@ -87,7 +66,7 @@ weight decay 0.05, seed 17.
87
  - **Checkpoint selection**: best validation calorie MAE on 80 held-out camera-A dishes (validation MAE 57.3 kcal).
88
  Training ran ~13 minutes on one RTX 4080 (16 GB).
89
  - **Calibration**: a conformal radius fitted on 86 held-out calibration dishes gives 90% prediction
90
- intervals of ±119 kcal, with 87.3% actual coverage on the locked test set (`calibration.json`).
91
 
92
  ## Training data (20,000 samples, leakage-audited)
93
 
@@ -142,8 +121,8 @@ print(f"{kcal:.0f} kcal ± 119 (90% interval), {mass_g:.0f} g, P{protein_g:.0f}/
142
 
143
  - **Domain**: trained and evaluated on Nutrition5k-style plated single dishes photographed from the side;
144
  accuracy on multi-plate scenes, packaged food, or drinks is untested.
145
- - **Heavy tail**: RMSE (533) is far above MAE (86) — very high-calorie dishes are occasionally missed badly.
146
- Use the calibrated interval, not the point estimate, for anything that matters.
147
  - **Frames, not meals**: training frames come from videos of ~1,250 distinct dishes; visual diversity is
148
  narrower than the sample count suggests.
149
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # CalorieK — food-photo calorie & macro estimation
2
 
3
  A single RGB food photo in, five numbers out: **calories (kcal), mass (g), protein (g), carbohydrate (g), fat (g)**.
4
  CalorieK is a SigLIP2-base vision tower with a small regression head, fine-tuned end-to-end and evaluated
5
  under a strict, leakage-audited Nutrition5k protocol.
6
 
7
+ ![CalorieK predicted vs. actual calories](https://huggingface.co/Dralkh/CalorieK/resolve/main/calorie_accuracy.png)
8
+
9
+ ## Headline result — locked Nutrition5k test set (606 dishes, official test split, never seen)
10
 
11
+ | Metric | CalorieK | CalorieCLIP (same dishes) |
12
  | --- | --- | --- |
13
+ | Calorie MAE | **56.3 kcal** | 126.4 kcal |
14
+ | Median absolute error | **30.0 kcal** | 106.2 kcal |
15
+ | Within ±50 kcal | **65.0%** | 20.3% |
16
+ | Within ±100 kcal | **84.3%** | 47.2% |
17
+ | Bias | **−19.5 kcal** | +97.5 kcal |
18
+ | Invalid predictions | 0 / 606 | 0 / 606 |
19
 
20
+ CalorieK more than halves CalorieCLIP's calorie MAE and nearly doubles its within-±100 hit rate on the
21
+ same dishes. Every test image is a deterministic central frame from the official Nutrition5k camera-A
22
+ side-angle video of an official _test-split_ dish — selected by dish ID, never by image quality.
23
+ Evaluation is dish-level (`physical_meal_id`).
24
 
25
+ > Two of the 608 official test dishes carry corrupt ground-truth labels (a single 7,974 g "olives"
26
+ > ingredient gives one dish 876 g of fat in a 159 g dish, and another an 8 kg mass) and are excluded
27
+ > as physically impossible (calories > 2000). Including them, CalorieK's calorie MAE is 86.2 kcal
28
+ > (RMSE 533, driven almost entirely by those two dishes); excluding them RMSE is 94.
29
+
30
+ ### Macronutrient accuracy (same 606 dishes)
31
 
32
  | Task | MAE | PMAE |
33
  | --- | --- | --- |
34
+ | Mass | 55.3 g | 30.1% |
35
+ | Protein | 6.2 g | 37.4% |
36
+ | Carbohydrate | 6.3 g | 35.3% |
37
+ | Fat | 5.0 g | 43.5% |
38
 
39
+ ## Comparison with open VLMs (paired 303-dish subset, seed 17)
40
 
41
  Each model answered the same calorie question on the same dishes, scored against the official
42
  Nutrition5k calorie labels.
43
 
44
+ ![CalorieK vs. baselines](https://huggingface.co/Dralkh/CalorieK/resolve/main/model_comparison.png)
45
+
46
  | Model | Params | MAE (kcal) | Median AE | Within ±100 kcal | Bias |
47
  | --- | --- | --- | --- | --- | --- |
48
+ | **CalorieK (ours)** | 93.7M | **54.7** | **27.8** | **82.5%** | −16.3 |
49
+ | Qwen3.5-9B (Q8_0)‡ | 9B | 82.6 | 55.7 | 68.6% | −14.0 |
50
+ | CalorieCLIP (public) | 151M | 126.7 | 106.4 | 46.9% | +101.0 |
51
+ | MiniMax M3 (reasoning)§ | 428B (MoE) | 130.6 | 94.7 | 52.8% | +83.7 |
52
 
53
  ‡ Qwen3.5-9B: 8-bit GGUF (Q8_0) via llama.cpp, 4k context, thinking off.
54
  § MiniMax M3: hosted reasoning model, chain-of-thought enabled — extensive per-dish reasoning did not
 
66
  - **Checkpoint selection**: best validation calorie MAE on 80 held-out camera-A dishes (validation MAE 57.3 kcal).
67
  Training ran ~13 minutes on one RTX 4080 (16 GB).
68
  - **Calibration**: a conformal radius fitted on 86 held-out calibration dishes gives 90% prediction
69
+ intervals of ±119 kcal (`calibration.json`).
70
 
71
  ## Training data (20,000 samples, leakage-audited)
72
 
 
121
 
122
  - **Domain**: trained and evaluated on Nutrition5k-style plated single dishes photographed from the side;
123
  accuracy on multi-plate scenes, packaged food, or drinks is untested.
124
+ - **High-calorie under-prediction**: the model plateaus and under-predicts on dishes above ~500 kcal
125
+ (see the scatter above). Use the calibrated interval, not the point estimate, for anything that matters.
126
  - **Frames, not meals**: training frames come from videos of ~1,250 distinct dishes; visual diversity is
127
  narrower than the sample count suggests.
128