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}
}
```
|