Machine Learning Workshop – Convolutional Neural Network (CNN)

Installing and loading some needed packages

# Needed package for plotting
import matplotlib.pyplot as plt
%matplotlib inline 

# Needed package for getting the current working directory
import os

os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
# Needed package for builing the convolutional neural network
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D
from tensorflow.keras.utils import plot_model

# Needed package for computer vision problems
import cv2
2023-05-30 15:18:20.540008: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  SSE4.1 SSE4.2 AVX AVX2 AVX512F AVX512_VNNI FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2023-05-30 15:18:20.579240: I tensorflow/core/util/port.cc:104] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.

Loading the MNIST data from keras library and split that into train and test dataset

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
image_index = 0
print('The number for index = ' + str(image_index) + ' is ' + str(y_train[image_index])) 
The number for index = 0 is 5
plt.imshow(x_train[image_index], cmap='Greys')
<matplotlib.image.AxesImage at 0x7f92e15b2220>

x_train.shape
(60000, 28, 28)
x_train[image_index].shape
(28, 28)

Normalize data and put them into the correct format

x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)
# Making sure that the values are float so that we can get decimal points after division
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')

x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print('Number of images in x_train', x_train.shape[0])
print('Number of images in x_test', x_test.shape[0])
x_train shape: (60000, 28, 28, 1)
Number of images in x_train 60000
Number of images in x_test 10000

Convolutional Neural Network (CNN) structure

model = Sequential()
model.add(Conv2D(32, kernel_size=(3,3), input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, kernel_size=(3,3), input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) 
model.add(Dense(256, activation=tf.nn.relu))
model.add(Dropout(0.2))
model.add(Dense(10,activation=tf.nn.softmax))
model.summary()
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 26, 26, 32)        320       
                                                                 
 max_pooling2d (MaxPooling2D  (None, 13, 13, 32)       0         
 )                                                               
                                                                 
 conv2d_1 (Conv2D)           (None, 11, 11, 32)        9248      
                                                                 
 max_pooling2d_1 (MaxPooling  (None, 5, 5, 32)         0         
 2D)                                                             
                                                                 
 flatten (Flatten)           (None, 800)               0         
                                                                 
 dense (Dense)               (None, 256)               205056    
                                                                 
 dropout (Dropout)           (None, 256)               0         
                                                                 
 dense_1 (Dense)             (None, 10)                2570      
                                                                 
=================================================================
Total params: 217,194
Trainable params: 217,194
Non-trainable params: 0
_________________________________________________________________

Training the CNN

model.compile(optimizer='adam', 
              loss='sparse_categorical_crossentropy', 
              metrics=['accuracy'])
model.fit(x=x_train,y=y_train, epochs=5)
model.evaluate(x_test, y_test)
  1/313 [..............................] - ETA: 36s - loss: 0.1098 - accuracy: 0.9688 30/313 [=>............................] - ETA: 0s - loss: 0.0378 - accuracy: 0.9844  64/313 [=====>........................] - ETA: 0s - loss: 0.0503 - accuracy: 0.9834 97/313 [========>.....................] - ETA: 0s - loss: 0.0576 - accuracy: 0.9836129/313 [===========>..................] - ETA: 0s - loss: 0.0601 - accuracy: 0.9830162/313 [==============>...............] - ETA: 0s - loss: 0.0551 - accuracy: 0.9844194/313 [=================>............] - ETA: 0s - loss: 0.0509 - accuracy: 0.9855229/313 [====================>.........] - ETA: 0s - loss: 0.0459 - accuracy: 0.9869266/313 [========================>.....] - ETA: 0s - loss: 0.0413 - accuracy: 0.9878305/313 [============================>.] - ETA: 0s - loss: 0.0390 - accuracy: 0.9885313/313 [==============================] - 1s 2ms/step - loss: 0.0390 - accuracy: 0.9884
[0.03904067724943161, 0.9883999824523926]
image_index = 59
plt.imshow(x_test[image_index].reshape(28, 28),cmap='Greys')
pred = model.predict(x_test[image_index].reshape(1, 28, 28, 1))
print(' For image_index = ' + str(image_index) + ' CNN predicted number = ' + str(pred.argmax()))
1/1 [==============================] - ETA: 0s1/1 [==============================] - 0s 48ms/step
 For image_index = 59 CNN predicted number = 5

In this part we are going to take a picture of your own handwriting and pass it into the CNN model, for doing that we need to do the following steps:

1. Write a number in 6 different ways on a paper and transfer the picture into the same directory that your Jupyter Notebook is

cwd = os.getcwd()
print('current working directory is = ' + cwd)
current working directory is = /home/connor/GDrive/Software/cnrrobertson.github.io/other/mlseminar/fall_2022/workshop4_cnn
file = r'test_images/original_image.jpeg'
test_image_original = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
plt.imshow(test_image_original, cmap = 'gray')
<matplotlib.image.AxesImage at 0x7f929e3b6fd0>

2. Take a picture of each of them individually – you can have only one picture and then crop it into 6 different pieces

fig, axs = plt.subplots(2, 3)


counter = 1
for row_number in range(0, 2):
    for col_number in range(0,3):
        
        file = r'test_images/copy_' + str(counter) +'.jpeg'
        copy_image = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
        axs[row_number, col_number].imshow(copy_image, cmap = 'gray')
        counter = counter + 1

4. Change the format of the picture into a readable form for your CNN model

file = r'test_images/copy_5.jpeg'
copy_1 = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
plt.imshow(copy_1, cmap = 'gray')
<matplotlib.image.AxesImage at 0x7f929d5d9e20>

# copy_1_resized = cv2.resize(copy_1, (28, 28), interpolation = cv2.INTER_LINEAR)
copy_1_resized = cv2.resize(copy_1, (28, 28))
copy_1_resized = cv2.bitwise_not(copy_1_resized)

plt.imshow(copy_1_resized, cmap = 'Greys')
<matplotlib.image.AxesImage at 0x7f929d53ef40>

pred = model.predict(copy_1_resized.reshape(1, 28, 28, 1))
print('CNN predicted number = ' + str(pred.argmax()))
1/1 [==============================] - ETA: 0s1/1 [==============================] - 0s 35ms/step
CNN predicted number = 8