Supervised learning: deep learning¶
In this practical, we will create a feed-forward neural network as well as a convolutional neural network to analyze the famous MNIST dataset.
Setup: installing TensorFlow¶
TensorFlow does not yet publish packages for very new Python versions (e.g. 3.13/3.14) — pip install tensorflow will fail on those. Use a dedicated conda environment pinned to Python 3.11 (any version in the 3.9–3.11 range works):
conda create -n daml python=3.11 -y
conda activate daml
pip install numpy matplotlib tensorflow
conda install jupyter -y
jupyter notebook
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
Let's set the seed value and use the same number as below to reproduce the same results.
tf.random.set_seed(45)
np.random.seed(45)
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
2. Plotting is very important when working with image data. We have defined a convenient plotting function for you. Use the plot_img() function below to plot the first training image. The img parameter has to be a 2D array with shape (28, 28).¶
def plot_img(img, cmap="gray_r", **kwargs):
plt.imshow(img, cmap=cmap, **kwargs)
plt.axis("off")
plt.show()
It is usually a good idea to normalize your features to have a manageable, standard range before entering them in neural networks.
3. As a preprocessing step, ensure the brightness values of the images in the training and test set are in the range (0, 1).¶
Multi-layer perceptron: multinomial logistic regression¶
The simplest neural network model is a multi-layer perceptron where we have no hidden layers and only input and output layers. We can call this a multinomial logistic regression model, where we have no hidden layers and 10 outputs (0-1) for our mnist data. That model is shown below.
multinom = keras.Sequential([
keras.Input(shape=(28, 28)),
layers.Flatten(),
layers.Dense(10, activation="softmax")
])
multinom.compile(
loss="sparse_categorical_crossentropy",
optimizer="adam",
metrics=["accuracy"]
)
4. Display a summary of the multinomial model using .summary(). Describe why this model has 7850 parameters.¶
5. Train the model for 5 epochs using the code below. What accuracy do we obtain in the validation set?¶
multinom.fit(x_train, y_train, epochs=5, validation_split=0.2, verbose=1)
6. Train the model for another 5 epochs. What accuracy do we obtain in the validation set?¶
Deep feed-forward neural networks¶
7. Create and compile a feed-forward neural network with the following properties. Ensure that the model has 50890 parameters.¶
- sequential model
- flatten layer
- dense layer with 64 hidden units and "relu" activation function
- dense output layer with 10 units and softmax activation function
8. Train the model for 10 epochs. What do you see in terms of validation accuracy, also compared to the multinomial model?¶
9. Create predictions for the test data using the two trained models (using the function below). Create a confusion matrix and compute test accuracy for these two models.¶
def class_predict(model, x):
return model.predict(x).argmax(axis=1)
10. Create and estimate (10 epochs) a deep feed-forward model with the following properties. Compare this model to the previous models on the test data.¶
- sequential model
- flatten layer
- dense layer with 128 hidden units and "relu" activation function
- dense layer with 64 hidden units and "relu" activation function
- dense output layer with 10 units and softmax activation function
Convolutional neural network¶
For each example, they need a (width, height, channels) array (tensor). For a colour image with 28*28 dimension, that shape is usually (28, 28, 3), where the channels indicate red, green, and blue. MNIST has no colour info, but we still need the channel dimension to enter the data into a convolution layer with shape (28, 28, 1). The training dataset x_train should thus have shape (60000, 28, 28, 1).
11. Add a "channel" dimension to the training and test data using the following code. Plot an image using the first channel of the 314th training example (this is a 9).¶
x_train = x_train[..., np.newaxis]
x_test = x_test[..., np.newaxis]
12. Create and compile a convolutional neural network using the following code. Describe the different layers in your own words.¶
cnn = keras.Sequential([
keras.Input(shape=(28, 28, 1)),
layers.Conv2D(filters=6, kernel_size=(5, 5)),
layers.MaxPooling2D(pool_size=(4, 4)),
layers.Flatten(),
layers.Dense(units=32, activation="relu"),
layers.Dense(10, activation="softmax")
])
cnn.compile(
loss="sparse_categorical_crossentropy",
optimizer="adam",
metrics=["accuracy"]
)
13. Fit this model on the training data (10 epochs) and compare it to the previous models.¶
14. Create another CNN which has better performance within 10 epochs.¶
Here are some things you could do:
- Reduce the convolution filter size & the pooling size and add a second convolutional & pooling layer with double the number of filters
- Add a dropout layer after the flatten layer
- Look up on the internet what works well and implement it!