Pankaj Mathur
Published in

Pankaj Mathur

A Simple Multilayer Perceptron with TensorFlow

Simple Multilayer Perceptron

In this notebook, we will build a simple multilayer perceptron, basic building block for Neural Networks, with TensorFlow. We are using MNIST example dataset provided by default with TensorFlow package.

Here are the hyper parameters we choose to run initial model:

  • learning_rate = 0.001
  • training_epochs = 10
  • batch_size = 256
  • display_step = 1

Here are the network parameters we choose to run multilayer perceptron:

  • n_hidden_1 = 256
  • n_hidden_2 = 256
  • n_input = 784
  • n_classes = 10

We achieved 94.8% accuracy in 20 epochs with learning rate of 0.01 by running multilayer perceptron model build with TensorFlow on MNIST dataset.


I am using Conda to install TensorFlow. You might already have a TensorFlow environment, but please check below to make sure you have all the necessary packages. If you have never used Conda environments before, please go through my other tutorial What is Anaconda and Why should I bother about it?

Assuming you have conda install on your machine, please run the following commands to have tensorflow-playground ready for you to play.

OS X or Linux

Run the following commands to setup your environment:

conda create -n tensorflow-playground python=3.5
source activate tensorflow-playground
conda install pandas matplotlib jupyter notebook scipy scikit-learn
pip install tensorflow


And installing on Windows. In your console or Anaconda shell:

conda create -n tensorflow-playground python=3.5
activate tensorflow-playground
conda install pandas matplotlib jupyter notebook scipy scikit-learn
pip install tensorflow

After creating conda environment, clone this repository on your local machine via Git or GitHub Desktop

under tensorflow-playground environment on your terminal or shell window, cd to the cloned directory and then run following command:

jupyter notebook

Please find the public Gist of this code:

That’s it, Just like my another article on quick logistic regression, now you can play around with various hyperparameters which you feel are good enough to improve accuracy on MNIST dataset.

If you a bit more adventurous, you can try replacing MNIST dataset with another sample dataset, such as CIFAR10. However, you have to download this data separately on your hard drive, extract it and access it via another python functions, something like below for your jupyter notebook.

import os
import os.path
import sys
import time
import re
import cPickle
import urllib, tarfile
current_path = os.path.abspath(getsourcefile(lambda:0))
parent_dir = os.path.split(os.path.dirname(current_path))[0]
sys.path.insert(0, parent_dir)
import common.load_notebooks
import common.utils
DATA_URL = ''def maybe_download_and_extract(dest_directory):
"""Download and extract the tarball from Alex's website."""
if not os.path.exists(dest_directory):
filename = DATA_URL.split('/')[-1]
filepath = os.path.join(dest_directory, filename)
if not os.path.exists(filepath):
def _progress(count, block_size, total_size):
sys.stdout.write('\r>> Downloading %s %.1f%%' % (filename,
float(count * block_size) / float(total_size) * 100.0))
filepath, _ = urllib.urlretrieve(DATA_URL, filepath, _progress)
statinfo = os.stat(filepath)
print('Successfully downloaded', filename, statinfo.st_size, 'bytes.')
with, 'r:gz') as t:
dataset_dir = os.path.join(dest_directory, t.getmembers()[0].name)

return dataset_dir
dataset_dir = maybe_download_and_extract('./../data')
checkpoint_dir = os.path.join(dataset_dir, 'chkpt_cifar10')
if not os.path.isdir(checkpoint_dir):
checkpoint_dir = os.path.join(dataset_dir, 'chkpt_cifar10')
if not os.path.isdir(checkpoint_dir):
#Here is the regular expression that matches a datafile
r_data_file = re.compile('^data_batch_\d+')
#training and validate datasets as numpy n-d arrays,
#apropriate portions of which are ready to be fed to the placeholder variables
train_all={'data':[], 'labels':[]}
validate_all={'data':[], 'labels':[]}
test_all={'data':{}, 'labels':[]}
def unpickle(relpath):
with open(relpath, 'rb') as fp:
d = cPickle.load(fp)
return d
def prepare_input(data=None, labels=None):
global image_height, image_width, image_depth
assert(data.shape[1] == image_height * image_width * image_depth)
assert(data.shape[0] == labels.shape[0])
#do mean normaization across all samples
mu = np.mean(data, axis=0)
mu = mu.reshape(1,-1)
sigma = np.std(data, axis=0)
sigma = sigma.reshape(1, -1)
data = data - mu
data = data / sigma
is_nan = np.isnan(data)
is_inf = np.isinf(data)
if np.any(is_nan) or np.any(is_inf):
print('data is not well-formed : is_nan {n}, is_inf: {i}'.format(n= np.any(is_nan), i=np.any(is_inf)))
#data is transformed from (no_of_samples, 3072) to (no_of_samples , image_height, image_width, image_depth)
#make sure the type of the data is no.float32
data = data.reshape([-1,image_depth, image_height, image_width])
data = data.transpose([0, 2, 3, 1])
data = data.astype(np.float32)
return data, labels
#return transform_input(data=data, labels=labels, h=image_height, w=image_width, d=image_depth)def convert_to_rgb_img_data(index=-1, data=None):
assert(index < data.shape[0])
image_holder = np.zeros(shape=[data.shape[1],data.shape[2], data.shape[3]], dtype=np.float32)
image_holder[:, :, :] = data[index, :, :, :]

def load_and_preprocess_input(dataset_dir=None):
global train_all, validate_all, label_names_for_validation_and_test
#for loading train dataset, iterate through the directory to get matchig data file
for root, dirs, files in os.walk(dataset_dir):
for f in files:
if m:
relpath = os.path.join(root, f)
d=unpickle(os.path.join(root, f))
#concatenate all the data in various files into one ndarray of shape
#data.shape == (no_of_samples, 3072), where 3072=image_depth x image_height x image_width
#labels.shape== (no_of_samples)
trn_all_data, trn_all_labels = (np.concatenate(trn_all_data).astype(np.float32),

#load the only test data set for validation and testing
#use only the first n_validate_samples samples for validating
test_temp=unpickle(os.path.join(dataset_dir, 'test_batch'))
vldte_all_data=test_temp['data'][0:(n_validate_samples+n_test_samples), :]
vldte_all_data, vldte_all_labels = (np.concatenate([vldte_all_data]).astype(np.float32),
#transform the test images in the same manner as the train images
train_all['data'], train_all['labels'] = prepare_input(data=trn_all_data, labels=trn_all_labels)
validate_and_test_data, validate_and_test_labels = prepare_input(data=vldte_all_data, labels=vldte_all_labels)

validate_all['data'] = validate_and_test_data[0:n_validate_samples, :, :, :]
validate_all['labels'] = validate_and_test_labels[0:n_validate_samples]
test_all['data'] = validate_and_test_data[n_validate_samples:(n_validate_samples+n_test_samples), :, :, :]
test_all['labels'] = validate_and_test_labels[n_validate_samples:(n_validate_samples+n_test_samples)]

#load all label-names
label_names_for_validation_and_test=unpickle(os.path.join(dataset_dir, 'batches.meta'))['label_names']


print('train_all: ', 'data: ', train_all['data'].shape, train_all['data'].dtype, ' labels: ', train_all['labels'].shape, train_all['labels'].dtype)
print('validate_all: ', 'data: ', validate_all['data'].shape, validate_all['data'].dtype, ' labels: ', validate_all['labels'].shape, validate_all['labels'].dtype)
print('test_all: ', 'data: ', test_all['data'].shape, test_all['data'].dtype, ' labels: ', test_all['labels'].shape, test_all['labels'].dtype)
print('label_names_for_validation_and_test', label_names_for_validation_and_test)

Please do let me know your thoughts, questions under the comments section. I would really appreciate getting some feedback on this article & ideas to improve it.

In the meanwhile, Happy Thinking…



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store