Files
percettroni_c/layer_multi.c
2025-02-20 21:54:37 +01:00

227 lines
7.3 KiB
C

#include <stdio.h>
#include "percettrone.h"
#include "grafico.h"
int MAX_EPOCHE = 100000;
/*
il tipo indica quali punti vogliamo disegnare nel grafico:
0: AND
1: OR
2: XOR
3: NAND
4: NOR
5: XNOR
*/
int tipo = 2;
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);
//XOR
/* 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;
double errore_epoca = 0.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);
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
{
double errore = (output[j] - yout);
/* if(errore < 0)
errore = -errore; */
errore_epoca += errore;
double derivata_pout = yout * (1 - yout);
double derivata_p1 = y_ext_1 * (1 - y_ext_1);
double derivata_p2 = y_ext_2 * (1 - y_ext_2);
if(derivata_pout == 0.0)
derivata_pout = 1;
if(derivata_p1 == 0.0)
derivata_p1 = 1;
if(derivata_p2 == 0.0)
derivata_p2 = 1;
// Gradienti percettrone 1
double gradiente_w1 = errore * derivata_pout * derivata_p1 * x[j][0];
double gradiente_w2 = errore * derivata_pout * derivata_p1 * x[j][1];
double gradiente_bias = errore * derivata_pout * derivata_p1;
correggi_pesi(&p_ext_1, gradiente_w1, gradiente_w2, gradiente_bias);
// Gradienti percettrone 2
gradiente_w1 = errore * derivata_pout * derivata_p2 * x[j][0];
gradiente_w2 = errore * derivata_pout * derivata_p2 * x[j][1];
gradiente_bias = errore * derivata_pout * derivata_p2;
correggi_pesi(&p_ext_2, gradiente_w1, gradiente_w2, gradiente_bias);
// Gradienti percettrone out
gradiente_w1 = errore * derivata_pout * y_ext_1;
gradiente_w2 = errore * derivata_pout * y_ext_2;
gradiente_bias = errore * derivata_pout;
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));
}
}
}
printf("Errore: %f\n", errore_epoca);
}
}