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
Post a Comment