Nov 24, 2018

Example 20: TensorFlow - Rock or Mine Prediction

Using TensorFlow to Create a Model for Making Predictions


TensorFlow is an open source artificial intelligence framework/library for high performance numerical computation. Its flexible architecture allows easy deployment of computation across a variety of platforms (CPUs, GPUs, TPUs), and from desktops to clusters of servers to mobile and edge devices. Originally developed by researchers and engineers at Google, it comes with strong support for machine learning and deep learning and the flexible numerical computation core is used across many other scientific domains.

Tensors are high dimensional generalizations of matrices, where each tensor is a computational unit that can compute based on defined operations. Each tensor takes input, computes, and pass results to next tensor in a continuous flow and hence the whole system is called as TensorFlow. A tensor can also act as a container that can house data in N dimensions, along with its linear operations.

The example below shows how to implement the TensorFlow framework to make deep learning and prediction. It shows an example to predict if an underwater object is rock or a mine based on sensor data from sonar.

For more details on TensorFlow, see this link: https://www.tensorflow.org/tutorials/

TensorFlow to predict if an underwater object is Rock or Mine

A naval mine is a self-contained explosive device placed in water to damage or destroy ships or submarines.

Situation: You have been hired by US Navy to create a model that can detect the difference between an underwater mine and a rock, because a mine dangerous but a rock is not. And it is difficult for humans to judge if an underwater object is rock or a mine.

Solution: We will write a model in TensorFlow to make the prediction for us if the underwater object is rock or a mine.

Dataset used is Sonar.csv, downloaded from the GitHub loccation:
https://github.com/selva86/datasets/blob/master/Sonar.csv

Creating and Training the Model

In [1]:
# Importing the libraries
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.utils import shuffle
from sklearn.model_selection import train_test_split
In [2]:
# Reading the dataset
def read_dataset():
    dir_path = "./MLData/00_Misc/"
    df = pd.read_csv(dir_path + "Sonar.csv")
    X = df[df.columns[0:60]].values
    y = df[df.columns[60]]

    # Encode the labels
    encoder = LabelEncoder()
    encoder.fit(y)
    y = encoder.transform(y)
    Y = one_hot_encode(y)
    return (X, Y)

# Define the encoder function
def one_hot_encode(labels):
    n_labels = len(labels)
    n_unique_lables = len(np.unique(labels))
    encode = np.zeros((n_labels, n_unique_lables))
    encode[np.arange(n_labels), labels] = 1
    return encode

# Read the datset
X, Y = read_dataset()

# Shuffle the dataset to mix up the rows
X, Y = shuffle(X, Y, random_state=1)
In [3]:
# Convert the dataset into train and test sets
train_x, test_x, train_y, test_y = train_test_split(X, Y, test_size=0.20, random_state=415)

# Inspect the shape of the training and testing sets
print('Shape of train_x:', train_x.shape)
print('Shape of train_y:', train_y.shape)
print('Shape of test_x:', test_x.shape)
print('Shape of test_y:', test_y.shape)
Shape of train_x: (165, 60)
Shape of train_y: (165, 2)
Shape of test_x: (42, 60)
Shape of test_y: (42, 2)
In [4]:
# Define the important parameters and variable to work with the tensors
learning_rate = 0.3
training_epochs = 1000
cost_history = np.empty(shape=[1], dtype=float) # loss function

n_dim = X.shape[1]
print('Dimention n_dim =', n_dim)
n_class = 2
# Save model in NMI (Naval Mine Identifier) folder
model_path = './TensorFlow/NMI/'

# Define the number of hidden layers and neurons for each layer
n_hidden_1 = 60
n_hidden_2 = 60
n_hidden_3 = 60
n_hidden_4 = 60

# Inputs and outputs
x = tf.placeholder(tf.float32, [None, n_dim])
y_ = tf.placeholder(tf.float32, [None, n_class])

# Model parameters
W = tf.Variable(tf.zeros([n_dim, n_class]))
b = tf.Variable(tf.zeros([n_class]))
Dimention n_dim = 60
In [5]:
# Define the model
def multilayer_perceptron(x, weights, biases):

    # Hidden layer with sigmoid activations
    layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
    layer_1 = tf.nn.sigmoid(layer_1)

    # Hidden layer with sigmoid activations
    layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])
    layer_2 = tf.nn.sigmoid(layer_2)

    # Hidden layer with sigmoid activations
    layer_3 = tf.add(tf.matmul(layer_2, weights['h3']), biases['b3'])
    layer_3 = tf.nn.sigmoid(layer_3)

    # Hidden layer with RELU activations
    layer_4 = tf.add(tf.matmul(layer_3, weights['h4']), biases['b4'])
    layer_4 = tf.nn.relu(layer_4)

    # Output layer with linear activations
    out_layer = tf.matmul(layer_4, weights['out']) + biases['out']
    return out_layer

# Define the weights and the biases for each layer
weights = {
    'h1': tf.Variable(tf.truncated_normal([n_dim, n_hidden_1])),
    'h2': tf.Variable(tf.truncated_normal([n_hidden_1, n_hidden_2])),
    'h3': tf.Variable(tf.truncated_normal([n_hidden_2, n_hidden_3])),
    'h4': tf.Variable(tf.truncated_normal([n_hidden_3, n_hidden_4])),
    'out': tf.Variable(tf.truncated_normal([n_hidden_4, n_class])),
}
biases = {
    'b1': tf.Variable(tf.truncated_normal([n_hidden_1])),
    'b2': tf.Variable(tf.truncated_normal([n_hidden_2])),
    'b3': tf.Variable(tf.truncated_normal([n_hidden_3])),
    'b4': tf.Variable(tf.truncated_normal([n_hidden_4])),
    'out': tf.Variable(tf.truncated_normal([n_class])),
}
In [6]:
# Initialize all the variables
init = tf.global_variables_initializer()
saver = tf.train.Saver()

# Call your model defined
y = multilayer_perceptron(x, weights, biases)

# Define the cost function and optimizer
cost_function = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=y, labels=y_))
training_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost_function)

# Launch the graph
sess = tf.Session()
sess.run(init)

mse_history = []
accuracy_history = []
In [7]:
# Calculate the cost and accuracy of each epoch
for epoch in range(training_epochs):
    sess.run(training_step, feed_dict={x: test_x, y_: test_y})
    cost = sess.run(cost_function, feed_dict={x: test_x, y_: test_y})
    cost_history = np.append(cost_history, cost)
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

    pred_y = sess.run(y, feed_dict={x: test_x})
    mse = tf.reduce_mean(tf.square(pred_y - test_y))
    mse_ = sess.run(mse)
    mse_history.append(mse_)
    accuracy = (sess.run(accuracy, feed_dict={x: test_x, y_: test_y}))
    accuracy_history.append(accuracy)

    print('Epoch: {:<6} Cost: {:<25} MSE: {:<22} Training Accuracy: {:<5}'.format(epoch, cost, mse_, accuracy))

save_path = saver.save(sess, model_path)
print('\nModel saved in folder:', save_path)
Epoch: 0      Cost: 87.35811614990234         MSE: 7626.536575162109      Training Accuracy: 0.5  
Epoch: 1      Cost: 6.894620418548584         MSE: 50.3020761355475       Training Accuracy: 0.5  
Epoch: 2      Cost: 3.361487865447998         MSE: 30.955426477005094     Training Accuracy: 0.5  
Epoch: 3      Cost: 0.7260686159133911        MSE: 0.5013900211897269     Training Accuracy: 0.5  
Epoch: 4      Cost: 0.6929373741149902        MSE: 0.4070605510426611     Training Accuracy: 0.5  
Epoch: 5      Cost: 0.6781018376350403        MSE: 0.3915892640169834     Training Accuracy: 0.5  
Epoch: 6      Cost: 0.6673206686973572        MSE: 0.413629547479418      Training Accuracy: 0.5476190447807312
Epoch: 7      Cost: 0.6539391875267029        MSE: 0.43283417493563126    Training Accuracy: 0.5714285969734192
Epoch: 8      Cost: 0.6401854157447815        MSE: 0.7254811923994738     Training Accuracy: 0.8095238208770752
Epoch: 9      Cost: 0.6277029514312744        MSE: 0.712054768438198      Training Accuracy: 0.7142857313156128
Epoch: 10     Cost: 0.6079661846160889        MSE: 0.6807539846352033     Training Accuracy: 0.7142857313156128
Epoch: 11     Cost: 0.5888373255729675        MSE: 0.6808916494234316     Training Accuracy: 0.6904761791229248
Epoch: 12     Cost: 0.5802644491195679        MSE: 0.9947860587779411     Training Accuracy: 0.761904776096344
Epoch: 13     Cost: 0.691802442073822         MSE: 1.2704975080195413     Training Accuracy: 0.5952380895614624
Epoch: 14     Cost: 1.0724416971206665        MSE: 7.073339179326677      Training Accuracy: 0.5  
Epoch: 15     Cost: 0.7017775774002075        MSE: 0.32697795582732325    Training Accuracy: 0.3333333432674408
Epoch: 16     Cost: 0.6909409165382385        MSE: 0.30531752647624294    Training Accuracy: 0.5  
Epoch: 17     Cost: 0.6857782006263733        MSE: 0.29894629882540735    Training Accuracy: 0.5  
Epoch: 18     Cost: 0.6818772554397583        MSE: 0.2998910234735752     Training Accuracy: 0.5  
Epoch: 19     Cost: 0.6782846450805664        MSE: 0.304250631405728      Training Accuracy: 0.6428571343421936
Epoch: 20     Cost: 0.6729066371917725        MSE: 0.30683943536091124    Training Accuracy: 0.6666666865348816
... ... ...
... ... ...  
Epoch: 980    Cost: 0.0004381746693979949     MSE: 65.1975496060161       Training Accuracy: 1.0  
Epoch: 981    Cost: 0.00043725321302190423    MSE: 65.23066313808093      Training Accuracy: 1.0  
Epoch: 982    Cost: 0.00043633501627482474    MSE: 65.24792157525519      Training Accuracy: 1.0  
Epoch: 983    Cost: 0.0004354701086413115     MSE: 65.28058534778091      Training Accuracy: 1.0  
Epoch: 984    Cost: 0.0004345519992057234     MSE: 65.29738636418675      Training Accuracy: 1.0  
Epoch: 985    Cost: 0.00043365085730329156    MSE: 65.31476968373434      Training Accuracy: 1.0  
Epoch: 986    Cost: 0.0004327717761043459     MSE: 65.34742013339917      Training Accuracy: 1.0  
Epoch: 987    Cost: 0.0004318650171626359     MSE: 65.36430631560093      Training Accuracy: 1.0  
Epoch: 988    Cost: 0.00043099772301502526    MSE: 65.38175463251966      Training Accuracy: 1.0  
Epoch: 989    Cost: 0.00043012158130295575    MSE: 65.414328670666        Training Accuracy: 1.0  
Epoch: 990    Cost: 0.00042922041029669344    MSE: 65.4312450261207       Training Accuracy: 1.0  
Epoch: 991    Cost: 0.00042836731881834567    MSE: 65.44871264235509      Training Accuracy: 1.0  
Epoch: 992    Cost: 0.0004275025276001543     MSE: 65.4811798462491       Training Accuracy: 1.0  
Epoch: 993    Cost: 0.0004266126488801092     MSE: 65.49808408031514      Training Accuracy: 1.0  
Epoch: 994    Cost: 0.0004257822292856872     MSE: 65.51554527402554      Training Accuracy: 1.0  
Epoch: 995    Cost: 0.0004249004414305091     MSE: 65.54788411123789      Training Accuracy: 1.0  
Epoch: 996    Cost: 0.0004240360576659441     MSE: 65.56476974501572      Training Accuracy: 1.0  
Epoch: 997    Cost: 0.0004232137289363891     MSE: 65.59666945461045      Training Accuracy: 1.0  
Epoch: 998    Cost: 0.0004223266732878983     MSE: 65.61311084598309      Training Accuracy: 1.0  
Epoch: 999    Cost: 0.0004214906657580286     MSE: 65.6301134269209       Training Accuracy: 1.0  

Model saved in folder: ./TensorFlow/NMI/
In [8]:
# Print the final accuracy
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Test Accuracy: ',(sess.run(accuracy, feed_dict={x: test_x, y_: test_y})))

# Print the final mean square error
pred_y = sess.run(y, feed_dict={x: test_x})
mse = tf.reduce_mean(tf.square(pred_y - test_y))
print('Mean Square Error: %.4f' % sess.run(mse))
Test Accuracy:  1.0
Mean Square Error: 65.6301
In [9]:
# Plot Accuracy graph
fig = plt.figure(figsize=(10,7))
plt.plot(accuracy_history)
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.show()
In [10]:
# Plot Loss graph
fig = plt.figure(figsize=(10,7))
plt.plot(range(len(cost_history)),cost_history)
plt.axis([0,training_epochs,0,np.max(cost_history)/100])
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

Using the Model to make Prediction if Rock or Mine

In [11]:
# Reading the new dataset
def read_dataset():
    dir_path = "./MLData/00_Misc/"
    df = pd.read_csv(dir_path + "Sonar_new.csv")
    X_new = df[df.columns[0:60]].values
    y_new = df[df.columns[60]]

    # Encode the labels
    encoder = LabelEncoder()
    encoder.fit(y_new)
    y_new = encoder.transform(y_new)
    Y_new = one_hot_encode(y_new)
    return (X_new, Y_new)

# Define the encoder function
def one_hot_encode(labels):
    n_labels = len(labels)
    n_unique_lables = len(np.unique(labels))
    encode = np.zeros((n_labels, n_unique_lables))
    encode[np.arange(n_labels), labels] = 1
    return encode

# Read the datset
X_new, Y_new = read_dataset()
In [12]:
X_new.shape, Y_new.shape
Out[12]:
((15, 60), (15, 2))
In [13]:
saver.restore(sess, model_path)

prediction = tf.argmax(y, 1)
correct_prediction = tf.equal(prediction, tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

print("**************************************************************")
print("* 1 stands for M, (i.e. Mine) and 0 stands for R (i.e. Rock) *")
print("**************************************************************")
for i in range(1,15):
    prediction_run = sess.run(prediction, feed_dict={x:X_new[i].reshape(1,60)})
    accuracy_run = sess.run(accuracy, feed_dict={x:X_new[i].reshape(1,60), y_:Y_new[i].reshape(1,2)})
    print(i,"Original Class: ", int(sess.run(y_[i][1],feed_dict={y_:Y_new})), " Predicted Values: ", prediction_run[0] )
    print("Accuracy: ",str(accuracy_run*100)+"%")
INFO:tensorflow:Restoring parameters from ./TensorFlow/NMI/
**************************************************************
* 1 stands for M, (i.e. Mine) and 0 stands for R (i.e. Rock) *
**************************************************************
1 Original Class:  0  Predicted Values:  0
Accuracy:  100.0%
2 Original Class:  1  Predicted Values:  1
Accuracy:  100.0%
3 Original Class:  0  Predicted Values:  0
Accuracy:  100.0%
4 Original Class:  1  Predicted Values:  1
Accuracy:  100.0%
5 Original Class:  0  Predicted Values:  1
Accuracy:  0.0%
6 Original Class:  1  Predicted Values:  1
Accuracy:  100.0%
7 Original Class:  1  Predicted Values:  1
Accuracy:  100.0%
8 Original Class:  1  Predicted Values:  0
Accuracy:  0.0%
9 Original Class:  0  Predicted Values:  0
Accuracy:  100.0%
10 Original Class:  0  Predicted Values:  0
Accuracy:  100.0%
11 Original Class:  1  Predicted Values:  0
Accuracy:  0.0%
12 Original Class:  1  Predicted Values:  1
Accuracy:  100.0%
13 Original Class:  0  Predicted Values:  0
Accuracy:  100.0%
14 Original Class:  1  Predicted Values:  1
Accuracy:  100.0%
In [ ]:
 
The above results show the predictions made by the trained Multilayer Perceptron model to indicate if the underwater object is Rock or Mine. Here 1 stands for Mine and 0 stands for Rock. As you can see, for the 14 sample objects given to the model to predict if it is Rock or Mine, the model made 11 correct predictions and 3 incorrect predictions, giving a prediction accuracy of 73.3%. The accuracy level of the predictions can be increased by training the model with some more data. The main intention of the example is to show how Google's TensorFlow can be used for Artificial Intelligence and Machine Learning.