Assignment 5-A

Computer Vision Image Classifier

Build a production-ready image classification system that combines all Module 5 concepts: CNN architecture design, data augmentation, transfer learning with pretrained models, model evaluation with confusion matrices, and deployment-ready inference pipelines.

8-12 hours
Challenging
250 Points
Submit Assignment
What You'll Build
  • Custom CNN from scratch
  • Transfer learning with EfficientNet
  • Data augmentation pipeline
  • Model evaluation & visualization
  • Production inference function
Contents
01

Assignment Overview

In this assignment, you will build a complete Medical Image Classification System for detecting plant diseases from leaf images. This comprehensive project requires you to apply ALL concepts from Module 5: CNN architecture design, data augmentation, transfer learning with pretrained models, model evaluation with metrics and visualizations, and creating production-ready inference pipelines.

Required Libraries: You must use TensorFlow 2.x and Keras for model building. Additional allowed libraries: NumPy, Matplotlib, Seaborn, scikit-learn (for metrics only). No PyTorch or other deep learning frameworks.
Skills Applied: This assignment tests your understanding of CNN Fundamentals (Topic 5.1) and Image Classification with Transfer Learning (Topic 5.2) from Module 5.
CNN Architecture (5.1)

Convolutional layers, pooling, batch normalization, dropout, and model design

Transfer Learning (5.2)

Pretrained models, feature extraction, fine-tuning strategies

Evaluation & Deployment (5.2)

Confusion matrix, classification report, inference pipeline

Ready to submit? Already completed the assignment? Submit your work now!
Submit Now
02

The Scenario

AgriTech Solutions - Plant Disease Detection

You have been hired as a Machine Learning Engineer at AgriTech Solutions, a startup developing AI-powered tools for farmers. The CEO has given you this challenge:

"Farmers are losing millions of dollars every year due to plant diseases that go undetected until it's too late. We need an AI system that can analyze photos of plant leaves and instantly tell farmers if their crops are healthy or diseased—and if diseased, what specific disease it is. Can you build this for us using deep learning?"

Your Task

Create a Jupyter Notebook called plant_disease_classifier.ipynb that implements a complete image classification system. You will build TWO models: a custom CNN from scratch and a transfer learning model using EfficientNetB0. Your system must achieve at least 85% validation accuracy and include comprehensive evaluation with visualizations.

Model 1: Custom CNN

Design your own CNN architecture from scratch with at least 3 convolutional blocks, batch normalization, and dropout. Target: 70%+ accuracy.

Model 2: Transfer Learning

Use EfficientNetB0 pretrained on ImageNet with fine-tuning. Implement both feature extraction and fine-tuning phases. Target: 85%+ accuracy.

03

The Dataset

You will use a subset of the PlantVillage Dataset containing leaf images from 6 classes. Download and organize the data as shown below.

Dataset Download: Download the dataset from Kaggle PlantVillage Dataset or use TensorFlow Datasets: tfds.load('plant_village')

Dataset Structure

Organize your dataset into the following folder structure:

plant_disease_data/
├── train/
│   ├── Tomato_healthy/           # ~1000 images
│   ├── Tomato_Early_blight/      # ~1000 images
│   ├── Tomato_Late_blight/       # ~1000 images
│   ├── Potato_healthy/           # ~150 images
│   ├── Potato_Early_blight/      # ~1000 images
│   └── Potato_Late_blight/       # ~1000 images
├── validation/
│   ├── Tomato_healthy/           # ~200 images
│   ├── Tomato_Early_blight/      # ~200 images
│   ├── Tomato_Late_blight/       # ~200 images
│   ├── Potato_healthy/           # ~50 images
│   ├── Potato_Early_blight/      # ~200 images
│   └── Potato_Late_blight/       # ~200 images
└── test/
    ├── Tomato_healthy/           # ~100 images
    ├── Tomato_Early_blight/      # ~100 images
    ├── Tomato_Late_blight/       # ~100 images
    ├── Potato_healthy/           # ~25 images
    ├── Potato_Early_blight/      # ~100 images
    └── Potato_Late_blight/       # ~100 images
Dataset Details
  • Total Classes: 6 (2 healthy + 4 diseased)
  • Image Size: Varies (resize to 224×224)
  • Format: JPEG/PNG color images
  • Split: ~70% train, ~15% validation, ~15% test
  • Class Imbalance: Note that Potato_healthy has fewer samples
Class Labels
IndexClass NameType
0Potato_Early_blightDiseased
1Potato_Late_blightDiseased
2Potato_healthyHealthy
3Tomato_Early_blightDiseased
4Tomato_Late_blightDiseased
5Tomato_healthyHealthy
Important: The dataset has class imbalance (Potato_healthy has fewer images). You must handle this using class weights or data augmentation strategies.
04

Requirements

Your plant_disease_classifier.ipynb must implement ALL of the following tasks. Each task is mandatory and will be evaluated individually.

1
Data Loading & Exploration

Create functions to load and explore the dataset:

  • Use keras.utils.image_dataset_from_directory() to load train, validation, and test sets
  • Set image_size=(224, 224) and batch_size=32
  • Display sample images from each class (at least 2 per class)
  • Print class distribution and identify any imbalance
  • Apply performance optimization with cache(), shuffle(), and prefetch()
def load_datasets(data_dir, image_size=(224, 224), batch_size=32):
    """Load train, validation, and test datasets from directory."""
    # Must return: train_ds, val_ds, test_ds, class_names
    pass

def visualize_samples(dataset, class_names, samples_per_class=2):
    """Display sample images from each class."""
    pass
2
Data Augmentation Pipeline

Create a data augmentation layer using Keras preprocessing layers:

  • Must include: RandomFlip, RandomRotation, RandomZoom
  • Add at least one more augmentation (contrast, brightness, or translation)
  • Visualize augmentation effects on a sample image (show original + 5 augmented versions)
data_augmentation = keras.Sequential([
    layers.RandomFlip("horizontal"),
    layers.RandomRotation(0.2),
    layers.RandomZoom(0.2),
    # Add more augmentation layers
], name='data_augmentation')
3
Model 1: Custom CNN Architecture

Design and build a CNN from scratch:

  • Minimum 3 convolutional blocks (Conv2D → BatchNorm → ReLU → MaxPool)
  • Progressive filter increase (e.g., 32 → 64 → 128)
  • Use GlobalAveragePooling2D instead of Flatten
  • Include Dropout layers (at least 2) for regularization
  • Include the data augmentation layer at the start
  • Print model summary showing total and trainable parameters
def create_custom_cnn(input_shape, num_classes, data_augmentation):
    """Build a custom CNN with best practices."""
    # Must include: Rescaling, augmentation, 3+ conv blocks, 
    # BatchNorm, GlobalAveragePooling2D, Dropout
    pass
4
Training Custom CNN with Callbacks

Train the custom CNN with proper configuration:

  • Compile with Adam optimizer, appropriate loss, and accuracy metric
  • Implement ModelCheckpoint to save best model
  • Implement EarlyStopping with patience=5
  • Implement ReduceLROnPlateau to reduce learning rate on plateau
  • Train for maximum 30 epochs
  • Handle class imbalance using class_weight parameter
def compute_class_weights(train_ds, class_names):
    """Compute class weights to handle imbalance."""
    pass

callbacks = [
    keras.callbacks.ModelCheckpoint(...),
    keras.callbacks.EarlyStopping(...),
    keras.callbacks.ReduceLROnPlateau(...)
]
5
Model 2: Transfer Learning with EfficientNetB0

Implement transfer learning with two phases:

  • Load EfficientNetB0 with include_top=False and weights='imagenet'
  • Phase 1 (Feature Extraction): Freeze base model, train only classification head for 10 epochs
  • Phase 2 (Fine-tuning): Unfreeze last 20 layers, train with 10x lower learning rate
  • Use the EfficientNet preprocessing function
  • Target accuracy: 85%+ on validation set
def create_transfer_model(input_shape, num_classes):
    """Create EfficientNetB0 transfer learning model."""
    base_model = keras.applications.EfficientNetB0(
        input_shape=input_shape,
        include_top=False,
        weights='imagenet'
    )
    # Freeze base_model
    # Add classification head
    pass

def fine_tune_model(model, base_model, train_ds, val_ds, unfreeze_layers=20):
    """Phase 2: Unfreeze top layers and fine-tune."""
    pass
6
Training History Visualization

Create comprehensive training visualizations:

  • Plot accuracy curves (train vs validation) for both models
  • Plot loss curves (train vs validation) for both models
  • Create a comparison chart of both models' final performance
  • Use proper labels, legends, and titles
def plot_training_history(history, title="Training History"):
    """Plot accuracy and loss curves."""
    # Create 1x2 subplot with accuracy and loss
    pass

def compare_models(history_custom, history_transfer):
    """Compare performance of both models."""
    pass
7
Model Evaluation on Test Set

Comprehensive evaluation on the held-out test set:

  • Evaluate both models on test set using model.evaluate()
  • Generate predictions for all test images
  • Create confusion matrix visualization using seaborn heatmap
  • Generate classification report with precision, recall, F1-score per class
  • Identify which disease classes are most commonly confused
def evaluate_model(model, test_ds, class_names):
    """Full evaluation with confusion matrix and classification report."""
    # Get predictions
    # Create confusion matrix
    # Print classification report
    pass
8
Visualize Misclassifications

Analyze model failures:

  • Find and display at least 9 misclassified images
  • Show true label, predicted label, and confidence for each
  • Identify if there are patterns in misclassifications
  • Write a brief analysis (in markdown cell) explaining why certain classes might be confused
def visualize_misclassifications(model, test_ds, class_names, n=9):
    """Display misclassified images with labels and confidence."""
    pass
9
Production Inference Pipeline

Create a deployment-ready prediction function:

  • Accept a single image path as input
  • Handle image loading, resizing, and preprocessing
  • Return top-3 predictions with class names and confidence scores
  • Include error handling for invalid image paths
  • Demonstrate with 3 sample images (show image + predictions)
def create_prediction_pipeline(model, class_names, image_size=(224, 224)):
    """Create production-ready prediction function."""
    
    def predict(image_path):
        # Load and preprocess image
        # Get predictions
        # Return top 3 results as list of dicts
        pass
    
    return predict

# Usage demonstration
predict = create_prediction_pipeline(best_model, class_names)
results = predict('test_leaf.jpg')
print(results)  # [{'class': 'Tomato_healthy', 'confidence': 0.95}, ...]
10
Save Best Model

Export your best performing model:

  • Save the best model in Keras format (.keras)
  • Print the final test accuracy and model file size
  • Write a summary comparing both models in a markdown cell
# Save the best model
best_model.save('plant_disease_model.keras')
print(f"Model saved. File size: {os.path.getsize('plant_disease_model.keras') / 1e6:.2f} MB")
05

Submission

Create a public GitHub repository with the exact name shown below:

Required Repository Name
plant-disease-classifier
github.com/<your-username>/plant-disease-classifier
Required Files
plant-disease-classifier/
├── plant_disease_classifier.ipynb    # Your main Jupyter Notebook
├── plant_disease_model.keras         # Your best saved model
├── requirements.txt                  # Python dependencies
├── images/
│   ├── confusion_matrix.png          # Confusion matrix visualization
│   ├── training_history.png          # Training curves
│   ├── sample_predictions.png        # Sample prediction results
│   └── augmentation_demo.png         # Data augmentation visualization
├── README.md                         # Required documentation
└── .gitignore                        # Ignore data folder, checkpoints
README.md Must Include:
  • Your full name and submission date
  • Project overview and problem statement
  • Dataset description and preprocessing steps
  • Model architectures (custom CNN and transfer learning)
  • Results summary with accuracy comparison table
  • Key findings and what you learned
  • Instructions to run your notebook
Do Include
  • Both models implemented and trained
  • All 10 tasks completed in notebook
  • Clear markdown explanations between code cells
  • All required visualizations saved as images
  • Saved model file (.keras format)
  • requirements.txt with all dependencies
  • README.md with all required sections
Do Not Include
  • Dataset images (use .gitignore)
  • Model checkpoints during training
  • __pycache__ or .ipynb_checkpoints folders
  • Virtual environment folders
  • Code that doesn't run without errors
  • Notebooks with unexecuted cells
Important: Run all cells in your notebook from top to bottom before submitting to ensure everything executes correctly. Save all visualizations to the images/ folder.
Submit Your Assignment

Enter your GitHub username - we'll verify your repository automatically

06

Grading Rubric

Your assignment will be graded on the following criteria (250 points total):

Criteria Points Description
Data Loading & Augmentation 30 Correct dataset loading, visualization, and augmentation pipeline with performance optimization
Custom CNN Architecture 40 Well-designed architecture with BatchNorm, Dropout, GlobalAveragePooling, achieving 70%+ accuracy
Transfer Learning Model 50 Correct implementation of feature extraction + fine-tuning phases, achieving 85%+ accuracy
Training & Callbacks 30 Proper use of callbacks, class weights for imbalance, and training configuration
Evaluation & Metrics 35 Confusion matrix, classification report, misclassification analysis with insights
Visualizations 25 Training curves, sample predictions, confusion matrix heatmaps - all properly labeled
Inference Pipeline 20 Production-ready prediction function with error handling and demonstration
Code Quality & Documentation 20 Clean code, docstrings, markdown explanations, proper README
Total 250
Bonus Points (+25)

Achieve 90%+ test accuracy with either model, or implement Grad-CAM visualization

Passing Score

175+ points (70%) with both models trained and 85%+ transfer learning accuracy

Auto-Fail

Notebook doesn't run, plagiarism detected, or missing required files

Ready to Submit?

Make sure you have completed all requirements and reviewed the grading rubric above.

Submit Your Assignment
07

What You Will Practice

CNN Architecture Design (5.1)

Building convolutional blocks, choosing filter sizes, applying BatchNormalization and Dropout for regularization

Transfer Learning (5.2)

Loading pretrained models, feature extraction vs fine-tuning, learning rate scheduling for fine-tuning

Data Augmentation

Using Keras preprocessing layers, RandomFlip, RandomRotation, RandomZoom, and understanding when augmentation helps

Model Evaluation

Confusion matrix interpretation, precision/recall/F1 metrics, identifying misclassification patterns

08

Pro Tips

Model Architecture
  • Start simple - add complexity only if needed
  • Use GlobalAveragePooling2D over Flatten
  • Place Dropout AFTER Dense layers, not Conv layers
  • BatchNorm goes before or after activation (be consistent)
Transfer Learning
  • Always freeze base model first, train head
  • Use 10-100x lower learning rate for fine-tuning
  • Unfreeze only top layers (last 20-30)
  • Use the model's own preprocessing function
Training Tips
  • Use callbacks - don't manually stop training
  • Monitor validation loss, not training loss
  • If overfitting: add more augmentation/dropout
  • If underfitting: increase model capacity
Common Mistakes
  • Forgetting to set training=False for inference
  • Not normalizing images (use Rescaling or preprocess_input)
  • Evaluating on training data instead of test data
  • High learning rate destroying pretrained weights
09

Pre-Submission Checklist

Code Requirements
Repository Requirements