mnist = input_data.read_data_sets('/data/mnist', one_hot=True) 

"""
Explanation: Step 1: Read in data<br>
using TF Learn's built in function to load MNIST data to the folder data/mnist
End of explanation
"""


with tf.Session() as sess:
	start_time = time.time()
	sess.run(tf.global_variables_initializer())	
	n_batches = int(mnist.train.num_examples/batch_size)
	for i in range(n_epochs): # train the model n_epochs times
		total_loss = 0

		for _ in range(n_batches):
			X_batch, Y_batch = mnist.train.next_batch(batch_size)
			# TO-DO: run optimizer + fetch loss_batch
			# 
			# 
			total_loss += loss_batch
		print('Average loss epoch {0}: {1}'.format(i, total_loss/n_batches))

	print('Total time: {0} seconds'.format(time.time() - start_time))

	print('Optimization Finished!') # should be around 0.35 after 25 epochs

	# test the model
	preds = tf.nn.softmax(logits)
	correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(Y, 1))
	accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32)) # need numpy.count_nonzero(boolarr) :(
	
	n_batches = int(mnist.test.num_examples/batch_size)
	total_correct_preds = 0
	
	for i in range(n_batches):
		X_batch, Y_batch = mnist.test.next_batch(batch_size)
		accuracy_batch = sess.run([accuracy], feed_dict={X: X_batch, Y:Y_batch}) 
		total_correct_preds += accuracy_batch	
	
	print('Accuracy {0}'.format(total_correct_preds/mnist.test.num_examples))

"""
Explanation: Step 2: create placeholders for features and labels<br>
each image in the MNIST data is of shape 28*28 = 784<br>
therefore, each image is represented with a 1x784 tensor<br>
there are 10 classes for each image, corresponding to digits 0 - 9.<br>
Features are of the type float, and labels are of the type int<br>
Step 3: create weights and bias<br>
weights and biases are initialized to 0<br>
shape of w depends on the dimension of X and Y so that Y = X * w + b<br>
shape of b depends on Y<br>
Step 4: build model<br>
the model that returns the logits.<br>
this logits will be later passed through softmax layer<br>
to get the probability distribution of possible label of the image<br>
DO NOT DO SOFTMAX HERE<br>
Step 5: define loss function<br>
use cross entropy loss of the real labels with the softmax of logits<br>
use the method:<br>
tf.nn.softmax_cross_entropy_with_logits(logits, Y)<br>
then use tf.reduce_mean to get the mean loss of the batch<br>
Step 6: define training op<br>
using gradient descent to minimize loss
End of explanation
"""


