Leaf margin classifier (ResNeXt-101)
Classifies a leaf photo by the shape of its margin: dente (toothed edge) or lisse (smooth edge).
- Code: https://github.com/dihiaganoun/Leaf-Classification
- Live demo: https://leaf-margin-classifier.streamlit.app
Model
- Architecture: ResNeXt-101 32×8d (torchvision), ImageNet weights, new 2-class
fchead - Fine-tuning:
layer3,layer4andfctrained, earlier layers frozen - Input: 224×224 RGB, ImageNet normalization
- Classes (output order):
["dente", "lisse"] - File:
resnext101_leaves.pthis a PyTorchstate_dict
Results
Held-out test split (15% of ~6,500 images, 984 images):
| Metric | Score |
|---|---|
| Accuracy | 98.68% |
| F1 | 0.9861 |
| Precision | 0.9935 |
| Recall | 0.9787 |
| Balanced accuracy | 0.9864 |
Usage
import torch, torch.nn as nn
from huggingface_hub import hf_hub_download
from PIL import Image
from torchvision import models, transforms
path = hf_hub_download("dganoun/leaf-classifier-resnext101", "resnext101_leaves.pth")
model = models.resnext101_32x8d(weights=None)
model.fc = nn.Linear(model.fc.in_features, 2)
model.load_state_dict(torch.load(path, map_location="cpu", weights_only=True))
model.eval()
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
x = transform(Image.open("leaf.jpg").convert("RGB")).unsqueeze(0)
probs = model(x).softmax(1)[0]
print(dict(zip(["dente", "lisse"], probs.tolist())))
Or install the project package from GitHub and call leaf_classifier.load_model().
Limitations
- Trained on images of single leaves; accuracy on real-world photos with cluttered backgrounds has not been measured.
- See the GitHub README for notes on the training notebook.
Evaluation results
- Test accuracyself-reported0.987
- Test F1self-reported0.986