From 32cbb7c6cb7207a192c2645009bd06093c6af886 Mon Sep 17 00:00:00 2001 From: mirimatcode Date: Thu, 23 Jan 2025 11:28:01 +0100 Subject: [PATCH] soluzione funzionante per AND, OR, XOR. Funzione sigmoide. Funziona solo con i certi bias --- multi_layer.py | 67 +++++++++++++++++++++++++++++++------------ percettrone.py | 22 ++++++++------ pesi_xor.txt | 6 ++++ tempCodeRunnerFile.py | 3 -- 4 files changed, 68 insertions(+), 30 deletions(-) create mode 100644 pesi_xor.txt delete mode 100644 tempCodeRunnerFile.py diff --git a/multi_layer.py b/multi_layer.py index 90f6808..18f056d 100644 --- a/multi_layer.py +++ b/multi_layer.py @@ -1,20 +1,29 @@ from percettrone import Percettrone from stampe_video import disegna_funzione, stampa_risultati_multilayer +MAX_EPOCHE = 10000 + x = [(0,0),(0,1),(1,0),(1,1)] # Combinazioni #output = (0,1,1,0) # XOR Logico #output = (0,0,0,1) # AND Logico output = (0,1,1,1) # OR Logico corrette = 0 -pin_est_1 = Percettrone(bias=0) -pin_est_2 = Percettrone(bias=-1.5) -pinout = Percettrone(bias=0) -""" pin_est_1 = Percettrone(w1=0.3, w2=4, bias=-0.5) -pin_est_2 = Percettrone(w1=0.2, w2=4, bias=-1.5) -pinout = Percettrone(w1=0.3, w2=2, bias=-1) """ +soglia_errore_accettabile = 0.001 +soglia_funzione_attivazione = 0.5 -for i in range(1,100000): #Epoche +pin_est_1 = Percettrone(w1=1, w2=1, bias=-2.5, lre=0.2) +pin_est_2 = Percettrone(w1=1, w2=1,bias=-1, lre=0.2) +pinout = Percettrone(w1=1, w2=1, bias=-1, lre=0.2) + +''' +#Pesi per AND, OR e XOR (sigmoide) +pin_est_1 = Percettrone(w1=1, w2=1, bias=-2.5, lre=0.2) +pin_est_2 = Percettrone(w1=1, w2=1,bias=-1, lre=0.2) +pinout = Percettrone(w1=1, w2=1, bias=-1, lre=0.2) +''' + +for i in range(1, MAX_EPOCHE): #Epoche if corrette == 4: print(f"Epoche necessarie: {i-1}") @@ -25,20 +34,42 @@ for i in range(1,100000): #Epoche print(f"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tEPOCA {i}") for j in range(0,4): #Combinazioni - y_est_1 = pin_est_1.funzione_gradino(x[j][0], x[j][1]) - y_est_2 = pin_est_2.funzione_gradino(x[j][0], x[j][1]) - yout = pinout.funzione_gradino(y_est_1, y_est_2) + previsione = -1 + y_est_1 = pin_est_1.funzione_sigmoide(x[j][0], x[j][1]) + y_est_2 = pin_est_2.funzione_sigmoide(x[j][0], x[j][1]) + yout = pinout.funzione_sigmoide(y_est_1, y_est_2) - errore = output[j] - yout + if yout >= soglia_funzione_attivazione: + previsione = 1 + else: + previsione = 0 + + if previsione == output[j]: + corrette += 1 + + errore = -(output[j] - yout) print("\n") disegna_funzione(pin_est_1, y_est_1, x[j][0], x[j][1], False) - disegna_funzione(pinout, yout, y_est_1, y_est_2, True, errore) + disegna_funzione(pinout, previsione, y_est_1, y_est_2, True, errore) disegna_funzione(pin_est_2, y_est_2, x[j][0], x[j][1], False) - if errore != 0: - pin_est_1.correggi_pesi(x[j][0], x[j][1], errore) - pin_est_2.correggi_pesi(x[j][0], x[j][1], errore) - pinout.correggi_pesi(y_est_1, y_est_2, errore) - else: - corrette += 1 \ No newline at end of file + #if errore != 0: + # Gradienti Percettrone 1 + appoggio_w1 = errore * yout * (1-yout) * pinout.w1 * y_est_1 * (1-y_est_1) * x[j][0] + appoggio_w2 = errore * yout * (1-yout) * pinout.w1 * y_est_1 * (1-y_est_1) * x[j][1] + appoggio_bias = errore * yout * (1-yout) * pinout.bias * y_est_1 * (1-y_est_1) + pin_est_1.correggi_pesi(appoggio_w1, appoggio_w2, appoggio_bias) + + # Gradienti Percettrone 2 + appoggio_w1 = errore * yout * (1-yout) * pinout.w2 * y_est_2 * (1-y_est_2) * x[j][0] + appoggio_w2 = errore * yout * (1-yout) * pinout.w2 * y_est_2 * (1-y_est_2) * x[j][1] + appoggio_bias = errore * yout * (1-yout) * pinout.bias * y_est_2 * (1-y_est_2) + pin_est_2.correggi_pesi(appoggio_w1, appoggio_w2, appoggio_bias) + + # Gradienti Percettrone out + appoggio_w1 = errore * y_est_1 + appoggio_w2 = errore * y_est_2 + pinout.correggi_pesi(appoggio_w1, appoggio_w2, errore) + #else: + # corrette += 1 \ No newline at end of file diff --git a/percettrone.py b/percettrone.py index 45675ed..80e5b2c 100644 --- a/percettrone.py +++ b/percettrone.py @@ -1,17 +1,21 @@ -class Percettrone: +import math - def __init__(self, w1 = 1, w2 = 1, bias = 1, lre = 1): +class Percettrone: + def __init__(self, w1 = 1, w2 = 1, bias = 1, lre = 0.2): self.w1 = w1 self.w2 = w2 self.bias = bias self.lre = lre + # # il return verrĂ  confrontato col valore di soglia di attivazione def funzione_gradino(self, x1, x2): - if ((x1 * self.w1) + (x2 * self.w2) + self.bias) >= 0: - return 1 - return 0 + return ((x1 * self.w1) + (x2 * self.w2) + self.bias) + + # il return verrĂ  confrontato col valore di soglia di attivazione + def funzione_sigmoide(self, x1, x2): + return (1 / (1 + math.exp(-((x1 * self.w1) + (x2 * self.w2) + self.bias)))) - def correggi_pesi(self, x1, x2, errore): - self.bias = self.bias + (errore * self.lre) - self.w1 = self.w1 + (errore * x1 * self.lre) - self.w2 = self.w2 + (errore * x2 * self.lre) \ No newline at end of file + def correggi_pesi(self, gradiente_w1, gradiente_w2, gradiente_bias): + self.bias = self.bias - (gradiente_bias * self.lre) + self.w1 = self.w1 - (gradiente_w1 * self.lre) + self.w2 = self.w2 - (gradiente_w2 * self.lre) \ No newline at end of file diff --git a/pesi_xor.txt b/pesi_xor.txt new file mode 100644 index 0000000..3dc8443 --- /dev/null +++ b/pesi_xor.txt @@ -0,0 +1,6 @@ +Percettrone 1: + W1: 2.3138819308216796, W2: 2.326257532279927, bias: -0.9188571437718164 +Percettrone 2: + W1: 1.5239321297796238, W2: 1.329809031263888, bias: -2.149847621526194 +Percettrone OUT: + W1: 3.119539190190677, W2: -3.7529684395700835, bias: -0.9507100523883126 \ No newline at end of file diff --git a/tempCodeRunnerFile.py b/tempCodeRunnerFile.py deleted file mode 100644 index ce4a57d..0000000 --- a/tempCodeRunnerFile.py +++ /dev/null @@ -1,3 +0,0 @@ -pin_est_1 = Percettrone(w1=0.3, w2=4, bias=-0.5) -pin_est_2 = Percettrone(w1=0.2, w2=4, bias=-0.5) -pinout = Percettrone(w1=0.3, w2=2, bias=-1) \ No newline at end of file