I have a simple neural network with 2 input neurons, 3 hidden neurons and 1 output neuron. hidden layer has bias.
I'm not used matrix operations to doing feed forward and backpropagation. when I run training function on a simple linear dataset, the error raises up and the predication result is wrong.
import random
from math import exp,pow,tanh
def random_weight():
return random.random()
def sigmoid(x):
return 1.0 / (1.0 + exp(-x))
def sigmoid_drv(x):
return sigmoid(x)*(1.0-sigmoid(x))
w11_I = random_weight()
w12_I = random_weight()
w21_I = random_weight()
w22_I = random_weight()
w31_I = random_weight()
w32_I = random_weight()
w11_II = random_weight()
w12_II = random_weight()
w13_II = random_weight()
b_I = 1
activation = sigmoid
activation_drv = sigmoid_drv
def predict(x1,x2):
global w11_I,w12_I,w21_I,w22_I,w31_I,w32_I,w11_II,w12_II,w13_II,b_I
a1_I = w11_I*x1 + w12_I*x2 + b_I
z1_I = activation(a1_I)
a2_I = w21_I*x1 + w22_I*x2 + b_I
z2_I = activation(a2_I)
a3_I = w31_I*x1 + w32_I*x2 + b_I
z3_I = activation(a3_I)
a1_II = w11_II*z1_I + w12_II*z2_I + w13_II*z3_I
z1_II = activation(a1_II)
return a1_I, z1_I, a2_I, z2_I, a3_I, z3_I, a1_II, z1_II
def train(x1,x2,y,alpha):
global w11_I,w12_I,w21_I,w22_I,w31_I,w32_I,w11_II,w12_II,w13_II,b_I
a1_I, z1_I, a2_I, z2_I, a3_I, z3_I, a1_II, z1_II = predict(x1,x2)
error = 0.5 * pow(y-z1_II,2)
delta = y-z1_II * activation_drv(a1_II)
w11_II += delta * z1_I * alpha
w12_II += delta * z2_I * alpha
w13_II += delta * z3_I * alpha
w11_I += delta * w11_II * activation_drv(a1_I) * x1 * alpha
w12_I += delta * w11_II * activation_drv(a1_I) * x2 * alpha
w21_I += delta * w12_II * activation_drv(a2_I) * x1 * alpha
w22_I += delta * w12_II * activation_drv(a2_I) * x2 * alpha
w31_I += delta * w13_II * activation_drv(a3_I) * x1 * alpha
w32_I += delta * w13_II * activation_drv(a3_I) * x2 * alpha
b_I += (delta * w11_II * activation_drv(a1_I) + delta * w12_II * activation_drv(a2_I) + delta * w13_II * activation_drv(a3_I)) * alpha
return error
data = [
[0,0,0],
[0,1,1],
[1,0,1],
[1,1,1],
]
for i in range(0,10):
err = 0
dt = data[::]
random.shuffle(dt)
for j in dt:
err += train(j[0],j[1],j[2],0.01)
print(err)
print("-"*30)
for j in data:
_, _, _, _, _, _, _, res = predict(j[0],j[1])
print(j[0],",",j[1],"=",res)
For example the result of the code is:
0.363894453262
0.366966815948
0.366406041572
0.369982058232
0.36988850637
0.375869833099
0.378106172616
0.380456639936
0.37901554717
0.383723920259
------------------------------
(0, ',', 0, '=', 0.8439871540493414)
(0, ',', 1, '=', 0.861714406183168)
(1, ',', 0, '=', 0.8515477541104413)
(1, ',', 1, '=', 0.8676931366534011)
---------------- UPDATE ----------------
I change codes to this :
import random
from math import exp,pow
def random_weight():
return random.random()
def sigmoid(x):
return 1.0 / (1.0 + exp(-x))
def sigmoid_drv(x):
return sigmoid(x)*(1.0-sigmoid(x))
w11_I = random_weight()
w12_I = random_weight()
w21_I = random_weight()
w22_I = random_weight()
w31_I = random_weight()
w32_I = random_weight()
w11_II = random_weight()
w12_II = random_weight()
w13_II = random_weight()
b_I = random_weight()
activation = sigmoid
activation_drv = sigmoid_drv
def predict(x1,x2):
global w11_I,w12_I,w21_I,w22_I,w31_I,w32_I,w11_II,w12_II,w13_II,b_I
a1_I = w11_I*x1 + w12_I*x2 + b_I
z1_I = activation(a1_I)
a2_I = w21_I*x1 + w22_I*x2 + b_I
z2_I = activation(a2_I)
a3_I = w31_I*x1 + w32_I*x2 + b_I
z3_I = activation(a3_I)
a1_II = w11_II*z1_I + w12_II*z2_I + w13_II*z3_I
z1_II = activation(a1_II)
return a1_I, z1_I, a2_I, z2_I, a3_I, z3_I, a1_II, z1_II
def train(x1,x2,y,alpha):
global w11_I,w12_I,w21_I,w22_I,w31_I,w32_I,w11_II,w12_II,w13_II,b_I
a1_I, z1_I, a2_I, z2_I, a3_I, z3_I, a1_II, z1_II = predict(x1,x2)
error = 0.5 * pow(z1_II-y,2)
delta = z1_II-y * activation_drv(a1_II)
d_w11_II = delta * z1_I * alpha
d_w12_II = delta * z2_I * alpha
d_w13_II = delta * z3_I * alpha
d_w11_I = delta * w11_II * activation_drv(a1_I) * x1 * alpha
d_w12_I = delta * w11_II * activation_drv(a1_I) * x2 * alpha
d_w21_I = delta * w12_II * activation_drv(a2_I) * x1 * alpha
d_w22_I = delta * w12_II * activation_drv(a2_I) * x2 * alpha
d_w31_I = delta * w13_II * activation_drv(a3_I) * x1 * alpha
d_w32_I = delta * w13_II * activation_drv(a3_I) * x2 * alpha
d_b_I = (delta * w11_II * activation_drv(a1_I) + delta * w12_II * activation_drv(a2_I) + delta * w13_II * activation_drv(a3_I)) * alpha
w11_II -= d_w11_II
w12_II -= d_w12_II
w13_II -= d_w13_II
w11_I -= d_w11_I
w12_I -= d_w12_I
w21_I -= d_w21_I
w22_I -= d_w22_I
w31_I -= d_w31_I
w32_I -= d_w32_I
b_I -= d_b_I
return error
data = [
[0,0,0],
[0,1,0],
[1,0,0],
[1,1,1],
]
for i in range(0,10):
err = 0
dt = data[::]
random.shuffle(dt)
for j in dt:
err += train(j[0],j[1],j[2],0.01)
print(err)
print("-"*30)
for j in data:
_, _, _, _, _, _, _, res = predict(j[0],j[1])
print(j[0],",",j[1],"=",res)
I'm subtract weight errors with weights now. Error of network reduces. But prediction is still wrong.
The result of above code:
0.7793443881847488
0.7577581315356949
0.7432698222320477
0.7316129719356839
0.7160385688813552
0.6943522088277978
0.6862277294774705
0.6656984495700775
0.6584361784187711
0.6410006126876817
------------------------------
0 , 0 = 0.6049212721996029
0 , 1 = 0.6227402202339664
1 , 0 = 0.6139758543180651
1 , 1 = 0.6293581473456563