#!/usr/bin/env python
# coding: utf-8
#
# # Digit Classification with Neural Networks
# ## About this project
# Our goal with this notebook is to build a neural network classifier in Keras to recognize hand-written digits. We will use the MNIST data set that consists of thousands of hand writtent numbers that span 0-9
#
# Similar to the process shown below:
#
#
# ## Import Libraries
#
# Here we import the libraries that we will be using throughout the notebook.
#
# The libraries that we will be using include:
# * [Numpy](https://www.numpy.org/)
# * [Keras](https://keras.io/)
# * [Matplotlib](https://matplotlib.org/) <-for plotting and visualizations
# In[1]:
from keras.datasets import mnist
from keras.preprocessing.image import load_img, array_to_img
from keras.utils.np_utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense
import numpy as np
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
# ## Load the data
# In[2]:
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# In[3]:
print(type(X_train))
print(X_train.shape)
print(y_train.shape) #60k is the answers
print(X_test.shape) #10K entries
print(y_test.shape)
# ## Understanding the image data format
# In[4]:
#Lets look at the data to see what it looks like
print(X_train[0].shape) #Look at the size of the 1st entry
#Plot it to see what it looks like
plt.imshow(X_train[0])
#Print the answer
print("The answer is {}".format(y_train[0]))
# ## Preprocessing the image data
# In[ ]:
image_height, image_width =28, 28
# In[ ]:
#Lets reshape each image to be a single vector rather than a matrix
#Have to flatten to plug into neural net
X_train =X_train.reshape(60000,image_height*image_width)
X_test =X_test.reshape(10000,image_height*image_width)
# In[7]:
print(X_train.shape) #28X28 =784
print(X_test.shape)
# In[8]:
#Check to see if image is between 0-255
print(min(X_train[0]), max(X_train[0])) #it is! so we need to normalize
#We will convert data to float (insead of int) to scale the data betwn 0-1 (not 0-255)
X_train = X_train.astype('float32') #Convert to float
X_test = X_test.astype('float32') #Convert to float
# In[9]:
#Normalize the data
X_train /= 255.0
X_test /= 255.0
print(min(X_train[0]), max(X_train[0])) #Normalized
# In[10]:
# We want the output to be in one of 9 bins to rep each of the 0-9 numbers
#In order to do this we can convert the answers to a categorical value
#We do this using the 'to_categorical' method
y_train =to_categorical(y_train, 10)
y_test =to_categorical(y_test, 10)
print(y_train.shape)
print(y_test.shape)
# In[11]:
print(y_test[0])
plt.imshow(X_test[0].reshape(image_height, image_width))
# ## Build a model
# In[12]:
#Assign the model type
model = Sequential()
# In[13]:
#Add layers to the model
model.add(Dense(512, activation='relu',input_shape=(784,)))
model.add(Dense(512, activation='relu'))
model.add(Dense(10, activation='softmax'))
# ## Compile the model
# In[14]:
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# In[15]:
model.summary()
# ## Calculating the number of parameters for each layer
#
# ### *Layer 1*
# * After flattening each image we get:
# * 28 X 28=784
# * We then pass the 784 into 512 nodes in the model plus a bias layer 512 (zeros)
# * This gives:
# * 784(pixels) X 512(neurons) X 512(bias)=401920
#
#
# ### *Layer 2*
# * We have 512 (output from previous), going into another 512 nodes (in new layer), plus another 512
# * This gives:
# * 512 (input) X 512 (this layer) X 512 =262656
#
# ### *Layer 3*
# * We have 512 (incoming from last layer), going into 10 nodes (in this layer), 10 bias units
# * This gives:
# * 512 (last layer) X 10 (nodes in this layer) + 10 (bias) =5130
# ## Train the model
# Now we can train our model.
# To do this we have to pass:
# * Training data
# * Number of epochs (the number of times that model passes through the training data)
# * Validation data (testing data)
#
# In[16]:
history =model.fit(X_train, y_train, epochs =20, validation_data=(X_test, y_test))
# In[ ]:
# ## What is the accuracy of the model?
# ### Plot the accuracy of the training model
# In[17]:
#Look at the attributes in the history object to find the accuracy
history.__dict__
# In[23]:
#Plot the accuracy
plt.plot(history.history['acc'],label='train')
plt.xlabel('Epoch Number')
plt.ylabel('Accuracy')
plt.title('Model Accuracy Over Epoch')
plt.legend()
# ### Plot the accuracy of training and validation set
# In[24]:
#Plot the accuracy of training data and validation data
plt.plot(history.history['acc'],label='train')
plt.plot(history.history['val_acc'],label='val')
plt.xlabel('Epoch Number')
plt.ylabel('Accuracy')
plt.title('Model Accuracy Over Epoch')
plt.legend()
# ### Accuracy of training and validation with loss
# In[25]:
#Plot the accuracy of training data and validation data AND loss
plt.plot(history.history['acc'],label='train')
plt.plot(history.history['val_acc'],label='val')
plt.plot(history.history['loss'],label='loss')
plt.xlabel('Epoch Number')
plt.ylabel('Accuracy')
plt.title('Model Accuracy Over Epoch')
plt.legend()
# plt.yscale('log')
# ## Evaluating model
# In[21]:
score=model.evaluate(X_test, y_test)
# In[22]:
#We get score as a list
#The second item in score gives us the accuracy of or model
score