DEEP LEARNING • LESSON 15

Complete Project Code

Now we combine everything we learned in this project into one complete deep learning program. The model will learn to recognize handwritten digits from the MNIST dataset.

PROJECT GOAL

Build a neural network that recognizes handwritten digits.

We will load the MNIST dataset, prepare the images, build and train a neural network, evaluate its accuracy, make predictions, and finally save the trained model.

01

The Complete Project

Here is the complete Python program. Read it once from top to bottom before looking at each individual section.

import tensorflow as tf
import numpy as np


# ==========================================
# 1. LOAD DATASET
# ==========================================

(x_train, y_train), (x_test, y_test) = \
    tf.keras.datasets.mnist.load_data()


# ==========================================
# 2. PREPARE THE DATA
# ==========================================

x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0


# ==========================================
# 3. BUILD THE NEURAL NETWORK
# ==========================================

model = tf.keras.Sequential([

    tf.keras.layers.Input(
        shape=(28, 28)
    ),

    tf.keras.layers.Flatten(),

    tf.keras.layers.Dense(
        128,
        activation="relu"
    ),

    tf.keras.layers.Dropout(0.2),

    tf.keras.layers.Dense(
        64,
        activation="relu"
    ),

    tf.keras.layers.Dense(
        10,
        activation="softmax"
    )
])


# ==========================================
# 4. COMPILE THE MODEL
# ==========================================

model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"]
)


# ==========================================
# 5. TRAIN THE MODEL
# ==========================================

model.fit(
    x_train,
    y_train,
    epochs=5,
    batch_size=32,
    validation_split=0.1
)


# ==========================================
# 6. EVALUATE THE MODEL
# ==========================================

test_loss, test_accuracy = model.evaluate(
    x_test,
    y_test
)

print(
    f"Test Accuracy: {test_accuracy * 100:.2f}%"
)


# ==========================================
# 7. MAKE A PREDICTION
# ==========================================

image = x_test[0]

prediction = model.predict(
    np.expand_dims(image, axis=0)
)

predicted_digit = np.argmax(
    prediction[0]
)

confidence = np.max(
    prediction[0]
)

actual_digit = y_test[0]

print("Actual:", actual_digit)
print("Predicted:", predicted_digit)
print(
    f"Confidence: {confidence * 100:.2f}%"
)


# ==========================================
# 8. SAVE THE MODEL
# ==========================================

model.save("mnist_digit_model.keras")

print("Model saved successfully.")
02

Step 1 — Load the Dataset

(x_train, y_train), (x_test, y_test) = \
    tf.keras.datasets.mnist.load_data()

MNIST contains handwritten digit images from 0 to 9. Each image is 28 × 28 pixels.

Training data
60,000 images
       ↓
Used to learn


Test data
10,000 images
       ↓
Used to evaluate

The model should not learn from the test data. Otherwise, the test result would not be a fair measurement of how well the model handles unseen data.

03

Step 2 — Prepare the Data

x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0

Image pixels normally have values from 0 to 255. We convert them into values between 0 and 1.

Original:

0
50
100
150
200
255


After normalization:

0.00
0.20
0.39
0.59
0.78
1.00

This makes the numerical values easier for the neural network to work with.

04

Step 3 — Build the Neural Network

model = tf.keras.Sequential([

    tf.keras.layers.Input(
        shape=(28, 28)
    ),

    tf.keras.layers.Flatten(),

    tf.keras.layers.Dense(
        128,
        activation="relu"
    ),

    tf.keras.layers.Dropout(0.2),

    tf.keras.layers.Dense(
        64,
        activation="relu"
    ),

    tf.keras.layers.Dense(
        10,
        activation="softmax"
    )
])

The network receives a 28 × 28 image and eventually produces 10 output values — one for each digit from 0 to 9.

28 × 28 Image
      ↓
   Flatten
      ↓
   128 neurons
      ↓
   Dropout
      ↓
    64 neurons
      ↓
   10 outputs
      ↓
0 1 2 3 4 5 6 7 8 9
05

Step 4 — Compile the Model

model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"]
)

Compilation tells Keras how the model should learn and how its performance should be measured.

optimizer
    ↓
How the weights are updated


loss
    ↓
How prediction errors are measured


accuracy
    ↓
How many predictions are correct
06

Step 5 — Train the Model

model.fit(
    x_train,
    y_train,
    epochs=5,
    batch_size=32,
    validation_split=0.1
)

During training, the network sees the training images, makes predictions, calculates errors, and updates its weights.

Image
  ↓
Prediction
  ↓
Calculate Error
  ↓
Update Weights
  ↓
Next Image
  ↓
Repeat

An epoch means one complete pass through the training portion of the dataset.

07

Step 6 — Evaluate the Model

test_loss, test_accuracy = model.evaluate(
    x_test,
    y_test
)

print(
    f"Test Accuracy: {test_accuracy * 100:.2f}%"
)

The test dataset contains images the model did not use during training.

For example, the output might look like:

Test Accuracy: 97.50%

That means the model correctly classified roughly 97.5% of the test examples.

08

Step 7 — Make a Prediction

image = x_test[0]

prediction = model.predict(
    np.expand_dims(image, axis=0)
)

predicted_digit = np.argmax(
    prediction[0]
)

We take one test image and send it through the trained model.

Image
  ↓
model.predict()
  ↓
10 probabilities
  ↓
np.argmax()
  ↓
Predicted digit

For example:

Probabilities:

0 → 0.01
1 → 0.01
2 → 0.02
3 → 0.01
4 → 0.01
5 → 0.02
6 → 0.01
7 → 0.89
8 → 0.01
9 → 0.01

Highest probability = 7

Prediction = 7
09

Step 8 — Check the Prediction

confidence = np.max(
    prediction[0]
)

actual_digit = y_test[0]

print("Actual:", actual_digit)
print("Predicted:", predicted_digit)

print(
    f"Confidence: {confidence * 100:.2f}%"
)

Example:

Actual: 7
Predicted: 7
Confidence: 89.00%

Here the model predicted the correct digit.

10

Step 9 — Save the Model

model.save("mnist_digit_model.keras")

Saving the model means we do not have to train it from scratch every time we want to use it.

Train Model
     ↓
Save Model
     ↓
mnist_digit_model.keras
     ↓
Load Later
     ↓
Make Predictions

Later, we can load it using:

model = tf.keras.models.load_model(
    "mnist_digit_model.keras"
)
11

The Whole Project in Simple Words

1. Get images
       ↓
2. Clean and normalize images
       ↓
3. Create neural network
       ↓
4. Tell the network how to learn
       ↓
5. Train it with examples
       ↓
6. Test it with unseen examples
       ↓
7. Give it a new image
       ↓
8. Get its prediction
       ↓
9. Save the trained model
12

Complete Example

Imagine you show the trained model this handwritten digit:

        ████
       ██
       ████
          ██
       ████

        "7"

The model does not actually see the character as the number 7. It sees pixel values.

Pixel Values
     ↓
Neural Network
     ↓
Learned Patterns
     ↓
Output Probabilities
     ↓
Highest Probability
     ↓
7

This is the important idea behind image classification: the neural network learns patterns from examples instead of us manually writing rules for every possible image.

13

Why This Is a Real Deep Learning Project

This is not just a neural-network example. It contains the major steps used in a real machine learning workflow.

Data
 ↓
Preprocessing
 ↓
Model
 ↓
Training
 ↓
Validation
 ↓
Testing
 ↓
Prediction
 ↓
Deployment / Usage

Real projects are more complicated because the data, model architecture, evaluation metrics, and deployment requirements are different. But the basic workflow is built from the same ideas.

14

Important Things to Remember

Training data
→ teaches the model


Validation data
→ helps monitor training


Test data
→ measures performance on unseen data


model.fit()
→ trains


model.evaluate()
→ evaluates


model.predict()
→ predicts


model.save()
→ saves the trained model
KEY TAKEAWAY

A deep learning project is a complete pipeline, not just a neural network.

We start with data, prepare it, build a model, train it, evaluate it, improve it, make predictions, and save the final model. Understanding this complete workflow is more important than memorizing individual lines of code.

Quick Check

What is the purpose of training data?

Training data is used by the neural network to learn patterns and update its weights.

Why do we keep test data separate?

To measure how well the trained model performs on data it did not use for learning.

What happens during prediction?

New input is passed through the trained model and the model produces an output.