Skip to content

Commit

Permalink
update for Adaline model
Browse files Browse the repository at this point in the history
  • Loading branch information
llinjupt committed Apr 5, 2019
1 parent 9645b96 commit 1e3ec91
Show file tree
Hide file tree
Showing 18 changed files with 1,193 additions and 129 deletions.
307 changes: 229 additions & 78 deletions footstone/adaline.py

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion footstone/convolute.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ def show_matrix(matrix, color='black'):
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()

def plot_matrix(matrix, color='black'):
h, w = matrix.shape

plt.figure(figsize=(w / 2 + 1, h / 2 + 1))
tb = plt.table(cellText=matrix, loc=(0,0), cellLoc='center')

tc = tb.properties()['child_artists']
for cell in tc:
cell.set_height(1/h)
cell.set_width(1/w)

ax = plt.gca()
ax.set_xticks([])
ax.set_yticks([])
plt.show()

def chessboard(square=10, size=15, color=(255, 0, 0)):
'''Create a chessboard color with order RGB'''

Expand Down Expand Up @@ -318,4 +334,3 @@ def convolute_speed_cmp(image=None, count=100, type=0):
convolution(gray + count, kernel)
print("convolution cost walltime {:.02f}s with loop {}".format(time.time()-start, count))

convolute_speed_cmp(None, 10, 2)
80 changes: 80 additions & 0 deletions footstone/crossvalid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 14 16:10:34 2018
@author: Red
"""

import numpy as np
import matplotlib.pyplot as plt

def draw_points(X, labels, title='', figsize=(4,4), coordinate=False):
plt.figure(figsize=figsize)

plt.title(title)
plt.xlabel("x1")
plt.ylabel("x2")

# x1 and x2 features
x1 = X[:, 0]
x2 = X[:, 1]

plt.xlim(-10, 10)
plt.ylim(-10, 10)

max,min = np.max(labels), np.min(labels)
plt.scatter(x1[labels == max], x2[labels == max], c='black', marker='o')
plt.scatter(x1[labels == min], x2[labels == min], c='black', marker='o')

circle = plt.Circle((0, 0), radius=1.1, fill=False, color='red')
plt.gca().add_patch(circle)

if coordinate:
for index, x, y in zip(range(len(labels)), x1, x2):
plt.annotate('(%.2f,%.2f)'%(x,y), xy=(x,y), xytext=(-20,-20),
textcoords = 'offset pixels', ha='left', va='bottom')

return plt

# generate noraml distribution train set
def normal_dis_trainset(positive=100, negtive=100, type='normal'):
np.random.seed(0)

if type == 'normal':
numA = np.random.normal(3, 2, (2, positive))
numB = np.random.normal(-6, 2, (2, negtive))
elif type == 'ones':
numA = np.ones((2, positive)) - 3
numB = np.ones((2, negtive)) + 5
else:
numA = np.zeros((2, positive)) - 3
numB = np.zeros((2, negtive)) + 5

Ax, Ay = numA[0] * 0.5, numA[1]
Bx, By = numB[0], numB[1]

labels = np.zeros((negtive + positive, 1))
trainset = np.zeros((negtive + positive, 2))
trainset[0:positive,0] = Ax[:]
trainset[0:positive,1] = Ay[:]
labels[0:positive] = 1

trainset[positive:,0] = Bx[:]
trainset[positive:,1] = By[:]
labels[positive:] = -1

return trainset, labels.reshape(positive + negtive,)

def data_split(X, y, ratio=0.3, random_state=0):
from sklearn.model_selection import train_test_split

# 'X_train, X_test, y_train, y_test = '
return train_test_split(X, y, test_size=ratio, random_state=random_state)

if __name__ == "__main__":
X,y = normal_dis_trainset(3, 3)

X_train, X_test, y_train, y_test = data_split(X, y)
print(y_train)
print(y_test)

45 changes: 45 additions & 0 deletions footstone/drawutils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import matplotlib.pyplot as plt
from matplotlib.patches import Arc
import numpy as np

'''
(a) Ax + By + C = 0
(b) (y - y0) / (x - x0) = B / A
=>
x = (B*B*x0 - A*B*y0 - A*C) / (A*A + B*B)
y = (-A*B*x0 + A*A*y0 - B*C) / (A*A + B*B)
'''
def get_footpoint(px, py, w_):
if w_.shape[0] != 3:
print("can't calculate footpoint with {}".formate(w_))
return None

A,B,C = w_[1], w_[2], w_[0]
x = (B*B*px - A*B*py - A*C)/(A*A + B*B)
y = (-A*B*px + A*A*py - B*C)/(A*A + B*B)

return x, y

def get_angle(p0, p1=np.array([0,0]), p2=None):
''' compute angle (in degrees) for p0p1p2 corner
Inputs:
p0,p1,p2 - points in the form of [x,y]
'''
if p2 is None:
p2 = p1 + np.array([1, 0])
v0 = np.array(p0) - np.array(p1)
v1 = np.array(p2) - np.array(p1)

angle = np.math.atan2(np.linalg.det([v0,v1]),np.dot(v0,v1))
return np.degrees(angle)

def rotation_transform(theta):
''' rotation matrix given theta
Inputs:
theta - theta (in degrees)
'''
theta = np.radians(theta)
A = [[np.math.cos(theta), -np.math.sin(theta)],
[np.math.sin(theta), np.math.cos(theta)]]
return np.array(A)
10 changes: 5 additions & 5 deletions footstone/knn_mnist.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def draw_normal_distribution(points=100):
Ax, Ay = rand_num[0] - 3, rand_num[1] - 3
Bx, By = rand_num[2] + 3, rand_num[3] + 3

plt.figure()
plt.figure(figsize=(4,4))
plt.title("Normal Distribution with {} points".format(points))
plt.xlim(-10, 10)
plt.ylim(-10, 10)
Expand Down Expand Up @@ -137,7 +137,7 @@ def error_ratio_draw(self):
if __name__ == '__main__':
# knn = kNN()
# knn.batch_test()
knn_sk = kNN_sklearn(alg='brute')
knn_sk.batch_test()
knn_sk.error_ratio_draw()

# knn_sk = kNN_sklearn(alg='brute')
# knn_sk.batch_test()
# knn_sk.error_ratio_draw()
draw_normal_distribution(10000)
181 changes: 181 additions & 0 deletions footstone/nnplot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
from matplotlib import pyplot
from math import cos, sin, atan

class Neuron():
def __init__(self, x, y):
self.x = x
self.y = y

def draw(self, color='black'):
circle = pyplot.Circle((self.x, self.y), radius=neuron_radius, fill=False, color=color)
pyplot.gca().add_patch(circle)

class Axon():
# start and end coordinates like style (x,y)
def __init__(self, start, end):
self.start = start
self.end = end

def draw(self, lw=1, color='black'):
line = pyplot.Line2D((self.start[0], self.end[0]),
(self.start[1], self.end[1]), lw=lw, color=color)
pyplot.gca().add_line(line)

def draw_arrow(self):
pyplot.annotate("", xy=self.end, xytext=self.start, arrowprops=dict(arrowstyle="->"))

class Layer_BT():
def __init__(self, network, number_of_neurons):
self.previous_layer = self.__get_previous_layer(network)
self.y = self.__calculate_layer_y_position()
self.neurons = self.__intialise_neurons(number_of_neurons)

def __intialise_neurons(self, number_of_neurons):
neurons = []
x = self.__calculate_left_margin_so_layer_is_centered(number_of_neurons)
for iteration in range(number_of_neurons):
neuron = Neuron(x, self.y)
neurons.append(neuron)
x += horizontal_distance
return neurons

def __calculate_left_margin_so_layer_is_centered(self, number_of_neurons):
return horizontal_distance * (neuron_in_layer_space - number_of_neurons) / 2

def __calculate_layer_y_position(self):
if self.previous_layer:
return self.previous_layer.y + vertical_distance

return 0

def __get_previous_layer(self, network):
if len(network.layers) > 0:
return network.layers[-1]
else:
return None

def __line_between_two_neurons(self, prev_neuron, neuron):
angle = atan((prev_neuron.x - neuron.x) / float(prev_neuron.y - neuron.y))

x_adjustment = (neuron_radius + neuron_axon_space) * sin(angle)
y_adjustment = (neuron_radius + neuron_axon_space)* cos(angle)
axon = Axon((neuron.x - x_adjustment, neuron.y - y_adjustment),
(prev_neuron.x + x_adjustment, prev_neuron.y + y_adjustment))
axon.draw()

def draw(self, layer_name=''):
x = self.neurons[0].x
y = self.neurons[0].y
pyplot.text(x - 2.5, y, layer_name, fontsize=14,
verticalalignment="center",
horizontalalignment="center")

for neuron in self.neurons:
neuron.draw()
if self.previous_layer:
for previous_layer_neuron in self.previous_layer.neurons:
self.__line_between_two_neurons(previous_layer_neuron, neuron)

# draw neuron network from left to right
class Layer_LR():
def __init__(self, network, number_of_neurons):
self.previous_layer = self.__get_previous_layer(network)
self.x = self.__calculate_layer_x_position()
self.neurons = self.__intialise_neurons(number_of_neurons)

def __intialise_neurons(self, number_of_neurons):
neurons = []
y = self.__calculate_left_margin_so_layer_is_centered(number_of_neurons)
for iteration in range(number_of_neurons):
neuron = Neuron(self.x, -y)
neurons.append(neuron)
y += vertical_distance
return neurons

def __calculate_left_margin_so_layer_is_centered(self, number_of_neurons):
return vertical_distance * (neuron_in_layer_space - number_of_neurons) / 2

def __calculate_layer_x_position(self):
if self.previous_layer:
return self.previous_layer.x + horizontal_distance

return 0

def __get_previous_layer(self, network):
if len(network.layers) > 0:
return network.layers[-1]
else:
return None

def __line_between_two_neurons(self, prev_neuron, neuron):
angle = atan((neuron.y - prev_neuron.y) / float(neuron.x - prev_neuron.x))
x_adjustment = (neuron_radius + neuron_axon_space) * cos(angle)
y_adjustment = (neuron_radius + neuron_axon_space) * sin(angle)

axon = Axon((prev_neuron.x + x_adjustment, prev_neuron.y + y_adjustment),
(neuron.x - x_adjustment, neuron.y - y_adjustment))
axon.draw(color='gray')

def draw(self, layer_name=''):
x = self.neurons[0].x
y = self.neurons[0].y
pyplot.text(x, y + 1.5, layer_name, fontsize=14,
verticalalignment="center",
horizontalalignment="center")

for neuron in self.neurons:
neuron.draw()
if self.previous_layer:
for previous_layer_neuron in self.previous_layer.neurons:
self.__line_between_two_neurons(previous_layer_neuron, neuron)

# draw the network from left to right: 'h', bottom to top : 'v'
class NeuralNetwork():
def __init__(self, direction='h'):
self.layers = []
self.layerclass = Layer_LR if direction == 'h' else Layer_BT

def add_layer(self, number_of_neurons):
layer = self.layerclass(self, number_of_neurons)
self.layers.append(layer)

def draw(self):
layers = len(self.layers)

if layers == 0:
return

if layers >= 1:
self.layers[0].draw('Input')

for layer in self.layers[1:-1]:
layer.draw('Hidden')

if layers >= 2:
self.layers[-1].draw('Output')

pyplot.axis('scaled')
pyplot.xticks([])
pyplot.yticks([])

ax = pyplot.gca()
ax.spines['left'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_color('none')

pyplot.show()

if __name__ == "__main__":
vertical_distance = 3
horizontal_distance = 6
neuron_radius = 0.6
neuron_axon_space = 0.3 * neuron_radius
neuron_in_layer_space = 4

network = NeuralNetwork()
network.add_layer(2)
network.add_layer(3)
network.add_layer(2)
network.add_layer(4)
network.draw()

0 comments on commit 1e3ec91

Please sign in to comment.