MNIST with Convolutional Neural Networks
import numpy as np
import pandas as pd
import random
import tensorflow as tf
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Conv2D, Dense, MaxPooling2D
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.datasets import mnist
Loading and transforming the data
(X_train, y_train), (X_test, y_test) = mnist.load_data()
print(X_train.shape)
(60000, 28, 28)
X_train[0].min(), X_train[0].max()
X_train = (X_train - 0.0) / (255.0 - 0.0)
X_test = (X_test - 0.0) / (255.0 - 0.0)
X_train[0].min(), X_train[0].max()
def plot_digit(image, digit, plt, i):
plt.subplot(4, 5, i + 1)
plt.imshow(image, cmap=plt.get_cmap('gray'))
plt.title(f"Digit: {digit}")
plt.xticks([])
plt.yticks([])
plt.figure(figsize=(16, 10))
for i in range(20):
plot_digit(X_train[i], y_train[i], plt, i)
plt.show()
X_train = X_train.reshape((X_train.shape + (1,)))
X_test = X_test.reshape((X_test.shape + (1,)))
y_train[0:20]
Building the model
model = Sequential([
Conv2D(32, (3, 3), activation="relu", input_shape=(28, 28, 1)),
MaxPooling2D((2, 2)),
Flatten(),
Dense(100, activation="relu"),
Dense(10, activation="softmax")
])
optimizer = SGD(learning_rate=0.01, momentum=0.9)
model.compile(
optimizer=optimizer,
loss="sparse_categorical_crossentropy",
metrics=["accuracy"]
)
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 5408) 0
_________________________________________________________________
dense_2 (Dense) (None, 100) 540900
_________________________________________________________________
dense_3 (Dense) (None, 10) 1010
=================================================================
Total params: 542,230
Trainable params: 542,230
Non-trainable params: 0
_________________________________________________________________
Training and testing the model
model.fit(X_train, y_train, epochs=10, batch_size=32)
Epoch 1/10
1875/1875 [==============================] - 7s 3ms/step - loss: 0.2412 - accuracy: 0.9252
Epoch 2/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0847 - accuracy: 0.9748
Epoch 3/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0535 - accuracy: 0.9831
Epoch 4/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0383 - accuracy: 0.9886
Epoch 5/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0288 - accuracy: 0.9909
Epoch 6/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0212 - accuracy: 0.9936
Epoch 7/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0163 - accuracy: 0.9951
Epoch 8/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0129 - accuracy: 0.9961
Epoch 9/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0092 - accuracy: 0.9973
Epoch 10/10
1875/1875 [==============================] - 6s 3ms/step - loss: 0.0072 - accuracy: 0.9983
plt.figure(figsize=(16, 10))
for i in range(20):
image = random.choice(X_test).squeeze()
digit = np.argmax(model.predict(image.reshape((1, 28, 28, 1)))[0], axis=-1)
plot_digit(image, digit, plt, i)
plt.show()
predictions = np.argmax(model.predict(X_test), axis=-1)
accuracy_score(y_test, predictions)