Perceptron/Perceptron.py

91 lines
2.5 KiB
Python
Raw Normal View History

#!/bin/python3
import numpy as np
import random
2022-01-26 14:38:00 +01:00
cicli = 1000000
hidden_layer = 2
epsilon = 0.01
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
[0,1,1],
[1,0,1],
[1,1,1]])
#output data
2022-01-26 14:38:00 +01:00
Y = np.array([[0], #xi, output voluto 0 1 1 0
[1],
2022-01-26 14:38:00 +01:00
[1],
[0]])
2022-01-26 14:38:00 +01:00
#np.random.seed(1) #per avere sempre lo stesso
#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
#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
# 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)
for i in range(cicli):
2022-01-26 14:38:00 +01:00
#print(str(int(100*i/cicli))+"---------------------------------------") #% sul numero totale di cicli
2022-01-26 14:38:00 +01:00
old_error = error_func(l2)
2022-01-26 14:38:00 +01:00
#FASE BACKWARD
#calcolo delta_nu
2022-01-26 14:38:00 +01:00
delta_nu = Y - l2
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]
#print(sum)
2022-01-26 14:38:00 +01:00
syn1[:,0] += sum
for j in range(hidden_layer): #loop tra i neuroni hidden
sum=0
for nu in range(len(X)): #loop tra gli esempi
sum += epsilon*delta_nu[nu]*fdt(np.dot(l1[nu],syn1),True)*syn1[j]*fdt(np.dot(X[nu],syn0[:,j]),True)
syn0[:,j] += sum
2022-01-26 14:38:00 +01:00
#fase forward
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 14:38:00 +01:00
current_error = error_func(l2)
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):
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
if(i % 10000) == 0: # stampo errore ogni 10k
for i in range(len(np.transpose(l2))):
print(np.transpose(l2)[i])
print(str(int(100*i/cicli))+"-------"+str(current_error))
print("Error: "+str(error_func(l2)))
for i in range(len(np.transpose(l2))):
print(np.transpose(l2)[i])