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