In [1]:
import numpy as np
import matplotlib.pyplot as plt
In [2]:
#Debug
def allShape(list):
for arr in list:
print(arr.shape)
#定義常用函數
def sigmoid_cross_entropy(y_hat, y):
return y_hat - y
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
def sigmoid_prime(x):
return sigmoid(x) * (1 - sigmoid(x))
def ReLU_square(y_hat, y):
return 2 * (y_hat - y) * ReLU_prime(y_hat)
def ReLU(x):
return np.maximum(x,np.zeros(x.shape))
def ReLU_prime(x):
return (x > 0).astype(float)
In [3]:
#學習速率
learning_rate = 0.01
#選用函數
def loss_prime(y_hat, y):
return sigmoid_cross_entropy(y_hat, y)
def connect(x):
return sigmoid(x)
def connect_prime(x):
return sigmoid_prime(x)
'''
def loss_prime(y_hat, y):
return ReLU_square(y_hat, y)
def connect(x):
return ReLU(x)
def connect_prime(x):
return ReLU_prime(x)
'''
Out[3]:
In [4]:
class Network(object):
def __init__(self, sizes):
self.num_layers = len(sizes)
self.sizes = sizes
self.biases = [np.zeros((1, y)) for y in sizes[1:]]
self.weights = [np.random.rand(x, y) - 0.5 for x, y in zip(sizes[:-1], sizes[1:])]
def feedforward(self, x):
(xs, _) = self.feedforwardRecord(x)
return xs[-1]
def feedforwardRecord(self, x):
xs = [np.array(x)]
ss = [np.array(x)]
for b, w in zip(self.biases, self.weights):
s = np.dot(x, w) + b
x = connect(s)
xs.append(x)
ss.append(s)
return (xs, ss)
def backpropagationWith(self, xs, ss, y):
delta_out = []
delta_in = loss_prime(xs[-1], y)
dbs = [np.mean(delta_in, axis=0)]
dws = [np.mean(np.dot(np.transpose(xs[-1]), delta_in), axis=0)]
for idx in range(self.num_layers - 2, 0, -1):
delta_out = np.dot(delta_in, np.transpose(self.weights[idx]))
delta_in = delta_out * connect_prime(ss[idx])
db = delta_in
dw = np.dot(np.transpose(xs[idx - 1]), delta_in)
dbs.insert(0, np.mean(db, axis=0))
dws.insert(0, np.mean(dw, axis=0))
return (dbs, dws)
def updateWith(self, dbs, dws):
new_b = []
for b, db in zip(self.biases, dbs):
new_b.append(b - learning_rate * db)
new_w = []
for w, dw in zip(self.weights, dws):
new_w.append(w - learning_rate * dw)
self.biases = new_b
self.weights = new_w
def showbiasesweights(self):
allShape(self.biases)
print(self.biases)
allShape(self.weights)
print(self.weights)
In [5]:
myNN = Network([2, 3, 1])
In [6]:
def judgeFunction(x):
#必須補維度 將來計算 才能正常 或許是 右乘相關
return np.logical_or(np.sum(x, axis=1) < 0.5, np.sum(x, axis=1) > 1.5).astype(float)[:,np.newaxis]
total_test = 10000000
to_print = 10000
batch = 50
acc = 0
for i in range(total_test):
x = np.random.rand(batch, 2)
ys = judgeFunction(x)
(xs, ss) = myNN.feedforwardRecord(x)
y_hats = xs[-1]
(dbs, dws) = myNN.backpropagationWith(xs, ss, ys)
myNN.updateWith(dbs, dws)
acc_batch = 0
for y_hat, y in zip(y_hats, ys):
acc_batch += float(y == float(y_hat > 0.5))
acc += acc_batch / batch
if (i + 1) % to_print == 0:
score = acc / float(to_print)
process = int((i + 1) / to_print)
print('{num:03d}'.format(num = process), ">", '{num:.6f}'.format(num = score))
acc = 0
if score > 0.99:
break
In [7]:
def colorFrom(y):
if y > 0.5:
return 'red'
else:
return 'blue'
plt.figure(figsize=(9, 9))
x0s = np.linspace(0, 1, 20, dtype = np.double)
x1s = np.linspace(0, 1, 20, dtype = np.double)
fig = plt.figure()
ax = fig.add_subplot(1,2,1)
for x0 in x0s:
for x1 in x1s:
y = myNN.feedforward(np.array([[x0, x1]]))
ax.scatter(x0, x1, c = colorFrom(y), s = 30, alpha = 0.5, marker = 's')
ax = fig.add_subplot(1,2,2)
for x0 in x0s:
for x1 in x1s:
y = judgeFunction(np.array([[x0, x1]]))
ax.scatter(x0, x1, c = colorFrom(y), s = 30, alpha = 0.5, marker = 's')
plt.show()
In [8]:
myNN.showbiasesweights()