Neural Network for Classification with TensorFlow

This Notebook is an account of working for the Udemy course by Daniel Bourke: TensorFlow Developer Certificate in 2022: Zero to Mastery

Classification problems are those where our motive is to classify given data by predicting the labels for the input data after the networks looks at a large sample of examples

Example Classification Problems:

  • Is this email spam or not spam? (Binary Classification)

  • Is this a photo of sushi, steak or pizza? (Multi-Class Classification problem)

  • What tags should this article have?(Multi-label Classification)

This Notebook covers:

  • Architecture of a neural network classification model.

  • Input shapes and output shapes of a classification model(features and labels)

  • Creating custom data to view and fit.

  • Steps in modelling

    • Creating a model
    • compiling a model
    • fitting a model
    • evaluating a model.
  • Different classification evaluation methods.

  • Saving and Loading models.

Classification Inputs and Outputs:

Input and Output Shapes

[batch_size, width, height, colour_channels] gets represented as a tensor.
Example shape of the tensor encoded from an image of resolution 224X224 pixels.

Shape = [None,224,224,3] or

Shape = [32,224,224,3]

we have set the batch_size as 32 in the second one because it is the common batch to take for a model. It's actually a default batch_size in tensorflow. we mostly take batches of 32 so that we don't run out of memory during our training. The batch_size can be configured according to the memory of the computer we are working on. some of the other examples of batch sizes are: 64, 128, 256 etc..

Examples of output shape:
Shape = [n], where n is the number of classes we have in our classification model.

Architecture of a Classification model

Example architecture of a classification model:

# 1. Create a model (specified to your problem)
model = tf.keras.Sequential([
  tf.keras.Input(shape= (224,224,3)),
  tf.keras.layers.Dense(100, activation = "relu"),
  tf.keras.layers.Dense(3, activation = "softmax")
])

# 2. Compile the Model
model.compile(loss = tf.keras.losses.CategoricalCrossentropy(),
optimizer = tf.keras.Adam(),
metrics = ["accuracy"])

# 3. Fit the model
model.fit(X_train, y_train, epochs = 5)

# 4. Evaluate the model
model.evaluate(X_test, y_test)
Hyperparameter Binary Classification Mutliclass Classification
Input layer shape Same as number of features Same as Binary Classification
Hidden Layer(s) Problem Specific Same as Binary Classification
Neurons per hidden layer Problem Specific(genearlly 10 to 100) Same as Binary Classification
Output layer shape 1(one class or the other) 1 per class
Hidden Activation Usually ReLU(rectified linear unit) Same as Binary Classification
Output Activation Sigmoid Softmax
Loss function Cross Entropy(tf.keras.losses.BinaryCrossentropy) Cross entropy(tf.keras.losses.CategoricalCrossentropy)
Optimizer SGD(Stochastic gradient Descent), Adam Same as Binary Classification

Creating data to view and fit

from sklearn.datasets import make_circles

# Make 1000 examples 
n_samples = 1000

# Create circles
X, y = make_circles(n_samples,
                    noise = 0.03,
                    random_state = 42)
X
array([[ 0.75424625,  0.23148074],
       [-0.75615888,  0.15325888],
       [-0.81539193,  0.17328203],
       ...,
       [-0.13690036, -0.81001183],
       [ 0.67036156, -0.76750154],
       [ 0.28105665,  0.96382443]])
y[:10]
array([1, 1, 1, 1, 0, 1, 1, 1, 1, 0])

our data is hard to understand right now. Let's visualize it!

import pandas as pd
import numpy as np
circles = pd.DataFrame({"X0": X[:,0], "X1": X[:,1], "lablel": y}) 
circles
X0 X1 lablel
0 0.754246 0.231481 1
1 -0.756159 0.153259 1
2 -0.815392 0.173282 1
3 -0.393731 0.692883 1
4 0.442208 -0.896723 0
... ... ... ...
995 0.244054 0.944125 0
996 -0.978655 -0.272373 0
997 -0.136900 -0.810012 1
998 0.670362 -0.767502 0
999 0.281057 0.963824 0

1000 rows × 3 columns

import matplotlib.pyplot as plt
from matplotlib import style
style.use('dark_background')
plt.scatter(X[:,0], X[:,1], c= y, cmap = plt.cm.RdYlBu );

Resources:

X.shape, y.shape
((1000, 2), (1000,))
len(X), len(y)
(1000, 1000)
X[0], y[0]
(array([0.75424625, 0.23148074]), 1)

Steps in Modelling

The steps in modelling with TensorFlow are typically:

  1. Create or import a model
  2. Compile the model
  3. Fit the model
  4. Evaluate the model
  5. Tweak
  6. Evaluate....
import tensorflow as tf
print(tf.__version__)
2.7.0
tf.random.set_seed(42)

# 1. Create the model using Sequential API

model_1 = tf.keras.Sequential([
  tf.keras.layers.Dense(1)                             
])

# 2. Compile the model
model_1.compile(loss = tf.keras.losses.BinaryCrossentropy(),
                optimizer = tf.keras.optimizers.SGD(),
                metrics = ["accuracy"])

# 3. Fit the model
model_1.fit(X,y, epochs = 5)
Epoch 1/5
32/32 [==============================] - 1s 1ms/step - loss: 2.8544 - accuracy: 0.4600
Epoch 2/5
32/32 [==============================] - 0s 1ms/step - loss: 0.7131 - accuracy: 0.5430
Epoch 3/5
32/32 [==============================] - 0s 1ms/step - loss: 0.6973 - accuracy: 0.5090
Epoch 4/5
32/32 [==============================] - 0s 1ms/step - loss: 0.6950 - accuracy: 0.5010
Epoch 5/5
32/32 [==============================] - 0s 1ms/step - loss: 0.6942 - accuracy: 0.4830
<keras.callbacks.History at 0x7f848eb26310>
model_1.fit(X,y ,epochs = 200, verbose = 0)
model_1.evaluate(X,y)
32/32 [==============================] - 0s 1ms/step - loss: 0.6935 - accuracy: 0.5000
[0.6934829950332642, 0.5]

Since we are working on a binary classification problem and our model is getting around ~50% accuracy so, it's practically guessing

# Add another layer and train for longer 
# Set the random seed
tf.random.set_seed(42)

# 1. Create a model, this time with 2 layers
model_2 = tf.keras.Sequential([
  tf.keras.layers.Dense(1),
  tf.keras.layers.Dense(1)
])

# 2. Compile the model
model_2.compile(loss = tf.keras.losses.BinaryCrossentropy(),
                optimizer = tf.keras.optimizers.SGD(),
                metrics = ["accuracy"])

# 3. Fit the model
model_2.fit(X,y, epochs = 100, verbose = 0)
<keras.callbacks.History at 0x7f848eb26190>
model_2.evaluate(X,y)
32/32 [==============================] - 0s 1ms/step - loss: 0.6933 - accuracy: 0.5000
[0.6933314800262451, 0.5]

Improving our model

Let's see what we change in each of the modelling steps:

  1. Create a model - we might add more layers or increase the number of hidden units within a layer.

  2. Compiling a model - we can choose different optimization function like Adam, instead of SGD.

  3. Fitting a model - we can fit our model for more epochs(train for longer)

# Set the random seed
tf.random.set_seed(42)

# 1. Create the model (this time 3 layers)
model_3 = tf.keras.Sequential([
  tf.keras.layers.Dense(100), # add 100 dense neurons
  tf.keras.layers.Dense(10),
  tf.keras.layers.Dense(1)  # add another layer with 10 neurons                            
]) 

# 2. Compile the model
model_3.compile(loss = tf.keras.losses.BinaryCrossentropy(),
                optimizer = tf.keras.optimizers.Adam(),
                metrics = ["accuracy"])

# 3. Fit the model
model_3.fit(X,y, epochs=100, verbose = 0)
<keras.callbacks.History at 0x7f848e9b8650>
model_3.evaluate(X,y)
32/32 [==============================] - 0s 1ms/step - loss: 0.6980 - accuracy: 0.5080
[0.6980254650115967, 0.5080000162124634]

still ~50% accuracy ..really bad result for us

To visualize our model's predictions let's create a function plot_decision_boundary, this will:

  • Take in a trained model, features(X) and labels(y)

  • Create a meshgrid of te different X values.

  • Make predictions across the meshgird

  • Plot the predictions as well as line between zones(where each unique class falls)

def plot_decision_boundary(model, X,y):
  """
  plots the decision boundary created by a model prediction on X

  """

  # Define the axis boundaries of the plot and create a meshgrid
  x_min, x_max = X[:,0].min() -0.1, X[:,0].max() + 0.1
  y_min, y_max = X[:,1].min() - 0.1, X[:,1].max() + 0.1
  xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100),
                       np.linspace(y_min,y_max,100))
  
  # Create X value(you are goind to make predictions on these)
  x_in = np.c_[xx.ravel(), yy.ravel()] # stack 2D arrays together
  
  # Make predictions
  y_pred = model.predict(x_in)

  # Check for mutli-class
  if len(y_pred[0]) > 1 :
    print("doing multi class classification")
    # We have to reshape our prediction to get them ready for plotting\
    y_pred = np.argmax(y_pred, axis = 1).reshape(xx.shape)
  else: 
    print("doing binary classification")
    y_pred = np.round(y_pred).reshape(xx.shape)

  # Plot the decision boundary
  plt.contourf(xx, yy, y_pred, cmap = plt.cm.RdYlBu, alpha = 0.7)
  plt.scatter(X[:,0], X[:,1], c= y, s= 40, cmap = plt.cm.RdYlBu)
  plt.xlim(xx.min(), xx.max())
  plt.ylim(yy.min(), yy.max())
plot_decision_boundary(model_3, X, y)
doing binary classification

This looks like model is fitting a linear boundary. That is the reason why our model is performing poorly on our metrics.

# Let's see if our model can be used for a regression problem..

tf.random.set_seed(42)

# Create some regression data
X_regression = tf.range(0,1000,5)
y_regression = tf.range(100,1100, 5) # # y = X +100

# Let's split our training data into training and test splits
X_reg_train = X_regression[:150]
X_reg_test = X_regression[150:]
y_reg_train = y_regression[:150]
y_reg_test = y_regression[150:]

We compiled our model for a binary classification problem, Now we are working on a regression problem, let's change the model to suit our data.

tf.random.set_seed(42)

# 1. Create teh model 
model_3 = tf.keras.Sequential([
  tf.keras.layers.Dense(100),
  tf.keras.layers.Dense(10),
  tf.keras.layers.Dense(1)
])

# 2. Compile the model, this time with a regression-specific loss function
model_3.compile(loss = tf.keras.losses.mae,
                optimizer = tf.keras.optimizers.Adam(),
                metrics = ["mae"])

# 3. Fit the model
model_3.fit(tf.expand_dims(X_reg_train, axis=-1), y_reg_train, epochs =100, verbose = 0)
<keras.callbacks.History at 0x7f848e28fa10>
y_reg_preds = model_3.predict(X_reg_test)

# Plot the model's predictoins against our regression data
plt.figure(figsize = (10,7))
plt.scatter(X_reg_train, y_reg_train, c= 'b', label = "Training data")
plt.scatter(X_reg_test, y_reg_test, c = 'g', label ="Test data")
plt.scatter(X_reg_test, y_reg_preds, c = 'r', label = "Predictions")
plt.legend();

We missed to capture the Non-linearity !

The Missing Piece: Non-linearity:

# Set the seed
tf.random.set_seed(42)

# 1. Create the model
model_4 = tf.keras.Sequential([
  tf.keras.layers.Dense(1, activation = tf.keras.activations.linear)
])
# 2. Compile the model
model_4.compile(loss = "binary_crossentropy",
                optimizer = tf.keras.optimizers.Adam(lr = 0.001),
                metrics = ["accuracy"])

# 3. Fit the model
history = model_4.fit(X, y, epochs = 100)

/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/adam.py:105: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.
  super(Adam, self).__init__(name, **kwargs)
Epoch 1/100
32/32 [==============================] - 0s 1ms/step - loss: 4.2979 - accuracy: 0.4670
Epoch 2/100
32/32 [==============================] - 0s 1ms/step - loss: 4.2317 - accuracy: 0.4400
Epoch 3/100
32/32 [==============================] - 0s 1ms/step - loss: 4.1610 - accuracy: 0.4310
Epoch 4/100
32/32 [==============================] - 0s 1ms/step - loss: 4.1183 - accuracy: 0.4270
Epoch 5/100
32/32 [==============================] - 0s 1ms/step - loss: 4.0784 - accuracy: 0.4240
Epoch 6/100
32/32 [==============================] - 0s 1ms/step - loss: 3.9604 - accuracy: 0.4170
Epoch 7/100
32/32 [==============================] - 0s 1ms/step - loss: 3.8936 - accuracy: 0.4110
Epoch 8/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7818 - accuracy: 0.4140
Epoch 9/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7564 - accuracy: 0.4140
Epoch 10/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7547 - accuracy: 0.4150
Epoch 11/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7537 - accuracy: 0.4140
Epoch 12/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7526 - accuracy: 0.4140
Epoch 13/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7518 - accuracy: 0.4140
Epoch 14/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7510 - accuracy: 0.4140
Epoch 15/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7503 - accuracy: 0.4130
Epoch 16/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7497 - accuracy: 0.4130
Epoch 17/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7490 - accuracy: 0.4130
Epoch 18/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7484 - accuracy: 0.4130
Epoch 19/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7478 - accuracy: 0.4120
Epoch 20/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7472 - accuracy: 0.4120
Epoch 21/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7466 - accuracy: 0.4110
Epoch 22/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7461 - accuracy: 0.4110
Epoch 23/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7455 - accuracy: 0.4110
Epoch 24/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7450 - accuracy: 0.4110
Epoch 25/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7366 - accuracy: 0.4120
Epoch 26/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7256 - accuracy: 0.4120
Epoch 27/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7230 - accuracy: 0.4140
Epoch 28/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7215 - accuracy: 0.4140
Epoch 29/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7204 - accuracy: 0.4150
Epoch 30/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7196 - accuracy: 0.4160
Epoch 31/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7188 - accuracy: 0.4170
Epoch 32/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7181 - accuracy: 0.4170
Epoch 33/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7174 - accuracy: 0.4170
Epoch 34/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7167 - accuracy: 0.4170
Epoch 35/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7161 - accuracy: 0.4160
Epoch 36/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7153 - accuracy: 0.4150
Epoch 37/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7147 - accuracy: 0.4150
Epoch 38/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7141 - accuracy: 0.4150
Epoch 39/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7135 - accuracy: 0.4150
Epoch 40/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7129 - accuracy: 0.4150
Epoch 41/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7123 - accuracy: 0.4150
Epoch 42/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7118 - accuracy: 0.4160
Epoch 43/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7112 - accuracy: 0.4160
Epoch 44/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7107 - accuracy: 0.4160
Epoch 45/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7101 - accuracy: 0.4150
Epoch 46/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7096 - accuracy: 0.4170
Epoch 47/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7091 - accuracy: 0.4170
Epoch 48/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7014 - accuracy: 0.4170
Epoch 49/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6892 - accuracy: 0.4190
Epoch 50/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6856 - accuracy: 0.4190
Epoch 51/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6846 - accuracy: 0.4190
Epoch 52/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6837 - accuracy: 0.4190
Epoch 53/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6829 - accuracy: 0.4190
Epoch 54/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6821 - accuracy: 0.4190
Epoch 55/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6814 - accuracy: 0.4190
Epoch 56/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6807 - accuracy: 0.4200
Epoch 57/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6727 - accuracy: 0.4210
Epoch 58/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6690 - accuracy: 0.4190
Epoch 59/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6677 - accuracy: 0.4190
Epoch 60/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6585 - accuracy: 0.4190
Epoch 61/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6489 - accuracy: 0.4200
Epoch 62/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6330 - accuracy: 0.4190
Epoch 63/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6282 - accuracy: 0.4200
Epoch 64/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6162 - accuracy: 0.4220
Epoch 65/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6062 - accuracy: 0.4240
Epoch 66/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6031 - accuracy: 0.4260
Epoch 67/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6012 - accuracy: 0.4280
Epoch 68/100
32/32 [==============================] - 0s 2ms/step - loss: 3.5999 - accuracy: 0.4280
Epoch 69/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5904 - accuracy: 0.4290
Epoch 70/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5858 - accuracy: 0.4300
Epoch 71/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5846 - accuracy: 0.4300
Epoch 72/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5836 - accuracy: 0.4300
Epoch 73/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5826 - accuracy: 0.4310
Epoch 74/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5817 - accuracy: 0.4330
Epoch 75/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5656 - accuracy: 0.4360
Epoch 76/100
32/32 [==============================] - 0s 2ms/step - loss: 3.5355 - accuracy: 0.4410
Epoch 77/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5335 - accuracy: 0.4410
Epoch 78/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5319 - accuracy: 0.4420
Epoch 79/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5306 - accuracy: 0.4420
Epoch 80/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5208 - accuracy: 0.4420
Epoch 81/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5172 - accuracy: 0.4420
Epoch 82/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5157 - accuracy: 0.4430
Epoch 83/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5144 - accuracy: 0.4450
Epoch 84/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5132 - accuracy: 0.4450
Epoch 85/100
32/32 [==============================] - 0s 2ms/step - loss: 3.5043 - accuracy: 0.4460
Epoch 86/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5002 - accuracy: 0.4470
Epoch 87/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4905 - accuracy: 0.4470
Epoch 88/100
32/32 [==============================] - 0s 2ms/step - loss: 3.4788 - accuracy: 0.4470
Epoch 89/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4661 - accuracy: 0.4470
Epoch 90/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4452 - accuracy: 0.4490
Epoch 91/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4198 - accuracy: 0.4560
Epoch 92/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4176 - accuracy: 0.4550
Epoch 93/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4072 - accuracy: 0.4580
Epoch 94/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4036 - accuracy: 0.4580
Epoch 95/100
32/32 [==============================] - 0s 1ms/step - loss: 3.3944 - accuracy: 0.4590
Epoch 96/100
32/32 [==============================] - 0s 1ms/step - loss: 3.3290 - accuracy: 0.4590
Epoch 97/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2727 - accuracy: 0.4600
Epoch 98/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2636 - accuracy: 0.4580
Epoch 99/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2509 - accuracy: 0.4570
Epoch 100/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2459 - accuracy: 0.4570
plt.scatter(X[:,0], X[:,1], c = y, cmap = plt.cm.RdYlBu);
plot_decision_boundary(model_4, X, y)
doing binary classification

Let's try build our first neural network with a non-linear activation function

# Set random seed
tf.random.set_seed(42)

# 1. Create a model with non-linear activation
model_5 = tf.keras.Sequential([
  tf.keras.layers.Dense(1, activation = tf.keras.activations.relu)
  
                                 
])
# 2. Compile the model
model_5.compile(loss= tf.keras.losses.BinaryCrossentropy(),
                optimizer = tf.keras.optimizers.Adam(lr = 0.001),
                metrics = ["accuracy"])

# 3. Fit the model
history = model_5.fit(X,y,epochs= 100)

/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/adam.py:105: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.
  super(Adam, self).__init__(name, **kwargs)
Epoch 1/100
32/32 [==============================] - 0s 2ms/step - loss: 4.2979 - accuracy: 0.4670
Epoch 2/100
32/32 [==============================] - 0s 1ms/step - loss: 4.2317 - accuracy: 0.4400
Epoch 3/100
32/32 [==============================] - 0s 1ms/step - loss: 4.1610 - accuracy: 0.4310
Epoch 4/100
32/32 [==============================] - 0s 2ms/step - loss: 4.1183 - accuracy: 0.4270
Epoch 5/100
32/32 [==============================] - 0s 1ms/step - loss: 4.0784 - accuracy: 0.4240
Epoch 6/100
32/32 [==============================] - 0s 1ms/step - loss: 3.9604 - accuracy: 0.4170
Epoch 7/100
32/32 [==============================] - 0s 1ms/step - loss: 3.8936 - accuracy: 0.4110
Epoch 8/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7818 - accuracy: 0.4140
Epoch 9/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7564 - accuracy: 0.4140
Epoch 10/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7547 - accuracy: 0.4150
Epoch 11/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7537 - accuracy: 0.4140
Epoch 12/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7526 - accuracy: 0.4140
Epoch 13/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7518 - accuracy: 0.4140
Epoch 14/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7510 - accuracy: 0.4140
Epoch 15/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7503 - accuracy: 0.4130
Epoch 16/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7497 - accuracy: 0.4130
Epoch 17/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7490 - accuracy: 0.4130
Epoch 18/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7484 - accuracy: 0.4130
Epoch 19/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7478 - accuracy: 0.4120
Epoch 20/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7472 - accuracy: 0.4120
Epoch 21/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7466 - accuracy: 0.4110
Epoch 22/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7461 - accuracy: 0.4110
Epoch 23/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7455 - accuracy: 0.4110
Epoch 24/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7450 - accuracy: 0.4110
Epoch 25/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7366 - accuracy: 0.4120
Epoch 26/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7256 - accuracy: 0.4120
Epoch 27/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7230 - accuracy: 0.4140
Epoch 28/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7215 - accuracy: 0.4140
Epoch 29/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7204 - accuracy: 0.4150
Epoch 30/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7196 - accuracy: 0.4160
Epoch 31/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7188 - accuracy: 0.4170
Epoch 32/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7181 - accuracy: 0.4170
Epoch 33/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7174 - accuracy: 0.4170
Epoch 34/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7167 - accuracy: 0.4170
Epoch 35/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7161 - accuracy: 0.4160
Epoch 36/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7153 - accuracy: 0.4150
Epoch 37/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7147 - accuracy: 0.4150
Epoch 38/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7141 - accuracy: 0.4150
Epoch 39/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7135 - accuracy: 0.4150
Epoch 40/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7129 - accuracy: 0.4150
Epoch 41/100
32/32 [==============================] - 0s 2ms/step - loss: 3.7123 - accuracy: 0.4150
Epoch 42/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7118 - accuracy: 0.4160
Epoch 43/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7112 - accuracy: 0.4160
Epoch 44/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7107 - accuracy: 0.4160
Epoch 45/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7101 - accuracy: 0.4150
Epoch 46/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7096 - accuracy: 0.4170
Epoch 47/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7091 - accuracy: 0.4170
Epoch 48/100
32/32 [==============================] - 0s 1ms/step - loss: 3.7014 - accuracy: 0.4170
Epoch 49/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6892 - accuracy: 0.4190
Epoch 50/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6856 - accuracy: 0.4190
Epoch 51/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6846 - accuracy: 0.4190
Epoch 52/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6837 - accuracy: 0.4190
Epoch 53/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6829 - accuracy: 0.4190
Epoch 54/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6821 - accuracy: 0.4190
Epoch 55/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6814 - accuracy: 0.4190
Epoch 56/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6807 - accuracy: 0.4200
Epoch 57/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6727 - accuracy: 0.4210
Epoch 58/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6690 - accuracy: 0.4190
Epoch 59/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6677 - accuracy: 0.4190
Epoch 60/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6585 - accuracy: 0.4190
Epoch 61/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6489 - accuracy: 0.4200
Epoch 62/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6330 - accuracy: 0.4190
Epoch 63/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6282 - accuracy: 0.4200
Epoch 64/100
32/32 [==============================] - 0s 2ms/step - loss: 3.6162 - accuracy: 0.4220
Epoch 65/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6062 - accuracy: 0.4240
Epoch 66/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6031 - accuracy: 0.4260
Epoch 67/100
32/32 [==============================] - 0s 1ms/step - loss: 3.6012 - accuracy: 0.4280
Epoch 68/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5999 - accuracy: 0.4280
Epoch 69/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5904 - accuracy: 0.4290
Epoch 70/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5858 - accuracy: 0.4300
Epoch 71/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5846 - accuracy: 0.4300
Epoch 72/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5836 - accuracy: 0.4300
Epoch 73/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5826 - accuracy: 0.4310
Epoch 74/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5817 - accuracy: 0.4330
Epoch 75/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5656 - accuracy: 0.4360
Epoch 76/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5355 - accuracy: 0.4410
Epoch 77/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5335 - accuracy: 0.4410
Epoch 78/100
32/32 [==============================] - 0s 2ms/step - loss: 3.5319 - accuracy: 0.4420
Epoch 79/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5306 - accuracy: 0.4420
Epoch 80/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5208 - accuracy: 0.4420
Epoch 81/100
32/32 [==============================] - 0s 2ms/step - loss: 3.5172 - accuracy: 0.4420
Epoch 82/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5157 - accuracy: 0.4430
Epoch 83/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5144 - accuracy: 0.4450
Epoch 84/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5132 - accuracy: 0.4450
Epoch 85/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5043 - accuracy: 0.4460
Epoch 86/100
32/32 [==============================] - 0s 1ms/step - loss: 3.5002 - accuracy: 0.4470
Epoch 87/100
32/32 [==============================] - 0s 2ms/step - loss: 3.4905 - accuracy: 0.4470
Epoch 88/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4788 - accuracy: 0.4470
Epoch 89/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4661 - accuracy: 0.4470
Epoch 90/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4452 - accuracy: 0.4490
Epoch 91/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4198 - accuracy: 0.4560
Epoch 92/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4176 - accuracy: 0.4550
Epoch 93/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4072 - accuracy: 0.4580
Epoch 94/100
32/32 [==============================] - 0s 1ms/step - loss: 3.4036 - accuracy: 0.4580
Epoch 95/100
32/32 [==============================] - 0s 1ms/step - loss: 3.3944 - accuracy: 0.4590
Epoch 96/100
32/32 [==============================] - 0s 1ms/step - loss: 3.3290 - accuracy: 0.4590
Epoch 97/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2727 - accuracy: 0.4600
Epoch 98/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2636 - accuracy: 0.4580
Epoch 99/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2509 - accuracy: 0.4570
Epoch 100/100
32/32 [==============================] - 0s 1ms/step - loss: 3.2459 - accuracy: 0.4570

Still the result looks bad. Our model is performing worse than guessing.

#set the random seed
tf.random.set_seed(42)

# 1. Create the model
model_6 = tf.keras.Sequential([
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = 'relu'),
  tf.keras.layers.Dense(1)

])

# 2. Compile the model
model_6.compile(loss = "binary_crossentropy",
                optimizer = tf.keras.optimizers.Adam(lr = 0.001),
                metrics = ["accuracy"])

# 3. Fit the model
history = model_6.fit(X,y, epochs = 250)

/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/adam.py:105: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.
  super(Adam, self).__init__(name, **kwargs)
Epoch 1/250
32/32 [==============================] - 1s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 2/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 3/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 4/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 5/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 6/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 7/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 8/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 9/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 10/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 11/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 12/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 13/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 14/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 15/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 16/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 17/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 18/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 19/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 20/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 21/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 22/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 23/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 24/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 25/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 26/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 27/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 28/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 29/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 30/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 31/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 32/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 33/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 34/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 35/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 36/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 37/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 38/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 39/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 40/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 41/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 42/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 43/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 44/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 45/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 46/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 47/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 48/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 49/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 50/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 51/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 52/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 53/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 54/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 55/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 56/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 57/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 58/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 59/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 60/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 61/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 62/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 63/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 64/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 65/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 66/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 67/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 68/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 69/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 70/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 71/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 72/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 73/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 74/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 75/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 76/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 77/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 78/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 79/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 80/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 81/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 82/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 83/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 84/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 85/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 86/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 87/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 88/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 89/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 90/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 91/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 92/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 93/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 94/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 95/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 96/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 97/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 98/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 99/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 100/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 101/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 102/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 103/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 104/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 105/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 106/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 107/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 108/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 109/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 110/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 111/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 112/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 113/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 114/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 115/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 116/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 117/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 118/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 119/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 120/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 121/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 122/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 123/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 124/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 125/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 126/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 127/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 128/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 129/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 130/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 131/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 132/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 133/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 134/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 135/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 136/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 137/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 138/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 139/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 140/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 141/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 142/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 143/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 144/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 145/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 146/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 147/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 148/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 149/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 150/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 151/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 152/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 153/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 154/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 155/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 156/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 157/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 158/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 159/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 160/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 161/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 162/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 163/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 164/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 165/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 166/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 167/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 168/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 169/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 170/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 171/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 172/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 173/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 174/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 175/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 176/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 177/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 178/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 179/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 180/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 181/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 182/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 183/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 184/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 185/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 186/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 187/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 188/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 189/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 190/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 191/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 192/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 193/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 194/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 195/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 196/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 197/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 198/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 199/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 200/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 201/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 202/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 203/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 204/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 205/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 206/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 207/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 208/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 209/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 210/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 211/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 212/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 213/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 214/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 215/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 216/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 217/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 218/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 219/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 220/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 221/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 222/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 223/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 224/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 225/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 226/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 227/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 228/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 229/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 230/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 231/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 232/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 233/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 234/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 235/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 236/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 237/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 238/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 239/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 240/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 241/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 242/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 243/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 244/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 245/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 246/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 247/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 248/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 249/250
32/32 [==============================] - 0s 2ms/step - loss: 7.7125 - accuracy: 0.5000
Epoch 250/250
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000

Let's evaluate the model to see how it is doing

model_6.evaluate(X,y)
32/32 [==============================] - 0s 1ms/step - loss: 7.7125 - accuracy: 0.5000
[7.712474346160889, 0.5]

It's performing much worse than guessing now.

plot_decision_boundary(model_6, X, y)
doing binary classification

It's time to fix the model and provide the missing piece and that is

#set the random seed
tf.random.set_seed(42)

# 1. Create the model
model_7 = tf.keras.Sequential([
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(1, activation = "sigmoid")

])

# 2. Compile the model
model_7.compile(loss = "binary_crossentropy",
                optimizer = tf.keras.optimizers.Adam(lr = 0.001),
                metrics = ["accuracy"])

# 3. Fit the model
history = model_7.fit(X,y, epochs = 250)

/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/adam.py:105: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.
  super(Adam, self).__init__(name, **kwargs)
Epoch 1/250
32/32 [==============================] - 1s 2ms/step - loss: 0.6891 - accuracy: 0.5020
Epoch 2/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6848 - accuracy: 0.5170
Epoch 3/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6824 - accuracy: 0.5160
Epoch 4/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6813 - accuracy: 0.5300
Epoch 5/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6802 - accuracy: 0.5390
Epoch 6/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6794 - accuracy: 0.5380
Epoch 7/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6785 - accuracy: 0.5500
Epoch 8/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6778 - accuracy: 0.5480
Epoch 9/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6772 - accuracy: 0.5530
Epoch 10/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6766 - accuracy: 0.5510
Epoch 11/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6760 - accuracy: 0.5500
Epoch 12/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6754 - accuracy: 0.5550
Epoch 13/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6747 - accuracy: 0.5560
Epoch 14/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6741 - accuracy: 0.5540
Epoch 15/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6734 - accuracy: 0.5580
Epoch 16/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6727 - accuracy: 0.5550
Epoch 17/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6722 - accuracy: 0.5550
Epoch 18/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6716 - accuracy: 0.5550
Epoch 19/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6710 - accuracy: 0.5590
Epoch 20/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6702 - accuracy: 0.5600
Epoch 21/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6696 - accuracy: 0.5640
Epoch 22/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6688 - accuracy: 0.5600
Epoch 23/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6682 - accuracy: 0.5700
Epoch 24/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6679 - accuracy: 0.5570
Epoch 25/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6671 - accuracy: 0.5670
Epoch 26/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6662 - accuracy: 0.5750
Epoch 27/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6657 - accuracy: 0.5810
Epoch 28/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6645 - accuracy: 0.5700
Epoch 29/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6642 - accuracy: 0.5700
Epoch 30/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6634 - accuracy: 0.5790
Epoch 31/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6627 - accuracy: 0.5760
Epoch 32/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6619 - accuracy: 0.5760
Epoch 33/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6610 - accuracy: 0.5760
Epoch 34/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6606 - accuracy: 0.5760
Epoch 35/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6597 - accuracy: 0.5790
Epoch 36/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6586 - accuracy: 0.5780
Epoch 37/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6580 - accuracy: 0.5780
Epoch 38/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6573 - accuracy: 0.5790
Epoch 39/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6564 - accuracy: 0.5790
Epoch 40/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6556 - accuracy: 0.5760
Epoch 41/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6548 - accuracy: 0.5780
Epoch 42/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6540 - accuracy: 0.5750
Epoch 43/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6530 - accuracy: 0.5780
Epoch 44/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6521 - accuracy: 0.5810
Epoch 45/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6496 - accuracy: 0.5810
Epoch 46/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6481 - accuracy: 0.5830
Epoch 47/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6472 - accuracy: 0.5850
Epoch 48/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6451 - accuracy: 0.5880
Epoch 49/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6426 - accuracy: 0.5880
Epoch 50/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6404 - accuracy: 0.5940
Epoch 51/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6384 - accuracy: 0.6010
Epoch 52/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6364 - accuracy: 0.6130
Epoch 53/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6344 - accuracy: 0.6110
Epoch 54/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6312 - accuracy: 0.6280
Epoch 55/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6287 - accuracy: 0.6380
Epoch 56/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6259 - accuracy: 0.6840
Epoch 57/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6227 - accuracy: 0.6950
Epoch 58/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6200 - accuracy: 0.6990
Epoch 59/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6168 - accuracy: 0.6950
Epoch 60/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6133 - accuracy: 0.7240
Epoch 61/250
32/32 [==============================] - 0s 2ms/step - loss: 0.6101 - accuracy: 0.7200
Epoch 62/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6059 - accuracy: 0.7330
Epoch 63/250
32/32 [==============================] - 0s 1ms/step - loss: 0.6014 - accuracy: 0.7400
Epoch 64/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5966 - accuracy: 0.7460
Epoch 65/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5905 - accuracy: 0.7440
Epoch 66/250
32/32 [==============================] - 0s 1ms/step - loss: 0.5830 - accuracy: 0.7450
Epoch 67/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5757 - accuracy: 0.7460
Epoch 68/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5683 - accuracy: 0.7800
Epoch 69/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5614 - accuracy: 0.8010
Epoch 70/250
32/32 [==============================] - 0s 1ms/step - loss: 0.5548 - accuracy: 0.8010
Epoch 71/250
32/32 [==============================] - 0s 1ms/step - loss: 0.5474 - accuracy: 0.8240
Epoch 72/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5406 - accuracy: 0.8460
Epoch 73/250
32/32 [==============================] - 0s 1ms/step - loss: 0.5327 - accuracy: 0.8470
Epoch 74/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5243 - accuracy: 0.8620
Epoch 75/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5148 - accuracy: 0.8870
Epoch 76/250
32/32 [==============================] - 0s 2ms/step - loss: 0.5042 - accuracy: 0.8820
Epoch 77/250
32/32 [==============================] - 0s 1ms/step - loss: 0.4927 - accuracy: 0.9300
Epoch 78/250
32/32 [==============================] - 0s 1ms/step - loss: 0.4824 - accuracy: 0.9090
Epoch 79/250
32/32 [==============================] - 0s 2ms/step - loss: 0.4733 - accuracy: 0.9460
Epoch 80/250
32/32 [==============================] - 0s 2ms/step - loss: 0.4632 - accuracy: 0.9600
Epoch 81/250
32/32 [==============================] - 0s 1ms/step - loss: 0.4546 - accuracy: 0.9600
Epoch 82/250
32/32 [==============================] - 0s 2ms/step - loss: 0.4456 - accuracy: 0.9580
Epoch 83/250
32/32 [==============================] - 0s 1ms/step - loss: 0.4360 - accuracy: 0.9630
Epoch 84/250
32/32 [==============================] - 0s 2ms/step - loss: 0.4260 - accuracy: 0.9690
Epoch 85/250
32/32 [==============================] - 0s 1ms/step - loss: 0.4145 - accuracy: 0.9700
Epoch 86/250
32/32 [==============================] - 0s 1ms/step - loss: 0.4059 - accuracy: 0.9740
Epoch 87/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3962 - accuracy: 0.9750
Epoch 88/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3873 - accuracy: 0.9720
Epoch 89/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3795 - accuracy: 0.9750
Epoch 90/250
32/32 [==============================] - 0s 2ms/step - loss: 0.3716 - accuracy: 0.9750
Epoch 91/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3635 - accuracy: 0.9840
Epoch 92/250
32/32 [==============================] - 0s 2ms/step - loss: 0.3554 - accuracy: 0.9830
Epoch 93/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3482 - accuracy: 0.9800
Epoch 94/250
32/32 [==============================] - 0s 2ms/step - loss: 0.3404 - accuracy: 0.9820
Epoch 95/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3329 - accuracy: 0.9880
Epoch 96/250
32/32 [==============================] - 0s 2ms/step - loss: 0.3268 - accuracy: 0.9870
Epoch 97/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3190 - accuracy: 0.9870
Epoch 98/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3122 - accuracy: 0.9890
Epoch 99/250
32/32 [==============================] - 0s 1ms/step - loss: 0.3059 - accuracy: 0.9880
Epoch 100/250
32/32 [==============================] - 0s 2ms/step - loss: 0.2993 - accuracy: 0.9890
Epoch 101/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2931 - accuracy: 0.9900
Epoch 102/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2871 - accuracy: 0.9900
Epoch 103/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2805 - accuracy: 0.9900
Epoch 104/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2749 - accuracy: 0.9920
Epoch 105/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2698 - accuracy: 0.9910
Epoch 106/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2639 - accuracy: 0.9910
Epoch 107/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2589 - accuracy: 0.9900
Epoch 108/250
32/32 [==============================] - 0s 2ms/step - loss: 0.2539 - accuracy: 0.9890
Epoch 109/250
32/32 [==============================] - 0s 2ms/step - loss: 0.2483 - accuracy: 0.9920
Epoch 110/250
32/32 [==============================] - 0s 2ms/step - loss: 0.2433 - accuracy: 0.9920
Epoch 111/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2390 - accuracy: 0.9900
Epoch 112/250
32/32 [==============================] - 0s 2ms/step - loss: 0.2354 - accuracy: 0.9900
Epoch 113/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2293 - accuracy: 0.9910
Epoch 114/250
32/32 [==============================] - 0s 2ms/step - loss: 0.2251 - accuracy: 0.9910
Epoch 115/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2209 - accuracy: 0.9920
Epoch 116/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2164 - accuracy: 0.9920
Epoch 117/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2130 - accuracy: 0.9900
Epoch 118/250
32/32 [==============================] - 0s 2ms/step - loss: 0.2092 - accuracy: 0.9910
Epoch 119/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2050 - accuracy: 0.9910
Epoch 120/250
32/32 [==============================] - 0s 1ms/step - loss: 0.2016 - accuracy: 0.9890
Epoch 121/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1979 - accuracy: 0.9920
Epoch 122/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1938 - accuracy: 0.9910
Epoch 123/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1906 - accuracy: 0.9920
Epoch 124/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1872 - accuracy: 0.9910
Epoch 125/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1839 - accuracy: 0.9900
Epoch 126/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1809 - accuracy: 0.9920
Epoch 127/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1771 - accuracy: 0.9910
Epoch 128/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1747 - accuracy: 0.9920
Epoch 129/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1712 - accuracy: 0.9930
Epoch 130/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1682 - accuracy: 0.9930
Epoch 131/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1662 - accuracy: 0.9910
Epoch 132/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1630 - accuracy: 0.9930
Epoch 133/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1603 - accuracy: 0.9910
Epoch 134/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1578 - accuracy: 0.9910
Epoch 135/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1552 - accuracy: 0.9940
Epoch 136/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1530 - accuracy: 0.9920
Epoch 137/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1510 - accuracy: 0.9920
Epoch 138/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1480 - accuracy: 0.9930
Epoch 139/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1459 - accuracy: 0.9920
Epoch 140/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1439 - accuracy: 0.9910
Epoch 141/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1420 - accuracy: 0.9930
Epoch 142/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1392 - accuracy: 0.9940
Epoch 143/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1376 - accuracy: 0.9920
Epoch 144/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1356 - accuracy: 0.9930
Epoch 145/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1332 - accuracy: 0.9920
Epoch 146/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1314 - accuracy: 0.9910
Epoch 147/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1295 - accuracy: 0.9900
Epoch 148/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1276 - accuracy: 0.9930
Epoch 149/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1257 - accuracy: 0.9930
Epoch 150/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1242 - accuracy: 0.9920
Epoch 151/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1229 - accuracy: 0.9910
Epoch 152/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1208 - accuracy: 0.9920
Epoch 153/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1190 - accuracy: 0.9930
Epoch 154/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1174 - accuracy: 0.9920
Epoch 155/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1156 - accuracy: 0.9940
Epoch 156/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1143 - accuracy: 0.9930
Epoch 157/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1128 - accuracy: 0.9920
Epoch 158/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1112 - accuracy: 0.9930
Epoch 159/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1099 - accuracy: 0.9920
Epoch 160/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1090 - accuracy: 0.9900
Epoch 161/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1079 - accuracy: 0.9930
Epoch 162/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1058 - accuracy: 0.9930
Epoch 163/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1046 - accuracy: 0.9940
Epoch 164/250
32/32 [==============================] - 0s 1ms/step - loss: 0.1031 - accuracy: 0.9930
Epoch 165/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1027 - accuracy: 0.9890
Epoch 166/250
32/32 [==============================] - 0s 2ms/step - loss: 0.1010 - accuracy: 0.9930
Epoch 167/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0996 - accuracy: 0.9930
Epoch 168/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0986 - accuracy: 0.9920
Epoch 169/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0970 - accuracy: 0.9930
Epoch 170/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0959 - accuracy: 0.9920
Epoch 171/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0949 - accuracy: 0.9920
Epoch 172/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0937 - accuracy: 0.9920
Epoch 173/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0926 - accuracy: 0.9930
Epoch 174/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0915 - accuracy: 0.9920
Epoch 175/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0913 - accuracy: 0.9910
Epoch 176/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0900 - accuracy: 0.9930
Epoch 177/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0885 - accuracy: 0.9940
Epoch 178/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0882 - accuracy: 0.9900
Epoch 179/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0869 - accuracy: 0.9920
Epoch 180/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0859 - accuracy: 0.9930
Epoch 181/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0851 - accuracy: 0.9930
Epoch 182/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0840 - accuracy: 0.9920
Epoch 183/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0831 - accuracy: 0.9920
Epoch 184/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0823 - accuracy: 0.9920
Epoch 185/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0816 - accuracy: 0.9940
Epoch 186/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0809 - accuracy: 0.9930
Epoch 187/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0801 - accuracy: 0.9940
Epoch 188/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0786 - accuracy: 0.9920
Epoch 189/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0780 - accuracy: 0.9930
Epoch 190/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0773 - accuracy: 0.9930
Epoch 191/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0767 - accuracy: 0.9920
Epoch 192/250
32/32 [==============================] - 0s 5ms/step - loss: 0.0759 - accuracy: 0.9910
Epoch 193/250
32/32 [==============================] - 0s 7ms/step - loss: 0.0748 - accuracy: 0.9910
Epoch 194/250
32/32 [==============================] - 0s 6ms/step - loss: 0.0742 - accuracy: 0.9920
Epoch 195/250
32/32 [==============================] - 0s 3ms/step - loss: 0.0735 - accuracy: 0.9930
Epoch 196/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0728 - accuracy: 0.9920
Epoch 197/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0719 - accuracy: 0.9920
Epoch 198/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0716 - accuracy: 0.9930
Epoch 199/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0704 - accuracy: 0.9920
Epoch 200/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0702 - accuracy: 0.9920
Epoch 201/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0695 - accuracy: 0.9930
Epoch 202/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0686 - accuracy: 0.9930
Epoch 203/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0682 - accuracy: 0.9930
Epoch 204/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0671 - accuracy: 0.9920
Epoch 205/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0668 - accuracy: 0.9930
Epoch 206/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0666 - accuracy: 0.9930
Epoch 207/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0654 - accuracy: 0.9920
Epoch 208/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0654 - accuracy: 0.9930
Epoch 209/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0647 - accuracy: 0.9920
Epoch 210/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0641 - accuracy: 0.9920
Epoch 211/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0643 - accuracy: 0.9920
Epoch 212/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0627 - accuracy: 0.9920
Epoch 213/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0623 - accuracy: 0.9920
Epoch 214/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0615 - accuracy: 0.9930
Epoch 215/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0610 - accuracy: 0.9920
Epoch 216/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0610 - accuracy: 0.9910
Epoch 217/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0599 - accuracy: 0.9930
Epoch 218/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0594 - accuracy: 0.9910
Epoch 219/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0591 - accuracy: 0.9930
Epoch 220/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0589 - accuracy: 0.9920
Epoch 221/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0583 - accuracy: 0.9930
Epoch 222/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0575 - accuracy: 0.9920
Epoch 223/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0574 - accuracy: 0.9930
Epoch 224/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0569 - accuracy: 0.9930
Epoch 225/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0567 - accuracy: 0.9950
Epoch 226/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0560 - accuracy: 0.9920
Epoch 227/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0554 - accuracy: 0.9950
Epoch 228/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0549 - accuracy: 0.9920
Epoch 229/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0543 - accuracy: 0.9920
Epoch 230/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0538 - accuracy: 0.9930
Epoch 231/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0533 - accuracy: 0.9930
Epoch 232/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0531 - accuracy: 0.9920
Epoch 233/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0529 - accuracy: 0.9930
Epoch 234/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0523 - accuracy: 0.9930
Epoch 235/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0519 - accuracy: 0.9930
Epoch 236/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0515 - accuracy: 0.9930
Epoch 237/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0513 - accuracy: 0.9900
Epoch 238/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0512 - accuracy: 0.9920
Epoch 239/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0503 - accuracy: 0.9930
Epoch 240/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0503 - accuracy: 0.9940
Epoch 241/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0500 - accuracy: 0.9920
Epoch 242/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0494 - accuracy: 0.9930
Epoch 243/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0491 - accuracy: 0.9930
Epoch 244/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0492 - accuracy: 0.9920
Epoch 245/250
32/32 [==============================] - 0s 1ms/step - loss: 0.0487 - accuracy: 0.9940
Epoch 246/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0483 - accuracy: 0.9930
Epoch 247/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0479 - accuracy: 0.9950
Epoch 248/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0475 - accuracy: 0.9930
Epoch 249/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0471 - accuracy: 0.9950
Epoch 250/250
32/32 [==============================] - 0s 2ms/step - loss: 0.0471 - accuracy: 0.9940
model_7.evaluate(X,y)
32/32 [==============================] - 0s 1ms/step - loss: 0.0459 - accuracy: 0.9920
[0.04593363776803017, 0.9919999837875366]
plot_decision_boundary(model_7,X,y)
doing binary classification

Wow, we are very close our model segregated the data points almost all the blue ones are inside the blue decision boundary.

Note: The combination of linear(straight lines) and non-linear(non-straight lines) functions is one of they key fundamentals of neural networks.

A = tf.cast(tf.range(-10,10), tf.float32)
A
<tf.Tensor: shape=(20,), dtype=float32, numpy=
array([-10.,  -9.,  -8.,  -7.,  -6.,  -5.,  -4.,  -3.,  -2.,  -1.,   0.,
         1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.],
      dtype=float32)>
plt.plot(A);

It's a straight line!!

def sigmoid(x):
  return 1/(1+tf.exp(-x))

# Use the sigmoid function on our toy tensor
sigmoid(A)
<tf.Tensor: shape=(20,), dtype=float32, numpy=
array([4.5397872e-05, 1.2339458e-04, 3.3535014e-04, 9.1105117e-04,
       2.4726233e-03, 6.6928510e-03, 1.7986210e-02, 4.7425874e-02,
       1.1920292e-01, 2.6894143e-01, 5.0000000e-01, 7.3105860e-01,
       8.8079703e-01, 9.5257413e-01, 9.8201376e-01, 9.9330717e-01,
       9.9752742e-01, 9.9908900e-01, 9.9966466e-01, 9.9987662e-01],
      dtype=float32)>
plt.plot(sigmoid(A));

The sigmoid function transformed the linear graph into non-linear plot

def relu(x):
  return tf.maximum(0,x)

relu(A)
<tf.Tensor: shape=(20,), dtype=float32, numpy=
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 5., 6.,
       7., 8., 9.], dtype=float32)>
plt.plot(relu(A));
tf.keras.activations.linear(A)
<tf.Tensor: shape=(20,), dtype=float32, numpy=
array([-10.,  -9.,  -8.,  -7.,  -6.,  -5.,  -4.,  -3.,  -2.,  -1.,   0.,
         1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.],
      dtype=float32)>
plt.plot(tf.keras.activations.linear(A));

So, a linear function doesn't do anything for our input data. So for our data which had non-linear relation it failed to plot the best decision boundary.

A brief review of standard activation functions:

  • Linear: tf.keras.activations.linear(A)
  • Sigmoid: tf.keras.activations.sigmoid(A)
  • ReLU: tf.keras.activations.relu(A)

Evaluating and improving our classification model

so far we have been training and testing on the same data set. But we risk the model overfitting more to training data and achieve high accuracy on train set but fail to give us correct predictions on test set. And that is disastrous for an ML application. Three sets of data:

  • Training set
  • Validation set
  • Test set
X_train, y_train = X[:800], y[:800]
X_test, y_test = X[800:], y[800:]

X_train.shape, X_test.shape, y_train.shape, y_test.shape
((800, 2), (200, 2), (800,), (200,))
# Let's create a model to fit on the training data and evaluate on the testing data

# Set the random seed
tf.random.set_seed(42)

# 1. Create the model (same as model_7)
model_8 = tf.keras.Sequential([
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(1, activation = "sigmoid")                          
])

# 2. Compile the Modle
model_8.compile(loss = "binary_crossentropy",
                optimizer = tf.keras.optimizers.Adam(lr = 0.01),
                metrics = ["accuracy"])

# 3. Fit the Model
history = model_8.fit(X_train, y_train, epochs = 25)

/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/adam.py:105: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.
  super(Adam, self).__init__(name, **kwargs)
Epoch 1/25
25/25 [==============================] - 1s 2ms/step - loss: 0.6847 - accuracy: 0.5425
Epoch 2/25
25/25 [==============================] - 0s 2ms/step - loss: 0.6777 - accuracy: 0.5525
Epoch 3/25
25/25 [==============================] - 0s 2ms/step - loss: 0.6736 - accuracy: 0.5512
Epoch 4/25
25/25 [==============================] - 0s 3ms/step - loss: 0.6681 - accuracy: 0.5775
Epoch 5/25
25/25 [==============================] - 0s 3ms/step - loss: 0.6633 - accuracy: 0.5850
Epoch 6/25
25/25 [==============================] - 0s 2ms/step - loss: 0.6546 - accuracy: 0.5838
Epoch 7/25
25/25 [==============================] - 0s 3ms/step - loss: 0.6413 - accuracy: 0.6750
Epoch 8/25
25/25 [==============================] - 0s 3ms/step - loss: 0.6264 - accuracy: 0.7013
Epoch 9/25
25/25 [==============================] - 0s 3ms/step - loss: 0.6038 - accuracy: 0.7487
Epoch 10/25
25/25 [==============================] - 0s 2ms/step - loss: 0.5714 - accuracy: 0.7738
Epoch 11/25
25/25 [==============================] - 0s 3ms/step - loss: 0.5404 - accuracy: 0.7650
Epoch 12/25
25/25 [==============================] - 0s 3ms/step - loss: 0.5015 - accuracy: 0.7837
Epoch 13/25
25/25 [==============================] - 0s 3ms/step - loss: 0.4683 - accuracy: 0.7975
Epoch 14/25
25/25 [==============================] - 0s 3ms/step - loss: 0.4113 - accuracy: 0.8450
Epoch 15/25
25/25 [==============================] - 0s 3ms/step - loss: 0.3625 - accuracy: 0.9125
Epoch 16/25
25/25 [==============================] - 0s 3ms/step - loss: 0.3209 - accuracy: 0.9312
Epoch 17/25
25/25 [==============================] - 0s 3ms/step - loss: 0.2847 - accuracy: 0.9488
Epoch 18/25
25/25 [==============================] - 0s 3ms/step - loss: 0.2597 - accuracy: 0.9525
Epoch 19/25
25/25 [==============================] - 0s 3ms/step - loss: 0.2375 - accuracy: 0.9563
Epoch 20/25
25/25 [==============================] - 0s 2ms/step - loss: 0.2135 - accuracy: 0.9663
Epoch 21/25
25/25 [==============================] - 0s 2ms/step - loss: 0.1938 - accuracy: 0.9775
Epoch 22/25
25/25 [==============================] - 0s 3ms/step - loss: 0.1752 - accuracy: 0.9737
Epoch 23/25
25/25 [==============================] - 0s 3ms/step - loss: 0.1619 - accuracy: 0.9787
Epoch 24/25
25/25 [==============================] - 0s 3ms/step - loss: 0.1550 - accuracy: 0.9775
Epoch 25/25
25/25 [==============================] - 0s 3ms/step - loss: 0.1490 - accuracy: 0.9762
model_8.evaluate(X_test, y_test)
7/7 [==============================] - 0s 6ms/step - loss: 0.1247 - accuracy: 1.0000
[0.1246885135769844, 1.0]
plt.figure(figsize = (12,6))
plt.subplot(1,2,1)
plt.title("Train")
plot_decision_boundary(model_8, X_train, y_train)
plt.subplot(1,2,2)
plt.title("Test")
plot_decision_boundary(model_8, X_test, y_test)
doing binary classification
doing binary classification

Excellent!! our model performed with 100% accuracy on the test set and that too with 25 epochs (because we have turned up the learning rate by 10X)

model_8.summary()
Model: "sequential_8"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_17 (Dense)            (32, 4)                   12        
                                                                 
 dense_18 (Dense)            (32, 4)                   20        
                                                                 
 dense_19 (Dense)            (32, 1)                   5         
                                                                 
=================================================================
Total params: 37
Trainable params: 37
Non-trainable params: 0
_________________________________________________________________

Plot the Loss or Training Curve:

history.history

{'accuracy': [0.5425000190734863,
  0.5525000095367432,
  0.5512499809265137,
  0.5774999856948853,
  0.5849999785423279,
  0.5837500095367432,
  0.675000011920929,
  0.7012500166893005,
  0.7487499713897705,
  0.7737500071525574,
  0.7649999856948853,
  0.7837499976158142,
  0.7975000143051147,
  0.8450000286102295,
  0.9125000238418579,
  0.9312499761581421,
  0.9487500190734863,
  0.9524999856948853,
  0.956250011920929,
  0.9662500023841858,
  0.9775000214576721,
  0.9737499952316284,
  0.9787499904632568,
  0.9775000214576721,
  0.9762499928474426],
 'loss': [0.6846511960029602,
  0.6777209639549255,
  0.6735945343971252,
  0.6681485772132874,
  0.6632686853408813,
  0.6545672416687012,
  0.6412575244903564,
  0.6264281272888184,
  0.6038310527801514,
  0.5714036226272583,
  0.540442943572998,
  0.5015039443969727,
  0.46833187341690063,
  0.4113016128540039,
  0.3625059425830841,
  0.32090437412261963,
  0.2847079932689667,
  0.25971999764442444,
  0.23746901750564575,
  0.21351958811283112,
  0.1938202977180481,
  0.17524366080760956,
  0.16189303994178772,
  0.1549890637397766,
  0.14897282421588898]}
# Convert the history object into a DataFrame
pd.DataFrame(history.history)

loss accuracy
0 0.684651 0.54250
1 0.677721 0.55250
2 0.673595 0.55125
3 0.668149 0.57750
4 0.663269 0.58500
5 0.654567 0.58375
6 0.641258 0.67500
7 0.626428 0.70125
8 0.603831 0.74875
9 0.571404 0.77375
10 0.540443 0.76500
11 0.501504 0.78375
12 0.468332 0.79750
13 0.411302 0.84500
14 0.362506 0.91250
15 0.320904 0.93125
16 0.284708 0.94875
17 0.259720 0.95250
18 0.237469 0.95625
19 0.213520 0.96625
20 0.193820 0.97750
21 0.175244 0.97375
22 0.161893 0.97875
23 0.154989 0.97750
24 0.148973 0.97625
pd.DataFrame(history.history).plot()
plt.title("Loss curve of Model_8")
Text(0.5, 1.0, 'Loss curve of Model_8')

Note: For many problems, the loss function going down means the model is improving (the predictions it's maksing are getting closer to the ground truth labels)

Finding the best learning rate

To find the ideal learning rate (the learning rate where the loss decreases the most during training) we're going to use the following steps:

  • A learning rate callback - you can think of a call back as an extra piece of functionality, you can add to your model while training
  • Create another model
  • A modified loss curve plot
# Set the random seed
tf.random.set_seed(42)

# Create a model (same as model_8)
model_9 = tf.keras.Sequential([
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(1, activation = "sigmoid")                                      
])

# Compile the Model
model_9.compile(loss = "binary_crossentropy",
                optimizer = "Adam",
                metrics = ["accuracy"])

# Create a learning rate call back
lr_scheduler = tf.keras.callbacks.LearningRateScheduler(lambda epoch: 1e-4 * 10**(epoch/20))


# Fit the model
history_9 = model_9.fit(X_train,
                        y_train,
                        epochs = 100,
                        callbacks = [lr_scheduler])

Epoch 1/100
25/25 [==============================] - 1s 3ms/step - loss: 0.6945 - accuracy: 0.4988 - lr: 1.0000e-04
Epoch 2/100
25/25 [==============================] - 0s 4ms/step - loss: 0.6938 - accuracy: 0.4975 - lr: 1.1220e-04
Epoch 3/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6930 - accuracy: 0.4963 - lr: 1.2589e-04
Epoch 4/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6922 - accuracy: 0.4975 - lr: 1.4125e-04
Epoch 5/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6914 - accuracy: 0.5063 - lr: 1.5849e-04
Epoch 6/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6906 - accuracy: 0.5013 - lr: 1.7783e-04
Epoch 7/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6898 - accuracy: 0.4950 - lr: 1.9953e-04
Epoch 8/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6889 - accuracy: 0.5038 - lr: 2.2387e-04
Epoch 9/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6880 - accuracy: 0.5013 - lr: 2.5119e-04
Epoch 10/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6871 - accuracy: 0.5050 - lr: 2.8184e-04
Epoch 11/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6863 - accuracy: 0.5200 - lr: 3.1623e-04
Epoch 12/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6856 - accuracy: 0.5163 - lr: 3.5481e-04
Epoch 13/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6847 - accuracy: 0.5175 - lr: 3.9811e-04
Epoch 14/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6842 - accuracy: 0.5200 - lr: 4.4668e-04
Epoch 15/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6835 - accuracy: 0.5213 - lr: 5.0119e-04
Epoch 16/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6829 - accuracy: 0.5213 - lr: 5.6234e-04
Epoch 17/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6826 - accuracy: 0.5225 - lr: 6.3096e-04
Epoch 18/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6819 - accuracy: 0.5300 - lr: 7.0795e-04
Epoch 19/100
25/25 [==============================] - 0s 3ms/step - loss: 0.6816 - accuracy: 0.5312 - lr: 7.9433e-04
Epoch 20/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6811 - accuracy: 0.5387 - lr: 8.9125e-04
Epoch 21/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6806 - accuracy: 0.5400 - lr: 0.0010
Epoch 22/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6801 - accuracy: 0.5412 - lr: 0.0011
Epoch 23/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6796 - accuracy: 0.5400 - lr: 0.0013
Epoch 24/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6790 - accuracy: 0.5425 - lr: 0.0014
Epoch 25/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6784 - accuracy: 0.5450 - lr: 0.0016
Epoch 26/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6778 - accuracy: 0.5387 - lr: 0.0018
Epoch 27/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6770 - accuracy: 0.5425 - lr: 0.0020
Epoch 28/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6760 - accuracy: 0.5537 - lr: 0.0022
Epoch 29/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6754 - accuracy: 0.5512 - lr: 0.0025
Epoch 30/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6739 - accuracy: 0.5575 - lr: 0.0028
Epoch 31/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6726 - accuracy: 0.5500 - lr: 0.0032
Epoch 32/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6711 - accuracy: 0.5512 - lr: 0.0035
Epoch 33/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6688 - accuracy: 0.5562 - lr: 0.0040
Epoch 34/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6672 - accuracy: 0.5612 - lr: 0.0045
Epoch 35/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6660 - accuracy: 0.5888 - lr: 0.0050
Epoch 36/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6625 - accuracy: 0.5625 - lr: 0.0056
Epoch 37/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6560 - accuracy: 0.5813 - lr: 0.0063
Epoch 38/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6521 - accuracy: 0.6025 - lr: 0.0071
Epoch 39/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6415 - accuracy: 0.7088 - lr: 0.0079
Epoch 40/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6210 - accuracy: 0.7113 - lr: 0.0089
Epoch 41/100
25/25 [==============================] - 0s 1ms/step - loss: 0.5904 - accuracy: 0.7487 - lr: 0.0100
Epoch 42/100
25/25 [==============================] - 0s 2ms/step - loss: 0.5688 - accuracy: 0.7312 - lr: 0.0112
Epoch 43/100
25/25 [==============================] - 0s 1ms/step - loss: 0.5346 - accuracy: 0.7563 - lr: 0.0126
Epoch 44/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4533 - accuracy: 0.8150 - lr: 0.0141
Epoch 45/100
25/25 [==============================] - 0s 1ms/step - loss: 0.3455 - accuracy: 0.9112 - lr: 0.0158
Epoch 46/100
25/25 [==============================] - 0s 2ms/step - loss: 0.2570 - accuracy: 0.9463 - lr: 0.0178
Epoch 47/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1968 - accuracy: 0.9575 - lr: 0.0200
Epoch 48/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1336 - accuracy: 0.9700 - lr: 0.0224
Epoch 49/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1310 - accuracy: 0.9613 - lr: 0.0251
Epoch 50/100
25/25 [==============================] - 0s 1ms/step - loss: 0.1002 - accuracy: 0.9700 - lr: 0.0282
Epoch 51/100
25/25 [==============================] - 0s 1ms/step - loss: 0.1166 - accuracy: 0.9638 - lr: 0.0316
Epoch 52/100
25/25 [==============================] - 0s 1ms/step - loss: 0.1368 - accuracy: 0.9513 - lr: 0.0355
Epoch 53/100
25/25 [==============================] - 0s 1ms/step - loss: 0.0879 - accuracy: 0.9787 - lr: 0.0398
Epoch 54/100
25/25 [==============================] - 0s 1ms/step - loss: 0.1187 - accuracy: 0.9588 - lr: 0.0447
Epoch 55/100
25/25 [==============================] - 0s 2ms/step - loss: 0.0733 - accuracy: 0.9712 - lr: 0.0501
Epoch 56/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1132 - accuracy: 0.9550 - lr: 0.0562
Epoch 57/100
25/25 [==============================] - 0s 1ms/step - loss: 0.1057 - accuracy: 0.9613 - lr: 0.0631
Epoch 58/100
25/25 [==============================] - 0s 1ms/step - loss: 0.0664 - accuracy: 0.9750 - lr: 0.0708
Epoch 59/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1898 - accuracy: 0.9275 - lr: 0.0794
Epoch 60/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1895 - accuracy: 0.9312 - lr: 0.0891
Epoch 61/100
25/25 [==============================] - 0s 1ms/step - loss: 0.4131 - accuracy: 0.8612 - lr: 0.1000
Epoch 62/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1707 - accuracy: 0.9725 - lr: 0.1122
Epoch 63/100
25/25 [==============================] - 0s 2ms/step - loss: 0.0569 - accuracy: 0.9937 - lr: 0.1259
Epoch 64/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1007 - accuracy: 0.9638 - lr: 0.1413
Epoch 65/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1323 - accuracy: 0.9488 - lr: 0.1585
Epoch 66/100
25/25 [==============================] - 0s 2ms/step - loss: 0.1819 - accuracy: 0.9375 - lr: 0.1778
Epoch 67/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6672 - accuracy: 0.7613 - lr: 0.1995
Epoch 68/100
25/25 [==============================] - 0s 1ms/step - loss: 0.5301 - accuracy: 0.6687 - lr: 0.2239
Epoch 69/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4140 - accuracy: 0.7925 - lr: 0.2512
Epoch 70/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4574 - accuracy: 0.7412 - lr: 0.2818
Epoch 71/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4759 - accuracy: 0.7262 - lr: 0.3162
Epoch 72/100
25/25 [==============================] - 0s 2ms/step - loss: 0.3748 - accuracy: 0.8112 - lr: 0.3548
Epoch 73/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4710 - accuracy: 0.8150 - lr: 0.3981
Epoch 74/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4143 - accuracy: 0.8087 - lr: 0.4467
Epoch 75/100
25/25 [==============================] - 0s 2ms/step - loss: 0.5961 - accuracy: 0.7412 - lr: 0.5012
Epoch 76/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4787 - accuracy: 0.7713 - lr: 0.5623
Epoch 77/100
25/25 [==============================] - 0s 2ms/step - loss: 0.4720 - accuracy: 0.7113 - lr: 0.6310
Epoch 78/100
25/25 [==============================] - 0s 2ms/step - loss: 0.2565 - accuracy: 0.8675 - lr: 0.7079
Epoch 79/100
25/25 [==============================] - 0s 2ms/step - loss: 1.1824 - accuracy: 0.6275 - lr: 0.7943
Epoch 80/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6873 - accuracy: 0.5425 - lr: 0.8913
Epoch 81/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7068 - accuracy: 0.5575 - lr: 1.0000
Epoch 82/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6879 - accuracy: 0.5838 - lr: 1.1220
Epoch 83/100
25/25 [==============================] - 0s 2ms/step - loss: 0.6996 - accuracy: 0.5700 - lr: 1.2589
Epoch 84/100
25/25 [==============================] - 0s 1ms/step - loss: 0.6471 - accuracy: 0.5863 - lr: 1.4125
Epoch 85/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7457 - accuracy: 0.5312 - lr: 1.5849
Epoch 86/100
25/25 [==============================] - 0s 1ms/step - loss: 0.7546 - accuracy: 0.5038 - lr: 1.7783
Epoch 87/100
25/25 [==============================] - 0s 1ms/step - loss: 0.7681 - accuracy: 0.5063 - lr: 1.9953
Epoch 88/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7596 - accuracy: 0.4963 - lr: 2.2387
Epoch 89/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7778 - accuracy: 0.5063 - lr: 2.5119
Epoch 90/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7741 - accuracy: 0.4787 - lr: 2.8184
Epoch 91/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7851 - accuracy: 0.5163 - lr: 3.1623
Epoch 92/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7441 - accuracy: 0.4888 - lr: 3.5481
Epoch 93/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7354 - accuracy: 0.5163 - lr: 3.9811
Epoch 94/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7548 - accuracy: 0.4938 - lr: 4.4668
Epoch 95/100
25/25 [==============================] - 0s 2ms/step - loss: 0.8087 - accuracy: 0.4863 - lr: 5.0119
Epoch 96/100
25/25 [==============================] - 0s 2ms/step - loss: 0.7714 - accuracy: 0.4638 - lr: 5.6234
Epoch 97/100
25/25 [==============================] - 0s 2ms/step - loss: 0.8001 - accuracy: 0.5013 - lr: 6.3096
Epoch 98/100
25/25 [==============================] - 0s 1ms/step - loss: 0.9554 - accuracy: 0.4963 - lr: 7.0795
Epoch 99/100
25/25 [==============================] - 0s 1ms/step - loss: 0.9268 - accuracy: 0.4913 - lr: 7.9433
Epoch 100/100
25/25 [==============================] - 0s 2ms/step - loss: 0.8563 - accuracy: 0.4663 - lr: 8.9125
pd.DataFrame(history_9.history).plot(figsize=(10,7), xlabel = "epochs");
# Plot the learning rate versus the loss
lrs = 1e-4 * (10**(tf.range(100)/20))
plt.figure(figsize=(10,7))
plt.semilogx(lrs, history_9.history["loss"])
plt.xlabel("Learning rate")
plt.ylabel("Loss")
plt.title("learning rate vs. Loss");

Let's analyze the plot and pick the best learning rate. You can use this plot to pick the learning rate when you are trying to improve the performance of your model. genearally the default learning rates that come with the pre-built functions works well too.

In this case, pick the learning rate around the value where the the loss decreases faster.

10**0, 10**-1, 10**-2, 10**-3, 10**-4
(1, 0.1, 0.01, 0.001, 0.0001)

Pick the value 0.02 where the loss is still decreasing steadily.

10**-2
0.01
# Let's try using a higher *ideal*  learning rate with the same model

# Set the random seed
tf.random.set_seed(42)

# Create a model (same as model_8)
model_10 = tf.keras.Sequential([
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(1, activation = "sigmoid")                                      
])

# Compile the Model
model_10.compile(loss = "binary_crossentropy",
                optimizer = tf.keras.optimizers.Adam(lr = 0.02),
                metrics = ["accuracy"])



# Fit the model with 20 epochs(5 less than before)
history_10 = model_10.fit(X_train,
                        y_train,
                        epochs = 20)

/usr/local/lib/python3.7/dist-packages/keras/optimizer_v2/adam.py:105: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.
  super(Adam, self).__init__(name, **kwargs)
Epoch 1/20
25/25 [==============================] - 0s 1ms/step - loss: 0.6837 - accuracy: 0.5600
Epoch 2/20
25/25 [==============================] - 0s 1ms/step - loss: 0.6744 - accuracy: 0.5750
Epoch 3/20
25/25 [==============================] - 0s 1ms/step - loss: 0.6626 - accuracy: 0.5875
Epoch 4/20
25/25 [==============================] - 0s 1ms/step - loss: 0.6332 - accuracy: 0.6388
Epoch 5/20
25/25 [==============================] - 0s 2ms/step - loss: 0.5830 - accuracy: 0.7563
Epoch 6/20
25/25 [==============================] - 0s 1ms/step - loss: 0.4907 - accuracy: 0.8313
Epoch 7/20
25/25 [==============================] - 0s 2ms/step - loss: 0.4251 - accuracy: 0.8450
Epoch 8/20
25/25 [==============================] - 0s 1ms/step - loss: 0.3596 - accuracy: 0.8875
Epoch 9/20
25/25 [==============================] - 0s 2ms/step - loss: 0.3152 - accuracy: 0.9100
Epoch 10/20
25/25 [==============================] - 0s 1ms/step - loss: 0.2512 - accuracy: 0.9500
Epoch 11/20
25/25 [==============================] - 0s 1ms/step - loss: 0.2152 - accuracy: 0.9500
Epoch 12/20
25/25 [==============================] - 0s 2ms/step - loss: 0.1721 - accuracy: 0.9750
Epoch 13/20
25/25 [==============================] - 0s 2ms/step - loss: 0.1443 - accuracy: 0.9837
Epoch 14/20
25/25 [==============================] - 0s 2ms/step - loss: 0.1232 - accuracy: 0.9862
Epoch 15/20
25/25 [==============================] - 0s 2ms/step - loss: 0.1085 - accuracy: 0.9850
Epoch 16/20
25/25 [==============================] - 0s 2ms/step - loss: 0.0940 - accuracy: 0.9937
Epoch 17/20
25/25 [==============================] - 0s 2ms/step - loss: 0.0827 - accuracy: 0.9962
Epoch 18/20
25/25 [==============================] - 0s 1ms/step - loss: 0.0798 - accuracy: 0.9937
Epoch 19/20
25/25 [==============================] - 0s 1ms/step - loss: 0.0845 - accuracy: 0.9875
Epoch 20/20
25/25 [==============================] - 0s 2ms/step - loss: 0.0790 - accuracy: 0.9887
model_10.evaluate(X_test,y_test)
7/7 [==============================] - 0s 3ms/step - loss: 0.0574 - accuracy: 0.9900
[0.05740184709429741, 0.9900000095367432]
model_8.evaluate(X_test,y_test)
7/7 [==============================] - 0s 3ms/step - loss: 0.1247 - accuracy: 1.0000
[0.1246885135769844, 1.0]

Which model should we chooose?
one has got the best accuracy and the other has very low loss value.

plt.figure(figsize = (12,6))
plt.subplot(1,2,1)
plt.title("Train")
plot_decision_boundary(model_10, X_train, y_train)
plt.subplot(1,2,2)
plt.title("Test")
plot_decision_boundary(model_10, X_test,y_test)
plt.show();
doing binary classification
doing binary classification

More classification evaluation methods

Alongside visualizing our models results as much as possible, there are a handful of other classification evaluation methods & metrics should be familiar with:

Classification Evaluation methods:

Keys: tp = true-positive, tn = true-negative , fp = false-positive, fn = false-negative.

Metric Name Metric Formula Code When to use
Accuracy Accuracy = $\frac{tp=tn}{tp+tn+fp+fn}$ tf.keras.metrics.Accuracy() or sklearn.metrics.accuracy_score() Default metric for classification problems. Not the bset for imbalanced cases
Precision Precision = $\frac{tp}{tp+fp}$ tf.keras.metrics.Precision() or sklearn.metrics.precision_score() High precision lead to less false positives
Recall Recall = $\frac{tp}{tp+fn}$ tf.keras.metrics.Recall() or sklearn.metrics.recall_score() Higher recall leads to less false negatives
F1-Score F1-Score = $2\frac{precision \cdot recall}{precision + recall}$ sklearn.metrics.f1_score() Combination of precision and recall, usually a good overall metric for a classification model
Confusion matrix NA custom function or sklearn.metrics.confusion_matrix() When comparing predictions to truth labels to see where model gets confused. Can be hard to use with large number of classes
loss, accuracy = model_10.evaluate(X_test, y_test)
print(f"Model loss on the test set: {loss}")
print(f"Model accuracy on the test set: {(accuracy*100) : .2f}% ")
7/7 [==============================] - 0s 4ms/step - loss: 0.0574 - accuracy: 0.9900
Model loss on the test set: 0.05740184709429741
Model accuracy on the test set:  99.00% 

Anatomy of confusion matrix

  • True positive = model predicts 1 when truth is 1
  • True negative = model predicts 0 when truth is 0
  • False positive = model predicts 1 when truth is 0
  • False negative = model predicts 0 when truth is 1

In the confusion matrix the correct predictions are along the diagonals.(i.e. True positives, True negatives)

from sklearn.metrics import confusion_matrix

# Make predictions
y_preds  = model_10.predict(X_test)

# Create confusion matrix
confusion_matrix(y_test, y_preds)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-68-c579ca7d54a1> in <module>()
      6 
      7 # Create confusion matrix
----> 8 confusion_matrix(y_test,y_preds)

/usr/local/lib/python3.7/dist-packages/sklearn/metrics/_classification.py in confusion_matrix(y_true, y_pred, labels, sample_weight, normalize)
    305     (0, 2, 1, 1)
    306     """
--> 307     y_type, y_true, y_pred = _check_targets(y_true, y_pred)
    308     if y_type not in ("binary", "multiclass"):
    309         raise ValueError("%s is not supported" % y_type)

/usr/local/lib/python3.7/dist-packages/sklearn/metrics/_classification.py in _check_targets(y_true, y_pred)
     93         raise ValueError(
     94             "Classification metrics can't handle a mix of {0} and {1} targets".format(
---> 95                 type_true, type_pred
     96             )
     97         )

ValueError: Classification metrics can't handle a mix of binary and continuous targets

Let's check the values of y_preds we passed in

y_preds[1:10]
array([[9.9923790e-01],
       [9.9032348e-01],
       [9.9706942e-01],
       [3.9622977e-01],
       [1.8126935e-02],
       [9.6829069e-01],
       [1.9746721e-02],
       [9.9967170e-01],
       [5.6460500e-04]], dtype=float32)

Looks like our predictions array has come out in prediction probability form. The standard output from the sigmoid(or softmax)

tf.round(y_preds)[:10]
<tf.Tensor: shape=(10, 1), dtype=float32, numpy=
array([[1.],
       [1.],
       [1.],
       [1.],
       [0.],
       [0.],
       [1.],
       [0.],
       [1.],
       [0.]], dtype=float32)>
confusion_matrix(y_test, tf.round(y_preds))
array([[99,  2],
       [ 0, 99]])

Now, we got our confusion matrix let's evaluate and make the confusion matrix in much more understandable form

import itertools

figsize = (10,10)

# Create the confusion matrix
cm = confusion_matrix(y_test, tf.round(y_preds))
cm_norm = cm.astype("float")/ cm.sum(axis = 1)[:, np.newaxis] # Noramlize our confusion matrix 
n_classes = cm.shape[0]

# Let's make it neat and clear
fig, ax = plt.subplots(figsize = figsize)
# Create a matrix plot
cax = ax.matshow(cm, cmap = plt.cm.Blues)
fig.colorbar(cax)

# Create classes
classes = False

if classes:
  labels  = classes
else:
  labels = np.arange(cm.shape[0])

# Let's label the axis
ax.set(title = "Confusion Matrix",
       xlabel = "Predicted Label",
       ylabel = "True Label",
       xticks = np.arange(n_classes),
       yticks = np.arange(n_classes),
       xticklabels = labels,
       yticklabels = labels)

# Set x-axis labels to the bottom
ax.xaxis.set_label_position("bottom")
ax.xaxis.tick_bottom()

# ADjust label size
ax.yaxis.label.set_size(20)
ax.xaxis.label.set_size(20)
ax.title.set_size(20)

# Set threshold for different colors
threshold = (cm.max() + cm.min())/2.

# Plot the text on each cell
for i,j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):

  plt.text(j, i, f"{cm[i,j]} ({cm_norm[i,j]*100:.1f}% )",
           horizontalalignment = "center",
           color = "white" if cm[i,j] > threshold else "black",
           size = 15)

We will try to code up a function to reuse the plotting of confusion matrix for another time

def plot_confusion_matrix(y_test,y_preds):
  import itertools
  figsize = (10,10)

  # Create the confusion matrix
  cm = confusion_matrix(y_test, tf.round(y_preds))
  cm_norm = cm.astype("float")/ cm.sum(axis = 1)[:, np.newaxis] # Noramlize our confusion matrix 
  n_classes = cm.shape[0]

  # Let's make it neat and clear
  fig, ax = plt.subplots(figsize = figsize)
  # Create a matrix plot
  cax = ax.matshow(cm, cmap = plt.cm.Blues)
  fig.colorbar(cax)

  # Create classes
  classes = False

  if classes:
    labels  = classes
  else:
    labels = np.arange(cm.shape[0])

  # Let's label the axis
  ax.set(title = "Confusion Matrix",
         xlabel = "Predicted Label",
         ylabel = "True Label",
         xticks = np.arange(n_classes),
         yticks = np.arange(n_classes),
         xticklabels = labels,
         yticklabels = labels)

  # Set x-axis labels to the bottom
  ax.xaxis.set_label_position("bottom")
  ax.xaxis.tick_bottom()

  # Adjust label size
  ax.yaxis.label.set_size(20)
  ax.xaxis.label.set_size(20)
  ax.title.set_size(20)

  # Set threshold for different colors
  threshold = (cm.max() + cm.min())/2.

  # Plot the text on each cell
  for i,j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):

    plt.text(j, i, f"{cm[i,j]} ({cm_norm[i,j]*100:.1f}% )",
             horizontalalignment = "center",
             color = "white" if cm[i,j] > threshold else "black",
             size = 15)
plot_confusion_matrix(y_test,y_preds)

Great, our function is working and we can reuse the function for other models from now on so that we can save time rewriting all the code for the above plot.

Working with larger examples (Multi-class Classification)

When you have more than two classes as an option, it is known as multi-class classification.

  • This means if you have 3 different classes, it's multi-class classification
  • It aslo means if we have hundred different classes, it's a multi-class classification.

To practice mutli-class classification, we are going to build a neural netowrk to classify images of different items of clothing.

import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
fashion_mnist = tf.keras.datasets.fashion_mnist
# The data has already been sorted into training and test sets for us
(train_data, train_labels), (test_data, test_labels) = fashion_mnist.load_data()
train_data[2]

array([[  0,   0,   0,   0,   0,   0,   0,   0,   0,  22, 118,  24,   0,
          0,   0,   0,   0,  48,  88,   5,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  12, 100, 212, 205, 185,
        179, 173, 186, 193, 221, 142,  85,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  85,  76, 199, 225,
        248, 255, 238, 226, 157,  68,  80,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  91,  69,  91, 201,
        218, 225, 209, 158,  61,  93,  72,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  79,  89,  61,  59,
         87, 108,  75,  56,  76,  97,  73,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  75,  89,  80,  80,
         67,  63,  73,  83,  80,  96,  72,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  77,  88,  77,  80,
         83,  83,  83,  83,  81,  95,  76,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  89,  96,  80,  83,
         81,  84,  85,  85,  85,  97,  84,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  93,  97,  81,  85,
         84,  85,  87,  88,  84,  99,  87,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  95,  87,  84,  87,
         88,  85,  87,  87,  84,  92,  87,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,  97,  87,  87,  85,
         88,  87,  87,  87,  88,  85, 107,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  17, 100,  88,  87,  87,
         88,  87,  87,  85,  89,  77, 118,   8,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  10,  93,  87,  87,  87,
         87,  87,  88,  87,  89,  80, 103,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   9,  96,  87,  87,  87,
         87,  87,  88,  87,  88,  87, 103,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  12,  96,  85,  87,  87,
         87,  85,  87,  87,  88,  89, 100,   2,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  20,  95,  84,  88,  85,
         87,  88,  88,  88,  89,  88,  99,   8,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  21,  96,  85,  87,  85,
         88,  88,  88,  88,  89,  89,  99,  10,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  24,  96,  85,  87,  85,
         87,  88,  88,  89,  88,  91, 102,  14,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  25,  93,  84,  88,  87,
         87,  87,  87,  87,  89,  91, 103,  29,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  30,  95,  85,  88,  88,
         87,  87,  87,  87,  89,  88, 102,  37,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  34,  96,  88,  87,  87,
         87,  87,  87,  87,  85,  85,  97,  38,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  40,  96,  87,  85,  87,
         87,  87,  87,  87,  85,  84,  92,  49,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  46,  95,  83,  84,  87,
         87,  87,  87,  87,  87,  84,  87,  84,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  72,  95,  85,  84,  85,
         88,  87,  87,  89,  87,  85,  83,  63,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  64, 100,  84,  87,  88,
         85,  88,  88,  84,  87,  83,  95,  53,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,  10, 102, 100,  91,  91,
         89,  85,  84,  84,  87, 108, 106,  14,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   0,   8,  73,  93, 104,
        107, 103, 103, 106, 102,  75,  10,   0,   0,   0,   0,   0,   0,
          0,   0],
       [  0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,  18,
         42,  57,  56,  32,   8,   0,   0,   1,   0,   0,   0,   0,   0,
          0,   0]], dtype=uint8)
train_labels[0]
9
# Show the first training example
print(f"Training sample:\n {train_data[0]}\n")
print(f"Training label:\n {train_labels[0]}\n")

Training sample:
 [[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   1   0   0  13  73   0
    0   1   4   0   0   0   0   1   1   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   3   0  36 136 127  62
   54   0   0   0   1   3   4   0   0   3]
 [  0   0   0   0   0   0   0   0   0   0   0   0   6   0 102 204 176 134
  144 123  23   0   0   0   0  12  10   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0 155 236 207 178
  107 156 161 109  64  23  77 130  72  15]
 [  0   0   0   0   0   0   0   0   0   0   0   1   0  69 207 223 218 216
  216 163 127 121 122 146 141  88 172  66]
 [  0   0   0   0   0   0   0   0   0   1   1   1   0 200 232 232 233 229
  223 223 215 213 164 127 123 196 229   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0 183 225 216 223 228
  235 227 224 222 224 221 223 245 173   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0 193 228 218 213 198
  180 212 210 211 213 223 220 243 202   0]
 [  0   0   0   0   0   0   0   0   0   1   3   0  12 219 220 212 218 192
  169 227 208 218 224 212 226 197 209  52]
 [  0   0   0   0   0   0   0   0   0   0   6   0  99 244 222 220 218 203
  198 221 215 213 222 220 245 119 167  56]
 [  0   0   0   0   0   0   0   0   0   4   0   0  55 236 228 230 228 240
  232 213 218 223 234 217 217 209  92   0]
 [  0   0   1   4   6   7   2   0   0   0   0   0 237 226 217 223 222 219
  222 221 216 223 229 215 218 255  77   0]
 [  0   3   0   0   0   0   0   0   0  62 145 204 228 207 213 221 218 208
  211 218 224 223 219 215 224 244 159   0]
 [  0   0   0   0  18  44  82 107 189 228 220 222 217 226 200 205 211 230
  224 234 176 188 250 248 233 238 215   0]
 [  0  57 187 208 224 221 224 208 204 214 208 209 200 159 245 193 206 223
  255 255 221 234 221 211 220 232 246   0]
 [  3 202 228 224 221 211 211 214 205 205 205 220 240  80 150 255 229 221
  188 154 191 210 204 209 222 228 225   0]
 [ 98 233 198 210 222 229 229 234 249 220 194 215 217 241  65  73 106 117
  168 219 221 215 217 223 223 224 229  29]
 [ 75 204 212 204 193 205 211 225 216 185 197 206 198 213 240 195 227 245
  239 223 218 212 209 222 220 221 230  67]
 [ 48 203 183 194 213 197 185 190 194 192 202 214 219 221 220 236 225 216
  199 206 186 181 177 172 181 205 206 115]
 [  0 122 219 193 179 171 183 196 204 210 213 207 211 210 200 196 194 191
  195 191 198 192 176 156 167 177 210  92]
 [  0   0  74 189 212 191 175 172 175 181 185 188 189 188 193 198 204 209
  210 210 211 188 188 194 192 216 170   0]
 [  2   0   0   0  66 200 222 237 239 242 246 243 244 221 220 193 191 179
  182 182 181 176 166 168  99  58   0   0]
 [  0   0   0   0   0   0   0  40  61  44  72  41  35   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]]

Training label:
 9

train_data[0].shape, train_labels[0].shape
((28, 28), ())
import matplotlib.pyplot as plt
plt.imshow(train_data[7]);
train_labels[7]
2

Indexing of labels

Label Description
0 T-shirt/top
1 Trouser
2 Pullover
3 Dress
4 Coat
5 Sandal
6 Shirt
7 Sneaker
8 Bag
9 Ankle boot
class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat",
"Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]

len(class_names)
10
index_of_choice = 100
plt.imshow(train_data[17], cmap = plt.cm.binary)
plt.title(class_names[train_labels[index_of_choice]])
Text(0.5, 1.0, 'Bag')
import random
plt.figure(figsize = (7,7))
for i in range(4):
  ax = plt.subplot(2,2,i+1)
  rand_index = random.choice(range(len(train_data)))
  plt.imshow(train_data[rand_index], cmap = plt.cm.binary)
  plt.title(class_names[train_labels[rand_index]])
  plt.axis(False)

Building a Multi-class classification model

For our multi-class classification model, we can use similar architecture to our binary classifier, however we have to tweak few things:

  • Input shape = 28 x 28 (the shape of one image)
  • Output shape = 10(one per class of clothing)
  • Loss function = tf.keras.losses.CategoricalCrossentropy()
    • If your labels are one-hot encoded, use CategoricalCrossentropy()
    • If your labels are integer form use SparseCategoricalentropy()
  • Output layer activation = softmax not sigmoid
flatten_model = tf.keras.Sequential([tf.keras.layers.Flatten(input_shape=(28,28))])
flatten_model.output_shape
(None, 784)

The dimension 784 is the total number of pixels in a 28 x 28 greyscale image

train_labels[0:10]
array([9, 0, 0, 3, 0, 2, 7, 2, 5, 5], dtype=uint8)

our train labels are in the form of integers we need to transform into one-hot encoded vector.
If we change the loss to sparse categorical entropy it does this task by itself.

tf.one_hot(train_labels[:10], depth=10), tf.one_hot(test_labels[:10], depth=10)
(<tf.Tensor: shape=(10, 10), dtype=float32, numpy=
 array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]], dtype=float32)>,
 <tf.Tensor: shape=(10, 10), dtype=float32, numpy=
 array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]], dtype=float32)>)
# Set the random seed
tf.random.set_seed(42)

# Create the model
model_11 = tf.keras.Sequential([
  tf.keras.layers.Flatten(input_shape = (28,28)), # To avoid shape mismatch errors we flatten the model                               
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(10, activation = tf.keras.activations.softmax) # Changed to softmax for mutli-class detection                                
])

# compile the model
model_11.compile(loss = tf.keras.losses.CategoricalCrossentropy(), # changed the loss function
                 optimizer = tf.keras.optimizers.Adam(),
                 metrics = ["accuracy"])

# Fit the model
non_norm_history = model_11.fit(train_data,
                                tf.one_hot(train_labels,depth=10),
                                epochs =10,
                                validation_data = (test_data, tf.one_hot(test_labels, depth=10)))

Epoch 1/10
1875/1875 [==============================] - 4s 2ms/step - loss: 2.1671 - accuracy: 0.1606 - val_loss: 1.7959 - val_accuracy: 0.2046
Epoch 2/10
1875/1875 [==============================] - 4s 2ms/step - loss: 1.7066 - accuracy: 0.2509 - val_loss: 1.6567 - val_accuracy: 0.2805
Epoch 3/10
1875/1875 [==============================] - 4s 2ms/step - loss: 1.6321 - accuracy: 0.2806 - val_loss: 1.6094 - val_accuracy: 0.2857
Epoch 4/10
1875/1875 [==============================] - 3s 2ms/step - loss: 1.6052 - accuracy: 0.2833 - val_loss: 1.6041 - val_accuracy: 0.2859
Epoch 5/10
1875/1875 [==============================] - 3s 2ms/step - loss: 1.5975 - accuracy: 0.2862 - val_loss: 1.6064 - val_accuracy: 0.2756
Epoch 6/10
1875/1875 [==============================] - 4s 2ms/step - loss: 1.5950 - accuracy: 0.2920 - val_loss: 1.5747 - val_accuracy: 0.2994
Epoch 7/10
1875/1875 [==============================] - 4s 2ms/step - loss: 1.5775 - accuracy: 0.3040 - val_loss: 1.6030 - val_accuracy: 0.3000
Epoch 8/10
1875/1875 [==============================] - 4s 2ms/step - loss: 1.5708 - accuracy: 0.3175 - val_loss: 1.5635 - val_accuracy: 0.3315
Epoch 9/10
1875/1875 [==============================] - 3s 2ms/step - loss: 1.5638 - accuracy: 0.3280 - val_loss: 1.5534 - val_accuracy: 0.3334
Epoch 10/10
1875/1875 [==============================] - 3s 2ms/step - loss: 1.5432 - accuracy: 0.3346 - val_loss: 1.5390 - val_accuracy: 0.3549
model_11.summary()
Model: "sequential_22"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 flatten_10 (Flatten)        (None, 784)               0         
                                                                 
 dense_56 (Dense)            (None, 4)                 3140      
                                                                 
 dense_57 (Dense)            (None, 4)                 20        
                                                                 
 dense_58 (Dense)            (None, 10)                50        
                                                                 
=================================================================
Total params: 3,210
Trainable params: 3,210
Non-trainable params: 0
_________________________________________________________________
train_data.min(), test_data.max()
(0, 255)

Neural Networks prefer data to be scaled or normalized this means, they like to have the numbers in the tensors between 0 & 1

train_data_norm = train_data/ 255.0
test_data_norm = test_data/ 255.0

# Check the min and max values of the scaled training data
train_data_norm.min(), train_data_norm.max()
(0.0, 1.0)
tf.random.set_seed(42)

# Create a model (same as model_11)
model_12 = tf.keras.Sequential([
  tf.keras.layers.Flatten(input_shape= (28,28)),                                
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(10, activation = "softmax")                                
])

# Compile the model
model_12.compile(loss = tf.keras.losses.SparseCategoricalCrossentropy(),
                 optimizer = tf.keras.optimizers.Adam(),
                 metrics = ["accuracy"])

# Fit the Model
norm_history = model_12.fit(train_data_norm,
                            train_labels,
                            epochs = 10,
                            validation_data = (test_data_norm,test_labels))
Epoch 1/10
1875/1875 [==============================] - 4s 2ms/step - loss: 1.0348 - accuracy: 0.6474 - val_loss: 0.6937 - val_accuracy: 0.7617
Epoch 2/10
1875/1875 [==============================] - 4s 2ms/step - loss: 0.6376 - accuracy: 0.7757 - val_loss: 0.6400 - val_accuracy: 0.7820
Epoch 3/10
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5942 - accuracy: 0.7914 - val_loss: 0.6247 - val_accuracy: 0.7783
Epoch 4/10
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5750 - accuracy: 0.7979 - val_loss: 0.6078 - val_accuracy: 0.7881
Epoch 5/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5641 - accuracy: 0.8006 - val_loss: 0.6169 - val_accuracy: 0.7881
Epoch 6/10
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5544 - accuracy: 0.8043 - val_loss: 0.5855 - val_accuracy: 0.7951
Epoch 7/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5488 - accuracy: 0.8063 - val_loss: 0.6097 - val_accuracy: 0.7836
Epoch 8/10
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5428 - accuracy: 0.8077 - val_loss: 0.5787 - val_accuracy: 0.7971
Epoch 9/10
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5373 - accuracy: 0.8097 - val_loss: 0.5698 - val_accuracy: 0.7977
Epoch 10/10
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5360 - accuracy: 0.8124 - val_loss: 0.5658 - val_accuracy: 0.8014

Note: Neural Networks tend to prefer data in numerical form as well as sclaed/normalized form.

import pandas as pd
# Plot non-normalized data loss curves
pd.DataFrame(non_norm_history.history).plot(title= "Non-normalized data")
# Plot normalized data loss curves
pd.DataFrame(norm_history.history).plot(title="Normalized data")
<matplotlib.axes._subplots.AxesSubplot at 0x7f847ec5c750>

Note: Same model with even slightly different data can produce dramatically different results. So, when you are comparing models, it's important to make sure you are comparing them on the same criteria(eg. same architecture but different data or same data but different architecture)

Brief description of steps in modelling:

  • Turn all the data into numbers (neural networks can't handle strings)
  • Make sure all of your tensors are the right shape
  • Scale features (normalize or standardize, neural networks tend to prefer normalization)

Finding the ideal learning rate

# Set random seed
tf.random.set_seed(42)

# Create model
model_13 = tf.keras.Sequential([
  tf.keras.layers.Flatten(input_shape = (28,28)),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(10 ,activation = "softmax")                                
])

# Compile the model
model_13.compile(loss = tf.keras.losses.SparseCategoricalCrossentropy(),
                 optimizer = tf.keras.optimizers.Adam(),
                 metrics = ["accuracy"])

# Create a learning rate call back
lr_scheduler = tf.keras.callbacks.LearningRateScheduler(lambda epoch: 1e-3 * 10**(epoch/20))

# Fit the model
find_lr_history = model_13.fit(train_data_norm,
                               train_labels,
                               epochs= 40,
                               validation_data = (test_data_norm, test_labels),
                               callbacks = [lr_scheduler])

Epoch 1/40
1875/1875 [==============================] - 8s 4ms/step - loss: 1.0348 - accuracy: 0.6474 - val_loss: 0.6937 - val_accuracy: 0.7617 - lr: 0.0010
Epoch 2/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.6366 - accuracy: 0.7759 - val_loss: 0.6400 - val_accuracy: 0.7808 - lr: 0.0011
Epoch 3/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5934 - accuracy: 0.7911 - val_loss: 0.6278 - val_accuracy: 0.7770 - lr: 0.0013
Epoch 4/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5749 - accuracy: 0.7969 - val_loss: 0.6122 - val_accuracy: 0.7871 - lr: 0.0014
Epoch 5/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5655 - accuracy: 0.7987 - val_loss: 0.6061 - val_accuracy: 0.7913 - lr: 0.0016
Epoch 6/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5569 - accuracy: 0.8022 - val_loss: 0.5917 - val_accuracy: 0.7940 - lr: 0.0018
Epoch 7/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5542 - accuracy: 0.8036 - val_loss: 0.5898 - val_accuracy: 0.7896 - lr: 0.0020
Epoch 8/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5509 - accuracy: 0.8039 - val_loss: 0.5829 - val_accuracy: 0.7949 - lr: 0.0022
Epoch 9/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5468 - accuracy: 0.8047 - val_loss: 0.6036 - val_accuracy: 0.7833 - lr: 0.0025
Epoch 10/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5478 - accuracy: 0.8058 - val_loss: 0.5736 - val_accuracy: 0.7974 - lr: 0.0028
Epoch 11/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5446 - accuracy: 0.8059 - val_loss: 0.5672 - val_accuracy: 0.8016 - lr: 0.0032
Epoch 12/40
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5432 - accuracy: 0.8067 - val_loss: 0.5773 - val_accuracy: 0.7950 - lr: 0.0035
Epoch 13/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5425 - accuracy: 0.8056 - val_loss: 0.5775 - val_accuracy: 0.7992 - lr: 0.0040
Epoch 14/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5407 - accuracy: 0.8078 - val_loss: 0.5616 - val_accuracy: 0.8075 - lr: 0.0045
Epoch 15/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5408 - accuracy: 0.8052 - val_loss: 0.5773 - val_accuracy: 0.8039 - lr: 0.0050
Epoch 16/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5437 - accuracy: 0.8058 - val_loss: 0.5682 - val_accuracy: 0.8015 - lr: 0.0056
Epoch 17/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5419 - accuracy: 0.8075 - val_loss: 0.5995 - val_accuracy: 0.7964 - lr: 0.0063
Epoch 18/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5488 - accuracy: 0.8058 - val_loss: 0.5544 - val_accuracy: 0.8087 - lr: 0.0071
Epoch 19/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5506 - accuracy: 0.8042 - val_loss: 0.6068 - val_accuracy: 0.7864 - lr: 0.0079
Epoch 20/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5537 - accuracy: 0.8030 - val_loss: 0.5597 - val_accuracy: 0.8076 - lr: 0.0089
Epoch 21/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5572 - accuracy: 0.8036 - val_loss: 0.5998 - val_accuracy: 0.7934 - lr: 0.0100
Epoch 22/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5615 - accuracy: 0.8013 - val_loss: 0.5756 - val_accuracy: 0.8034 - lr: 0.0112
Epoch 23/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5655 - accuracy: 0.8017 - val_loss: 0.6386 - val_accuracy: 0.7668 - lr: 0.0126
Epoch 24/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5819 - accuracy: 0.7963 - val_loss: 0.6356 - val_accuracy: 0.7869 - lr: 0.0141
Epoch 25/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5810 - accuracy: 0.7977 - val_loss: 0.6481 - val_accuracy: 0.7865 - lr: 0.0158
Epoch 26/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5960 - accuracy: 0.7901 - val_loss: 0.6997 - val_accuracy: 0.7802 - lr: 0.0178
Epoch 27/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.6101 - accuracy: 0.7870 - val_loss: 0.6124 - val_accuracy: 0.7917 - lr: 0.0200
Epoch 28/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.6178 - accuracy: 0.7846 - val_loss: 0.6137 - val_accuracy: 0.7962 - lr: 0.0224
Epoch 29/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.6357 - accuracy: 0.7771 - val_loss: 0.6655 - val_accuracy: 0.7621 - lr: 0.0251
Epoch 30/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.6671 - accuracy: 0.7678 - val_loss: 0.7597 - val_accuracy: 0.7194 - lr: 0.0282
Epoch 31/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.6836 - accuracy: 0.7585 - val_loss: 0.6958 - val_accuracy: 0.7342 - lr: 0.0316
Epoch 32/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.7062 - accuracy: 0.7553 - val_loss: 0.7015 - val_accuracy: 0.7732 - lr: 0.0355
Epoch 33/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.7383 - accuracy: 0.7500 - val_loss: 0.7146 - val_accuracy: 0.7706 - lr: 0.0398
Epoch 34/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.8033 - accuracy: 0.7300 - val_loss: 0.8987 - val_accuracy: 0.6848 - lr: 0.0447
Epoch 35/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.8429 - accuracy: 0.7110 - val_loss: 0.8750 - val_accuracy: 0.7053 - lr: 0.0501
Epoch 36/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.8651 - accuracy: 0.7033 - val_loss: 0.8176 - val_accuracy: 0.6989 - lr: 0.0562
Epoch 37/40
1875/1875 [==============================] - 4s 2ms/step - loss: 0.9203 - accuracy: 0.6837 - val_loss: 0.7876 - val_accuracy: 0.7333 - lr: 0.0631
Epoch 38/40
1875/1875 [==============================] - 4s 2ms/step - loss: 1.2374 - accuracy: 0.5191 - val_loss: 1.3699 - val_accuracy: 0.4902 - lr: 0.0708
Epoch 39/40
1875/1875 [==============================] - 4s 2ms/step - loss: 1.1828 - accuracy: 0.5311 - val_loss: 1.1010 - val_accuracy: 0.5819 - lr: 0.0794
Epoch 40/40
1875/1875 [==============================] - 4s 2ms/step - loss: 1.6640 - accuracy: 0.3303 - val_loss: 1.8528 - val_accuracy: 0.2779 - lr: 0.0891
import numpy as np
import matplotlib.pyplot as plt

lrs = 1e-3 * (10**(tf.range(40)/20))
plt.semilogx(lrs, find_lr_history.history["loss"])
plt.xlabel("Learning rate")
plt.ylabel("Loss")
plt.title("Finding the ideal learning rate")
Text(0.5, 1.0, 'Finding the ideal learning rate')

How do we find ideal learing rate?

  • Just take a look at the graph and see at what value the above graph the curve is lowest and go backwards a little.

SO, it looks like $10^{-3}$ seems to be good

# Let's refit a model with the ideal learning rate

# Set the random seed
tf.random.set_seed(42)

# Create the model
model_14 = tf.keras.Sequential([
  tf.keras.layers.Flatten(input_shape = (28,28)),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(4, activation = "relu"),
  tf.keras.layers.Dense(10, activation = "softmax")                                
])

# Compile the model
model_14.compile(loss = tf.keras.losses.SparseCategoricalCrossentropy(),
                 optimizer = tf.keras.optimizers.Adam(),
                 metrics = ["accuracy"])



# Fit the model
history_14 = model_14.fit(train_data_norm,
                          train_labels,
                          epochs = 20,
                          validation_data = (test_data_norm,test_labels))

Epoch 1/20
1875/1875 [==============================] - 4s 2ms/step - loss: 1.0348 - accuracy: 0.6474 - val_loss: 0.6937 - val_accuracy: 0.7617
Epoch 2/20
1875/1875 [==============================] - 4s 2ms/step - loss: 0.6376 - accuracy: 0.7757 - val_loss: 0.6400 - val_accuracy: 0.7820
Epoch 3/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5942 - accuracy: 0.7914 - val_loss: 0.6247 - val_accuracy: 0.7783
Epoch 4/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5750 - accuracy: 0.7979 - val_loss: 0.6078 - val_accuracy: 0.7881
Epoch 5/20
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5641 - accuracy: 0.8006 - val_loss: 0.6169 - val_accuracy: 0.7881
Epoch 6/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5544 - accuracy: 0.8043 - val_loss: 0.5855 - val_accuracy: 0.7951
Epoch 7/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5488 - accuracy: 0.8063 - val_loss: 0.6097 - val_accuracy: 0.7836
Epoch 8/20
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5428 - accuracy: 0.8077 - val_loss: 0.5787 - val_accuracy: 0.7971
Epoch 9/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5373 - accuracy: 0.8097 - val_loss: 0.5698 - val_accuracy: 0.7977
Epoch 10/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5360 - accuracy: 0.8124 - val_loss: 0.5658 - val_accuracy: 0.8014
Epoch 11/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5311 - accuracy: 0.8130 - val_loss: 0.5714 - val_accuracy: 0.8002
Epoch 12/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5284 - accuracy: 0.8132 - val_loss: 0.5626 - val_accuracy: 0.8027
Epoch 13/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5271 - accuracy: 0.8138 - val_loss: 0.5619 - val_accuracy: 0.8041
Epoch 14/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5249 - accuracy: 0.8143 - val_loss: 0.5718 - val_accuracy: 0.7991
Epoch 15/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5231 - accuracy: 0.8148 - val_loss: 0.5706 - val_accuracy: 0.8024
Epoch 16/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5203 - accuracy: 0.8162 - val_loss: 0.5731 - val_accuracy: 0.8023
Epoch 17/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5191 - accuracy: 0.8176 - val_loss: 0.5594 - val_accuracy: 0.8030
Epoch 18/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5176 - accuracy: 0.8157 - val_loss: 0.5582 - val_accuracy: 0.8053
Epoch 19/20
1875/1875 [==============================] - 3s 2ms/step - loss: 0.5156 - accuracy: 0.8169 - val_loss: 0.5644 - val_accuracy: 0.8007
Epoch 20/20
1875/1875 [==============================] - 4s 2ms/step - loss: 0.5146 - accuracy: 0.8177 - val_loss: 0.5660 - val_accuracy: 0.8075

Evaluating our multi-class classification model

To evaluate our multi-class classification model we could:

  • Evaluate our multi-class classification metrics(such as confusion matrix)
  • Assess some of its predictions (through visualizations)
  • Improve its results (by training it for longer or changing the architecture)
  • Save and export it for use in application.
    Let's go through the first two steps for evaluation process
import itertools
from sklearn.metrics import confusion_matrix

figsize = (10,10)


def make_confusion_matrix(y_true, y_pred, classes=None, figsize= (15,15), text_size= 10 ):
  
  # Create the confusion matrix
  cm = confusion_matrix(y_true, tf.round(y_pred))
  cm_norm = cm.astype("float")/ cm.sum(axis = 1)[:, np.newaxis] # Noramlize our confusion matrix 
  n_classes = cm.shape[0]

  # Let's make it neat and clear
  fig, ax = plt.subplots(figsize = figsize)
  # Create a matrix plot
  cax = ax.matshow(cm, cmap = plt.cm.Blues)
  fig.colorbar(cax)


  
  # set labels to be classes
  if classes:
    labels  = classes
  else:
    labels = np.arange(cm.shape[0])

  # Let's label the axis
  ax.set(title = "Confusion Matrix",
         xlabel = "Predicted Label",
         ylabel = "True Label",
         xticks = np.arange(n_classes),
         yticks = np.arange(n_classes),
         xticklabels = labels,
         yticklabels = labels)

  # Set x-axis labels to the bottom
  ax.xaxis.set_label_position("bottom")
  ax.xaxis.tick_bottom()

  # Adjust label size
  ax.yaxis.label.set_size(text_size)
  ax.xaxis.label.set_size(text_size)
  ax.title.set_size(text_size)

  # Set threshold for different colors
  threshold = (cm.max() + cm.min())/2.

  # Plot the text on each cell
  for i,j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):

    plt.text(j, i, f"{cm[i,j]} ({cm_norm[i,j]*100:.1f}% )",
             horizontalalignment = "center",
             color = "white" if cm[i,j] > threshold else "black",
             size = 15)
class_names
['T-shirt/top',
 'Trouser',
 'Pullover',
 'Dress',
 'Coat',
 'Sandal',
 'Shirt',
 'Sneaker',
 'Bag',
 'Ankle boot']
y_probs = model_14.predict(test_data_norm) # probs is short for prediction probability

# View the first 5 predictions
y_probs[:5]
array([[8.56299753e-11, 3.53615629e-13, 2.66337556e-05, 4.63562024e-08,
        5.09498605e-05, 9.61192474e-02, 8.17780403e-08, 9.18688551e-02,
        4.06052778e-03, 8.07873666e-01],
       [3.42785552e-06, 1.28992649e-16, 9.59891498e-01, 2.05162564e-07,
        1.53292371e-02, 2.45320095e-13, 2.41428725e-02, 1.13834485e-28,
        6.32718089e-04, 4.47896404e-08],
       [6.10630595e-05, 9.96576726e-01, 4.38669758e-08, 3.34058981e-03,
        1.32494861e-05, 1.43831603e-21, 8.27906115e-06, 7.32374630e-18,
        5.48116041e-08, 4.92251402e-14],
       [7.50314357e-05, 9.90536869e-01, 4.25285322e-07, 9.22318175e-03,
        1.36231421e-04, 1.82760903e-18, 2.68082422e-05, 4.81248308e-14,
        1.45215904e-06, 2.22114601e-11],
       [7.21899569e-02, 1.54957536e-06, 2.55668938e-01, 1.03631355e-02,
        4.35413495e-02, 1.10693023e-13, 6.16930187e-01, 6.75438989e-23,
        1.30491622e-03, 1.21404065e-09]], dtype=float32)

NOTE:
Remember to make predictions on the same kind of data your model ws trained on(eg. if you trained your model on normalized data, you'll want to make predictions on normalized data)

y_probs[0], tf.argmax(y_probs[0]) , class_names[tf.argmax(y_probs[0])]
(array([8.5629975e-11, 3.5361563e-13, 2.6633756e-05, 4.6356202e-08,
        5.0949860e-05, 9.6119247e-02, 8.1778040e-08, 9.1868855e-02,
        4.0605278e-03, 8.0787367e-01], dtype=float32),
 <tf.Tensor: shape=(), dtype=int64, numpy=9>,
 'Ankle boot')
y_preds = y_probs.argmax(axis = 1)

# View the first 10 prediction labels
y_preds[:10]
array([9, 2, 1, 1, 6, 1, 4, 6, 5, 7])
from sklearn.metrics import confusion_matrix
confusion_matrix(y_true = test_labels,
                  y_pred = y_preds)
array([[696,   8,  25,  87,   9,   5, 160,   0,  10,   0],
       [  2, 939,   2,  35,   9,   0,  13,   0,   0,   0],
       [ 19,   2, 656,  10, 188,   0, 110,   0,  15,   0],
       [ 39,  10,  10, 819,  55,   0,  47,   1,  19,   0],
       [  0,   0,  95,  23, 800,   0,  73,   0,   7,   2],
       [  0,   0,   1,   0,   0, 894,   0,  60,   7,  38],
       [106,   4, 158,  57, 159,   1, 499,   0,  16,   0],
       [  0,   0,   0,   0,   0,  31,   0, 936,   0,  33],
       [  4,   1,  38,  15,   8,  12,   9,   5, 906,   2],
       [  0,   0,   1,   0,   2,  15,   0,  51,   1, 930]])
make_confusion_matrix(y_true = test_labels,
                      y_pred = y_preds,
                      classes = class_names,
                      figsize = (20,20),
                      text_size = 10)

Note:
Often when working with images and other forms of visual data, it's a good idea to visualize as much as possible to develop a further understanding of the data and the inputs and outputs of your models.

How about we create a function for:

  • Plot a random image
  • Make a prediction on said image
  • Label the plot with the truth label & the predited label.
import random

def plot_random_image(model,images, true_labels, classes):
  """
  Picks a random image , plots it and labels it with a prediction and truth value
  """
  # Setup  random integer
  i = random.randint(0,len(images))

  # Create a prediction 
  target_image = images[i]
  pred_probs = model.predict(target_image.reshape(1,28,28))
  pred_label = classes[pred_probs.argmax()]
  true_label = classes[true_labels[i]]

  # Plot the image
  plt.imshow(target_image, cmap = plt.cm.binary)

  # Change the color of the titles depending on if the prediction is right or wrong
  if pred_label == true_label:
    color = "green"
  else:
    color = "red"

  # ADD xlabel infomation (predictions/true label)
  plt.xlabel("pred:{} {:2.0f}% (True: {})".format(pred_label,
                                                  100*tf.reduce_max(pred_probs),
                                                  true_label,
                                                  color = color)) # set color to green or red based on if prediction is correct or wrong.
plot_random_image(model= model_14,
                  images = test_data_norm, # always make predictions on the same kind of data your model was trained on
                  true_labels = test_labels,
                  classes = class_names)

Yeah! we finally did it. We are getting the correct predictions for the images in the dataset. Run the cell to view predictions for random images in the dataset.

What patterns the model learning?

model_14.layers
[<keras.layers.core.flatten.Flatten at 0x7f8480bf8590>,
 <keras.layers.core.dense.Dense at 0x7f8480bf8450>,
 <keras.layers.core.dense.Dense at 0x7f847eb5b950>,
 <keras.layers.core.dense.Dense at 0x7f8480bf6c50>]
model_14.layers[1]
<keras.layers.core.dense.Dense at 0x7f8480bf8450>
weights, biases = model_14.layers[1].get_weights()

#Shapes
weights, weights.shape
(array([[ 0.7150263 , -0.06077093, -0.99763095, -1.0484313 ],
        [ 0.2773212 , -0.471554  , -0.52916455,  0.02329255],
        [ 0.7752433 ,  0.5402759 , -1.128857  , -0.7426156 ],
        ...,
        [-0.3945342 ,  0.47628632, -0.2264153 ,  0.2550593 ],
        [-0.40515798,  0.61810046,  0.23928414, -0.50387603],
        [ 0.23884593,  0.11606961, -0.12131374,  0.04352392]],
       dtype=float32), (784, 4))

In (784,4), 784 is the number of pixel values in the image from the dataset.
and the number 4 is the number of nodes in that layer of the neural network

Reading resouce: kernel initializer and glorot_uniform in the tf.keras.layers.Dense

Now let's check out the bias vector

biases, biases.shape
(array([ 2.4485964e-02, -6.1471871e-04, -2.7230152e-01,  8.1124878e-01],
       dtype=float32), (4,))

The difference between Weights matrix and bias vector is that the weight matrix has one value per data point. Whereas bias vector has one value per hidden unit of that layer.

Every neuron has a bias vector. Each of these is paired with a weights matrix.

The Bias vector get initialized as zeros(at least in the case of a TensorFlow Dense layer).

The Bias vector dictates how much the patterns within the corresponding weights matrix should influence the next layer.

from tensorflow.keras.utils import plot_model
# See the inputs and outputs of each layer
plot_model(model_14,show_shapes= True)
Back to top of page