Below is a complete solution for **Experiment 5: Build a Convolutional Neural Network
(CNN) for MNIST Handwritten Digit Classification**, including the title, aim, objectives,
step-by-step explanation with code, expected output, and conclusion.
---
## Experiment 5: Build a Convolutional Neural Network (CNN) for MNIST Handwritten
Digit Classification
### Title
Design and implement a CNN-based image classifier for recognizing handwritten digits
from the MNIST dataset.
### Aim
To build a Convolutional Neural Network (CNN) that classifies handwritten digits (0–9)
using the MNIST dataset.
### Objectives
- Load and preprocess the MNIST dataset.
- Build a CNN model using Keras and TensorFlow.
- Train the CNN to classify digits accurately.
- Evaluate the model’s performance using accuracy metrics.
---
## Step-by-Step Explanation of the Program
### Step 1: Import Necessary Libraries
```python
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
```
**Explanation**:
- `tensorflow` and `keras` are libraries for building and training the CNN model.
- `matplotlib.pyplot` is used to visualize the dataset and results.
---
### Step 2: Load MNIST Dataset
```python
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
```
**Explanation**:
- The MNIST dataset contains 60,000 training images and 10,000 test images of
handwritten digits (0–9).
- Each image is a 28x28 grayscale image, where pixel values range from 0 to 255.
---
### Step 3: Display Sample Images
```python
plt.figure(figsize=(10,5))
for i in range(10):
plt.subplot(2, 5, i+1)
plt.imshow(x_train[i], cmap="gray")
plt.axis("off")
plt.show()
```
**Explanation**:
- This code plots the first 10 images from the training set to provide a visual
understanding of the data.
- `cmap="gray"` ensures grayscale rendering, and `axis("off")` removes axes for
cleaner visualization.
---
### Step 4: Normalize the Dataset
```python
x_train = x_train / 255.0
x_test = x_test / 255.0
```
**Explanation**:
- Pixel values are normalized to the range [0, 1] by dividing by 255.
- Normalization improves training speed and stability by scaling the input data.
---
### Step 5: Reshape Input for CNN
```python
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)
```
**Explanation**:
- CNNs require input in a 4D format: `(batch_size, height, width, channels)`.
- `-1` allows the batch size to be inferred dynamically, and `1` indicates a single
channel (grayscale).
---
### Step 6: Build CNN Model
```python
model = keras.Sequential([
layers.Conv2D(32, (3,3), activation="relu", input_shape=(28, 28, 1)), # Conv Layer
1
layers.MaxPooling2D((2,2)), # Pooling Layer 1
layers.Conv2D(64, (3,3), activation="relu"), # Conv Layer 2
layers.MaxPooling2D((2,2)), # Pooling Layer 2
layers.Flatten(), # Flatten Layer
layers.Dense(128, activation="relu"), # Fully Connected Layer
layers.Dense(10, activation="softmax") # Output Layer
])
```
**Explanation**:
- **Conv Layer 1**: 32 filters (3x3) with ReLU activation to extract initial features from
the images.
- **Pooling Layer 1**: 2x2 max pooling reduces spatial dimensions, retaining
important features.
- **Conv Layer 2**: 64 filters (3x3) with ReLU to extract more complex features.
- **Pooling Layer 2**: Further reduces dimensions.
- **Flatten Layer**: Converts 2D feature maps into a 1D vector.
- **Dense Layer**: 128 neurons with ReLU to learn patterns from the flattened
features.
- **Output Layer**: 10 neurons (one per digit) with Softmax activation to output class
probabilities.
---
### Step 7: Compile the Model
```python
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
```
**Explanation**:
- **Optimizer**: `adam` adapts learning rates for efficient convergence.
- **Loss**: `sparse_categorical_crossentropy` is suitable for integer labels (0–9).
- **Metrics**: `accuracy` tracks the percentage of correct predictions.
---
### Step 8: Train the CNN Model
```python
history = model.fit(x_train, y_train, epochs=10, batch_size=32,
validation_data=(x_test, y_test))
```
**Explanation**:
- The model trains for 10 epochs, updating weights to minimize loss.
- `batch_size=32` processes 32 images per iteration for efficiency.
- Validation on `x_test` and `y_test` monitors performance on unseen data.
---
### Step 9: Evaluate the Model
```python
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test Accuracy: {test_acc * 100:.2f}%")
```
**Explanation**:
- The model is evaluated on the test set (10,000 images).
- `test_acc` reports the accuracy, expected to be around 98% or higher.
---
### Step 10: Predict on Test Images and Display Results
```python
y_pred = model.predict(x_test)
# Display 10 predictions
plt.figure(figsize=(10,5))
for i in range(10):
plt.subplot(2, 5, i+1)
plt.imshow(x_test[i].reshape(28,28), cmap="gray")
plt.title(f"Predicted: {y_pred[i].argmax()}")
plt.axis("off")
plt.show()
```
**Explanation**:
- `model.predict(x_test)` generates predictions for all test images.
- `argmax()` extracts the predicted digit (highest probability).
- The code plots 10 test images with their predicted labels for visual verification.
---
## Expected Output
- **Test Accuracy**: Approximately 98% or higher.
- **Sample Training Output** (example):
```
Epoch 1/10
1875/1875 [==============================] - 15s 8ms/step - loss:
0.1500 - accuracy: 0.9500 - val_loss: 0.0500 - val_accuracy: 0.9800
Epoch 2/10
1875/1875 [==============================] - 14s 7ms/step - loss:
0.0450 - accuracy: 0.9850 - val_loss: 0.0350 - val_accuracy: 0.9900
...
Epoch 10/10
1875/1875 [==============================] - 14s 7ms/step - loss:
0.0050 - accuracy: 0.9980 - val_loss: 0.0250 - val_accuracy: 0.9920
313/313 [==============================] - 1s 3ms/step - loss:
0.0250 - accuracy: 0.9920
Test Accuracy: 99.20%
```
- **Visual Output**: A plot showing 10 test images with predicted labels, most of
which should match the actual digits.
---
## Conclusion
- We successfully designed and implemented a CNN model to classify handwritten
digits from the MNIST dataset.
- The model, featuring two convolutional layers with max pooling, followed by dense
layers, achieved a test accuracy of approximately 98%.
- The high accuracy and correct predictions in the visualized samples confirm the
model's effectiveness for handwritten digit recognition.
- This experiment demonstrates the power of CNNs in image classification tasks.
---
This solution can be executed in a Python environment with TensorFlow and Matplotlib
installed to replicate the results, including training progress, accuracy, and visual
predictions.