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:
print("Created an empty layer. Add modules instead of neurons by add_module().")
def add_module(self, network):
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
def add_layer(self, layer):
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.add_layer(Layer(no_neurons=4, activation_func=step_func, input_dims=2))
net.add_layer(Layer(no_neurons=1, activation_func=step_func, input_dims=4))
net.list_layers()
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()
In [67]:
net2 = Network()
net2.add_layer(Layer(no_neurons=4, activation_func=step_func, input_dims=2))
net2.add_layer(Layer(no_neurons=1, activation_func=step_func, input_dims=4))
net2.list_layers()
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()
In [69]:
net3 = Network()
net3.add_layer(Layer(no_neurons=4, activation_func=step_func, input_dims=2))
net3.add_layer(Layer(no_neurons=1, activation_func=step_func, input_dims=4))
net3.list_layers()
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()
In [84]:
final_net = Network()
network_layer = Layer()
network_layer.add_module(net)
network_layer.add_module(net2)
network_layer.add_module(net3)
final_net.add_layer(network_layer)
final_net.add_layer(Layer(no_neurons=1, activation_func=step_func, input_dims=3))
nOR = final_net.layers[1].neurons[0]
nOR.set_to_OR()
final_net.plot(plot_neurons=False)
In [ ]:
In [ ]: