Skip to content

Latest commit

Β 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌿 Plant Disease Foundation Model

A Self-Supervised Learning (SSL) foundation model for plant disease classification, built with SimCLR and a ResNet-18 backbone. The model is pre-trained on unlabelled plant images and then fine-tuned for 38-class plant disease classification. GradCAM explainability is integrated for inference visualisation.


πŸ“‹ Table of Contents


Overview

This project implements a two-stage transfer learning pipeline:

  1. SSL Pre-training (SimCLR) β€” trains an encoder on unlabelled plant images using contrastive learning. No labels required.
  2. Fine-tuning β€” loads the pre-trained encoder and trains a classification head on labelled plant disease images (38 classes).
  3. GradCAM Inference β€” generates visual explanations highlighting which leaf regions influenced each prediction.

Why Self-Supervised Learning?

Property SSL Approach
Labels needed for pre-training None
Transfer to new tasks Add a small classification head
Data efficiency at fine-tune High β€” few labels needed
Explainability GradCAM heatmaps per prediction

Project Structure

Plant-disease-classification-FM/
β”‚
β”œβ”€β”€ model.py                  # Encoder (ResNet-18) + ProjectionHead + SimCLRModel
β”œβ”€β”€ dataset.py                # SSL contrastive dataset + augmentation pipeline
β”œβ”€β”€ loss.py                   # NT-Xent contrastive loss
β”œβ”€β”€ train.py                  # SSL pre-training loop + checkpoint saving
β”œβ”€β”€ finetune.py               # Fine-tuning classifier + full metrics reporting
β”œβ”€β”€ gradcam_inference.py      # GradCAM inference + visualisation
β”‚
β”œβ”€β”€ requirements.txt          # Python dependencies
β”œβ”€β”€ .gitignore
β”œβ”€β”€ .gitattributes
β”‚
β”œβ”€β”€ data/                     # (not committed β€” see .gitignore)
β”‚   β”œβ”€β”€ train/
β”‚   β”‚   β”œβ”€β”€ Apple___Apple_scab/
β”‚   β”‚   └── ...
β”‚   └── val/
β”‚       β”œβ”€β”€ Apple___Apple_scab/
β”‚       └── ...
β”‚
β”œβ”€β”€ checkpoints/              # SSL pre-training checkpoints (not committed)
β”‚   β”œβ”€β”€ foundation_encoder.pt
β”‚   └── checkpoint_epoch_*.pt
β”‚
β”œβ”€β”€ finetune_checkpoints/     # Fine-tuning outputs (not committed)
β”‚   β”œβ”€β”€ best_model.pt
β”‚   β”œβ”€β”€ final_model.pt
β”‚   β”œβ”€β”€ metrics_log.csv
β”‚   └── confusion_matrix_*.png
β”‚
└── xai/                      # GradCAM outputs (not committed)
    β”œβ”€β”€ <ClassName>/
    β”‚   β”œβ”€β”€ original.jpg
    β”‚   β”œβ”€β”€ gradcam_heatmap.png
    β”‚   β”œβ”€β”€ gradcam_overlay.png
    β”‚   └── gradcam_panel.png
    β”œβ”€β”€ summary_grid.png
    └── confidence_report.png

Pipeline

Unlabelled plant images
        β”‚
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ SSL Pre-    β”‚  train.py        β†’ checkpoints/foundation_encoder.pt
  β”‚ training    β”‚  (SimCLR)
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ Fine-tuning β”‚  finetune.py     β†’ finetune_checkpoints/best_model.pt
  β”‚ Classifier  β”‚  (38 classes)
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  GradCAM   β”‚  gradcam_        β†’ xai/
  β”‚  Inference  β”‚  inference.py
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Installation

Requirements

  • Python 3.9+
  • PyTorch 2.0+
  • CUDA-capable GPU recommended (CPU works but is slow for training)

Setup

# Clone the repository
git clone https://github.com/gadhane/Plant-disease-classification-FM.git
cd Plant-disease-classification-FM

# Create and activate a virtual environment
python -m venv venv
source venv/bin/activate        # Linux / macOS
venv\Scripts\activate           # Windows

# Install dependencies
pip install -r requirements.txt

Data Format

data/
  train/
    Apple___Apple_scab/
    Apple___Black_rot/
    Apple___Cedar_apple_rust/
    Apple___healthy/
    Tomato___Early_blight/
    Tomato___Late_blight/
    Tomato___healthy/
    ...  (38 classes total)
  val/
    Apple___Apple_scab/
    ...

Usage

1. SSL Pre-training

Train the foundation model on unlabelled images (labels/folder names are ignored):

python train.py \
  --data_dir data \
  --epochs 100 \
  --batch_size 64 \
  --image_size 224 \
  --embed_dim 256 \
  --temperature 0.5 \
  --save_dir checkpoints

Key arguments:

Argument Default Description
--data_dir data Root folder with plant images
--epochs 100 Training epochs
--batch_size 64 Larger = more negatives = better SSL
--embed_dim 256 Encoder output dimension
--temperature 0.5 NT-Xent loss temperature
--resume None Path to checkpoint to resume from

Outputs:

checkpoints/
  foundation_encoder.pt         ← use this for fine-tuning
  checkpoint_epoch_010.pt
  checkpoint_epoch_020.pt
  ...

2. Fine-tuning

Fine-tune the foundation encoder on labelled plant disease images:

python finetune.py \
  --data_dir data \
  --checkpoint_path checkpoints/foundation_encoder.pt \
  --strategy partial \
  --epochs 30 \
  --batch_size 32 \
  --lr 1e-3

Key arguments:

Argument Default Description
--checkpoint_path checkpoints/foundation_encoder.pt Pre-trained encoder
--strategy partial frozen / partial / full
--epochs 30 Fine-tuning epochs
--num_classes 38 Number of disease classes
--lr 1e-3 Learning rate

3. GradCAM Inference

Run inference on one image per class and generate GradCAM visualisations:

python gradcam_inference.py \
  --model_path finetune_checkpoints/best_model.pt \
  --val_dir data/val \
  --xai_dir xai \
  --seed 42

Model Architecture

SSL Pre-training

Input (B, 3, 224, 224)
        β”‚
   β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
   β”‚ Encoder β”‚   ResNet-18 backbone (layer1β†’layer4β†’AvgPool)
   β”‚         β”‚   + Linear(512 β†’ 256) + BatchNorm1d
   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
        β”‚  (B, 256)  ← saved as foundation_encoder.pt
   β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ Projection  β”‚   Linear(256β†’512) β†’ BN β†’ ReLU
   β”‚    Head     β”‚   Linear(512β†’512) β†’ BN β†’ ReLU
   β”‚  [discarded]β”‚   Linear(512β†’128)
   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚  (B, 128) L2-normalised
        β–Ό
   NT-Xent Loss

Fine-tuning

Input (B, 3, 224, 224)
        β”‚
   β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
   β”‚ Encoder β”‚   Loaded from foundation_encoder.pt
   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
        β”‚  (B, 256)
   β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ Classifier    β”‚   Linear(256β†’512) β†’ BN β†’ ReLU β†’ Dropout(0.3)
   β”‚    Head       β”‚   Linear(512β†’256) β†’ BN β†’ ReLU β†’ Dropout(0.15)
   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   Linear(256β†’38)
        β”‚
   CrossEntropyLoss (label_smoothing=0.1)

Fine-tuning Strategies

Strategy Trainable Params When to Use
frozen Head only Few labels, fast training
partial ResNet layer4 + embedding fc + head Default β€” best balance
full Entire encoder + head Lots of labelled data

Output Files

checkpoints/                        # SSL pre-training
  foundation_encoder.pt             ← encoder weights for fine-tuning

finetune_checkpoints/               # Fine-tuning
  best_model.pt                     ← best validation accuracy
  final_model.pt                    ← last epoch
  metrics_log.csv                   ← all metrics, all epochs
  confusion_matrix_epoch_030.png    ← normalised heatmap

xai/                                # GradCAM
  <ClassName>/
    original.jpg
    gradcam_heatmap.png
    gradcam_overlay.png
    gradcam_panel.png               ← Original | Heatmap | Overlay
  summary_grid.png                  ← all 38 classes in one image
  confidence_report.png             ← per-class confidence bar chart

CI/CD

This project uses GitHub Actions for automated testing and linting.

Workflows

Workflow Trigger Description
ci.yml Push / PR to main, develop Lint + unit tests
codeql.yml Push / PR + weekly schedule Security analysis

Running Tests Locally

# Lint
flake8 . --max-line-length=120

# Tests
pytest tests/ -v

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Commit your changes: git commit -m "feat: add my feature"
  4. Push to the branch: git push origin feature/my-feature
  5. Open a Pull Request

License

This project is licensed under the MIT License. See LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages