LeNet-5: EMNIST Balanced Character Classifier

This repository hosts a modified LeNet-5 Convolutional Neural Network (CNN) trained specifically on the EMNIST Balanced dataset. It is designed to recognize 47 distinct classes of handwritten characters, including digits (0-9), uppercase letters (A-Z), and a subset of lowercase letters.

Model Performance

While LeNet-5 is a compact architecture, it performs robustly on the expanded EMNIST Balanced dataset:

Metric Score
Validation Accuracy ~88%
Weighted F1-Score 0.8751
Total Classes 47

Dataset Context

The EMNIST Balanced dataset is significantly more challenging than standard MNIST. It contains 131,600 images across 47 classes, designed to account for the inherent overlap in character shapes (e.g., lowercase 'o' vs uppercase 'O').

Architecture & Training Details

The model follows the classic LeNet-5 design with modern enhancements like ReLU activation and Dropout to improve generalization for the 47-class task.

1. Model Summary (LeNet-5 EMNIST Modified)

Layer Output Shape Param #
Conv2D (6 filters, 5ร—5, ReLU) (28, 28, 6) 156
AveragePooling2D (2ร—2) (14, 14, 6) 0
Conv2D (16 filters, 5ร—5, ReLU) (10, 10, 16) 2,416
AveragePooling2D (2ร—2) (5, 5, 16) 0
Flatten 400 0
Dropout (0.2) 400 0
Dense (120 units, ReLU) 120 48,120
Dropout (0.2) 120 0
Dense (84 units, ReLU) 84 10,164
Dense (47 units, Softmax) 47 3,995

Total Trainable Parameters: 64,851

2. Training Strategy

  • Optimizer: Adam
  • Loss Function: Categorical Crossentropy
  • Regularization: Dual Dropout layers (0.2) were added to the fully connected head to prevent overfitting on the complex 47-class distribution.

Usage

To load and use this model locally:

import tensorflow as tf
import numpy as np
import cv2

# Load the model
model = tf.keras.models.load_model('lenet5_emnist_balanced.keras')

def preprocess_char(img_path):
    # EMNIST images are 28x28 grayscale, often rotated/flipped
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    img = cv2.resize(img, (28, 28))
    img = img.astype('float32') / 255.0
    img = np.expand_dims(img, axis=[0, -1]) # Shape: (1, 28, 28, 1)
    return img

# Predict
input_data = preprocess_char('handwritten_sample.png')
prediction = model.predict(input_data)
class_id = np.argmax(prediction)
Downloads last month
69
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Space using Ghostraptor/lenet-5-emnist-balanced 1