Hello World - Image Classification (PYTHON)

Exploring the ins-and-outs of Deep Learning

February 01, 2023 · 13 mins read

Hello World for Image Classification

This project was my first crack at image classification using TensorFlow and Keras to run a CNN to conduct image classification on the MNIST fashion dataset. I learned a bunch about neural networks in python and how to set them up, compile them, and then use them on a dataset. This specific notebook was made with the help of a tutorial, you will also find a version of this notebook that uses my own methods to classify each image without the use of tutorial. That notebook will be a better indictator of my own programming style. Nevertheless, this notebook provides insights to my journey with advanced deep learning algoithms.

Instead of writing out my thoughts seperately, the code blocks themselves are commented with what I was thinking and the things I was learning along the way.

Tutorial Link Here

!pip install tensorflow
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
train_images = train_images / 255
test_images = test_images / 255
print("Train data shape: ", train_images.shape)
print("Train labels shape: ", train_labels.shape)
print("Test data shape: ", test_images.shape)
print("Test labels shape: ", test_labels.shape)
Train data shape:  (60000, 28, 28)
Train labels shape:  (60000,)
Test data shape:  (10000, 28, 28)
Test labels shape:  (10000,)
class_names = ['T-shirt', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
plt.imshow(train_images[0], cmap = "Greys", interpolation = "nearest")

png

# BUILD THE NEURAL NETWORK

# SET UP THE LAYERS
model = keras.Sequential([keras.layers.Flatten(input_shape = (28,28)),
                          keras.layers.Dense(128, activation = "relu"),
                          keras.layers.Dense(10)])

''' Flatten layer -- takes the array, which is currently in the shape (28,28), and flattens it into one long array of shape (1, 784)
    First Dense layer -- contains 128 fully connected nodes
    Second Dense layer -- this layer returns a logit array of length 10
    Each dense layer contains a score that the image belongs to one of the 10 classes '''

model.compile(optimizer = "adam",
              loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits = True),
              metrics = ["accuracy"])

''' loss -- measures how accurate the model is during training. We want this function to be minimized
          SparseCategoricalCrossentropy -- calculates the crossentropy between the labels and the predictions,
                                           use this when you have more than two categories to predict
    optimizer -- determines how to model will be updated based on the loss function and the data it sees
    metrics -- attribute used to monitor the training and testing steps '''
# TRAIN THE MODEL
# 50 epochs may be too much, accuracy does not go up too much after 15-20 epochs

model.fit(train_images, train_labels, epochs = 20, batch_size = 200)
Epoch 1/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1415 - accuracy: 0.9482
Epoch 2/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1353 - accuracy: 0.9505
Epoch 3/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1331 - accuracy: 0.9518
Epoch 4/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1320 - accuracy: 0.9520
Epoch 5/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1311 - accuracy: 0.9525
Epoch 6/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1302 - accuracy: 0.9524
Epoch 7/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1284 - accuracy: 0.9525
Epoch 8/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1270 - accuracy: 0.9539
Epoch 9/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1257 - accuracy: 0.9539
Epoch 10/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1254 - accuracy: 0.9546
Epoch 11/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1228 - accuracy: 0.9556
Epoch 12/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1214 - accuracy: 0.9560
Epoch 13/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1176 - accuracy: 0.9572
Epoch 14/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1174 - accuracy: 0.9576
Epoch 15/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1143 - accuracy: 0.9586
Epoch 16/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1122 - accuracy: 0.9593
Epoch 17/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1094 - accuracy: 0.9602
Epoch 18/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1090 - accuracy: 0.9598
Epoch 19/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1058 - accuracy: 0.9615
Epoch 20/20
300/300 [==============================] - 1s 4ms/step - loss: 0.1050 - accuracy: 0.9611
print(model.summary())
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
flatten (Flatten)            (None, 784)               0         
_________________________________________________________________
dense (Dense)                (None, 128)               100480    
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1290      
=================================================================
Total params: 101,770
Trainable params: 101,770
Non-trainable params: 0
_________________________________________________________________
None
# FIND THE ACCURACY WHEN USING THE TESTING DATA
# COMPARE THIS TO TRAINING ACCURACY TO SEE IF OVERFITTING HAS OCCURRED

test_loss, test_accuracy = model.evaluate(test_images, test_labels, verbose = 2)
print("\nTest Accuracy = ", test_accuracy * 100)
313/313 - 0s - loss: 0.3956 - accuracy: 0.8929

Test Accuracy =  89.28999900817871
probability_model = tf.keras.Sequential([model,
                                         tf.keras.layers.Softmax()])

''' This softmax layer takes the logits that the original model outputs and converts
    them into probabilities which are much easier to understand and interpret '''
predictions = probability_model.predict(test_images)
# argmax finds the index of the highest prediction value
# check with the actual label to see how this prediction was
print(np.argmax(predictions[0]))
print(test_labels[0])
9
9
def plot_image(i, predictions_array, true_label, img):
  true_label, img = true_label[i], img[i]
  plt.grid(False)
  plt.yticks([])
  plt.xticks([])

  plt.imshow(img, cmap = "Greys")

  predicted_label = np.argmax(predictions_array)
  if predicted_label == true_label:
    color = "green"
  else:
    color = "red"

  plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label], # 1. display the predicted class
                                     100 * np.max(predictions_array), # 2. display the confidence of the prediction
                                     class_names[true_label], # in parenthesis, display the actual class label
                                     color = color)) # if the prediction is correct, the color is green. Wrong predictions are red
def plot_value_array(i, predicitons_array, true_label):
  # assign the true label
  true_label = true_label[i]
  # get rid of the grid of the plot
  plt.grid(False)
  # set the ticks of the x-axis to be the number of classes we are predicting
  plt.xticks(range(10))
  # get rid of the y ticks
  plt.yticks([])
  # set up the bar plot, the x values are 0-9 and the y values are the values that appear in the prediction array
  thisplot = plt.bar(range(10), predicitons_array)
  # set the limit of the y axis to be between 0 and 1
  plt.ylim(0,1)
  # assign the predicted label to a name 
  predicted_label = np.argmax(predicitons_array)

  # set the colors of the two special cases in our bar plot
  thisplot[predicted_label].set_color("red")
  thisplot[true_label].set_color("green")
num_rows = 4
num_cols = 3
num_images = num_rows * num_cols
plt.figure(figsize = (2*2*num_cols, 2*num_rows))

for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions[i], test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions[i], test_labels)

plt.tight_layout()
plt.show()

png