In the previous tutorial, we looked at how we can create a sequential model in TensorFlow. So in this tutorial, we will look at the Tensorflow functional API. The functional API allows us to create a more complex ANN or CNN model in Tensorflow 2.0. When we use the sequential API to create our models, we can’t debug operations, define multiple inputs, outputs, and custom layers. When we use the Functional API our models have a more flexible structure.

In this tutorial, we will use the Fashion MNIST dataset to create our functional model. This dataset consists of 70000 images and we use 60000 images to train, 10000 images to test. Also, there are 10 different labels in the dataset that we can use. Without further ado, let’s look at close how we define the functional model in TensorFlow 2.0. First, we need to import TensorFlow and fashion MNIST dataset.

import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
import matplotlib.pyplot as plt
import random

Let’s load the fashion mnist dataset and apply the data preprocessing to the dataset. This dataset images consist of 28 by 28 pixels and these pixels have one channel, I mean these pixels are grayscale format.

# load the fashion mnist dataset
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
print("---------------------")
print("x_train : ", x_train.shape)
print("y_train : ", y_train.shape)
print("x_test : ", x_test.shape)
print("y_test : ", y_test.shape)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz
26427392/26421880 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz
8192/5148 [===============================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz
4423680/4422102 [==============================] - 0s 0us/step
---------------------
x_train :  (60000, 28, 28)
y_train :  (60000,)
x_test :  (10000, 28, 28)
y_test :  (10000,)

Features of The Fashion MNIST Dataset

  • 70,000 images
  • 60,000 training examples
  • 10,000 testing examples
  • 10 classes
  • 28×28 grayscale/single channel images

Before applying the pre-processing operation to the dataset, let’s look what is the images in the dataset. First, we need to create a label list for label names in the dataset.

Class List of The Fashion MNIST Dataset

  1. T-shirt
  2. Trouser
  3. Pullover
  4. Dress
  5. Coat
  6. Sandal
  7. Shirt
  8. Sneaker
  9. Bag
  10. Ankle boot
# create label list
labels = ["T-shirt","Trouser", "Pullover", "Dress", "Coat", "Sandal", "Shirt", "Sneaker", "Bag" ,"Ankle boot"]
rand = random.randint(0,10) # generate random numbers between 0-10.
image = x_train[rand]
plt.figure()
plt.imshow(image)
plt.colorbar()
plt.title(labels[y_train[rand]])
x_train = x_train.reshape(-1,28*28).astype("float32")/255.0
x_test = x_test.reshape(-1,28*28).astype("float32")/255.0
print(x_train.shape)
print(x_test.shape)
(60000, 784) (10000, 784)

After done the data pre-processing operations we can create the functional model.

def create_model():
    inputs = tf.keras.Input(shape=28*28, name="input_layer")
    x = tf.keras.layers.Dense(512, activation="relu", name="first_layer")(inputs)                                           
    x = tf.keras.layers.Dense(256, activation="relu", name="second_layer")(x)
    x = tf.keras.layers.Dense(128, activation="relu", name="third_layer")(x)
    outputs = tf.keras.layers.Dense(10, activation="softmax", name="output_layer")(x)

    model = tf.keras.Model(inputs = inputs, outputs = outputs)
    return model

model = create_model()
model.summary()
Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_layer (InputLayer)     [(None, 784)]             0         
_________________________________________________________________
first_layer (Dense)          (None, 512)               401920    
_________________________________________________________________
second_layer (Dense)         (None, 256)               131328    
_________________________________________________________________
third_layer (Dense)          (None, 128)               32896     
_________________________________________________________________
output_layer (Dense)         (None, 10)                1290      
=================================================================
Total params: 567,434
Trainable params: 567,434
Non-trainable params: 0

After finishing our functional model, we can make our model compile and fit. We can do this like on the following code.

model.compile(optimizer="adam", loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=32, epochs=3, validation_data=(x_test, y_test))
Epoch 1/3
1875/1875 [==============================] - 6s 2ms/step - loss: 0.5915 - accuracy: 0.7868 - val_loss: 0.4154 - val_accuracy: 0.8496
Epoch 2/3
1875/1875 [==============================] - 4s 2ms/step - loss: 0.3690 - accuracy: 0.8627 - val_loss: 0.3949 - val_accuracy: 0.8499
Epoch 3/3
1875/1875 [==============================] - 4s 2ms/step - loss: 0.3299 - accuracy: 0.8780 - val_loss: 0.3866 - val_accuracy: 0.8644
<tensorflow.python.keras.callbacks.History at 0x7f08dadb1630>

Let’s evaluate how much our model has learned. We can use model.evaluate and it returns us two. Therse are loss value and validation accuracy.

loss_value, val_accuracy = model.evaluate(x_test, y_test, batch_size=32, verbose=0)
print("val_accuracy : ", val_accuracy)
val_accuracy :  0.8644000291824341