Chapter 3.2 - Anatomy of a neural network


In [1]:
from keras.datasets import mnist


Using TensorFlow backend.

In [2]:
# Importing the data
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

In [3]:
# Preprocessing the training images
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32')
train_images = train_images / 255

In [4]:
train_images.shape


Out[4]:
(60000, 784)

In [5]:
# Preprocessing the test images
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32')
test_images = test_images / 255

In [6]:
test_images.shape


Out[6]:
(10000, 784)

In [7]:
# Importing - to_categorical
from keras.utils import to_categorical

In [8]:
train_labels.shape


Out[8]:
(60000,)

In [9]:
# One-hot encoding the training labels
train_labels = to_categorical(train_labels)

In [10]:
train_labels.shape


Out[10]:
(60000, 10)

In [11]:
test_labels = to_categorical(test_labels)

In [12]:
test_labels.shape


Out[12]:
(10000, 10)

Sequential vs Functional API

Sequential


In [13]:
# Importing Sequential model
from keras.models import Sequential

In [14]:
# Initializing a sequantial model
model_sequential = Sequential()

In [15]:
# Importing layers
from keras import layers

In [16]:
# Adding a hidden layers
model_sequential.add(layers.Dense(units = 32, 
                                  activation = 'relu', 
                                  input_shape = (784,)))

In [17]:
model_sequential.add(layers.Dense(units = 10, activation = 'softmax'))

Functional API


In [18]:
# Importing Functional API model
from keras.models import Model

In [19]:
# Importing layers (obsolete, but consistent)
from keras import layers

In [20]:
# Input layers
input_layer = layers.Input(shape = (784,))

In [21]:
# Hidden layer (fully connected to the input layer)
hidden_layers = layers.Dense(units = 32, activation = 'relu')(input_layer)

In [22]:
# Output layers
output_layer = layers.Dense(units = 10, activation = 'softmax')(hidden_layers)

In [23]:
model_functional = Model(inputs = input_layer, outputs = output_layer)

Compiling both models


In [24]:
# Importing optimizers
from keras import optimizers

In [25]:
# Compiling the Sequential model
model_sequential.compile(optimizer = optimizers.RMSprop(lr = 0.001),
                         loss = 'mse', 
                         metrics = ['accuracy'])

In [26]:
# Compiling the Functional model
model_functional.compile(optimizer = optimizers.RMSprop(lr = 0.001),
                         loss = 'mse', 
                         metrics = ['accuracy'])

Training both models


In [27]:
# Sequential
model_sequential.fit(x = train_images, 
                     y = train_labels, 
                     batch_size = 128, 
                     epochs = 10)


Epoch 1/10
60000/60000 [==============================] - 3s - loss: 0.0208 - acc: 0.8708     
Epoch 2/10
60000/60000 [==============================] - 2s - loss: 0.0114 - acc: 0.9281     
Epoch 3/10
60000/60000 [==============================] - 2s - loss: 0.0096 - acc: 0.9392     
Epoch 4/10
60000/60000 [==============================] - 2s - loss: 0.0085 - acc: 0.9463     
Epoch 5/10
60000/60000 [==============================] - 2s - loss: 0.0077 - acc: 0.9518     
Epoch 6/10
60000/60000 [==============================] - 2s - loss: 0.0071 - acc: 0.9564     
Epoch 7/10
60000/60000 [==============================] - 2s - loss: 0.0066 - acc: 0.9594     
Epoch 8/10
60000/60000 [==============================] - 2s - loss: 0.0061 - acc: 0.9626     
Epoch 9/10
60000/60000 [==============================] - 2s - loss: 0.0058 - acc: 0.9639     
Epoch 10/10
60000/60000 [==============================] - 2s - loss: 0.0054 - acc: 0.9667     
Out[27]:
<keras.callbacks.History at 0x25d5e6f0eb8>

In [28]:
model_functional.fit(x = train_images, 
                     y = train_labels, 
                     batch_size = 128, 
                     epochs = 10)


Epoch 1/10
60000/60000 [==============================] - 2s - loss: 0.0200 - acc: 0.8775     
Epoch 2/10
60000/60000 [==============================] - 2s - loss: 0.0112 - acc: 0.9287     
Epoch 3/10
60000/60000 [==============================] - 2s - loss: 0.0097 - acc: 0.9383     
Epoch 4/10
60000/60000 [==============================] - 2s - loss: 0.0087 - acc: 0.9451     
Epoch 5/10
60000/60000 [==============================] - 2s - loss: 0.0079 - acc: 0.9505     
Epoch 6/10
60000/60000 [==============================] - 2s - loss: 0.0074 - acc: 0.9541     
Epoch 7/10
60000/60000 [==============================] - 2s - loss: 0.0069 - acc: 0.9574     
Epoch 8/10
60000/60000 [==============================] - 2s - loss: 0.0065 - acc: 0.9604     
Epoch 9/10
60000/60000 [==============================] - 2s - loss: 0.0061 - acc: 0.9622     
Epoch 10/10
60000/60000 [==============================] - 2s - loss: 0.0058 - acc: 0.9645     
Out[28]:
<keras.callbacks.History at 0x25d5e794fd0>

Both models are completely equal!