2022-01-26 11:58:38 +01:00
|
|
|
#!/bin/python3
|
|
|
|
import numpy as np
|
|
|
|
import random
|
|
|
|
|
2022-01-26 14:38:00 +01:00
|
|
|
cicli = 1000000
|
2022-01-26 15:18:13 +01:00
|
|
|
hidden_layer = 4
|
|
|
|
epsilon = 0.006
|
2022-01-26 11:58:38 +01:00
|
|
|
|
|
|
|
def fdt(x,deriv=False):
|
|
|
|
if(deriv==True):
|
|
|
|
return (1-np.tanh(x)**2)
|
|
|
|
|
|
|
|
return np.tanh(x)
|
|
|
|
|
|
|
|
def error_func(output):
|
|
|
|
e=0
|
|
|
|
for i in range(len(output)):
|
|
|
|
e += (output[i]-Y[i])**2
|
|
|
|
return 0.5*e
|
|
|
|
|
|
|
|
#input data
|
2022-01-26 14:38:00 +01:00
|
|
|
X = np.array([[0,0,1], #input, 00 01 10 11
|
|
|
|
[1,0,1],
|
2022-01-26 15:18:13 +01:00
|
|
|
[0,1,1],
|
2022-01-26 14:38:00 +01:00
|
|
|
[1,1,1]])
|
2022-01-26 11:58:38 +01:00
|
|
|
|
|
|
|
#output data
|
2022-01-26 14:38:00 +01:00
|
|
|
Y = np.array([[0], #xi, output voluto 0 1 1 0
|
2022-01-26 11:58:38 +01:00
|
|
|
[1],
|
2022-01-26 14:38:00 +01:00
|
|
|
[1],
|
|
|
|
[0]])
|
2022-01-26 11:58:38 +01:00
|
|
|
|
2022-01-26 14:38:00 +01:00
|
|
|
#np.random.seed(1) #per avere sempre lo stesso
|
2022-01-26 11:58:38 +01:00
|
|
|
|
|
|
|
#sinapsi tra input e Perceptron di output
|
2022-01-26 14:38:00 +01:00
|
|
|
syn0 = 0.1*(2*np.random.random((3,hidden_layer)) -1) #Sinapsi tra input e hidden layer
|
2022-01-26 11:58:38 +01:00
|
|
|
#print(syn0) #2x1
|
2022-01-26 14:38:00 +01:00
|
|
|
syn1 = 0.1*(2*np.random.random((hidden_layer,1)) -1) #Sinapsi tra hidden layer e Perceptron di output
|
2022-01-26 11:58:38 +01:00
|
|
|
|
|
|
|
# fase forward
|
|
|
|
l0 = X
|
2022-01-26 14:38:00 +01:00
|
|
|
l1 = fdt(np.dot(l0,syn0)) #output layer hidden, 4x2 4 esempi, 2 neuroni di output
|
|
|
|
l2 = fdt(np.dot(l1,syn1)) #output della rete (per ogni esempio)
|
2022-01-26 11:58:38 +01:00
|
|
|
|
|
|
|
for i in range(cicli):
|
2022-01-26 14:38:00 +01:00
|
|
|
old_error = error_func(l2)
|
2022-01-26 11:58:38 +01:00
|
|
|
|
2022-01-26 14:38:00 +01:00
|
|
|
#FASE BACKWARD
|
2022-01-26 11:58:38 +01:00
|
|
|
#calcolo delta_nu
|
2022-01-26 14:38:00 +01:00
|
|
|
delta_nu = Y - l2
|
2022-01-26 11:58:38 +01:00
|
|
|
|
|
|
|
sum = 0
|
2022-01-26 14:38:00 +01:00
|
|
|
for nu in range(len(X)): #ciclo tra gli esempi, batch
|
|
|
|
sum += epsilon*(delta_nu[nu]*fdt(np.dot(l1[nu],syn1),True))*l1[nu]
|
2022-01-26 11:58:38 +01:00
|
|
|
#print(sum)
|
2022-01-26 14:38:00 +01:00
|
|
|
syn1[:,0] += sum
|
|
|
|
|
2022-01-26 15:18:13 +01:00
|
|
|
|
2022-01-26 14:38:00 +01:00
|
|
|
for j in range(hidden_layer): #loop tra i neuroni hidden
|
2022-01-26 15:18:13 +01:00
|
|
|
delta_w=0
|
2022-01-26 14:38:00 +01:00
|
|
|
for nu in range(len(X)): #loop tra gli esempi
|
2022-01-26 15:18:13 +01:00
|
|
|
#delta_w = epsilon*delta_nu[nu]*fdt(np.dot(l1[nu],syn1),True)*syn1[j]*fdt(np.dot(X[nu],syn0[:,j]),True)
|
|
|
|
delta_w = epsilon*delta_nu[nu]*fdt(np.dot(l1[nu],syn1),True)*syn1[j]*fdt(np.dot(X[nu],syn0[:,j]),True)
|
|
|
|
syn0[:,j] += delta_w
|
2022-01-26 11:58:38 +01:00
|
|
|
|
2022-01-26 14:38:00 +01:00
|
|
|
|
|
|
|
#fase forward
|
2022-01-26 11:58:38 +01:00
|
|
|
l1 = fdt(np.dot(l0,syn0)) #output layer hidden, 4x4 4 esempi, 4 neuroni di output
|
2022-01-26 14:38:00 +01:00
|
|
|
l2 = fdt(np.dot(l1,syn1)) #output della rete (per ogni esempio)
|
2022-01-26 11:58:38 +01:00
|
|
|
|
2022-01-26 14:38:00 +01:00
|
|
|
current_error = error_func(l2)
|
2022-01-26 11:58:38 +01:00
|
|
|
|
2022-01-26 14:38:00 +01:00
|
|
|
# if (np.linalg.norm(sum) < 10**-8):
|
|
|
|
# print("Very low variation in weight-space - exiting")
|
|
|
|
# print("delta_w :"+str(np.linalg.norm(sum)))
|
|
|
|
# break
|
|
|
|
if (error_func(l2) < 0.001):
|
2022-01-26 11:58:38 +01:00
|
|
|
print("Very low error - exiting")
|
|
|
|
break
|
2022-01-26 14:38:00 +01:00
|
|
|
# if (abs(current_error - old_error) < 10**-8):
|
|
|
|
# print("Very low error variation - exiting")
|
|
|
|
# break
|
2022-01-26 15:18:13 +01:00
|
|
|
if(i % 5000) == 0: # stampo errore ogni 10k
|
2022-01-26 14:38:00 +01:00
|
|
|
for i in range(len(np.transpose(l2))):
|
|
|
|
print(np.transpose(l2)[i])
|
2022-01-26 15:18:13 +01:00
|
|
|
if (current_error < old_error):
|
|
|
|
anda="v"
|
|
|
|
else:
|
|
|
|
anda="^"
|
|
|
|
print(str(int(100*i/cicli))+"% ------- Error: "+str(current_error)+anda)
|
2022-01-26 14:38:00 +01:00
|
|
|
|
|
|
|
print("Error: "+str(error_func(l2)))
|
|
|
|
for i in range(len(np.transpose(l2))):
|
|
|
|
print(np.transpose(l2)[i])
|