#include #include "percettrone.h" #include "grafico.h" int MAX_EPOCHE = 10000; /* il tipo indica quali punti vogliamo disegnare nel grafico: 0: AND 1: OR 2: XOR 3: NAND 4: NOR 5: XNOR */ int tipo = 0; void main() { srand(time(NULL)); allegro_init(); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0); cls(tipo, 1); int output[4]; switch (tipo) { case 0: output[0] = 0; output[1] = 0; output[2] = 0; output[3] = 1; break; case 1: output[0] = 0; output[1] = 1; output[2] = 1; output[3] = 1; break; case 2: output[0] = 0; output[1] = 1; output[2] = 1; output[3] = 0; break; case 3: output[0] = 1; output[1] = 1; output[2] = 1; output[3] = 0; break; case 4: output[0] = 1; output[1] = 0; output[2] = 0; output[3] = 0; break; case 5: output[0] = 1; output[1] = 0; output[2] = 0; output[3] = 1; break; default: break; } Percettrone p_ext_1 = crea_percettrone(); int colore_rosso = makecol(255, 0, 0); Percettrone p_ext_2 = crea_percettrone(); int colore_verde = makecol(0, 255, 0); Percettrone pout = crea_percettrone(); int colore_blu = makecol(0, 0, 255); p_ext_1.w1 = 1.332870; p_ext_1.w2 = -0.628797; p_ext_1.bias = 0.729138; p_ext_2.w1 = 0.459249; p_ext_2.w2 = 0.394682; p_ext_2.bias = 0.833102; pout.w1 = -0.004388; pout.w2 = 0.090205; pout.bias = -0.067931; // Contatore per fermare il percettrone, se vale 4 significa che ha indovinato tutte e 4 le combinazioni int corrette = 0; Retta *rette_p_ext_1 = (Retta *)malloc(sizeof(Retta)); Retta *rette_p_ext_2 = (Retta *)malloc(sizeof(Retta)); //Retta *rette_layer_uno = (Retta *)malloc(sizeof(Retta)); Retta *rette_pout = (Retta *)malloc(sizeof(Retta)); // Soglia sigmoide double soglia_funzione_attivazione = 0.5; for (int i = 0; i < MAX_EPOCHE; i++) { if (corrette == 4) { printf("\nEpoche necessarie: %d\n", i); stampa_risultati_layer_multi(p_ext_1, p_ext_2, pout); for (int z = 0; z < i; z++) { cls(tipo, 1); traccia_retta(rette_p_ext_1[z].m, rette_p_ext_1[z].q, colore_rosso); traccia_retta(rette_p_ext_2[z].m, rette_p_ext_2[z].q, colore_verde); //traccia_retta(rette_layer_uno[z].m, rette_layer_uno[z].q, colore_rosso); traccia_retta(rette_pout[z].m, rette_pout[z].q, colore_blu); //printf("Sto tracciando la retta p1 con coefficiente: %f e intercetta: %f\n", rette_p_ext_1[z].m, rette_p_ext_1[z].q); //printf("Sto tracciando la retta p2 con coefficiente: %f e intercetta: %f\n", rette_p_ext_2[z].m, rette_p_ext_2[z].q); //printf("Sto tracciando la retta pout con coefficiente: %f e intercetta: %f\n", rette_pout[z].m, rette_pout[z].q); stampa_epoca(z + 1); sleep_ms(10); } readkey(); break; } printf("\nEpoca %d\n", i); corrette = 0; for (int j = 0; j < 4; j++) { double y_ext_1 = funzione_sigmoide(p_ext_1, x[j][0], x[j][1]); double y_ext_2 = funzione_sigmoide(p_ext_2, x[j][0], x[j][1]); double yout = funzione_sigmoide(pout, y_ext_1, y_ext_2); double errore = -(output[j] - yout); int previsione = -1; if (yout >= soglia_funzione_attivazione) { previsione = 1; } else { previsione = 0; } stampa_layer_uno(p_ext_1, y_ext_1, x[j][0], x[j][1], errore); stampa_layer_out(pout, previsione, y_ext_1, y_ext_2, errore); stampa_layer_uno(p_ext_2, y_ext_2, x[j][0], x[j][1], errore); if (previsione == output[j]) { corrette++; } else { // Gradienti percettrone 1 double gradiente_w1 = errore * yout * (1 - yout) * y_ext_1 * (1 - y_ext_1) * x[j][0]; double gradiente_w2 = errore * yout * (1 - yout) * y_ext_1 * (1 - y_ext_1) * x[j][1]; double gradiente_bias = errore * yout * (1 - yout) * y_ext_1 * (1 - y_ext_1); correggi_pesi(&p_ext_1, gradiente_w1, gradiente_w2, gradiente_bias); // Gradienti percettrone 2 gradiente_w1 = errore * yout * (1 - yout) * y_ext_2 * (1 - y_ext_2) * x[j][0]; gradiente_w2 = errore * yout * (1 - yout) * y_ext_2 * (1 - y_ext_2) * x[j][1]; gradiente_bias = errore * yout * (1 - yout) * y_ext_2 * (1 - y_ext_2); correggi_pesi(&p_ext_2, gradiente_w1, gradiente_w2, gradiente_bias); // Gradienti percettrone out gradiente_w1 = errore * yout * (1 - yout) * y_ext_1; gradiente_w2 = errore * yout * (1 - yout) * y_ext_2; gradiente_bias = errore * yout * (1 - yout); correggi_pesi(&pout, gradiente_w1, gradiente_w2, gradiente_bias); } // Prevengo la divisione per zero if(p_ext_1.w2 != 0 && p_ext_2.w2 != 0 && pout.w2 !=0) { rette_p_ext_1[i].m = -(p_ext_1.w1 / p_ext_1.w2); rette_p_ext_1[i].q = -(p_ext_1.bias / p_ext_1.w2); rette_p_ext_2[i].m = -(p_ext_2.w1 / p_ext_2.w2); rette_p_ext_2[i].q = -(p_ext_2.bias / p_ext_2.w2); /* rette_pout[i].m = -(pout.w1 * x[j][0]) / pout.w2; rette_pout[i].q = -(pout.bias / pout.w2); */ rette_pout[i].m = -(pout.w1 / pout.w2); rette_pout[i].q = -(pout.bias / pout.w2); // somma delle rette (m1 + m2)x + (q1 + q2) /* rette_layer_uno[i].m = rette_layer_uno[i].q = -(p_ext_1.bias / p_ext_1.w2); */ if (corrette != 4) { rette_p_ext_1 = (Retta *)realloc(rette_p_ext_1, sizeof(Retta) * (i + 2)); rette_p_ext_2 = (Retta *)realloc(rette_p_ext_2, sizeof(Retta) * (i + 2)); //rette_layer_uno = (Retta *)realloc(rette_layer_uno, sizeof(Retta) * (i + 2)); rette_pout = (Retta *)realloc(rette_pout, sizeof(Retta) * (i + 2)); } } } } }