Sentiment Analysis with Keras, Tensorflow 2.0, TensorFlow Hub using IMBD data in Google Colab.

by CM


Posted on October 26, 2019



The Goal:

In this article, we will leverage a Convolutional Network (CNN) in order to predict clothing types. In particular, we will use and train our model on the Fashion-Mnist Dataset from Zalando which holds 10 clothing categories ranging from shoes, over pants to ... Besides creating a model with high accuracy for predicting clothing items, we will have a look into running TensorBoard on Google Colab without the need for ngroc or other third party solutions. Indeed TF2 allows us easy access and use of TensorBoard right out of Colab. So let's get started


Key components are:

Dataset:
>> Fashion-MNIST is a dataset of Zalando’s article images consisting of a training set of 60,000 examples and a test set of 10,000 examples. Each example is a 28×28 grayscale image, associated with a label from 10 classes.

First, we make sure to use TensorFlow 2.0 and load the TensorBoard notebook extension in Google Colab.

### Use TensorFlow 2.0
try:
  # %tensorflow_version only exists in Colab.
  %tensorflow_version 2.x
except Exception:
  pass

# Load the TensorBoard notebook extension
%load_ext tensorboard

Second, we import all dependencies - (note that some libraries come preinstalled with Colab. In case you are using e.g. Jupyter notebook on your local machine, make sure to install ALL respective libraries, such as TensorFlow & Keras, e.g. using pip).

### Importing all dependencies
import datetime, os

import pandas as pd
import numpy as np

import tensorflow as tf

import matplotlib.pyplot as plt
import seaborn as sns

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dropout, Dense
from tensorflow.keras.callbacks import TensorBoard

from sklearn.model_selection import train_test_split

### Checking TF Version
print("TF-Version: ")
tf.__version__

We should see TF2 Version running.

==========================
OUTPUT
==========================

TF-Version:
'2.0.0'

We then need to upload our Fashion Mnist dataset to Colab. To upload data into Colab there are several options. In the following, we will use upload from Google Drive and use the pd.read_csv function to transform the uploaded CSV file into a Pandas dataframe.

#Mount Google Drive
from google.colab import drive
drive.mount('/content/gdrive')

------------------------------------------------------------------------------------------
Enter your authorization code: [Your Code]
··········
Mounted at /content/gdrive
------------------------------------------------------------------------------------------

We then store both CSV files in a pandas dataframe for further use. Make sure to input your file path and the "file name + .csv" correctly.

fashion_mnist_data_train = pd.read_csv('/content/gdrive/My Drive/Datasets/fashion-mnist_train.csv')
fashion_mnist_data_test = pd.read_csv('/content/gdrive/My Drive/Datasets/fashion-mnist_test.csv')

After we have uploaded both CSV files, we will review them in detail. Therefore, we can print the shape and the head of the dataframe.

print(fashion_mnist_data_train.shape)
print(fashion_mnist_data_train.head())

We find that our dataframe holds 60000 rows and 785 columns in our training dataset, whereas the first column indicates the label of the clothing type. The remaining 784 columns represent the image pixels (28x28 = 784px) of the individual images.

==========================
OUTPUT
==========================

(60000, 785)
   label  pixel1  pixel2  pixel3  ...  pixel781  pixel782  pixel783  pixel784
0      2       0       0       0  ...         0         0         0         0
1      9       0       0       0  ...         0         0         0         0
2      6       0       0       0  ...         0         0         0         0
3      0       0       0       0  ...         0         0         0         0
4      3       0       0       0  ...         0         0         0         0

[5 rows x 785 columns]

In addition, we check how many of each specific clothing types are within the training dataset. In this regard, we plot the count by using seaborn.

sns.countplot(x='label',
              edgecolor=(0,0,0),
              linewidth=2,
              palette="Dark2",
              color = "white",
              data=fashion_mnist_data_train)

We find that we have 6000 items per category in our training set.

========================== OUTPUT ==========================

Further, we want to have a look at the actual images / clothing types in the dataset. In this regard, we plot 10 random images of our dataset in gray-scale color.

# First, we define the label description of the individual items via a dictionary.
objects = {0: 'T-shirt/top',
           1: 'Pants',
           2: 'Pullover',
           3: 'Dress',
           4: 'Coat',
           5: 'Sandal',
           6: 'Shirt',
           7: 'Sneaker',
           8: 'Bag',
           9: 'Ankle boot'}

# We print 10 random clothing items.
f, axes = plt.subplots(2, 5)
for row in axes:
    for axe in row:
        index = np.random.randint(10000)
        img = np.array(fashion_mnist_data_train.iloc[index, 1:]).reshape((28, 28))
        obj = fashion_mnist_data_train.iloc[index, 0]
        axe.imshow(img, cmap='gray')
        axe.set_title(objects[obj])

We find the 10 items below.

========================== OUTPUT ==========================

We now convert our pandas dataframe to Numpy Arrays that we can later easily reshape for ideal use in our CNN. In particular, we make for operations:

  • In the first step, we convert the pandas dataframes to numpy arrays.
  • In the second step, we slice our arrays. In this regard, we attribute the first column (labels) to the the y_train / y_test array, respectively.
  • In the third step, we take the rest of the array (without the first column) and attribute those to the x_train / x_test, respectively.
  • In the fourth step, we normalize the pixel data as the CNN works better with normalized data.
#Convert Pandas Dataframe to Numpy Array
train_data = np.array(fashion_mnist_data_train, dtype='float32')
test_data = np.array(fashion_mnist_data_test, dtype='float32')

#Slice Array: Take entire array only column 1
y_train =  train_data[:, 0]
y_test =  test_data[:, 0]

#Slice Array: Take entire array from column2 to the end
x_train = train_data[:, 1:]
x_test = test_data[:, 1:]

#Normalize data
x_train = tf.keras.utils.normalize(x_train, axis=1)
x_test = tf.keras.utils.normalize(x_test, axis=1)

We now build our tensors that we will use in the CNN. In this regard, we will need to have a tensor of shape: 28x28x1.

#Rebuild image pixels
im_rows = 28 #ROWS
im_cols = 28 #COLS
batch_size = 512
im_shape = (im_rows, im_cols, 1) #ROWS+COLS+1COLOR
print(train_data.shape[0]) #60000
x_train = x_train.reshape(x_train.shape[0], *im_shape)
x_test =  x_test.reshape(x_test.shape[0], *im_shape)
print(x_train.shape) #(60000, 28, 28, 1)

We find that the transformation to a 28x28x1 tensor was successful.

(60000, 784)
(60000, 28, 28, 1)

We now start logging with TensorBoard.

%tensorboard --logdir logs

We start building our model initializing six layers. After building the model, we immediately compile the model using Adam as Optimizer, Sparse-Sparse_categorical_crossentropy as Loss function. Further, we will evaluate Accuracy, Mean Absolute Error and Mean Standard Error for the model. Lastly, we will define our TensorBoard callback function that we will use while fitting the CNN.

#CNN Model
cnn_model = Sequential()
cnn_model.add(tf.keras.layers.Conv2D (filters=32, kernel_size=(3,3), activation="relu", input_shape=im_shape))
cnn_model.add(tf.keras.layers.MaxPooling2D(pool_size=2))
cnn_model.add(tf.keras.layers.Dropout(0.2))
cnn_model.add(tf.keras.layers.Flatten())
cnn_model.add(tf.keras.layers.Dense(32, activation='relu'))
cnn_model.add(tf.keras.layers.Dense(10, activation='softmax'))

cnn_model.summary()

cnn_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc', 'mae','mse'])

logdir = os.path.join("logs", datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
tensorboard_callback = tf.keras.callbacks.TensorBoard(logdir, histogram_freq=1)

Your output should look similar like this below. Note that we only have an input of 26x26 in the Convolutional layer as we do use a kernel_size of 3. That results in 320 parameters for the first layer (32* (1* (3*3) + 1 = 320). With MaxPooling, we decrease the shape by a factor of 2 while dropping 20% of the weights with the Dropout layer. In the fourth layer, we flatten our input, thus 13*13*32 = 5408. In the following Dense layer, we will have 32 neurons and respective 173088 parameters as 5408*32 + 32. Overall a total of 173,738 trainable parameters.

==========================
OUTPUT
==========================
Model: "sequential_21"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_11 (Conv2D)           (None, 26, 26, 32)        320
_________________________________________________________________
max_pooling2d_11 (MaxPooling (None, 13, 13, 32)        0
_________________________________________________________________
dropout_11 (Dropout)         (None, 13, 13, 32)        0
_________________________________________________________________
flatten_11 (Flatten)         (None, 5408)              0
_________________________________________________________________
dense_52 (Dense)             (None, 32)                173088
_________________________________________________________________
dense_53 (Dense)             (None, 10)                330
=================================================================
Total params: 173,738
Trainable params: 173,738
Non-trainable params: 0
_________________________________________________________________

Perfect. After having our model build, we can directly go over to the training phase of our CNN. We will use a batch_size of 512, 10 Epochs and a 20% Validation Split of our training data to evaluate our training progress. Lastly, we will trigger our callback functions to later evaluate our training process on TensorBoard.

cnn_history = cnn_model.fit(x_train, y_train, batch_size=batch_size, epochs=10, verbose=1, validation_split=0.20, callbacks=[tensorboard_callback])

Your training output should look similar to this:

==========================
OUTPUT
==========================
Train on 48000 samples, validate on 12000 samples
Epoch 1/10
48000/48000 [==============================] - 1s 18us/sample - loss: 0.3113 - acc: 0.8883 - mae: 4.4233 - mse: 27.7013 - val_loss: 0.3269 - val_acc: 0.8849 - val_mae: 4.4067 - val_mse: 27.6051
Epoch 2/10
48000/48000 [==============================] - 1s 18us/sample - loss: 0.3048 - acc: 0.8897 - mae: 4.4233 - mse: 27.7016 - val_loss: 0.3205 - val_acc: 0.8861 - val_mae: 4.4067 - val_mse: 27.6057
Epoch 3/10
48000/48000 [==============================] - 1s 19us/sample - loss: 0.2987 - acc: 0.8930 - mae: 4.4233 - mse: 27.7019 - val_loss: 0.3255 - val_acc: 0.8846 - val_mae: 4.4067 - val_mse: 27.6057
Epoch 4/10
48000/48000 [==============================] - 1s 18us/sample - loss: 0.2919 - acc: 0.8940 - mae: 4.4233 - mse: 27.7024 - val_loss: 0.3154 - val_acc: 0.8891 - val_mae: 4.4067 - val_mse: 27.6056
Epoch 5/10
48000/48000 [==============================] - 1s 18us/sample - loss: 0.2861 - acc: 0.8956 - mae: 4.4233 - mse: 27.7026 - val_loss: 0.3095 - val_acc: 0.8909 - val_mae: 4.4067 - val_mse: 27.6061
Epoch 6/10
48000/48000 [==============================] - 1s 18us/sample - loss: 0.2795 - acc: 0.8992 - mae: 4.4233 - mse: 27.7029 - val_loss: 0.3063 - val_acc: 0.8923 - val_mae: 4.4067 - val_mse: 27.6069
Epoch 7/10
48000/48000 [==============================] - 1s 18us/sample - loss: 0.2748 - acc: 0.9016 - mae: 4.4233 - mse: 27.7032 - val_loss: 0.3113 - val_acc: 0.8902 - val_mae: 4.4067 - val_mse: 27.6075
Epoch 8/10
48000/48000 [==============================] - 1s 16us/sample - loss: 0.2739 - acc: 0.9011 - mae: 4.4233 - mse: 27.7034 - val_loss: 0.3039 - val_acc: 0.8943 - val_mae: 4.4067 - val_mse: 27.6070
Epoch 9/10
48000/48000 [==============================] - 1s 17us/sample - loss: 0.2666 - acc: 0.9040 - mae: 4.4233 - mse: 27.7037 - val_loss: 0.2969 - val_acc: 0.8958 - val_mae: 4.4067 - val_mse: 27.6074
Epoch 10/10
48000/48000 [==============================] - 1s 17us/sample - loss: 0.2622 - acc: 0.9054 - mae: 4.4233 - mse: 27.7039 - val_loss: 0.2959 - val_acc: 0.8949 - val_mae: 4.4067 - val_mse: 27.6078

We then evaluate our model by using the test data of our dataset. For better visibility, we will only display 3 decimal places.

score = cnn_model.evaluate(x_test, y_test, verbose=0)
print("Test Score: {:.3f} ".format(score[0]))
print("Test Accuracy {:.3f}".format(score[1]))
print("Test Mean absolute error: {:.3f}".format(score[2]))
print("Test Mean squared error: {:.3f}".format(score[3]))

We find that we already have a decent Accuracy, MAE, and MSE within our predictions. Althogh about 90% Accuracy is not ground-breaking, it is a very good starting point for your model.

Test Score: 0.308
Test Accuracy 0.894
Test Mean absolute error: 4.420
Test Mean squared error: 27.682

We then start TensorBoard right within Google Colab to have a closer look at our 10 epochs and the respective metrics. In particular, TensorBoard plot automatically the metrics while training. Hence, one is able to investigate whether the training goes into the right direction even within the actual training process. Further, gives you a detailed overview over your graph, distributions, and histograms.

from tensorboard import notebook
notebook.list() # View open TensorBoard instances
notebook.display(port=6006, height=1000)

==========================
OUTPUT
==========================

Known TensorBoard instances:
  - port 6006: logdir logs (started 0:21:55 ago; pid 2186)
Selecting TensorBoard with logdir logs (started 0:21:55 ago; port 6006, pid 2186).



Last but not least, we test our model by making one prediction that we will assess as well. Therefore, we choose a random training clothing item and see what our model predicts. In the example below, we clearly see a T-Shirt as the clothing item and rightfully does our Model. The prediction is correct.

plt.imshow(x_train[10].reshape(28,28), cmap=plt.cm.binary)
plt.show
my_array = [[x_train[10]]]
prediction  = cnn_model.predict(my_array)

final_prediction = (np.argmax(prediction))

for key, value in objects.items():
    if key == final_prediction:
       print(value)



We have done it. We have built a powerful CNN model that allows us to predict the clothing types with a high accuracy. Further, we initialized TensorBoard to evaluate our model in detail

Leverage TensorBoard!

#EpicML


News
Dec 2021

--- Quantum ---

Simulating matter on the quantum scale with AI #Deepmind
Nov 2021

--- Graviton3 ---

Amazon announced its Graviton3 processors for AI inferencing - the next generation of its custom ARM-based chip for AI inferencing applications. #Graviton3
May 2021

--- Vertex AI & TPU Gen4. ---

Google announced its fourth generation of tensor processing units (TPUs) for AI and ML workloads and the Vertex AI managed platform #VertexAI #TPU
Feb 2021

--- TensorFlow 3D ---

In February of 2021, Google released TensorFlow 3D to help enterprises develop and train models capable of understanding 3D scenes #TensorFlow3D
Nov 2020

--- AlphaFold ---

In November of 2020, AlphaFold 2 was recognised as a solution to the protein folding problem at CASP14 #protein_folding
Oct 2019

--- Google Quantum ---

A research effort from Google AI that aims to build quantum processors and develop novel quantum algorithms to dramatically accelerate computational tasks for machine learning. #quantum_supremacy
Oct 2016

--- AlphaGo ---

Mastering the game of Go with Deep Neural Networks. #neural_network