Deep Learning Project – Handwritten Digit Recognition using ANN

Machine Learning courses with 100+ Real-time projects Start Now!!

Program 1

Handwritten Digit Recognition with ANN

To build a machine learning model using an Artificial Neural Network (ANN) that can accurately classify handwritten digits (0–9) from grayscale images of size 28×28 pixels.

Dataset : MNIST  (60 000 train images / 10 000 test images)
Goal    : Classify digits 0–9 from 28×28 grayscale images
Model   : Simple feed-forward neural network (Dense layers)

# 1. Imports
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout
from tensorflow.keras.utils import to_categorical
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns`

# 2. Load the MNIST data
# X_train: 60,000 training images
# y_train: their correct labels
# X_test: 10,000 test images
# y_test: their labels
(X_train, y_train), (X_test, y_test) = mnist.load_data()   # shape (60000, 28, 28), (10000, 28, 28)
len(X_test)

# 3. Normalise pixel values (0-255 ➜ 0-1)
# Each pixel value is between 0 and 255.
# We scale them to 0–1 range, which makes training easier.

X_train = X_train.astype("float32") / 255.0
X_test  = X_test.astype("float32")  / 255.0
y_train

# 4. Convert labels to one-hot vectors
 #Converts labels (0–9) into 10-element vectors for softmax.
# Instead of labels like 3 or 9, we convert them to vectors like:
# Label 3 → [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
# This is needed for multi-class classification.

num_classes = 10
y_train_cat = to_categorical(y_train, num_classes)
y_test_cat  = to_categorical(y_test,  num_classes)
y_test_cat

# 5. Build the ANN model
# Flatten: Converts 28×28 image into a long row (784 pixels).
# Dense(256): First layer with 256 neurons → learns patterns.
# Dense(128): Second layer with 64 neurons → deeper learning.
# Dense(10): Output layer with 10 neurons (for 10 classes).
# softmax helps pick the best class.

model = Sequential([
    Flatten(input_shape=(28, 28)),      # 28×28 ➜ 784-vector
    Dense(256, activation="relu"),
    Dropout(0.3),
    Dense(128, activation="relu"),
    Dropout(0.3),
    Dense(num_classes, activation="softmax")   # 10 output neurons
])

# 6. Compile the model
model.compile(
    optimizer="adam",
    loss="categorical_crossentropy",
    metrics=["accuracy"]
)
model.summary()

# 7. Train the model
history = model.fit(
    X_train, y_train_cat,
    epochs=15,
    batch_size=128,
    validation_split=0.1,
    verbose=1
)

# 8. Evaluate on the test set
test_loss, test_acc = model.evaluate(X_test, y_test_cat, verbose=0)
print(f"\nTest accuracy: {test_acc*100:.2f}%")

# 9. Generate predictions
y_pred_probs = model.predict(X_test)
y_pred = np.argmax(y_pred_probs, axis=1)

print("\nClassification Report:")
print(classification_report(y_test, y_pred))

# 10. Confusion matrix
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8,6))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues")
plt.title("MNIST Confusion Matrix")
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.tight_layout()
plt.show()

# 11. Display a handful of predictions
plt.figure(figsize=(10,4))
for i in range(10):
    idx = np.random.randint(0, len(X_test))
    img = X_test[idx]
    true_digit = y_test[idx]
    pred_digit = y_pred[idx]
    color = "green" if true_digit == pred_digit else "red"

    plt.subplot(2, 5, i+1)
    plt.imshow(img, cmap="gray")
    plt.title(f"T:{true_digit} P:{pred_digit}", color=color, fontsize=10)
    plt.axis("off")

plt.tight_layout()
plt.show()

 

Your opinion matters
Please write your valuable feedback about DataFlair on Google

courses

DataFlair Team

DataFlair Team provides high-impact content on programming, Java, Python, C++, DSA, AI, ML, data Science, Android, Flutter, MERN, Web Development, and technology. We make complex concepts easy to grasp, helping learners of all levels succeed in their tech careers.

Leave a Reply

Your email address will not be published. Required fields are marked *