From bbbfa9af690138176fca43b13dfff71dfbbc0bf8 Mon Sep 17 00:00:00 2001 From: mirimatcode Date: Fri, 24 Jan 2025 10:07:13 +0100 Subject: [PATCH] versione finale si spera. Trova sempre soluzione con pesi random --- multi_layer.py | 73 ++++++++++++++++++++----------------------------- single_layer.py | 33 ++++++++++------------ stampe_video.py | 20 ++++++++------ 3 files changed, 55 insertions(+), 71 deletions(-) diff --git a/multi_layer.py b/multi_layer.py index 6561edc..ad45dd4 100644 --- a/multi_layer.py +++ b/multi_layer.py @@ -16,16 +16,17 @@ soglia_funzione_attivazione = 0.5 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) """ +""" pin_est_1 = Percettrone(w1=5.057571564186738, w2=-5.572150383812219, bias=-3.1715170666210444) +pin_est_2 = Percettrone(w1=-2.1393104621179835, w2=1.6774379439199167, bias=-0.7542487269674267) +pinout = Percettrone(w1=3.2061105491734967, w2=1.9571327990877703, bias=-1.319795396902547) """ + rette = {"P1":[], "P2":[], "POUT":[]} #Pesi per AND, OR e XOR (sigmoide) -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_1 = Percettrone() pin_est_2 = Percettrone() -pinout = Percettrone() """ +pinout = Percettrone() for i in range(1, MAX_EPOCHE): #Epoche @@ -39,25 +40,23 @@ for i in range(1, MAX_EPOCHE): #Epoche for j in range(0,4): #Combinazioni + # Calcolo le funzioni di attivazione 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) + # Determino la previsione if yout >= soglia_funzione_attivazione: previsione = 1 else: previsione = 0 - if previsione == output[j]: - corrette += 1 - - errore = -(output[j] - yout) - + # Stampo a video e preparo per il plot print("\n") disegna_funzione(pin_est_1, y_est_1, x[j][0], x[j][1], False) 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) - 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)]) @@ -65,39 +64,27 @@ for i in range(1, MAX_EPOCHE): #Epoche except ZeroDivisionError: pass - """ # 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) + # Confronto la previsione con l'output atteso + if previsione == output[j]: + corrette += 1 + else: + # Calcolo i gradienti e correggo i pesi + # 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 * 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 2 + gradiente_w1 = errore * yout * (1-yout) * y_est_2 * (1-y_est_2) * x[j][0] + gradiente_w2 = errore * yout * (1-yout) * y_est_2 * (1-y_est_2) * x[j][1] + gradiente_bias = errore * yout * (1-yout) * y_est_2 * (1-y_est_2) + pin_est_2.correggi_pesi(gradiente_w1, gradiente_w2, gradiente_bias) - # Gradienti Percettrone out - gradiente_w1 = errore * y_est_1 - gradiente_w2 = errore * y_est_2 - pinout.correggi_pesi(gradiente_w1, gradiente_w2, errore) """ - - # 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) + # 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/single_layer.py b/single_layer.py index 4f3d528..7c4a197 100644 --- a/single_layer.py +++ b/single_layer.py @@ -24,30 +24,11 @@ for i in range(1,100000): #Epoche for j in range(0,4): #Combinazioni y = p.funzione_sigmoide(x[j][0], x[j][1]) - - if y >= soglia_funzione_attivazione: - previsione = 1 - else: - previsione = 0 - - if previsione == output[j]: - corrette += 1 #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) - - if errore != 0: - pass - else: - corrette += 1 - print("\n") disegna_funzione(p, y, x[j][0], x[j][1], True, errore) @@ -57,5 +38,19 @@ for i in range(1,100000): #Epoche rette.append([m,q]) except ZeroDivisionError: pass + + if y >= soglia_funzione_attivazione: + previsione = 1 + else: + previsione = 0 + + if previsione == output[j]: + corrette += 1 + else: + #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) disegna_grafico_singolo(rette) \ No newline at end of file diff --git a/stampe_video.py b/stampe_video.py index 0549bbe..a308f67 100644 --- a/stampe_video.py +++ b/stampe_video.py @@ -24,7 +24,6 @@ def stampa_risultati_multilayer(pin_est_1, pin_est_2, pinout): print("Percettrone OUT:") print(f"\t W1: {pinout.w1}, W2: {pinout.w2}, bias: {pinout.bias}") - def disegna_grafico_singolo(lista_rette): import matplotlib.pyplot as plt import numpy as np @@ -52,12 +51,14 @@ def disegna_grafico_singolo(lista_rette): plt.xlim(-2, 2) plt.ylim(-2, 2) - for retta in lista_rette: + size = len(lista_rette) + for i in range(0, size): # Calcola i valori di y usando l'equazione della retta - y = retta[0] * x + retta[1] + y = lista_rette[i][0] * x + lista_rette[i][1] retta, = plt.plot(x, y, label=f'y = mx + q', color='blue') # RETTA - plt.pause(0.0001) - retta.remove() + if i < size-1: + plt.pause(0.0001) + retta.remove() plt.show() @@ -96,9 +97,10 @@ def disegna_grafico_multi(lista_rette): 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() - plot_due.remove() - plot_out.remove() + if i < size_vettori-1: + plt.pause(0.0001) + plot_uno.remove() + plot_due.remove() + plot_out.remove() plt.show() \ No newline at end of file