Convolutional Neural Network (CNN) model on the MNIST dataset using Keyras

 

The "MNIST" dataset is used in machine learning for handwritten digit recognition. It contains a collection of 28x28 pixel grayscale images of handwritten digits from 0 to 9. The MNIST dataset was created by collecting and preprocessing samples of handwriting from various sources, including US Census Bureau employees and American high school students. The dataset has been widely used to develop and test various machine learning algorithms and models.




The code for this tutorial 

https://github.com/ShilpaSayuraML/DL-course/blob/main/CNN/CNN_with_MNIST.ipynb


https://www.tensorflow.org/datasets/catalog/mnist


import numpy as np

import matplotlib.pyplot as plt

from keras.datasets import mnist


# Load the MNIST dataset

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()


print(train_images[0].shape)

print(train_images[0])


# Display the first 10 images

plt.figure(figsize=(10, 4))

for i in range(10):

    plt.subplot(2, 5, i+1)

    plt.imshow(train_images[i], cmap='gray')

    plt.title(f"Label: {train_labels[i]}")

    plt.axis('off')

 

plt.tight_layout()

plt.show()


This code builds, trains, and evaluates a simple CNN model for the MNIST dataset using Keras. The model architecture consists of convolutional layers followed by pooling layers, flattening, and fully connected layers. Remember that this is a basic example, and there are many ways to optimize and improve the model's performance.

 

Convolutional Neural Network (CNN) model on the MNIST dataset using Keras:


import numpy as np

from keras.datasets import mnist

from keras.utils import to_categorical

from keras.models import Sequential

from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

from sklearn.model_selection import train_test_split


# Load the MNIST dataset

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()


# Preprocess the input data

# before feeding it into the Convolutional Neural Network (CNN):


Reshaping: 

CNNs expect input data to be in a specific format, which includes the number of samples, height, width, and number of channels.


There is only one channel in grayscale images in the  MNIST dataset. It has  no RGB channels.  Therefore the shape is (num_samples, height, width, 1). The reshape function reshapes the original data into this format.


Normalization: Neural networks perform better when the input data is scaled to a smaller range. The pixel values of the images in the MNIST dataset range from 0 to 255, where 0 represents black and 255 represents white. Dividing all the pixel values by 255 scales the values to the range between 0 and 1. This normalization helps the model's optimization process by making it more stable and efficient.



train_images = train_images.reshape((60000, 28, 28, 1)).astype('float32') / 255 

test_images = test_images.reshape((10000, 28, 28, 1)).astype('float32') / 255


Represent categorical data ( labels) using one-hot encoding, which converts categorical data into a binary matrix, where each category is represented by a unique binary code.


The MNIST dataset labels represent digits from 0 to 9. 


For example, the label of 3,  would be converted to the binary array `[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]`. The position corresponding to the digit 3 is set to 1, and all other positions are set to 0.


train_labels = to_categorical(train_labels)

test_labels = to_categorical(test_labels)


# Split training data into train and validation sets

train_images, val_images, train_labels, val_labels = train_test_split(train_images, train_labels, test_size=0.2, random_state=42)



This code builds a Convolutional Neural Network (CNN) model for image classification using Keras deep learning library. 


model = Sequential():  initializes a sequential model. It is a linear stack of layers, that are added one after the other.


model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))): adds a 2D convolutional layer to the model. It has 32 filters (kernels), each of size 3x3. 


The 'relu' activation function is applied after the convolution operation. The input_shape specifies the shape of the input data, which is (28, 28, 1) for the MNIST dataset (28x28 grayscale images with a single channel).

I

model.add(MaxPooling2D((2, 2))): adds a 2D max-pooling layer to the model. Max-pooling reduces the spatial dimensions of the data while retaining the most important features. Here, the pooling window is 2x2.


model.add(Conv2D(64, (3, 3), activation='relu')): Another convolutional layer is added, this time with 64 filters of size 3x3 and a ReLU activation function.


model.add(MaxPooling2D((2, 2))): Another max-pooling layer with a 2x2 pooling window is added.


model.add(Conv2D(64, (3, 3), activation='relu')): Yet another convolutional layer with 64 filters and a ReLU activation function is added.


model.add(Flatten()): This layer flattens the 2D output from the convolutional layers into a 1D vector. This prepares the data for the fully connected layers.


model.add(Dense(64, activation='relu')): A fully connected (dense) layer with 64 neurons and a ReLU activation function is added. This layer processes the flattened data from the previous layer.


model.add(Dense(10, activation='softmax')): The final dense layer with 10 neurons is added. This layer uses the softmax activation function to produce probability distributions over the 10 possible classes (digits 0 to 9) for classification.


In summary, this CNN architecture consists of several convolutional and pooling layers for feature extraction, followed by fully connected layers for classification. The final layer's softmax activation produces class probabilities. This model structure is designed to learn hierarchical features from the input images and make predictions about their corresponding digits.



# Build the CNN model

model = Sequential()

model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))

model.add(MaxPooling2D((2, 2)))

model.add(Conv2D(64, (3, 3), activation='relu'))

model.add(MaxPooling2D((2, 2)))

model.add(Conv2D(64, (3, 3), activation='relu'))

model.add(Flatten())

model.add(Dense(64, activation='relu'))

model.add(Dense(10, activation='softmax'))


# Compile the model

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])


# Train the model

history = model.fit(train_images, train_labels, epochs=5, batch_size=64, validation_data=(val_images, val_labels))


# Evaluate the model on test data

test_loss, test_acc = model.evaluate(test_images, test_labels)

print("Test accuracy:", test_acc)

 


This code adds visualization for both accuracy and loss during training and validation. It creates two subplots, one for accuracy and the other for loss, showing the trends over epochs. This can help analyze how the model's performance changes during training and identify potential issues like overfitting or underfitting.



import matplotlib.pyplot as plt


# Plot the training and validation accuracy

plt.figure(figsize=(10, 4))

plt.subplot(1, 2, 1)

plt.plot(history.history['accuracy'], label='Training Accuracy')

plt.plot(history.history['val_accuracy'], label='Validation Accuracy')

plt.xlabel('Epoch')

plt.ylabel('Accuracy')

plt.title('Training and Validation Accuracy')

plt.legend()


# Plot the training and validation loss

plt.subplot(1, 2, 2)

plt.plot(history.history['loss'], label='Training Loss')

plt.plot(history.history['val_loss'], label='Validation Loss')

plt.xlabel('Epoch')

plt.ylabel('Loss')

plt.title('Training and Validation Loss')

plt.legend()


plt.tight_layout()

plt.show()



save the trained model




# Save the trained model

model.save('mnist_cnn_model.h5')


print("Model saved.")



obtain random samples from the MNIST dataset, perform inference, display actual vs. predicted labels, and calculate accuracy:




from keras.models import load_model


# Load the trained model

model = load_model('mnist_cnn_model.h5')


# Select 10 random samples

random_indices = np.random.choice(test_images.shape[0], size=10, replace=False)

sample_images = test_images[random_indices]

sample_labels = test_labels[random_indices]


# Preprocess the data

sample_images = sample_images.reshape((10, 28, 28, 1)).astype('float32') / 255


# Perform inference

predictions = model.predict(sample_images)

predicted_labels = np.argmax(predictions, axis=1)


# Display actual vs. predicted labels and accuracy

plt.figure(figsize=(10, 8))

for i in range(10):

    plt.subplot(5, 2, i + 1)

    plt.imshow(sample_images[i].squeeze(), cmap='gray')

    plt.title(f"Actual: {sample_labels[i]}\nPredicted: {predicted_labels[i]}", fontsize=10)

    plt.axis('off')


plt.tight_layout()

plt.show()


# Calculate accuracy

accuracy = np.mean(np.equal(sample_labels, predicted_labels))

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







    


Comments

Popular posts from this blog

AI-Typical Phrases to Avoid in Academic Writing

Tips for Humanizing AI Text

Overfilling and Underfitting in Machine Learning