From b87b4abd3712c94adcf982bf411476e8523836d2 Mon Sep 17 00:00:00 2001 From: mirimatcode Date: Thu, 23 Jan 2025 21:24:30 +0100 Subject: [PATCH] ultima modifica di oggi, le formule del costo, del gradiente dovrebbero essere giuste --- grafico.py | 27 ----------------- multi_layer.py | 80 ++++++++++++++++++++++++++++++------------------- percettrone.py | 3 +- single_layer.py | 41 ++++++++++++++----------- stampe_video.py | 54 +++++++++++++++++++-------------- 5 files changed, 107 insertions(+), 98 deletions(-) delete mode 100644 grafico.py diff --git a/grafico.py b/grafico.py deleted file mode 100644 index c1ba8f1..0000000 --- a/grafico.py +++ /dev/null @@ -1,27 +0,0 @@ -import matplotlib.pyplot as plt -import numpy as np - -""" class Grafico: - - def __init__(self): - self.x = np.linspace(-10, 10, 100) #Variazione di X per disegnare la retta penso - - plt.title('AND Logico') - plt.xlabel('X1') - plt.ylabel('X2') - - plt.xlim(0, 2) - plt.ylim(0, 2) - - def disegna_and(self): - plt.plot(0, 0, 'o', color='red', markeredgewidth=10) - plt.plot(0, 1, 'o', color='red',markeredgewidth=10) - plt.plot(1, 0, 'o', color='red',markeredgewidth=10) - plt.plot(1, 1, 'o', color='green',markeredgewidth=10) - - def mostra(self): - plt.show() - -grafico = Grafico() -grafico.disegna_and() -grafico.mostra() """ \ No newline at end of file diff --git a/multi_layer.py b/multi_layer.py index 3f849dc..6561edc 100644 --- a/multi_layer.py +++ b/multi_layer.py @@ -9,21 +9,23 @@ output = (0,1,1,0) # XOR Logico #output = (0,1,1,1) # OR Logico corrette = 0 -soglia_errore_accettabile = 0.001 soglia_funzione_attivazione = 0.5 -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) +#XOR +""" pin_est_1 = Percettrone(w1=1.7453135346642987, w2=1.6392557285802016, bias=-2.8396189093513544, lre=0.2) +pin_est_2 = Percettrone(w1=2.0579802021958487, w2=2.0049998768936956,bias=-1.510128337351728, lre=0.2) +pinout = Percettrone(w1=-4.872221528209076, w2=2.863271416125622, bias=-0.2593053838395353, lre=0.2) """ -discriminanti = {"P1":[], "P2":[], "POUT":[]} +rette = {"P1":[], "P2":[], "POUT":[]} -''' #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) -''' +pin_est_1 = Percettrone(w1=1, w2=1, bias=-2) +pin_est_2 = Percettrone(w1=2, w2=2, bias=-1.5) +pinout = Percettrone(w1=-4, w2=2, bias=-0.2) + +""" pin_est_1 = Percettrone() +pin_est_2 = Percettrone() +pinout = Percettrone() """ for i in range(1, MAX_EPOCHE): #Epoche @@ -36,7 +38,7 @@ for i in range(1, MAX_EPOCHE): #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 - 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) @@ -56,28 +58,46 @@ for i in range(1, MAX_EPOCHE): #Epoche 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) - discriminanti["P1"].append([-(pin_est_1.w1 * x[j][0])/pin_est_1.w2, -(pin_est_1.bias/pin_est_1.w2)]) - discriminanti["P2"].append([-(pin_est_2.w1 * x[j][0])/pin_est_2.w2, -(pin_est_2.bias/pin_est_2.w2)]) - discriminanti["POUT"].append([-(pinout.w1 * x[j][0])/pinout.w2, -(pinout.bias/pinout.w2)]) + try: + rette["P1"].append([-(pin_est_1.w1 * x[j][0])/pin_est_1.w2, -(pin_est_1.bias/pin_est_1.w2)]) + rette["P2"].append([-(pin_est_2.w1 * x[j][0])/pin_est_2.w2, -(pin_est_2.bias/pin_est_2.w2)]) + rette["POUT"].append([-(pinout.w1 * x[j][0])/pinout.w2, -(pinout.bias/pinout.w2)]) + except ZeroDivisionError: + pass - #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 1 + gradiente_w1 = errore * yout * (1-yout) * pinout.w1 * y_est_1 * (1-y_est_1) * x[j][0] + gradiente_w2 = errore * yout * (1-yout) * pinout.w1 * y_est_1 * (1-y_est_1) * x[j][1] + gradiente_bias = errore * yout * (1-yout) * pinout.bias * y_est_1 * (1-y_est_1) + pin_est_1.correggi_pesi(gradiente_w1, gradiente_w2, gradiente_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) + gradiente_w1 = errore * yout * (1-yout) * pinout.w2 * y_est_2 * (1-y_est_2) * x[j][0] + gradiente_w2 = errore * yout * (1-yout) * pinout.w2 * y_est_2 * (1-y_est_2) * x[j][1] + gradiente_bias = errore * yout * (1-yout) * pinout.bias * y_est_2 * (1-y_est_2) + pin_est_2.correggi_pesi(gradiente_w1, gradiente_w2, gradiente_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 + gradiente_w1 = errore * y_est_1 + gradiente_w2 = errore * y_est_2 + pinout.correggi_pesi(gradiente_w1, gradiente_w2, errore) """ -disegna_grafico_multi(discriminanti) \ No newline at end of file + # Gradienti Percettrone 1 + gradiente_w1 = errore * y_est_1 * (1-y_est_1) * x[j][0] + gradiente_w2 = errore * y_est_1 * (1-y_est_1) * x[j][1] + gradiente_bias = errore * y_est_1 * (1-y_est_1) + pin_est_1.correggi_pesi(gradiente_w1, gradiente_w2, gradiente_bias) + + # Gradienti Percettrone 2 + gradiente_w1 = errore * y_est_2 * (1-y_est_2) * x[j][0] + gradiente_w2 = errore * y_est_2 * (1-y_est_2) * x[j][1] + gradiente_bias = errore * y_est_2 * (1-y_est_2) + pin_est_2.correggi_pesi(gradiente_w1, gradiente_w2, gradiente_bias) + + # Gradienti Percettrone out + gradiente_w1 = errore * yout * (1-yout) * y_est_1 + gradiente_w2 = errore * yout * (1-yout) * y_est_2 + gradiente_bias = gradiente_bias = errore * yout * (1-yout) + pinout.correggi_pesi(gradiente_w1, gradiente_w2, errore) + +disegna_grafico_multi(rette) \ No newline at end of file diff --git a/percettrone.py b/percettrone.py index 80e5b2c..1846ec5 100644 --- a/percettrone.py +++ b/percettrone.py @@ -1,7 +1,8 @@ import math +import random class Percettrone: - def __init__(self, w1 = 1, w2 = 1, bias = 1, lre = 0.2): + def __init__(self, w1 = random.uniform(-1, 1), w2 = random.uniform(-1, 1), bias = random.uniform(-1, 1), lre = 0.2): self.w1 = w1 self.w2 = w2 self.bias = bias diff --git a/single_layer.py b/single_layer.py index d3e3eb4..4f3d528 100644 --- a/single_layer.py +++ b/single_layer.py @@ -5,15 +5,14 @@ x = [(0,0),(0,1),(1,0),(1,1)] # Combinazioni output = (0,0,0,1) # AND Logico #output = (0,1,1,1) # OR Logico -p = Percettrone(bias=-0.1, lre=0.1) +p = Percettrone() corrette = 0 #Fermo le epoche se termina prima -soglia_errore_accettabile = 0.001 soglia_funzione_attivazione = 0.5 -discriminanti = [] +rette = [] -for i in range(1,10000): #Epoche +for i in range(1,100000): #Epoche if corrette == 4: print(f"Epoche necessarie: {i-1}") @@ -34,21 +33,29 @@ for i in range(1,10000): #Epoche if previsione == output[j]: corrette += 1 - errore = output[j] - y + #La formula del costo è sicuro questa, la retta scappa se tolgo il meno + #Y è confermato, se metto la previsione invece di y la retta non corrisponde + errore = -(output[j] - y) + + #Il gradiente può non essere calcolato nel percettrone singolo, funziona lo stesso + gradiente_w1 = errore * y * (1-y) * x[j][0] + gradiente_w2 = errore * y * (1-y) * x[j][1] + gradiente_bias = errore * y * (1-y) + p.correggi_pesi(gradiente_w1, gradiente_w2, gradiente_bias) - print("\n") - disegna_funzione(p, y, x[j][0], x[j][1], True, errore) - - m = -(p.w1 * x[j][0])/p.w2 - q = -(p.bias/p.w2) - discriminanti.append([m,q]) - if errore != 0: - appoggio_w1 = errore * y * (1-y) * p.w1 * x[j][0] - appoggio_w2 = errore * y * (1-y) * p.w1 * x[j][1] - appoggio_bias = errore * y * (1-y) * p.bias - p.correggi_pesi(appoggio_w1, appoggio_w2, appoggio_bias) + pass else: corrette += 1 -disegna_grafico_singolo(discriminanti) \ No newline at end of file + print("\n") + disegna_funzione(p, y, x[j][0], x[j][1], True, errore) + + try: + m = -(p.w1 * x[j][0])/p.w2 + q = -(p.bias/p.w2) + rette.append([m,q]) + except ZeroDivisionError: + pass + +disegna_grafico_singolo(rette) \ No newline at end of file diff --git a/stampe_video.py b/stampe_video.py index e4fb9e2..0549bbe 100644 --- a/stampe_video.py +++ b/stampe_video.py @@ -39,21 +39,25 @@ def disegna_grafico_singolo(lista_rette): plt.xlabel('X1') plt.ylabel('X2') + # linee in coordinate 0,0 + plt.axhline(0, color='black', linewidth=0.5, linestyle='--') + plt.axvline(0, color='black', linewidth=0.5, linestyle='--') + #AND Logico - plt.plot(0, 0, 'o', color='red', markeredgewidth=10) - plt.plot(0, 1, 'o', color='red',markeredgewidth=10) - plt.plot(1, 0, 'o', color='red',markeredgewidth=10) - plt.plot(1, 1, 'o', color='green',markeredgewidth=10) + plt.plot(0, 0, 'o', color='red') + plt.plot(0, 1, 'o', color='red') + plt.plot(1, 0, 'o', color='red') + plt.plot(1, 1, 'o', color='green') - plt.xlim(0, 2) - plt.ylim(0, 2) + plt.xlim(-2, 2) + plt.ylim(-2, 2) - for discriminante in lista_rette: + for retta in lista_rette: # Calcola i valori di y usando l'equazione della retta - y = discriminante[0] * x + discriminante[1] - discriminante, = plt.plot(x, y, label=f'y = mx + q', color='blue') # RETTA + y = retta[0] * x + retta[1] + retta, = plt.plot(x, y, label=f'y = mx + q', color='blue') # RETTA plt.pause(0.0001) - discriminante.remove() + retta.remove() plt.show() @@ -68,25 +72,29 @@ def disegna_grafico_multi(lista_rette): plt.xlabel('X1') plt.ylabel('X2') + # linee in coordinate 0,0 + plt.axhline(0, color='black', linewidth=0.5, linestyle='--') + plt.axvline(0, color='black', linewidth=0.5, linestyle='--') + #XOR Logico - plt.plot(0, 0, 'o', color='red', markeredgewidth=5) - plt.plot(0, 1, 'o', color='green',markeredgewidth=5) - plt.plot(1, 0, 'o', color='green',markeredgewidth=5) - plt.plot(1, 1, 'o', color='red',markeredgewidth=5) + plt.plot(0, 0, 'o', color='red') + plt.plot(0, 1, 'o', color='green') + plt.plot(1, 0, 'o', color='green') + plt.plot(1, 1, 'o', color='red') - plt.xlim(0, 2) - plt.ylim(0, 2) + plt.xlim(-2, 2) + plt.ylim(-2, 2) - discriminanti_p1 = lista_rette["P1"] - discriminanti_p2 = lista_rette["P2"] - discriminanti_pout = lista_rette["POUT"] + rette_p1 = lista_rette["P1"] + rette_p2 = lista_rette["P2"] + rette_pout = lista_rette["POUT"] - size_vettori = len(discriminanti_pout) + size_vettori = len(rette_pout) for i in range(0, size_vettori): - plot_uno, = plt.plot(x, discriminanti_p1[i][0] * x + discriminanti_p1[i][1], label=f'percettrone 1', color='green') # RETTA - plot_due, = plt.plot(x, discriminanti_p2[i][0] * x + discriminanti_p2[i][1], label=f'percettrone 2', color='red') # RETTA - plot_out, = plt.plot(x, discriminanti_pout[i][0] * x + discriminanti_pout[i][1], label=f'percettrone out', color='blue') # RETTA + plot_uno, = plt.plot(x, rette_p1[i][0] * x + rette_p1[i][1], label='p1', color='orange') # RETTA + plot_due, = plt.plot(x, rette_p2[i][0] * x + rette_p2[i][1], label='p2', color='red') # RETTA + plot_out, = plt.plot(x, rette_pout[i][0] * x + rette_pout[i][1], label='pout', color='blue') # RETTA plt.pause(0.0001) plot_uno.remove()