license: mit tags: - image-classification - pytorch - resnet50 - agriculture - plant-disease - transfer-learning library_name: pytorch
PlantDoc AI β Plant Disease Classifier (ResNet50)
A 29-class plant disease classifier covering 9 plant species, trained via transfer learning on a frozen ResNet50 (ImageNet) backbone with a custom classification head. Built as the core model behind PlantDoc AI β a mobile-first app that lets a farmer photograph a leaf and get a diagnosis and offline voice advice in English, Urdu, or Sindhi.
This model handles classification only. Disease explanations (cause/impact/precautions) are generated separately by an LLM that receives the predicted class name β the LLM never sees the image.
Model Details
- Architecture: ResNet50, ImageNet-pretrained backbone (frozen), custom fully-connected head for 29-class output
- Framework: PyTorch
- Input: RGB leaf image, resized to 256Γ256, normalized with standard ImageNet mean/std
- Output: Class index (0β28) β disease label
- Training data: ~54,000 labeled leaf images across 9 plant species
- Training: 5 epochs, Google Colab
- Validation accuracy: 97.88%
Plant Species Covered
Apple, Banana, Tomato, Potato, [add remaining 5 species here]
Class Labels
β οΈ Note: several classes are internally labeled just
"Healthy"(one per plant, without a plant prefix). The index-to-label mapping below is required to correctly interpret model output β copy it exactly from yourapp.js/main.pysequence list.
CLASS_NAMES = [
"0: ...",
"1: ...",
# paste your full 29-class sequence list here, in exact index order
]
How to Use
import torch
from torchvision import models, transforms
from PIL import Image
# Rebuild the architecture (frozen ResNet50 backbone + custom head)
model = models.resnet50(weights=None)
model.fc = torch.nn.Linear(model.fc.in_features, 29) # 29-class head
# Load trained weights
state_dict = torch.load("checkpoint.pth", map_location="cpu")
model.load_state_dict(state_dict)
model.eval()
# Preprocess an image
transform = transforms.Compose([
transforms.Resize((256, 256)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
img = Image.open("leaf.jpg").convert("RGB")
input_tensor = transform(img).unsqueeze(0)
with torch.no_grad():
output = model(input_tensor)
predicted_class = output.argmax(dim=1).item()
print(f"Predicted class index: {predicted_class}")
A Note on Model Behavior
During evaluation, the model frequently confused Potato Late Blight with Tomato Late Blight. This isn't a failure to distinguish plant species β both diseases are caused by the same pathogen, Phytophthora infestans. The confusion reflects genuine shared disease biology rather than a modeling error, and is a useful reminder to investigate misclassifications before treating them as bugs.
Limitations
- Frozen backbone only β the ResNet50 base was not fine-tuned. Unfreezing and training end-to-end would likely yield a further 1β2% accuracy gain.
- Class naming is not human-readable out of the box (see note above on
"Healthy"labels); consumers of this model should apply a "Plant - Disease" mapping for display purposes. - Trained and validated on a fixed dataset; performance on images taken in different lighting, backgrounds, or camera qualities than the training set is untested.
Intended Use
Educational and assistive tool for early plant disease identification, particularly in low-connectivity settings. Not a substitute for professional agronomic diagnosis in high-stakes commercial farming decisions.
Links
- Full application (backend + frontend + training notebook): GitHub β PlantDoc-AI