import keras
from keras.datasets import mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
print "input of training set has shape {} and output has shape {}".format(x_train.shape, y_train.shape)
print "input of testing set has shape {} and output has shape {}".format(x_test.shape, y_test.shape)

"""
Explanation: This notebooks aims at visualizing the content of the MNIST dataset
As a fist step, we use keras to download the dataset.
Then we print the shape of it.
End of explanation
"""


import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

print "The first 15 <X_train> values:"
fig, axs = plt.subplots(3,5)
axs = [b for a in axs for b in a]
for i in range(3*5):
    axs[i].imshow(x_train[i], cmap='gray')
    axs[i].axis('off')
plt.show()

print "The first 15 <y_test> values:"
print y_train[: 3 * 5]

"""
Explanation: In case it needs disambiguation, we plot some arrays corresponding to the X values and some of the Y values:
End of explanation
"""


fig, axs = plt.subplots(2,2)
axs[0][0].hist(x_train.reshape([-1]), bins = 25)
axs[0][1].hist(y_train.reshape([-1]), bins = 10)
axs[1][0].hist(x_test.reshape([-1]), bins = 25)
axs[1][1].hist(y_test.reshape([-1]), bins = 10)
plt.show()

print "Standard deviation of x_train is {} and mean is {}".format(
    x_train.std(), x_train.mean())
print "Standard deviation of x_test is {} and mean is {}".format(
    x_test.std(), x_test.mean())

"""
Explanation: Now, we are sure that X_train contains grey-scaled images and Y_train the digit corresponding to its X_train image.
Data distribution
Next step consists in knowing how is our data distibuted
End of explanation
"""


# Normalize the MNIST data
def data_preprocessing(data, std, mean):
    data = data - mean
    data = data / std
    return data

std = x_train.std()
mean = x_train.mean()
x_train = data_preprocessing(x_train, std, mean)
x_test = data_preprocessing(x_test, std, mean)

# Show the results
fig, axs = plt.subplots(2,1)
axs[0].hist(x_train.reshape([-1]), bins = 25)
axs[1].hist(x_test.reshape([-1]), bins = 25)
plt.show()

print "Standard deviation of x_train is {} and mean is {}".format(
    x_train.std(), x_train.mean())
print "Standard deviation of x_test is {} and mean is {}".format(
    x_test.std(), x_test.mean())

"""
Explanation: Left plots tells us that the Xs are ranging in $[0, 255]$ and that most of the pixels are around zero.
Right plots shows the distribution of the 10 labels MNIST has. 
In both cases (train and test) we learn that "5" is the least represented digit and "1" is the most represented one.
Data normalization
As we'll see, we rather normlize and center this data such that X_train has a standard deviation of one and a mean of zero
End of explanation
"""


