Deep Learning  ·  Computer Vision  ·  OCR

Bengali Handwritten
Character Recognition

A custom SE-ResNet CNN that reads handwritten Bengali characters
with 95% validation accuracy across 84 character classes.

0 Classes
0K+ Images
0% Val Accuracy
0% Test Accuracy

What is this project?

🔤

The Problem

Bengali is spoken by 230M+ people worldwide. Digitizing handwritten Bengali text automatically is extremely challenging due to the complexity of 84 unique character classes including vowels, consonants, digits, and compound characters.

🧠

The Solution

A custom SE-ResNet architecture with Depthwise Separable Convolutions and Squeeze-and-Excitation blocks, trained on 166K+ labeled images with advanced augmentation including Cutout regularization.

🚀

The Result

95% validation accuracy and 90% test accuracy across all 84 classes. The trained model is publicly available for download via GitHub Releases. A web-based demo is in progress.

BanglaLekha-Isolated

BanglaLekha dataset samples
Unprocessed samples from BanglaLekha-Isolated Dataset
166,105 Total Images
84 Classes
~2,000 Samples / Class
32×32 Image Size (px)
Category Count Description
Digits 10 Numerals 0 through 9
Characters 50 Vowels and consonants
Compound 24 Conjunct characters

Dataset Split

Train 70%
Val 10%
Test 20%

SE-ResNet with Depthwise Separable Conv

📥
Input
32×32×1 Grayscale
↓
🔲
Stem
Conv2D(32) → BN → ReLU
↓
📦
Stage 1
2× SE-Residual Block
64 filters · stride 2
↓
📦
Stage 2
3× SE-Residual Block
128 filters · stride 2
↓
📦
Stage 3
2× SE-Residual Block
256 filters · stride 2
↓
🧠
Head
GAP → Dense(256) → Softmax(84)
↓
✅
Output
84-class prediction

SE-Residual Block

Each block uses Depthwise Separable Convolutions (more efficient than standard Conv2D) combined with a Squeeze-and-Excitation (SE) attention mechanism that recalibrates channel-wise feature responses.

x → Conv2D(1×1)           # pointwise expand
  → DepthwiseConv2D(3×3)  # spatial filter
  → Conv2D(1×1)           # pointwise compress
  → BatchNorm → ReLU
  → SE Block (ratio=16)   # channel attention
  → Add(skip connection)  # residual

Training Configuration

OptimizerAdam
Learning Rate1e-3
Batch Size128
Epochs50 max
LossSparseCategoricalCE
ES Patience8 epochs
Min LR1e-7
LR Factor0.5

Data Augmentation

Rotation ±10°
Width / Height shift 10%
Zoom range 10%
Shear 0.08
Custom Cutout — masks 8×8 patch (50% probability)
Class-index numeric sort fix (critical bug fix)

Training & Evaluation

95%Val Acc
90%Test Acc
~0.2Val Loss
99%+Confidence

Accuracy Curve

Train Validation
Model Accuracy Curve

Loss Curve

Train Validation
Model Loss Curve

Confusion Matrix — 84 Classes

Strong diagonal dominance · Minimal inter-class confusion
Confusion Matrix

Sample Predictions

Bengali character predictions
99.94%
99.99%
100%
99.39%

How the predictor works

  1. 1Load grayscale image (any size)
  2. 2Resize to 32×32 pixels
  3. 3Normalize pixels to [0, 1]
  4. 4Reshape to (1, 32, 32, 1)
  5. 5Run through SE-ResNet model
  6. 6Softmax → top class + confidence

Quick Start

import tensorflow as tf
import numpy as np
from PIL import Image

model = tf.keras.models.load_model(
  "final_bangla_cnn_model.keras"
)

img = Image.open("char.png")\
           .convert("L")\
           .resize((32, 32))

x = np.array(img) / 255.0
x = x.reshape(1, 32, 32, 1)

pred = model.predict(x)
cls  = np.argmax(pred)
conf = np.max(pred) * 100

print(f"Class: {cls}  Conf: {conf:.2f}%")

Project in VS Code

Project in VS Code

Built With

🐍

Python 3

Core language

🔶

TensorFlow

Deep learning framework

🧠

Keras

Model API (Functional)

🔢

NumPy

Array operations

📊

Matplotlib

Training visualization

🎨

Seaborn

Confusion matrix plot

🖼️

Pillow

Image preprocessing

⚡

Kaggle GPU

T4 x2 training

Explore the full project

Source code, trained model, and notebook all publicly available