Deep Learning: Feed Forward Neural Networks (FFNNs)

Deep Learning: Feed Forward Neural Networks (FFNNs)

a.k.a. Multi-Layered Perceptrons (MLPs)

A Deep Feed Forward Neural Network (FFNN) — aka Multi-Layered Perceptron (MLP)

A single Neuron from an Artificial Neural Network (ANN)

Weights act as soft gates to ignore some features (0) and focus on others (+1) or even inhibit them (-1)

A small selection of Popular Activation Functions

A Neuron’s output value often feeds in as an input to other Neurons in the Artificial Neural Network (ANN)The Perceptron, one of the first Neural Networks, is made of just a single Neuron

The Perceptron

Each Neuron is a linear binary classifier all on its own (e.g. an output value >= 0 indicates the blue class, while an output value < 0 indicates the red class)

import numpy as np

class Neuron:

def __init__(self, n_inputs, bias = 0., weights = None):
self.b = bias
if weights: self.ws = np.array(weights)
else: self.ws = np.random.rand(n_inputs)

def __call__(self, xs):
return self._f(xs @ self.ws + self.b)

def _f(self, x):
return max(x*.1, x)

perceptron = Neuron(n_inputs = 3, bias = -0.1, weights = [0.7, 0.6, 1.4])

perceptron([1.0, 0.5, -1.0])

Notice that by adjusting the values of the weights and bias, you can adjust the neuron’s decision boundary. (NB: a neuron learns by updating its weights and bias values to reduce the error of its decisions).

Limitations: The neuron is a binary classifier since it can only learn to distinguish between two classes (e.g. blue and red) max. The neuron is a linear classifier because it’s decision boundary approximates to a straight line for 2D data (or a flat plane for 3D data, etc)

Combining Neurons allows Neural Networks to learn more complex, Nonlinear Decision Boundaries

Neural Networks contain Layers

Deep neural networks contain multiple hidden layers

An example image that our ANN will learn to paint (It will be learning to associate certain colours to certain regions of the picture)

!curl -O https://pmcvariety.files.wordpress.com/2018/04/twitter-logo.jpg?w=100&h=100&crop=1

from PIL import Image
image = Image.open('twitter-logo.jpg?w=100')

import numpy as np
image_array = np.asarray(image)

training_inputs,training_outputs = [],[]
for row,rgbs in enumerate(image_array):
for column,rgb in enumerate(rgbs):
training_inputs.append((row,column))
r,g,b = rgb
training_outputs.append((r/255,g/255,b/255))

A fully-connected feed-forward neural network (FFNN) — aka A multi-layered perceptron (MLP)

  • It should have 2 neurons in the input layer (since there are 2 values to take in: x & y coordinates).
  • It should have 3 neurons in the output layer (since there are 3 values to learn: r, g, b).
  • The number of hidden layers and the number of neurons in each hidden layer are two hyperparameters to experiment with (as well as the number of epochs we will train it for, the activation function, etc) — I’ll use 10 hidden layers with 100 neurons in each hidden layer (making this a deep neural network)

from sklearn.neural_network import MLPRegressor

ann = MLPRegressor(hidden_layer_sizes= tuple(100 for _ in range(10)))

ann.fit(training_inputs, training_outputs)

ann.predict([[1,1]])

predicted_outputs = ann.predict(training_inputs)

predicted_image_array = np.zeros_like(image_array)
i = 0
for row,rgbs in enumerate(predicted_image_array):
for column in range(len(rgbs)):
r,g,b = predicted_outputs[i]
predicted_image_array[row][column] = [r*255,g*255,b*255]
i += 1
Image.fromarray(predicted_image_array)

Our ANN’s Painting (predicted pixel colours)

training_inputs,training_outputs = [],[]
for row,rgbs in enumerate(image_array):
for column,rgb in enumerate(rgbs):
training_inputs.append((row,column))
if sum(rgb) <= 600:
label = (0,1) #blue class
else:
label = (1,0) #grey class
training_outputs.append(label)

from sklearn.neural_network import MLPClassifier
ann = MLPClassifier(hidden_layer_sizes= tuple(100 for _ in range(10)))
ann.fit(training_inputs, training_outputs)

np.argmax(ann.predict([[1,1]]))

predicted_outputs = ann.predict(training_inputs)

predicted_image_array = np.zeros_like(image_array)
i = 0
for row,rgbs in enumerate(predicted_image_array):
for column in range(len(rgbs)):
prediction = np.argmax(predicted_outputs[i])
if prediction == 0:
predicted_image_array[row][column] = [245,245,245]
else:
predicted_image_array[row][column] = [135,206,250]
i += 1
Image.fromarray(predicted_image_array)

The predicted class for each pixelThe expected class for each pixel