# RapidMiner

Highlighted
Learner II

## What is TensorFlow? A typical “flow” of TensorFlow

“TensorFlow is an open source software library for numerical computation using dataflow graphs. Nodes in the graph represents mathematical operations, while graph edges represent multi-dimensional data arrays (aka tensors) communicated between them. The flexible architecture allows you to deploy computation to one or more CPUs or GPUs in a desktop, server, or mobile device with a single API.”

It’s easy to classify TensorFlow as a neural network library, but it’s not just that. Yes, it was designed to be a powerful neural network library. But it has the power to do much more than that. You can build other machine learning algorithms on it such as decision trees or k-Nearest Neighbors. You can literally do everything you normally would do in numpy! It’s aptly called “numpy on steroids”

The advantages of using TensorFlow are:

• It has an intuitive construct, because as the name suggests it has “flow of tensors”. You can easily visualize each and every part of the graph.
• Easily train on cpu/gpu for distributed computing
• Platform flexibility. You can run the models wherever you want, whether it is on mobile, server or PC.

## A typical “flow” of TensorFlow

Every library has its own “implementation details”, i.e. a way to write which follows its coding paradigm. For example, when implementing scikit-learn, you first create object of the desired algorithm, then build a model on train and get predictions on test set, something like this:

```# define hyperparamters of ML algorithm
clf = svm.SVC(gamma=0.001, C=100.)
# train
clf.fit(X, y)
# test
clf.predict(X_test)```

As I said earlier, TensorFlow follows a lazy approach. The usual workflow of running a program in TensorFlow is as follows:

• Build a computational graph, this can be any mathematical operation TensorFlow supports.
• Initialize variables, to compile the variables defined previously
• Create session, this is where the magic starts!
• Run graph in session, the compiled graph is passed to the session, which starts its execution.
• Close session, shutdown the session.

Few terminologies used in TensoFlow;

• `placeholder: A way to feed data into the graphs`
• `feed_dict: A dictionary to pass numeric values to computational graph`

Lets write a small program to add two numbers!

```# import tensorflow
import tensorflow as tf

# build computational graph
a = tf.placeholder(tf.int16)
b = tf.placeholder(tf.int16)

# initialize variables
init = tf.initialize_all_variables()

# create session and run the graph
with tf.Session() as sess:
sess.run(init)

# close session
sess.close()```

## Implementing Neural Network in TensorFlow

Note: We could have used a different neural network architecture to solve this problem, but for the sake of simplicity, we settle on feed forward multilayer perceptron with an in depth implementation.

Let us remember what we learned about neural networks first.

A typical implementation of Neural Network would be as follows:

• Define Neural Network architecture to be compiled
• Transfer data to your model
• Under the hood, the data is first divided into batches, so that it can be ingested. The batches are first preprocessed, augmented and then fed into Neural Network for training
• The model then gets trained incrementally
• Display the accuracy for a specific number of timesteps
• After training save the model for future use
• Test the model on a new data and check how it performs

Our problem is an image recognition, to identify digits from a given 28 x 28 image. We have a subset of images for training and the rest for testing our model. So first, download the train and test files. The dataset contains a zipped file of all the images in the dataset and both the train.csv and test.csv have the name of corresponding train and test images. Any additional features are not provided in the datasets, just the raw images are provided in ‘.png’ format.

As you know we will use TensorFlow to make a neural network model. So you should first install TensorFlow in your system.

We will follow the template as described above. Create a Jupyter notebook with python 2.7 kernel and follow the steps below.

• Let’s import all the required modules
```%pylab inline

import os
import numpy as np
import pandas as pd
from sklearn.metrics import accuracy_score
import tensorflow as tf```
• Let’s set a seed value, so that we can control our models randomness
```# To stop potential randomness
seed = 128
rng = np.random.RandomState(seed)```
• The first step is to set directory paths, for safekeeping!
```root_dir = os.path.abspath('../..')
data_dir = os.path.join(root_dir, 'data')
sub_dir = os.path.join(root_dir, 'sub')

# check for existence
os.path.exists(root_dir)
os.path.exists(data_dir)
os.path.exists(sub_dir)```
• Now let us read our datasets. These are in .csv formats, and have a filename along with the appropriate labels
```train = pd.read_csv(os.path.join(data_dir, 'Train', 'train.csv'))

filename label
0 0.png 4
1 1.png 9
2 2.png 1
3 3.png 7
4 4.png 3
• Let us see what our data looks like! We read our image and display it.
```img_name = rng.choice(train.filename)
filepath = os.path.join(data_dir, 'Train', 'Images', 'train', img_name)

pylab.imshow(img, cmap='gray')
pylab.axis('off')
pylab.show()```

The above image is represented as numpy array, as seen below

• For easier data manipulation, let’s store all our images as numpy arrays
```temp = []
for img_name in train.filename:
image_path = os.path.join(data_dir, 'Train', 'Images', 'train', img_name)
img = img.astype('float32')
temp.append(img)

train_x = np.stack(temp)

temp = []
for img_name in test.filename:
image_path = os.path.join(data_dir, 'Train', 'Images', 'test', img_name)
img = img.astype('float32')
temp.append(img)

test_x = np.stack(temp)```
• As this is a typical ML problem, to test the proper functioning of our model we create a validation set. Let’s take a split size of 70:30 for train set vs validation set
```split_size = int(train_x.shape[0]*0.7)

train_x, val_x = train_x[:split_size], train_x[split_size:]
train_y, val_y = train.label.values[:split_size], train.label.values[split_size:]```
• Now we define some helper functions, which we use later on, in our programs
```def dense_to_one_hot(labels_dense, num_classes=10):
"""Convert class labels from scalars to one-hot vectors"""
num_labels = labels_dense.shape[0]
index_offset = np.arange(num_labels) * num_classes
labels_one_hot = np.zeros((num_labels, num_classes))
labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1

return labels_one_hot

def preproc(unclean_batch_x):
"""Convert values to range 0-1"""
temp_batch = unclean_batch_x / unclean_batch_x.max()

return temp_batch

def batch_creator(batch_size, dataset_length, dataset_name):
"""Create batch with random samples and return appropriate format"""

batch_x = eval(dataset_name + '_x')[[batch_mask]].reshape(-1, input_num_units)
batch_x = preproc(batch_x)

if dataset_name == 'train':
batch_y = dense_to_one_hot(batch_y)

return batch_x, batch_y```
• Now comes the main part! Let us define our neural network architecture. We define a neural network with 3 layers;  input, hidden and output. The number of neurons in input and output are fixed, as the input is our 28 x 28 image and the output is a 10 x 1 vector representing the class. We take 500 neurons in the hidden layer. This number can vary according to your need. We also assign values to remaining variables.
• .
```### set all variables

# number of neurons in each layer
input_num_units = 28*28
hidden_num_units = 500
output_num_units = 10

# define placeholders
x = tf.placeholder(tf.float32, [None, input_num_units])
y = tf.placeholder(tf.float32, [None, output_num_units])

# set remaining variables
epochs = 5
batch_size = 128
learning_rate = 0.01

### define weights and biases of the neural network (refer this article if you don't understand the terminologies)

weights = {
'hidden': tf.Variable(tf.random_normal([input_num_units, hidden_num_units], seed=seed)),
'output': tf.Variable(tf.random_normal([hidden_num_units, output_num_units], seed=seed))
}

biases = {
'hidden': tf.Variable(tf.random_normal([hidden_num_units], seed=seed)),
'output': tf.Variable(tf.random_normal([output_num_units], seed=seed))
}```
• Now create our neural networks computational graph
```hidden_layer = tf.add(tf.matmul(x, weights['hidden']), biases['hidden'])
hidden_layer = tf.nn.relu(hidden_layer)

output_layer = tf.matmul(hidden_layer, weights['output']) + biases['output']```
• Also, we need to define cost of our neural network
`cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output_layer, y))`
• And set the optimizer, i.e. our backpropogation algorithm. Here we use Adam, which is an efficient variant of Gradient Descent algorithm. There are a number of other optimizers available in tensorflow (refer here)
`optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)`
• After defining our neural network architecture, let’s initialize all the variables
`init = tf.initialize_all_variables()`
• Now let us create a session, and run our neural network in the session. We also validate our models accuracy on validation set that we created
```with tf.Session() as sess:
# create initialized variables
sess.run(init)

### for each epoch, do:
###   for each batch, do:
###     create pre-processed batch
###     run optimizer by feeding batch
###     find cost and reiterate to minimize

for epoch in range(epochs):
avg_cost = 0
total_batch = int(train.shape[0]/batch_size)
for i in range(total_batch):
batch_x, batch_y = batch_creator(batch_size, train_x.shape[0], 'train')
_, c = sess.run([optimizer, cost], feed_dict = {x: batch_x, y: batch_y})

avg_cost += c / total_batch

print "Epoch:", (epoch+1), "cost =", "{:.5f}".format(avg_cost)

print "\nTraining complete!"

# find predictions on val set
pred_temp = tf.equal(tf.argmax(output_layer, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(pred_temp, "float"))
print "Validation Accuracy:", accuracy.eval({x: val_x.reshape(-1, input_num_units), y: dense_to_one_hot(val_y)})

predict = tf.argmax(output_layer, 1)
pred = predict.eval({x: test_x.reshape(-1, input_num_units)})```

This will be the output of the above code

```Epoch: 1 cost = 8.93566
Epoch: 2 cost = 1.82103
Epoch: 3 cost = 0.98648
Epoch: 4 cost = 0.57141
Epoch: 5 cost = 0.44550

Training complete!
Validation Accuracy: 0.952823```
• To test our model with our own eyes, let’s visualize its predictions
```img_name = rng.choice(test.filename)
filepath = os.path.join(data_dir, 'Train', 'Images', 'test', img_name)

test_index = int(img_name.split('.')[0]) - 49000

print "Prediction is: ", pred[test_index]

pylab.imshow(img, cmap='gray')
pylab.axis('off')
pylab.show()

```
```Prediction is:  8
```
• We see that our model performance is pretty good! Now let’s create a submission
```sample_submission.filename = test.filename

sample_submission.label = pred

sample_submission.to_csv(os.path.join(sub_dir, 'sub01.csv'), index=False)```

Gracy Layla
Polls
How can RapidMiner increase participation in our new competitions?