I have been working on this code for a while and it gave me a lot of headaches before I got it to work. It basically tries to use the MNIST dataset to classify handwritten digits. I am not using the prepackaged MNIST in TensorFlow because I want to learn preprocessing the data myself and for deeper understanding of TensorFlow.
It's finally working, but I would love it if someone with expertise could take a look at it and tell me what they think, and if the results it's producing are actually real stats or if it's overfitting.
It's giving me accuracy between 80% and 91%. The dataset I'm using is from here.
import numpy as np
import tensorflow as tf
sess = tf.Session()
from sklearn import preprocessing
import matplotlib.pyplot as plt
with tf.Session() as sess:
# lets load the file
train_file = 'mnist_train.csv'
test_file = 'mnist_test.csv'
#train_file = 'mnist_train_small.csv'
#test_file = 'mnist_test_small.csv'
train = np.loadtxt(train_file, delimiter=',')
test = np.loadtxt(test_file, delimiter=',')
x_train = train[:,1:785]
y_train = train[:,:1]
x_test = test[:,1:785]
y_test = test[:,:1]
print(x_test.shape)
# lets normalize the data
def normalize(input_data):
minimum = input_data.min(axis=0)
maximum = input_data.max(axis=0)
#normalized = (input_data - minimum) / ( maximum - minimum )
normalized = preprocessing.normalize(input_data, norm='l2')
return normalized
# convert to a onehot array
def one_hot(input_data):
one_hot = []
for item in input_data:
if item == 0.:
one_h = [1.,0.,0.,0.,0.,0.,0.,0.,0.,0.]
elif item == 1.:
one_h = [0.,1.,0.,0.,0.,0.,0.,0.,0.,0.]
elif item == 2.:
one_h = [0.,0.,1.,0.,0.,0.,0.,0.,0.,0.]
elif item == 3.:
one_h = [0.,0.,0.,1.,0.,0.,0.,0.,0.,0.]
elif item == 4.:
one_h = [0.,0.,0.,0.,1.,0.,0.,0.,0.,0.]
elif item == 5.:
one_h = [0.,0.,0.,0.,0.,1.,0.,0.,0.,0.]
elif item == 6.:
one_h = [0.,0.,0.,0.,0.,0.,1.,0.,0.,0.]
elif item == 7.:
one_h = [0.,0.,0.,0.,0.,0.,0.,1.,0.,0.]
elif item == 8.:
one_h = [0.,0.,0.,0.,0.,0.,0.,0.,1.,0.]
elif item == 9.:
one_h = [0.,0.,0.,0.,0.,0.,0.,0.,0.,1.]
one_hot.append(one_h)
one_hot = np.array(one_hot)
#one_hot = one_hot.reshape(len(one_hot),10,1)
#one_hot = one_hot.reshape(len(one_hot), 7,1)
#return tf.constant([one_hot])
return one_hot
def one_hot_tf(val):
indices = val
depth = 10
on_value = 1.0
off_value = 0.0
axis = -1
oh = tf.one_hot(indices, depth,
on_value=on_value, off_value=off_value,
axis=axis, dtype=tf.float32,
name='ONEHOT')
return (oh)
x_train = normalize(x_train)
x_test = normalize(x_test)
# x_train = sess.run(tf.convert_to_tensor(x_train))
# x_test = sess.run(tf.convert_to_tensor(x_test))
'''
data_initializer = tf.placeholder(dtype=x_train.dtype,
shape=x_train.shape)
label_initializer = tf.placeholder(dtype=x_test.dtype,
shape=x_test.shape)
x_train= sess.run(tf.Variable(data_initializer, trainable=False, collections=[]))
x_test = sess.run(tf.Variable(label_initializer, trainable=False, collections=[]))
'''
y_test = one_hot(y_test)
y_train = one_hot(y_train)
print(y_test[:5])
# y_test = sess.run(one_hot_tf(y_test))
# y_train = sess.run(one_hot_tf(y_train))
# define the parameters
input_nodes = 784
output_nodes = 10
hl1_nodes = 500
hl2_nodes = 500
hl3_nodes = 500
epochs = 10
x = tf.placeholder(tf.float32, [None, input_nodes])
y = tf.placeholder(tf.float32)
# graphing
loss_rate = []
def nn(data):
layer1 = {'w':tf.Variable(tf.random_normal([input_nodes, hl1_nodes])),
'b':tf.Variable(tf.random_normal([hl1_nodes]))}
layer2 = {'w':tf.Variable(tf.random_normal([hl1_nodes, hl2_nodes])),
'b':tf.Variable(tf.random_normal([hl2_nodes]))}
layer3 = {'w':tf.Variable(tf.random_normal([hl2_nodes, hl3_nodes])),
'b':tf.Variable(tf.random_normal([hl3_nodes]))}
output_layer = {'w':tf.Variable(tf.random_normal([hl3_nodes, output_nodes])),
'b':tf.Variable(tf.random_normal([output_nodes]))}
l1 = tf.add(tf.matmul(data, layer1['w']), layer1['b'])
l1 = tf.nn.relu(l1)
l2 = tf.add(tf.matmul(l1, layer2['w']), layer2['b'])
l2 = tf.nn.relu(l2)
l3 = tf.add(tf.matmul(l2, layer3['w']), layer3['b'])
l3 = tf.nn.relu(l3)
output = tf.add(tf.matmul(l3, output_layer['w']), output_layer['b'])
return(output)
def train(x):
prediction = nn(x)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y))
optimizer = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
init = tf.global_variables_initializer()
sess.run(init)
for epoch in range(epochs):
epochloss = 0
batch_size = 10
batches = 0
for batch in range(int(len(x_train)/batch_size)):
next_batch = batches+batch
_, c = sess.run([optimizer, loss], feed_dict={x:x_train[batches:next_batch, :], y:y_train[batches:next_batch, :]})
epochloss = epochloss + c
batches += batch
loss_rate.append(c)
print("Epoch ", epoch, " / ", epochs, " - Loss ", epochloss)
correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
print("Accuracy : ", accuracy.eval({x:x_test, y:y_test}))
train(x)
plt.plot(loss_rate)
plt.show()