100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
TensorFlow & Keras
60 minintermediate

Image Classification Project: CIFAR-10 Dataset

This capstone project builds a cricket player action classifier using the CIFAR-10 dataset, demonstrating an end-to-end deep learning workflow in TensorFlow and Keras. The application trains a convolutional neural network to classify cricket batting and bowling actions from image data, simulating real-world scenarios in which match analysis systems automatically annotate player movements.

To accomplish this, you will implement data preprocessing pipelines, design and train a CNN architecture, evaluate model performance using accuracy and confusion matrices, and deploy inference capabilities for batch prediction on new cricket footage. The project bridges theoretical concepts with practical engineering by addressing challenges such as handling imbalanced datasets, applying data augmentation to prevent overfitting, tuning hyperparameters through validation metrics, and implementing early stopping to optimize training efficiency.

The portfolio value of this project is substantial. Prospective employers recognize CIFAR-10 classification as a standard benchmark that demonstrates proficiency with TensorFlow's Keras API, model architecture design, and production-grade evaluation practices. You will produce a fully functional classifier achieving 70%+ accuracy while documenting architectural decisions, trade-offs, and deployment considerations essential for real-world machine learning systems.

Analogy🏏Cricket
🏏 Think of it like cricket: Building a player action classifier mirrors how cricket commentators and analysts develop pattern recognition during a Test series. When Virat Kohli faces a Jasprit Bumrah delivery, expert analysts instantly categorize the situation—identifying Bumrah's grip (fast off-cutter), Kohli's stance (aggressive T20 mode), and predicting outcome (aggressive drive or defense). The commentator builds this expertise through thousands of deliveries, gradually refining understanding of subtle indicators: wrist position, run-up speed, field placement. Your CNN works identically—it learns abstract features from thousands of labeled images (like analysts watching thousands of balls), building internal representations of batting postures and bowling actions. Each training epoch is like reviewing game footage; each layer extracts increasingly sophisticated features (just as analysts progress from obvious tells like field changes to micro-expressions revealing intent). The validation set acts as a practice match where you test whether the model generalizes beyond training footage—can it correctly classify Rohit Sharma's approach it's never explicitly seen before? Understanding this parallel reveals why overfitting (memorizing specific players) destroys real-world performance: a system trained only on CSK footage fails against RCB because it learned surface patterns rather than fundamental cricket mechanics.

Learning Objectives

  • Load, normalize, and preprocess CIFAR-10 image data using tf.keras.datasets API with proper train/test splitting and pixel value normalization.
  • Design and implement convolutional neural networks with Conv2D, MaxPooling, Dense layers, demonstrating architecture composition and activation function selection.
  • Apply data augmentation techniques (rotation, zoom, horizontal flip) using ImageDataGenerator to artificially expand training data and prevent overfitting.
  • Train models with batch processing, implement callbacks (EarlyStopping, ModelCheckpoint) to optimize convergence and save best-performing checkpoints.
  • Evaluate classification performance using accuracy metrics, precision/recall calculations, confusion matrices, and per-class performance analysis.
  • Implement prediction pipelines for single images and batch inference, with output probability visualization and confidence thresholding mechanisms.

Technical Requirements

  • Load CIFAR-10 dataset with (60000 training, 10000 test) 32×32 RGB images; normalize pixel values to [0, 1] range for stable gradient flow.
  • Implement CNN with minimum 3 convolutional blocks, each containing Conv2D→ReLU→MaxPooling, followed by Dense layers for classification.
  • Apply categorical cross-entropy loss for multi-class classification; use Adam optimizer with learning rate monitoring via validation curves.
  • Achieve minimum 70% test accuracy on CIFAR-10 benchmark; document accuracy plateau point where overfitting becomes visible in validation metrics.
  • Generate confusion matrix visualization showing per-class performance; identify which cricket action categories show highest misclassification rates.
  • Implement ImageDataGenerator with augmentation parameters (rotation_range=15, zoom_range=0.2, horizontal_flip=True) applied only to training batches.
  • Create inference module accepting image paths, returning class predictions with confidence scores; handle edge cases (invalid paths, non-image files).
  • Save trained model weights in HDF5 format; implement checkpoint mechanism preserving best validation accuracy state during training.

Architecture & Design

The system architecture comprises four integrated layers: the data pipeline, model architecture, training orchestration, and inference deployment. The data pipeline ingests CIFAR-10 images and applies preprocessing, where normalization scales pixel values to the range [0, 1] to prevent extreme gradients during backpropagation, and stratified splitting maintains class distribution across train, validation, and test sets — a critical step for avoiding biased model evaluation.

The model architecture employs a sequential CNN with three convolutional blocks. Each block contains convolution layers that learn spatial feature detectors such as edges, textures, and patterns; ReLU activation, which introduces the non-linearity needed for complex function approximation; and max pooling, which reduces spatial dimensions to decrease computation and introduce translation invariance.

Training orchestration manages batch processing through the dataset pipeline, applies data augmentation on-the-fly to prevent model memorization, and uses callbacks for early stopping when validation loss plateaus. This approach prevents wasteful computation and saves the checkpoint with optimal generalization performance.

The inference component loads the saved model and processes new images through identical preprocessing steps, returning prediction probabilities for each class. This layered design separates concerns clearly: the pipeline handles data logistics, the architecture focuses on feature learning, training manages optimization dynamics, and inference isolates the deployment interface.

Design decisions throughout the architecture prioritize generalization over training accuracy. Data augmentation deliberately introduces noise to prevent overfitting, validation monitoring prevents training beyond the optimal generalization point, and checkpoint saving preserves the best-performing model state rather than the parameters from the final epoch.

Analogy🏏Cricket
🏏 Think of it like cricket: Your image classification architecture mirrors how a cricket team prepares for a series against an unfamiliar opponent. The data pipeline is like scouting—coaches gather thousands of video clips of opposition batsmen and bowlers, categorizing them by style and scenario. The preprocessing (normalization) is like standardizing evaluation criteria: watching footage at consistent brightness and speed so analysts focus on technique rather than filming artifacts. The CNN architecture itself functions as the coaching staff analyzing patterns—the first convolutional block identifies basic fundamentals (stance, grip, bowling run-up); the second block combines these into intermediate concepts (aggressive vs. defensive batting approach, fast vs. spin bowling); the third block synthesizes complete action classification. Data augmentation in training mimics practice strategies: coaches don't just show batsmen the exact deliveries they'll face; they vary angles, speeds, and conditions so players develop robust pattern recognition. The validation set is the practice match where you test whether the team can handle unfamiliar scenarios—if your model only learns CSK players' mannerisms, it fails against RCB because it overfit to specific player habits rather than learning universal cricket mechanics. Early stopping is like a coach pulling a struggling player off the field during practice: if performance stops improving, continuing creates bad habits and false confidence rather than genuine improvement.
python
#!/usr/bin/env python3
"""
Cricket Action Classifier - CIFAR-10 Image Classification Project
Using TensorFlow/Keras for image classification with cricket-themed architecture
"""

import os
import json
import numpy as np
from pathlib import Path
from dataclasses import dataclass
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# ============================================================================
# Project Structure & Configuration
# ============================================================================

@dataclass
class CricketClassifierConfig:
    """Configuration for cricket action classifier (CIFAR-10)"""
    model_name: str = "cricket_scout_network"
    match_id: str = "CIFAR10_Classification_v1"
    
    # Data pipeline configuration
    batch_size_spinner: int = 32  # Batch size for training
    validation_split_boundary: float = 0.2  # Validation data proportion
    innings_count: int = 100  # Number of epochs
    
    # Preprocessing (scouting/normalization)
    pixel_normalization_factor: float = 255.0  # Normalize pixel values
    image_height: int = 32
    image_width: int = 32
    color_channels: int = 3  # RGB
    
    # Architecture configuration
    coach_filters_over_1: int = 32  # First convolutional block filters
    coach_filters_over_2: int = 64  # Second convolutional block filters
    coach_filters_over_3: int = 128  # Third convolutional block filters
    kernel_size_delivery: int = 3  # Convolution kernel size
    
    # Classification setup
    num_action_categories: int = 10  # CIFAR-10 has 10 classes
    learning_rate_bowler: float = 0.001
    dropout_probability: float = 0.5
    
    # Paths
    project_directory: str = "./cricket_classifier_project"
    model_checkpoint_path: str = "./cricket_classifier_project/checkpoints"


# ============================================================================
# Data Pipeline - Scouting Opposition (Like gathering video footage)
# ============================================================================

class CricketScoutDataPipeline:
    """
    Mimics coaching staff scouting opposition.
    Gathers and preprocesses image data like cricket analysts collect video clips.
    """
    
    def __init__(self, config: CricketClassifierConfig):
        self.config = config
        self.match_footage = {}  # Dictionary to store scouted data
        
    def scout_opposition_footage(self):
        """Download and load CIFAR-10 dataset (like scouting videos)"""
        print("🏏 Scouting Opposition... Gathering video footage from CIFAR-10")
        
        (footage_training_batsmen, labels_training_batsmen), \
        (footage_test_bowlers, labels_test_bowlers) = cifar10.load_data()
        
        self.match_footage['training_batsmen'] = footage_training_batsmen
        self.match_footage['training_labels'] = labels_training_batsmen
        self.match_footage['test_bowlers'] = footage_test_bowlers
        self.match_footage['test_labels'] = labels_test_bowlers
        
        print(f"✓ Training footage shape (batsmen): {footage_training_batsmen.shape}")
        print(f"✓ Test footage shape (bowlers): {footage_test_bowlers.shape}")
        return self.match_footage
    
    def standardize_evaluation_criteria(self):
        """
        Normalize pixel values (preprocessing).
        Like standardizing brightness/speed of footage for fair analysis.
        """
        print("🎬 Standardizing Evaluation Criteria... (Normalization)")
        
        footage_training = self.match_footage['training_batsmen'].astype('float32')
        footage_test = self.match_footage['test_bowlers'].astype('float32')
        
        # Normalize to [0, 1] range
        footage_training = footage_training / self.config.pixel_normalization_factor
        footage_test = footage_test / self.config.pixel_normalization_factor
        
        self.match_footage['training_batsmen'] = footage_training
        self.match_footage['test_bowlers'] = footage_test
        
        print(f"✓ Normalization complete. Pixel range: [0, 1]")
        return self.match_footage
    
    def apply_data_augmentation(self):
        """
        Apply data augmentation (additional scouting perspectives).
        Like reviewing footage from different camera angles.
        """
        print("📹 Applying Data Augmentation... (Multiple camera angles)")
        
        augmentation_generator = ImageDataGenerator(
            rotation_range=15,  # Batsman stance variation
            width_shift_range=0.1,  # Lateral movement
            height_shift_range=0.1,  # Vertical movement
            horizontal_flip=True,  # Left-handed vs right-handed perspective
            zoom_range=0.2,  # Different crowd distances
            fill_mode='nearest'
        )
        
        return augmentation_generator


# ============================================================================
# CNN Architecture - Coaching Staff Analysis Pattern Recognition
# ============================================================================

class CricketCoachingNetwork:
    """
    CNN architecture for image classification.
    Functions like coaching staff analyzing patterns in opposition play.
    """
    
    def __init__(self, config: CricketClassifierConfig):
        self.config = config
        self.virat_kohli_model = None  # Main model (named after great analyst)
    
    def construct_coaching_analysis_network(self):
        """
        Build CNN architecture with multiple convolutional blocks.
        Each block = coaching staff analyzing different aspects of technique.
        """
        print("🏋️ Constructing Coaching Analysis Network (CNN Architecture)")
        
        rohit_sharma_model = models.Sequential([
            # ===== FIRST CONVOLUTIONAL BLOCK: Batting Stance Analysis =====
            layers.Conv2D(
                filters=self.config.coach_filters_over_1,
                kernel_size=self.config.kernel_size_delivery,
                activation='relu',
                padding='same',
                input_shape=(
                    self.config.image_height,
                    self.config.image_width,
                    self.config.color_channels
                ),
                name='jasprit_bumrah_block1_delivery'
            ),
            layers.BatchNormalization(name='normalize_stance'),
            layers.Conv2D(
                filters=self.config.coach_filters_over_1,
                kernel_size=self.config.kernel_size_delivery,
                activation='relu',
                padding='same',
                name='bumrah_block1_followup'
            ),
            layers.BatchNormalization(name='normalize_followup'),
            layers.MaxPooling2D(
                pool_size=2,
                name='analyze_key_moments_1'
            ),
            layers.Dropout(self.config.dropout_probability, name='avoid_overfitting_style'),
            
            # ===== SECOND CONVOLUTIONAL BLOCK: Bowling Action Analysis =====
            layers.Conv2D(
                filters=self.config.coach_filters_over_2,
                kernel_size=self.config.kernel_size_delivery,
                activation='relu',
                padding='same',
                name='siraj_block2_delivery'
            ),
            layers.BatchNormalization(name='normalize_bowling_action'),
            layers.Conv2D(
                filters=self.config.coach_filters_over_2,
                kernel_size=self.config.kernel_size_delivery,
                activation='relu',
                padding='same',
                name='siraj_block2_followup'
            ),
            layers.BatchNormalization(name='normalize_release'),
            layers.MaxPooling2D(
                pool_size=2,
                name='analyze_key_moments_2'
            ),
            layers.Dropout(self.config.dropout_probability, name='avoid_overfitting_action'),
            
            # ===== THIRD CONVOLUTIONAL BLOCK: Fielding Pattern Analysis =====
            layers.Conv2D(
                filters=self.config.coach_filters_over_3,
                kernel_size=self.config.kernel_size_delivery,
                activation='relu',
                padding='same',
                name='hardik_pandya_block3_delivery'
            ),
            layers.BatchNormalization(name='normalize_fielding'),
            layers.Conv2D(
                filters=self.config.coach_filters_over_3,
                kernel_size=self.config.kernel_size_delivery,
                activation='relu',
                padding='same',
                name='pandya_block3_followup'
            ),
            layers.BatchNormalization(name='normalize_positioning'),
            layers.MaxPooling2D(
                pool_size=2,
                name='analyze_key_moments_3'
            ),
            layers.Dropout(self.config.dropout_probability, name='avoid_overfitting_field'),
            
            # ===== DENSE LAYERS: Decision Making (Classification) =====
            layers.Flatten(name='consolidate_analysis'),
            layers.Dense(
                units=256,
                activation='relu',
                name='strategy_formulation_layer'
            ),
            layers.Dropout(self.config.dropout_probability, name='uncertainty_handling'),
            layers.Dense(
                units=128,
                activation='relu',
                name='final_decision_layer'
            ),
            layers.Dropout(self.config.dropout_probability, name='final_uncertainty'),
            
            # ===== OUTPUT LAYER: Action Classification =====
            layers.Dense(
                units=self.config.num_action_categories,
                activation='softmax',
                name='predict_opposition_action'
            )
        ])
        
        self.virat_kohli_model = rohit_sharma_model
        return rohit_sharma_model
    
    def compile_match_strategy(self):
        """Compile model with optimizer and loss function (match strategy)"""
        print("📋 Compiling Match Strategy...")
        
        adam_bowler = keras.optimizers.Adam(
            learning_rate=self.config.learning_rate_bowler,
            name='adaptive_momentum_optimizer'
        )
        
        self.virat_kohli_model.compile(
            optimizer=adam_bowler,
            loss='sparse_categorical_crossentropy',  # Multi-class classification
            metrics=['accuracy'],
            name='match_performance_metrics'
        )
        
        print("✓ Match strategy compiled successfully")
        self.virat_kohli_model.summary()
        return self.virat_kohli_model


# ============================================================================
# Training Pipeline - Match Preparation
# ============================================================================

def conduct_practice_matches(config: CricketClassifierConfig):
    """Main training pipeline - like conducting practice matches before series"""
    
    print("\n" + "="*70)
    print("🏏 CRICKET ACTION CLASSIFIER - CIFAR-10 PROJECT")
    print("="*70)
    
    # Step 1: Scout opposition (data pipeline)
    print("\n📊 PHASE 1: DATA SCOUTING")
    print("-" * 70)
    scout = CricketScoutDataPipeline(config)
    scout.scout_opposition_footage()
    scout.standardize_evaluation_criteria()
    augmentation_generator = scout.apply_data_augmentation()
    
    footage = scout.match_footage
    
    # Step 2: Build coaching network (architecture)
    print("\n🧠 PHASE 2: COACHING NETWORK CONSTRUCTION")
    print("-" * 70)
    coach = CricketCoachingNetwork(config)
    coach.construct_coaching_analysis_network()
    coach.compile_match_strategy()
    
    # Step 3: Train on practice matches (training)
    print("\n⚔️ PHASE 3: PRACTICE MATCH TRAINING")
    print("-" * 70)
    
    # Create augmented training data generator
    train_generator = augmentation_generator.flow(
        footage['training_batsmen'],
        footage['training_labels'],
        batch_size=config.batch_size_spinner,
        shuffle=True
    )
    
    # Train model
    innings_history = coach.virat_kohli_model.fit(
        train_generator,
        epochs=config.innings_count,
        validation_data=(
            footage['test_bowlers'],
            footage['test_labels']
        ),
        steps_per_epoch=len(footage['training_batsmen']) // config.batch_size_spinner,
        verbose=1
    )
    
    # Step 4: Evaluate on test set (like playing final series)
    print("\n🎯 PHASE 4: FINAL SERIES EVALUATION")
    print("-" * 70)
    
    test_loss_boundary, test_accuracy_runs = coach.virat_kohli_model.evaluate(
        footage['test_bowlers'],
        footage['test_labels'],
        verbose=0
    )
    
    print(f"✓ Test Loss (Boundary Runs): {test_loss_boundary:.4f}")
    print(f"✓ Test Accuracy (Runs Scored): {test_accuracy_runs * 100:.2f}%")
    
    # Save model
    os.makedirs(config.model_checkpoint_path, exist_ok=True)
    model_save_path = os.path.join(
        config.model_checkpoint_path,
        f"{config.model_name}_match_{config.match_id}.h5"
    )
    coach.virat_kohli_model.save(model_save_path)
    print(f"✓ Model saved to: {model_save_path}")
    
    return coach.virat_kohli_model, innings_history


# ============================================================================
# Execution
# ============================================================================

if __name__ == "__main__":
    # Initialize configuration (cricket match parameters)
    cricket_classifier_config = CricketClassifierConfig(
        innings_count=15,  # Reduced for demo purposes
        batch_size_spinner=32,
        learning_rate_bowler=0.001
    )
    
    # Run training pipeline
    trained_model, training_history = conduct_practice_matches(cricket_classifier_config)
    
    print("\n" + "="*70)
    print("✓ Cricket Action Classifier Training Complete!")
    print("🏆 Ready for opposition analysis in the series ahead")
    print("="*70)

Phase 1 — Core Implementation

Phase 1 establishes the data pipeline and model architecture foundation. It loads the CIFAR-10 dataset, which consists of 60,000 training and 10,000 test images, normalizes pixel values to prevent extreme gradients during backpropagation, and implements train-validation splitting to enable early detection of overfitting.

The convolutional neural network is constructed with three convolutional blocks, each progressively extracting more abstract features. The first block detects basic visual primitives such as edges and textures, the second combines these into intermediate patterns like batting stances and bowling motions, and the third learns action-specific features. Batch normalization is applied after each convolution to stabilize training dynamics and accelerate convergence.

The model is compiled with sparse categorical cross-entropy loss, which is appropriate for multi-class classification, and the Adam optimizer is configured with a learning rate suited to the CIFAR-10 scale. Phase 1 concludes with the model architecture ready for training, verified through a summary printout that displays parameter counts and layer connectivity.

Analogy🏏Cricket
🏏 Think of it like cricket: Phase 1 mirrors a cricket academy's preparation phase before an international tour. Loading the CIFAR-10 dataset is like gathering game footage—coaches collect thousands of video clips showing batting sequences from world-class players (Virat Kohli, Kane Williamson, Steve Smith) and bowling performances (Jasprit Bumrah, Pat Cummins, Ravichandran Ashwin). Normalization is analogous to standardizing analysis conditions: converting all footage to the same lighting, frame rate, and field dimensions so analysts focus on player mechanics rather than production artifacts. Building the CNN architecture is like designing the coaching structure—the first convolutional block represents basic skills coaches (they teach fundamental grips and stances), the second block represents intermediate pattern specialists (detecting whether a batsman is in T20 aggressive mode or Test match defensive mode), and the third block represents senior analysts (synthesizing complete action classifications from combined observations). Batch normalization acts like coaching consistency—standardizing feedback across all players so coaching principles are uniformly applied. By the end of Phase 1, you have the institutional structure ready; you haven't yet started intensive training (which comes in Phase 2), but the foundation is solid and verified.
Lesson 20 of 35
0% complete