File size: 8,160 Bytes
d08d3b7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
---
base_model: torchvision/efficientnet_v2_s (IMAGENET1K_V1)
license: apache-2.0
library_name: pytorch
pipeline_tag: image-classification
tags:
- image-classification
- flowers
- oxford-102
- torchvision
- efficientnet
- transfer-learning
metrics:
- accuracy
- f1
model-index:
- name: EfficientNetV2-S Flower Classifier
  results:
  - task:
      type: image-classification
    dataset:
      name: Oxford-102 Flowers
      type: oxford-102-flowers
      split: validation
    metrics:
    - type: accuracy
      value: 0.9996511340141296
    - type: f1
      value: 0.9994719624519348
---

# EfficientNetV2-S Flower Classifier

Fine-tuned [`torchvision.models.efficientnet_v2_s`](https://docs.pytorch.org/vision/main/models/efficientnetv2.html) (ImageNet-1K pretrained) for 102-class flower classification on the Oxford-102 Flowers dataset, with the full backbone unfrozen during fine-tuning. Achieves **0.9997 accuracy / 0.9995 F1** on the validation split.

**Recommended when** you need near-best accuracy at a fraction of the size and latency β€” the default choice for serving. At ~82MB and ~30ms mean latency it is ~4x smaller and ~3x faster than [ViT-B/16 Flower Classifier](vit-b16-readme.md) for a ~0.05 percentage-point accuracy difference.

## Usage

```python
import torch
from huggingface_hub import hf_hub_download
from torchvision import models

weights_path = hf_hub_download(repo_id="bengid/flower-classifier", filename="ft_EfficientNetV2-S.pth")

model = models.efficientnet_v2_s(weights=None)
model.classifier[1] = torch.nn.Linear(model.classifier[1].in_features, 102)
model.load_state_dict(torch.load(weights_path, map_location="cpu", weights_only=True))
model.eval()

# preprocessing: resize(256) -> center-crop(224) -> normalize with dataset mean/std
# see src/utils.py:get_transforms() in the training repo for the exact pipeline
```

## Training Data

[Oxford-102 Flowers](https://www.robots.ox.ac.uk/~vgg/data/flowers/102/) β€” 8,189 images across 102 flower species, downloaded via `torchvision.datasets.Flowers102`. Class-weighted `CrossEntropyLoss` was used to correct for the dataset's uneven per-class image counts.

## Training Procedure

Single-stage fine-tune with a **two-phase backbone unfreeze** callback (`BackboneFinetuning`): the EfficientNetV2 backbone starts frozen (only the classification head trains), then unfreezes at a fixed epoch with its own, lower learning rate and a separate parameter group β€” unlike this project's original (v1) EfficientNet-B0 model, which only ever unfroze its *last 3 backbone blocks*.

### Hyperparameters

| Parameter | Value |
|---|---|
| Optimizer | AdamW |
| LR scheduler | Cosine annealing (T_max=30, eta_min=1e-06) |
| Head LR (before unfreeze) | 1e-3 |
| Head LR (after unfreeze) | 1e-3 |
| Backbone LR (after unfreeze) | 1e-5 |
| Unfreeze epoch | 5 |
| Max epochs | 30 |
| Batch size | 32 |
| Effective batch size | 32 |
| Gradient accumulation | 1 |
| Precision | 16-mixed |
| Weight decay | 0.01 |
| Early stopping patience | 5 |

## Evaluation

| Metric | Value |
|---|---|
| **Accuracy** | **0.9997** |
| **F1** | **0.9995** |
| Parameters | 20,308,150 |
| Model size | 81.8 MB |
| Checkpoint size | 245.0 MB |
| Mean latency | 29.6 ms |
| p95 latency | 30.9 ms |

Latency measured on {} at batch size 1.

## Strengths & Weaknesses

**Strengths:**
- Within 0.05pp of ViT-B/16's accuracy and F1 while being ~4x smaller (81.8MB vs 343.5MB) and ~3x faster (29.6ms vs 86.5ms mean latency) β€” the best accuracy-per-cost tradeoff of the four models trained.
- Convolutional inductive bias generalizes well from a modest fine-tuning dataset (~8k images), needing less data than attention-based architectures to reach its ceiling.
- Small enough to fit comfortably in the Docker image and serve cheaply (this is the architecture family the v2 API's original `helpers.py` defaulted to).

**Weaknesses:**
- Marginally lower accuracy/F1 than ViT-B/16, though the gap is negligible in practice (both are within noise of a perfect validation score).
- EfficientNetV2's published training recipe (progressive resizing, adaptive regularization) is more sensitive to schedule/hyperparameter choices than a straightforward ViT fine-tune; deviating far from a tuned recipe can cost more accuracy than it would for ViT.
- Like the ViT model, still requires unfreezing the *entire* backbone to reach these numbers β€” the smaller, cheaper EfficientNet-B0 v1 model that only partially unfroze its backbone topped out well below 93% for this reason.

## Limitations

- **Closed-set, single-label**: trained on exactly 102 Oxford flower species; will confidently misclassify any other flower species, non-flower image, or multi-flower image into one of the 102 known classes β€” there is no out-of-distribution rejection.
- **Fixed input pipeline**: expects a 224Γ—224 center-cropped, normalized input (resize-then-crop). Unusual aspect ratios or off-center subjects can crop the flower out of frame.
- **No adversarial robustness or calibration guarantees** β€” confidence scores are not calibrated probabilities.
- Reported metrics are on the Oxford-102 validation split; real-world images (different lighting, backgrounds, camera quality) may perform worse.

## Intended Use

**Intended uses:**
- Flower species identification within the 102 Oxford-102 classes (gardening/botany apps, educational tools, dataset labeling).
- Default backend model for this project's v2 `/classify` API endpoint β€” chosen for its accuracy/latency/size balance.

**Out-of-scope uses:**
- General-purpose plant, object, or scene classification outside the 102 trained species.
- Medical, toxicity, or safety-related plant identification.
- Any use where a wrong classification has safety or financial consequences without human review.

## Model Comparison

This project trained four models in total, in this order:

| Model | Val Acc | Val F1 | Params | Size (MB) | Best For |
|---|---|---|---|---|---|
| [SimpleCNN (scratch)](https://huggingface.co/bengid/flower-classifier/blob/main/flower_model_weights.pth) | ~0.63 | {} | {} | {} | historical baseline only |
| [EfficientNet-B0 (v1, partial unfreeze)](https://huggingface.co/bengid/flower-classifier/blob/main/ft_EfficientNet-B0.pth) | >0.93 | {} | {} | {} | historical baseline only |
| **EfficientNetV2-S (this model)** | **0.9997** | **0.9995** | 20,308,150 | 81.8 | efficient production serving |
| [ViT-B/16](https://huggingface.co/bengid/flower-classifier/blob/main/ft_ViT-B16.pth) | 1.0 | 1.0 | 85,877,094 | 343.5 | maximum accuracy |

### Why the earlier models underperformed

- **SimpleCNN (scratch)** was trained from randomly initialized weights with no ImageNet pretraining, on a 6-block custom CNN β€” too little capacity and too little prior visual knowledge to learn 102 fine-grained flower classes from ~8k images alone.
- **EfficientNet-B0 (v1)** started from ImageNet-pretrained weights but only ever unfroze its *last 3 backbone blocks* during fine-tuning (see this project's root `README.md`, "Fine-Tuning EfficientNet-B0" section, for the original two-stage recipe) β€” the earlier backbone layers, tuned for general ImageNet features, never adapted to flower-specific low/mid-level features, capping accuracy well below the fully-unfrozen v2 models.
- Both **EfficientNetV2-S** (this model) and **ViT-B/16** unfreeze the *entire* backbone during fine-tuning, which is the main driver of the jump from ~93% to ~99.97-100% accuracy.

## License

Apache 2.0, consistent with this project's license.

## Citation

**Base model (EfficientNetV2):**
```bibtex
@inproceedings{tan2021efficientnetv2,
  title={EfficientNetV2: Smaller Models and Faster Training},
  author={Tan, Mingxing and Le, Quoc V},
  booktitle={International Conference on Machine Learning},
  year={2021}
}
```

**Training dataset:**
```bibtex
@inproceedings{nilsback2008automated,
  title={Automated flower classification over a large number of classes},
  author={Nilsback, Maria-Elena and Zisserman, Andrew},
  booktitle={2008 Sixth Indian Conference on Computer Vision, Graphics \& Image Processing},
  pages={722--729},
  year={2008},
  organization={IEEE}
}
```