diff --git a/classificatore_singolo b/classificatore_singolo index 2cb26d7..f809243 100755 Binary files a/classificatore_singolo and b/classificatore_singolo differ diff --git a/classificatore_singolo.c b/classificatore_singolo.c index 46f2d36..c85c9c2 100644 --- a/classificatore_singolo.c +++ b/classificatore_singolo.c @@ -144,16 +144,16 @@ void main() */ + aggiorna_pesi(rete_neurale, gradienti, funzioni_attivazione, set.istanze[indice_set]); // Correggo il livello output - for (int indice_peso = 0; indice_peso < rete_neurale.layers[rete_neurale.size - 1].percettroni[0].size; indice_peso++) + /* for (int indice_peso = 0; indice_peso < rete_neurale.layers[rete_neurale.size - 1].percettroni[0].size; indice_peso++) { // Determino gradiente del peso double gradiente_peso = gradienti[rete_neurale.size - 1][0] * funzioni_attivazione[rete_neurale.size - 2][indice_peso]; rete_neurale.layers[rete_neurale.size - 1].percettroni[0].pesi[indice_peso] += gradiente_peso * LRE; } - rete_neurale.layers[rete_neurale.size - 1].percettroni[0].bias += gradienti[rete_neurale.size - 1][0] * LRE; - + rete_neurale.layers[rete_neurale.size - 1].percettroni[0].bias += gradienti[rete_neurale.size - 1][0] * LRE; */ diff --git a/percettroni.h b/percettroni.h index 36dec8e..219fd53 100644 --- a/percettroni.h +++ b/percettroni.h @@ -53,9 +53,10 @@ double **elabora_funzioni_attivazione(ReteNeurale*, Istanza, int); double *elabora_funzioni_attivazione_layer(Layer, double*, int); double **discesa_gradiente(ReteNeurale, double **, double, int); double *calcola_gradiente_output(Layer layer, double*, double, int); -double calcola_gradiente_disceso(ReteNeurale, int, int, double **, double); -void correggi_pesi_percettrone_double(Percettrone *, int, double **, double); -void correggi_pesi_percettrone_byte(Percettrone *, Istanza, double, int); +double calcola_gradiente_disceso(ReteNeurale, int, int, double**, double); +void aggiorna_pesi(ReteNeurale, double**, double**, Istanza); +void correggi_pesi_percettrone(Percettrone, double*, double); +//void correggi_pesi_percettrone_byte(Percettrone*, Istanza, double, int); int previsione(double); double sigmoide(double); @@ -258,6 +259,8 @@ double *elabora_funzioni_attivazione_layer(Layer layer, double *inputs, int tipo ################# RETROPROPAGAZIONE ################################ */ +NON CALCOLA I GRADIENTI, PARTE DIRETTAMENTE NAN, VERIFICARE LA PRESENZA DI DATI IN FUNZIONI E LE FUNZIONI DI CALCOLO + double **discesa_gradiente(ReteNeurale rete, double **funzioni, double errore, int tipo_derivata) { double **gradienti = (double**)malloc(sizeof(double*) * rete.size); @@ -265,6 +268,8 @@ double **discesa_gradiente(ReteNeurale rete, double **funzioni, double errore, i //Determino il gradiente di output a parte perchè non prende gradienti discesi dal livello superiore gradienti[rete.size-1] = calcola_gradiente_output(rete.layers[rete.size-1], funzioni[rete.size-1], errore, tipo_derivata); + //printf("grad di testa %f, size %d\n", gradienti[rete.size-1][0], rete.size); + //Determino gli altri livelli for (int indice_layer = rete.size - 2; indice_layer >= 0; indice_layer--) { @@ -280,10 +285,21 @@ double **discesa_gradiente(ReteNeurale rete, double **funzioni, double errore, i else derivata_attivazione = derivata_sigmoide(funzioni[indice_layer][indice_percettrone]); + // printf("derivata: %f, gradiente_disceso %f\n", derivata_attivazione, calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti, derivata_attivazione)); + gradienti[indice_layer][indice_percettrone] = calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti, derivata_attivazione); } } + /* for (int count = 0; count < rete.size; count++) + { + for (int count_2 = 0; count_2 < rete.layers[count].size; count_2++) + { + printf("[%d][%d]: %f\t", count, count_2, gradienti[count][count_2]); + } + printf("\n"); + } */ + return gradienti; } @@ -324,24 +340,38 @@ double calcola_gradiente_disceso(ReteNeurale rete, int livello, int indice_peso, ################# PREVISIONE E CORREZIONI ################################ */ -void aggiorna_pesi(ReteNeurale *rete_neurale, double **gradienti, double **funzioni_attivazione, Istanza istanza) { +void aggiorna_pesi(ReteNeurale rete_neurale, double **gradienti, double **funzioni_attivazione, Istanza istanza) { + + /* for (int xxx = 0; xxx < rete_neurale.size; xxx++) + { + for (int count = 0; count < rete_neurale.layers[xxx].size; count++) + { + for (int count_2 = 0; count_2 < rete_neurale.layers[xxx].percettroni[count].size; count_2++) + { + printf("[%d][%d]: %f\t", count, count_2, rete_neurale.layers[xxx].percettroni[count].pesi[count_2]); + } + printf("\n"); + } + } */ // Applico la correzione dal penultimo layer andando indietro fino al secondo (il primo si fa diverso) - for (int indice_layer = rete_neurale->size - 2; indice_layer >= 0; indice_layer--) + for (int indice_layer = rete_neurale.size - 1; indice_layer >= 0; indice_layer--) { // Applico la correzione a tutti i percettroni del layer dal primo a seguire for (int indice_percettrone = 0; indice_percettrone < rete_neurale.layers[indice_layer].size; indice_percettrone++) { // Devo prendere il gradiente del percettrone e moltiplicarlo con gli input associati ai pesi - if (indice_layer != 0) + if (indice_layer > 0) { - correggi_pesi_percettrone_double(&rete_neurale.layers[indice_layer].percettroni[indice_percettrone], indice_layer, funzioni_attivazione, gradienti[indice_layer][indice_percettrone]); + //printf(" [%d][%d]: %f ", indice_layer, indice_percettrone, gradienti[indice_layer][indice_percettrone]); + correggi_pesi_percettrone(rete_neurale.layers[indice_layer].percettroni[indice_percettrone], funzioni_attivazione[indice_layer-1], gradienti[indice_layer][indice_percettrone]); } else { - correggi_pesi_percettrone_byte(&rete_neurale.layers[0].percettroni[indice_percettrone], set.istanze[indice_set], gradienti[0][indice_percettrone], indice_percettrone); + correggi_pesi_percettrone(rete_neurale.layers[indice_layer].percettroni[indice_percettrone], get_double_from_bytes(istanza), gradienti[indice_layer][indice_percettrone]); } } + //printf("\n"); } } @@ -353,22 +383,31 @@ int previsione(double valore) return 0; } -void correggi_pesi_percettrone_double(Percettrone *p, int layer, double **input, double gradiente_percettrone) -{ +/* + Al secondo giro diventa NAN +*/ - for (int indice_peso = 0; indice_peso < p->size; indice_peso++) +void correggi_pesi_percettrone(Percettrone p, double *input, double gradiente_percettrone) +{ + //printf("grad_perc: %f", gradiente_percettrone); + for (int indice_peso = 0; indice_peso < p.size; indice_peso++) { + // Determino il gradiente del peso - double gradiente_peso = gradiente_percettrone * input[layer - 1][indice_peso]; + double gradiente_peso = gradiente_percettrone * input[indice_peso]; + + //printf("indice[%d], gradiente percettrone %f, gradiente peso %f ", indice_peso, gradiente_percettrone, gradiente_peso); // Modifico il peso - p->pesi[indice_peso] += (gradiente_peso * LRE); + p.pesi[indice_peso] += (gradiente_peso * LRE); + } - p->bias += (gradiente_percettrone * LRE); + p.bias += (gradiente_percettrone * LRE); + //printf("\n"); } -void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradiente_percettrone, int indice_percettrone) +/* void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradiente_percettrone, int indice_percettrone) { for (int indice_peso = 0; indice_peso < p->size; indice_peso++) { @@ -380,7 +419,7 @@ void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradie } p->bias += (gradiente_percettrone * LRE); -} +} */