Versione finale con grafico e legenda
This commit is contained in:
189
layer_multi.c
Normal file
189
layer_multi.c
Normal file
@@ -0,0 +1,189 @@
|
||||
#include <stdio.h>
|
||||
#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 = 2;
|
||||
|
||||
void stampa_risultati(Percettrone);
|
||||
|
||||
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);
|
||||
|
||||
// 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_pout = (Retta *)malloc(sizeof(Retta));
|
||||
|
||||
int size_iniziale = sizeof(rette_p_ext_1);
|
||||
|
||||
// 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_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 * x[j][0]) / 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 * x[j][0]) / 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);
|
||||
|
||||
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_pout = (Retta *)realloc(rette_pout, sizeof(Retta) * (i + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user