Basics of Neural Networks - Keras Demo

Author(s): ronbodkin@google.com, kozyr@google.com, bfoo@google.com

We show how to train a very simple neural network from scratch (but let's upgrade from numpy to keras). Keras is a higher-level API that makes TensorFlow easier to work work with.

Setup

Identical to numpy version


In [0]:
import numpy as np

# Set up the data and network:
n_outputs = 5  # We're attempting to learn XOR in this example, so our inputs and outputs will be the same.
n_hidden_units = 10  # We'll use a single hidden layer with this number of hidden units in it.
n_obs = 500  # How many observations of the XOR input to output vector will we use for learning?

# How quickly do we want to update our weights?
learning_rate = 0.1

# How many times will we try to use each observation to improve the weights?
epochs = 10  # Think of this as iterations if you like.

# Set random seed so that the exercise works out the same way for everyone:
np.random.seed(42)

Only in keras version


In [0]:
import tensorflow as tf
# Which version of TensorFlow are we using?
print(tf.__version__)

In [0]:
# Add keras to runtime
!pip install keras

In [0]:
# Import keras and basic types of NN layers we will use
# Keras is a higher-level API for neural networks that works with TensorFlow
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation
import keras.utils as np_utils

Create some data to learn from

Identical to numpy version


In [0]:
# Create the inputs:
training_vectors = np.random.binomial(1, 0.5, (n_obs, n_outputs))
# Each row is a binary vector to learn from.
print('One instance with ' + str(n_outputs) + ' features: ' + str(training_vectors[0]))

# Create the correct XOR outputs (t is for target):
xor_training_vectors = training_vectors ^ 1  # This is just XOR, everything is deterministic.
print('Correct label (simply XOR):    ' + str(xor_training_vectors[0]))

Build the network directly

There's no need to write the loss and activation functions from scratch or compute the their derivatives, or to write forward and backprop from scratch. We'll just select them and keras will take care of it. Thanks, keras!

Only in keras version


In [0]:
# 2 layer model with ReLU for hidden layer, sigmoid for output layer
# Uncomment below to try a 3 layer model with two hidden layers
model = Sequential()
model.add(Dense(units=n_hidden_units, input_dim=n_outputs))
model.add(Activation('relu'))
#model.add(Dense(units=n_hidden_units))
#model.add(Activation('sigmoid'))
model.add(Dense(units=n_outputs))
model.add(Activation('sigmoid'))

In [0]:
# Time to choose an optimizer. Let's use SGD:
sgd = keras.optimizers.SGD(lr=learning_rate, decay=1e-6, momentum=0.9, nesterov=True)

In [0]:
# Set up model using cross-entropy loss with SGD optimizer:
model.compile(optimizer=sgd,
              loss='binary_crossentropy',
              metrics=['accuracy'])

Train the neural network!

Only in keras version


In [0]:
# Fit model:
model.fit(training_vectors, xor_training_vectors, epochs=epochs)

Validate

Almost identical to numpy version

The only difference relates to the use of model.predict() and model.evaluate(). See loss_and_metrics and predicted.


In [0]:
# Print performance to screen:
def get_performance(n_valid):
  """Computes performance and prints it to screen.
  
  Args:
    n_valid: number of validation instances we'd like to simulate.
          
  Returns:
    None
  """
  flawless_tracker = []
  validation_vectors = np.random.binomial(1, 0.5, (n_valid, n_outputs))
  xor_validation_vectors = validation_vectors ^ 1
        
  loss_and_metrics = model.evaluate(validation_vectors,
                                    xor_validation_vectors, batch_size=n_valid)
  print(loss_and_metrics)

  for i in range(n_valid):
    predicted = model.predict(np.reshape(validation_vectors[i], (1,-1)), 1)
    labels = (predicted > 0.5).astype(int)[0,]
    if i < 3:
      print('********')
      print('Challenge ' + str(i + 1) + ': ' + str(validation_vectors[i]))
      print('Predicted ' + str(i + 1) + ': ' + str(labels))
      print('Correct   ' + str(i + 1) + ': ' + str(xor_validation_vectors[i]))
    instance_score = (np.array_equal(labels, xor_validation_vectors[i]))
    flawless_tracker.append(instance_score)
  
  print('\nProportion of flawless instances on ' + str(n_valid) +
        ' new examples: ' + str(round(100*np.mean(flawless_tracker),0)) + '%')

In [0]:
get_performance(5000)