# MLP

``````

In [1]:

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

``````
``````

In [2]:

import shapely
from shapely.geometry import Polygon
from shapely.geometry import Point
from shapely.geometry import MultiPoint

``````
``````

In [3]:

polygon_coords = [(0.5,0.5),(1,2.5),(2.5,4),(3,3),(2.5,2.5),(3.5,1),(2.5,0),(2,2),(1.5,1),(0.5,0.5)]
polygon = Polygon(polygon_coords)

def get_true_label(point):
label = 0
if Point(point).within(polygon):
label = 1
return label

``````
``````

In [4]:

def generate_grid_points(count_per_side):
size_x = 4
size_y = 4
xs = np.linspace(0,size_x, count_per_side)
ys = np.linspace(0,size_y, count_per_side)
xv, yv = np.meshgrid(xs, ys)
points = np.array(np.zeros(shape=(3,xv.flatten().shape[0]), dtype=float))
points[0] = xv.flatten()
points[1] = yv.flatten()
return points

def get_grid_points_with_labels(count_per_side, label_func):
points = generate_grid_points(count_per_side)
labels = []
for i in range(len(points[0])):
point = np.array([points[0][i], points[1][i]])
label = label_func(point)
points[2,i] = label
labels.append(label)

#points[2] = np.array(labels)
return points

``````
``````

In [5]:

def step_func(x):
if x <= 0:
return 0
else:
return 1

def identity(x):
return x

def perceptron(x, w, b):
return step_func(x*w + b)

``````
``````

In [83]:

class Neuron:
def __init__(self, activation_func, input_dims):
self.act_func = activation_func
self.in_dims = input_dims
self.w = np.random.rand(input_dims,)
self.b = np.random.randn()

def set_to_AND(self):
self.w = np.ones((self.in_dims,), dtype=np.float)
self.b = -self.in_dims + 0.5

def set_to_OR(self):
self.w = np.ones((self.in_dims,), dtype=np.float)
self.b = 0

def out(self, x):
x = x.flatten()
self.w = self.w.flatten()
return self.act_func(np.dot(x,self.w) + self.b)

def plot(self):
points = get_grid_points_with_labels(100, self.out)
plt.scatter(points[0],points[1],c=points[2])
plt.show()

class Layer:
def __init__(self, no_neurons=None, activation_func=None, input_dims=None):
self.neurons = []
if no_neurons is not None and activation_func is not None and input_dims is not None:
self.neurons = [Neuron(activation_func, input_dims) for i in range(no_neurons)]
else:

self.neurons.append(network)

def out(self, x):
return np.array([n.out(x) for n in self.neurons])

class Network:
def __init__(self):
self.layers = []
self.in_dims = 0

new_layer_in_dim = layer.neurons[0].in_dims

if len(self.layers) > 0 and len(self.layers[-1].neurons) != new_layer_in_dim:
last_layer_out_dim = len(self.layers[-1].neurons)
print("Provided layer has neurons with input dim", new_layer_in_dim,
"while last layer has",last_layer_out_dim,"neurons = output dimensions.\n",
"Provided layer will not be added!")
else:
self.layers.append(layer)
if len(self.layers) == 1:
self.in_dims = layer.neurons[0].in_dims

def out(self, x):
layer_output = x
for layer in self.layers:
layer_output = layer.out(layer_output)
return layer_output

def list_layers(self):
for layer in self.layers:
print(len(layer.neurons), "neurons")

def plot(self, plot_neurons=True):
if plot_neurons:
for l in range(len(self.layers)):
for n in range(len(self.layers[l].neurons)):
print("Layer",l,"neuron",n,":")
neuron = self.layers[l].neurons[n]
try:
neuron.plot()
except Exception:
print("Has",neuron.in_dims,"input dimensions. Cannot plot.")

print("Output of the whole network:")
points = get_grid_points_with_labels(100, self.out)
plt.scatter(points[0],points[1],c=points[2])
plt.show()

``````
``````

In [63]:

net = Network()
net.list_layers()

``````
``````

4 neurons
1 neurons

``````
``````

In [66]:

n1 = net.layers[0].neurons[0]
n1.b = -0.25
n1.w = np.array([-0.5,1])

n2 = net.layers[0].neurons[1]
n2.b = -1.5
n2.w = np.array([4,-1])

n3 = net.layers[0].neurons[2]
n3.b = 2
n3.w = np.array([-2,1])

n4 = net.layers[0].neurons[3]
n4.b = 3
n4.w = np.array([-0.5,-1])

nAND = net.layers[1].neurons[0]
nAND.set_to_AND()
net.plot()

``````
``````

Layer 0 neuron 0 :

Layer 0 neuron 1 :

Layer 0 neuron 2 :

Layer 0 neuron 3 :

Layer 1 neuron 0 :
Has 4 input dimensions. Cannot plot.
Output of the whole network:

``````
``````

In [67]:

net2 = Network()
net2.list_layers()

``````
``````

4 neurons
1 neurons

``````
``````

In [68]:

n1 = net2.layers[0].neurons[0]
n1.b = -3
n1.w = np.array([0.5,1])

n2 = net2.layers[0].neurons[1]
n2.b = 1.5
n2.w = np.array([1,-1])

n3 = net2.layers[0].neurons[2]
n3.b = 9
n3.w = np.array([-2,-1])

n4 = net2.layers[0].neurons[3]
n4.b = 0
n4.w = np.array([-1,1])

nAND = net2.layers[1].neurons[0]
nAND.set_to_AND()
net2.plot()

``````
``````

Layer 0 neuron 0 :

Layer 0 neuron 1 :

Layer 0 neuron 2 :

Layer 0 neuron 3 :

Layer 1 neuron 0 :
Has 4 input dimensions. Cannot plot.
Output of the whole network:

``````
``````

In [69]:

net3 = Network()
net3.list_layers()

``````
``````

4 neurons
1 neurons

``````
``````

In [70]:

n1 = net3.layers[0].neurons[0]
n1.b = 0
n1.w = np.array([1,-1])

n2 = net3.layers[0].neurons[1]
n2.b = -10
n2.w = np.array([4,1])

n3 = net3.layers[0].neurons[2]
n3.b = 2.5
n3.w = np.array([-1,1])

n4 = net3.layers[0].neurons[3]
n4.b = 6.25
n4.w = np.array([-1.5,-1])

nAND = net3.layers[1].neurons[0]
nAND.set_to_AND()
net3.plot()

``````
``````

Layer 0 neuron 0 :

Layer 0 neuron 1 :

Layer 0 neuron 2 :

Layer 0 neuron 3 :

Layer 1 neuron 0 :
Has 4 input dimensions. Cannot plot.
Output of the whole network:

``````
``````

In [84]:

final_net = Network()
network_layer = Layer()

nOR = final_net.layers[1].neurons[0]
nOR.set_to_OR()
final_net.plot(plot_neurons=False)

``````
``````

Output of the whole network:

``````
``````

In [ ]:

``````
``````

In [ ]:

``````