Skip to content
Om Salunkhe
Jupyter Notebook + FlaskMachine learning · Computer vision

Plant Disease Prediction

A convolutional neural network that classifies leaf images as healthy, powdery mildew, or rust — served through a small Flask upload app.

Role
Data preparation, model training, inference app
Year
2025
Stack
  • Python
  • TensorFlow / Keras
  • Jupyter
  • NumPy
  • Pillow
  • Flask
  • Matplotlib
  • Seaborn

01The problem

Leaf diseases like powdery mildew and rust are visible on the leaf surface, but recognising them reliably takes experience. An image classifier can give a fast first opinion from a single photo.

Built for — Growers and students who want a quick first check from a photo of a leaf.

CNN architecture: 225 by 225 RGB input, Conv2D 32 filters, max pooling, Conv2D 64 filters, max pooling, flatten, dense 64, dense 3 with softmax over Healthy, Powdery and Rust.InputRGB image225×225×3Conv2D32 · 3×3 · ReLU223×223×32MaxPool2×2111×111×32Conv2D64 · 3×3 · ReLU109×109×64MaxPool2×254×54×64Flatten186,624Dense64 · ReLU64Dense3 · softmax3HealthyPowderyRust

Accuracy by epoch

5 epochs · 1,322 training images · 60 validation images

  • Validation
  • Training
40%60%80%100%12345epochVal 83.3%Train 83.3%
fig.Model architecture as defined in Model_Training.ipynb.

02What I built

  • Organised a three-class leaf image dataset (Healthy, Powdery, Rust) into train, validation, and test splits.
  • Built the training pipeline with on-the-fly augmentation (rescale, shear, zoom, horizontal flip) using Keras ImageDataGenerator.
  • Designed and trained a compact CNN, plotted training vs. validation accuracy, and saved the model for reuse.
  • Wrapped the model in a Flask app: upload an image, it is resized and normalised exactly as in training, and the predicted class is returned.

03Key decisions

  1. D1

    A small CNN as a deliberate baseline

    Two convolution + max-pooling blocks (32 and 64 filters), a 64-unit dense layer, and a 3-way softmax. Small enough to train on a laptop CPU in minutes, which makes it a clear baseline to improve on.

  2. D2

    Augmentation instead of more data

    With roughly 440 training images per class, random shear, zoom, and flips help the model generalise rather than memorise the training set.

  3. D3

    Identical preprocessing in training and serving

    The Flask app resizes to 225×225 and scales pixels to [0, 1] exactly as the training generator does — a common source of silent accuracy loss when it drifts.

04By the numbers

Training images
1,322
Validation images
60
Test images
150
Classes
3

Figures taken directly from the repository.

05Results, honestly

  • After 5 epochs the model reached 83.3% accuracy on the 60-image validation set (training accuracy 83.3%), with validation loss still falling.
  • The 150-image test split was not formally evaluated in the notebook, and a sample Rust test image was predicted Healthy with near-equal probabilities (0.51 vs 0.49) — a clear sign the model needs more training and a proper test-set report.

06What I'd do next

  • Evaluate on the held-out test set with a per-class confusion matrix.
  • Try transfer learning from a pretrained backbone such as MobileNet or EfficientNet.
  • Add early stopping and train for more epochs while validation loss is still improving.