# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # ConvNets Intro - MNIST

# During an introduction to deep learning, I did a MNIST as a hello world deep learning problem. Simple network consisting of two fully-connected Dense layers achieved the 97.86% accuracy. Let's try to solve this problem using a convolutional neural network - hearth of computer vision - and see, how big of an improvement we will get.

from keras.datasets import mnist

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

from keras import models
from keras import layers

network = models.Sequential()
network.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) # 28x28 image size, 1 channel
network.add(layers.MaxPooling2D((2, 2)))
network.add(layers.Conv2D(64, (3, 3), activation='relu'))
network.add(layers.MaxPooling2D((2, 2)))
network.add(layers.Conv2D(64, (3, 3), activation='relu'))
network.add(layers.Flatten())
network.add(layers.Dense(64, activation='relu'))
network.add(layers.Dense(10, activation='softmax'))
network.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])

# We are using 3 convolutional layers with 3x3 kernel size. First conv layer uses 32 different 'filters', other two 64. By that, our neural network is able to learn abstract features and characteristics from the image. Between every 2 conv layers, we use max pooling layer to shrink down the 'image' size to half. We then flatten our output and use it as an input for two dense layers that are responsible for the final digit classification based on the discovered image features.

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

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

# Since we are using convolutional layers to learn characteristics of a given image, instead of only dense layers, we don't neet to squeze our 28x28x1 image into the single 1D tensor.

from keras.utils import to_categorical

y_train = to_categorical(train_labels)
y_test = to_categorical(test_labels)

X_train.shape, y_train.shape

network.fit(X_train, y_train, epochs=5, batch_size=64)

test_loss, test_acc = network.evaluate(X_test, y_test)
test_acc

StarcoderdataJupyterScriptsDedupFiltered