From faebcf7c59ccf413feb05bea0d6f8618a9c8648c Mon Sep 17 00:00:00 2001 From: mirimatcode Date: Mon, 24 Feb 2025 14:03:56 +0100 Subject: [PATCH] =?UTF-8?q?passare=20al=20calcolo=20delle=20funzioni=20di?= =?UTF-8?q?=20attivazione=20di=20prima=20perch=C3=A8=20mi=20sono=20rotto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- classificatore_singolo | Bin 25928 -> 26008 bytes classificatore_singolo.c | 127 +------ percettroni.h | 313 ++++-------------- prova_passaggio_parametri | Bin 0 -> 15672 bytes prova_passaggio_parametri.c | 30 +- ...100.bin => rete_pesi_deep_feed_forward.bin | Bin 6 files changed, 100 insertions(+), 370 deletions(-) create mode 100755 prova_passaggio_parametri rename rete_pesi_deep_feed_forward_93-100.bin => rete_pesi_deep_feed_forward.bin (100%) diff --git a/classificatore_singolo b/classificatore_singolo index f80924325f7a08c254efbfd1ca72bc50812fd473..a3507af1ebe7f1ce169e4d273d7d96c07d89e2eb 100755 GIT binary patch delta 4244 zcmZu!4OCQR8ou9UMu8P(#wCzZ1Oyx)b)cV<%63BI%B=&2DMF=e$WQB0tL;eIS#8** z-MV|B9rsfYZM#M7@nk={TH`6yP7L`oW2w>43e~3L|K%q$vKWiH`+VQM4A6SdnR&na zKJWW}&-;Gw_kA zBicwp@rm;Qc*(%4(jh7Dg){ z%F6e$G9)X9wa-~JwOo@GF(92|h3UUnmCl**TFSz3)nw8ot9BNICZ%RA8;N6v*vJV* zHNhQBnlv&`I=AWBQBo~sm&XTDOMB#+BXZ|yi`>*}mq`!``eJGUUI+5%z>JjHO6ezT z+DK9Q9zDRX~w6b;}T8FNG6GNe#TVN?pvNwKoX1L5|9Rv zozUyVxM{N{JieK}nwhyAg&gH)6v@wv6b%Nbv?kYlBzK;%aNS&08jx$SSY0yVR&1pR z=XqFGj96={EtD=Q5l){Q*@=?crde~l_#!9uho9AdBF5<*hwV05y* zw8z*M=zjp3tO{!R6(eV| zecuZkRZ8xXTQ;)QLg#nxW5_!e25;)4)viKuejoj(>kjf2{nC{#9_yv{>}lezUOFfH z2G4y6;5CW|HicjlM3^9$?4J^0azW!vLSPaym{^k;7|>S0y&W?Ny_upQblBOXI}PhG zyz5QtIT7pcz>(3Vr?L~1wlfF3U^DYgV&Qv1qmy!`##&6*qZ-Z6xl^=jbaPIM*m;ru z9pHLSF`)fQqn$ZRlQvxBal%-L(am`7|Z+;u+Z|ntWhUfTOX)n7a_#$TSBV zYh~4vl?_ttoXhujuzG02utCo>K*;KK^*6H?uvXmcVOG53&$ES4q&Di1X7q7RPF1aq!yx19#pD=bb{s^nG@Czk{X}I@p&s{St>mh@kb) zL5!UvVLb{?0cg1nfnH*9TdZx@8F6L2;uz$Gc-zqNj@N7e0#Y+eEg*TB=q<)ns^sOi zuaC7odlo^;y>g3m*+}&-U}rk#v73>dQmp}LD-W}s?~d{wRoaTRS?!;~3PHL`)Y1@o zN~7JgQ$71wRwc>@CAju1>_Qp29;J5NfIoM&y;*3nz3E4G|3>VmB$YLjaUmH8emg(h zQEtJwaWcbLt9Na0O6t6K8!SyyGht(cX|7+DJlAwL&d3$`ZQ+oRlHFRvil9pVdRunT z2>c-`0VHk-5aYbHm$tIQkyk)gH~T>!DKv!Or|o4~GRJ^JLW8izsvMw>#h~icz20oqN(C%OHNHf zWE#qyBB79*iX-NsLPI_#u$5#>v|rf z@`0{D3~B!ehXQ2G$GW~7a>IXgy$kXX-@>R$XWEZ3mC3u7|2JA=Sz5mtqBFHx&YauJX(Df%Et550rPRJq1AmnGL zrUtp@jIK|@4Y>_+7Gw#UvIMdnTY4>ICT@~u$R&`kLH-DN6tV_4)d1x2e)wB$IP5W) zWfg>!FA;!#c)KgP61AAgmY`@NyA6d*d~RX`>L_v%2c1`xN;cAa@V$gShVSR;Gx$D6 z_ZDRkiGG3alaxpq;^Y%Fc9D}7O3~zAdWV!MKHp9MEIB8Dh>(7acKstk-Y26R%n;@P7b*Z7eRn6p7jnJO`arKMt>s;61<}0=@<^Qnjf1C}x0F znJ9z-?7P6%b_%-etqb&T#m=d7F+73>{Oi~{M76LY_)h0HSn2N4O48_yS!}b2RVmbY zcU5v*3Zozh>;`7fC444}HldMjxqCxQ&_q}H9829K{YnnE5qR1d-h`S?7UG3hG7S9| zTD{CglBlxGP4em9Wp43HH|<+iRXvUOxge}%#PF~MV~z#*H^?5oD3GU2eP9Mx3ug@> z^g=TG-EKee_^y}qG$kd-__gNgnjm4gD`M;LDB=nfOjHBr6`fhvqca?nI?yx#ET-GbpU-|33iqvC4o zRy92E>vh%ZA6Z>fN4MO!!PGojw|+g2aNoogM5KPv;)|}jKZ>N%)z$8p#(X1GBYmOz rNs>TwR=FM8?S^hdR{B=2x=qBj@^bAhG1(@ik7;l1E#wE9Ug!EBGHnTB delta 4256 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 diff --git a/classificatore_singolo.c b/classificatore_singolo.c index c85c9c2..90bdbf8 100644 --- a/classificatore_singolo.c +++ b/classificatore_singolo.c @@ -3,9 +3,9 @@ // Scelgo quale categoria voglio identificare. nel caso dello xor -1 #define CATEGORIA 7 -#define NUM_LAYERS 4 -#define PERCETTRONI_LAYER_0 32 -#define MAX_EPOCHE 10 +#define NUM_LAYERS 2 +#define PERCETTRONI_LAYER_0 2 +#define MAX_EPOCHE 1 // 1 relu, 2 sigmoide #define TIPO_FUNZIONE 2 @@ -13,7 +13,6 @@ byte get_out_corretto(byte); void stampa_layer_indirizzo(Layer *); void stampa_tempo(time_t[], int); -void debug(int); void main() { @@ -34,8 +33,7 @@ void main() ReteNeurale rete_neurale; ReteNeurale *puntatore_rete = caricaReteNeurale(file_pesi); - if (puntatore_rete == NULL) - { + if (puntatore_rete == NULL) { rete_neurale = inizializza_rete_neurale_feed_forward(NUM_LAYERS, PERCETTRONI_LAYER_0, N_INPUTS); } else @@ -52,143 +50,39 @@ void main() /* ################# Addestramento ################################ */ - int corrette = 0; for (int i = 0; i < MAX_EPOCHE; i++) { - /* - ################# inizializzazione variabili per l'epoca in corso ################################ - */ - printf("Epoca %d\n", i); stampa_tempo(tempo_epoche, i); corrette = 0; double errore_totale = 0.0; - - /* 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"); - } - } */ - - for (int indice_set = 0; indice_set < set.size; indice_set++) + + for (int indice_set = 0; indice_set < 1/* set.size */; indice_set++) { - - /* - ################# Feed Forward ################################ - */ - // Elabora le funzioni di attivazione in base al tipo scelto. Ritorna un vettore bidimensionale dove la prima dimensione rappresenta l'indice del layer, la seconda quella del percettrone nel layer + double **funzioni_attivazione = elabora_funzioni_attivazione(rete_neurale, set.istanze[indice_set], TIPO_FUNZIONE); - double **funzioni_attivazione = elabora_funzioni_attivazione(&rete_neurale, set.istanze[indice_set], TIPO_FUNZIONE); - - /* - ################# Previsione ################################ - */ - // Siccome il dataset da il numero della categoria a cui appartiene l'immagine, se la categoria è quella che cerco io output_corretto varrà 1 altrimenti 0 byte output_corretto = get_out_corretto(set.istanze[indice_set].classificazione); - if (previsione(funzioni_attivazione[rete_neurale.size - 1][0]) == output_corretto) corrette++; - /* - ################# Funzione di perdita (errore) ################################ - */ - - // printf("funzione_attivazione_out: %f", funzioni_attivazione[rete_neurale.size - 1][0]); - // Derivata funzione di perdita double errore = (output_corretto - funzioni_attivazione[rete_neurale.size - 1][0]); // Sommo la funzione di perdita a errore_totale per stampare alla fine dell'epoca l'errore medio errore_totale += pow(errore, 2) * 0.5; - /* - ################# Retropropagazione ################################ - */ - /* double **gradienti = (double **)malloc(sizeof(double *) * NUM_LAYERS); - - // Alloco la dimensione per ogni layer - for (int indice_layer = 0; indice_layer < NUM_LAYERS; indice_layer++) - { - gradienti[indice_layer] = (double *)malloc(sizeof(double) * rete_neurale.layers[indice_layer].size); - } - - // Derivata funzione attivazione - double derivata_funzione_out = derivata_sigmoide(funzioni_attivazione[NUM_LAYERS - 1][0]); - // if (derivata_funzione_out == 0.0) derivata_funzione_out = 1; - - // Gradiente del percettrone output - gradienti[NUM_LAYERS - 1][0] = errore * derivata_funzione_out; - - //Crasha nella discesa del gradiente all'immagine indice 16 quando metto troppi percettroni - discesa_gradiente(rete_neurale, funzioni_attivazione, gradienti, TIPO_FUNZIONE); */ - double **gradienti = discesa_gradiente(rete_neurale, funzioni_attivazione, errore, TIPO_FUNZIONE); - - /* - ################# Aggiornamento dei pesi ################################ - */ - - /* - - **** SISTEMARE LA CORREZIONE IN VISTA DELLE ULTIME MODIFICHE PERCHÈ NON CORREGGE E MI SETTA TUTTI I PESI A NAN ***** - - */ - - 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++) - { - // 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; */ - - - - /* // Applico la correzione dal penultimo layer andando indietro fino al secondo (il primo si fa diverso) - for (int indice_layer = NUM_LAYERS - 2; 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) - { - correggi_pesi_percettrone_double(&rete_neurale.layers[indice_layer].percettroni[indice_percettrone], indice_layer, funzioni_attivazione, 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); - } - } - } */ + //debug_matrice(&rete_neurale, funzioni_attivazione); } errore_totale /= set.size; double percentuale = (corrette * 100) / set.size; printf("Errore: %f, accuratezza: %.2f%, corrette: %d\n", errore_totale, percentuale, corrette); - - // For di debug - /* for (int count = 0; count < rete_neurale.size; count++) - { - for (int count_2 = 0; count_2 < rete_neurale.layers[count].size; count_2++) - { - printf("[%d][%d]: %f\t", count, count_2, gradienti[count][count_2]); - } - printf("\n"); - } */ } // salvaReteNeurale(file_pesi, &rete_neurale); @@ -240,11 +134,6 @@ void stampa_tempo(time_t tempo_epoche[], int i) } } -void debug(int indice) -{ - printf("qui ci arrivo %d", indice); -} - /* if (i == MAX_EPOCHE - 1) { printf("\nUltima epoca (%d), stato della rete:\n", i); diff --git a/percettroni.h b/percettroni.h index 219fd53..c8197ba 100644 --- a/percettroni.h +++ b/percettroni.h @@ -49,13 +49,13 @@ ReteNeurale inizializza_rete_neurale_feed_forward(int, int, int); double funzione_attivazione_percettrone(Percettrone p, double*, int); -double **elabora_funzioni_attivazione(ReteNeurale*, Istanza, int); +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 aggiorna_pesi(ReteNeurale, double**, double**, Istanza); -void correggi_pesi_percettrone(Percettrone, double*, double); +void correggi_pesi_percettrone(Percettrone*, double*, double); //void correggi_pesi_percettrone_byte(Percettrone*, Istanza, double, int); int previsione(double); @@ -67,6 +67,10 @@ double derivata_relu(double); void salvaReteNeurale(const char *, ReteNeurale *); ReteNeurale *caricaReteNeurale(const char *); +void debug(double); +void debug_matrice(ReteNeurale*, double**); +void debug_vettore(double*, int); + /* ################# INIZIALIZZAZIONI E METODI UTILI ################################ */ @@ -171,26 +175,6 @@ double *get_double_from_bytes(Istanza istanza) { ################# FUNZIONI ATTIVAZIONE ################################ */ -//******************* I PESI SONO TUTTI NAN ******************************** - -//Tipo 1 = relu, tipo 2 = sigmoide -double funzione_attivazione_percettrone(Percettrone p, double *valori, int tipo) -{ - double sommatoria = 0.0; - for (int i = 0; i < p.size; i++) { - sommatoria += (valori[i] * p.pesi[i]); - //printf("valore [%f] peso[%f] ", valori[i], p.pesi[i]); - } - - sommatoria += p.bias; - //printf(" sommatoria %f\n",sommatoria); - - if(tipo == 1) - return relu(sommatoria); - - return sigmoide(sommatoria); -} - double sigmoide(double valore) { return 1.0 / (1.0 + exp(-valore)); } @@ -215,51 +199,64 @@ double derivata_relu(double valore) { //tipo_funzione 1: relu, 2:sigmoide -double **elabora_funzioni_attivazione(ReteNeurale *rete, Istanza istanza, int tipo_funzione) -{ - /* for(int xxx = 0; xxx < rete->size; xxx++) { - for (int count = 0; count < rete->layers[xxx].size; count++) - { - for (int count_2 = 0; count_2 < rete->layers[xxx].percettroni[count].size; count_2++) - { - printf("[%d][%d]: %f\t", count, count_2, rete->layers[xxx].percettroni[count].pesi[count_2]); - } - printf("\n"); - } - } */ +double **elabora_funzioni_attivazione(ReteNeurale rete, Istanza istanza, int tipo_funzione) +{ //Inizializzo il vettore bidimensionale che dovrò ritornare - double **funzioni = (double **)malloc(sizeof(double *) * rete->size); + double **funzioni = (double **)malloc(sizeof(double *) * rete.size); //Il primo layer devo farlo a parte perchè prende gli input dal dataset e non dal layer precedente - funzioni[0] = elabora_funzioni_attivazione_layer(rete->layers[0], get_double_from_bytes(istanza), tipo_funzione); + funzioni[0] = elabora_funzioni_attivazione_layer(rete.layers[0], get_double_from_bytes(istanza), tipo_funzione); - for(int indice_layer = 1; indice_layer < rete->size - 1; indice_layer ++) { - funzioni[indice_layer] = elabora_funzioni_attivazione_layer(rete->layers[indice_layer], funzioni[indice_layer-1], tipo_funzione); + for(int indice_layer = 1; indice_layer < rete.size - 1; indice_layer ++) { + funzioni[indice_layer] = elabora_funzioni_attivazione_layer(rete.layers[indice_layer], funzioni[indice_layer-1], tipo_funzione); } - funzioni[rete->size-1] = elabora_funzioni_attivazione_layer(rete->layers[rete->size-1], funzioni[rete->size-2], 2); + funzioni[rete.size-1] = elabora_funzioni_attivazione_layer(rete.layers[rete.size-1], funzioni[rete.size-2], 2); return funzioni; } + + //DA NAN double *elabora_funzioni_attivazione_layer(Layer layer, double *inputs, int tipo_funzione) { double *funzioni = (double *)malloc(sizeof(double) * layer.size); - for(int indice_percettrone = 0; indice_percettrone < layer.size; indice_percettrone ++) { + /* for(int indice_percettrone = 0; indice_percettrone < layer.size; indice_percettrone ++) { funzioni[indice_percettrone] = funzione_attivazione_percettrone(layer.percettroni[indice_percettrone], inputs, tipo_funzione); + } */ + + debug_vettore(funzioni, layer.percettroni->size); + return funzioni; +} + +//Tipo 1 = relu, tipo 2 = sigmoide +double funzione_attivazione_percettrone(Percettrone p, double *valori, int tipo) +{ + double sommatoria = 0.0; + for (int i = 0; i < p.size; i++) { + sommatoria += (valori[i] * p.pesi[i]); + //printf("valore [%f] peso[%f] ", valori[i], p.pesi[i]); } - return funzioni; + sommatoria += p.bias; + //printf(" sommatoria %f\n",sommatoria); + + if(tipo == 1) + //funzione = relu(sommatoria); + return relu(sommatoria); + else + //funzione = sigmoide(sommatoria); + return sigmoide(sommatoria); } /* ################# RETROPROPAGAZIONE ################################ */ -NON CALCOLA I GRADIENTI, PARTE DIRETTAMENTE NAN, VERIFICARE LA PRESENZA DI DATI IN FUNZIONI E LE FUNZIONI DI CALCOLO +//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) { @@ -268,8 +265,6 @@ 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--) { @@ -285,20 +280,11 @@ 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"); - } */ + //debug_matrice(&rete, gradienti); return gradienti; } @@ -318,6 +304,8 @@ double **discesa_gradiente(ReteNeurale rete, double **funzioni, double errore, i gradienti[0] = errore * derivata_funzione; + //debug_vettore(gradienti, layer.size); + return gradienti; } @@ -335,24 +323,13 @@ double calcola_gradiente_disceso(ReteNeurale rete, int livello, int indice_peso, return sommatoria * derivata_attivazione; } - /* ################# PREVISIONE E CORREZIONI ################################ */ 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"); - } - } */ + //debug_matrice(&rete_neurale, gradienti); // Applico la correzione dal penultimo layer andando indietro fino al secondo (il primo si fa diverso) for (int indice_layer = rete_neurale.size - 1; indice_layer >= 0; indice_layer--) @@ -363,15 +340,13 @@ void aggiorna_pesi(ReteNeurale rete_neurale, double **gradienti, double **funzio // Devo prendere il gradiente del percettrone e moltiplicarlo con gli input associati ai pesi if (indice_layer > 0) { - //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]); + 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(rete_neurale.layers[indice_layer].percettroni[indice_percettrone], get_double_from_bytes(istanza), gradienti[indice_layer][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"); } } @@ -387,42 +362,20 @@ int previsione(double valore) Al secondo giro diventa NAN */ -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[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.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(Percettrone *p, double *input, double gradiente_percettrone) { for (int indice_peso = 0; indice_peso < p->size; indice_peso++) { // Determino il gradiente del peso - double gradiente_peso = gradiente_percettrone * (double)input.dati[indice_peso]; + double gradiente_peso = gradiente_percettrone * input[indice_peso]; - // Modifico il peso Qui si impalla perchè per qualche ragione arriva size elevatissimo - p->pesi[indice_peso] += (gradiente_peso * LRE); + // Modifico il peso + p->pesi[indice_peso] = p->pesi[indice_peso] + (gradiente_peso * LRE); } - p->bias += (gradiente_percettrone * LRE); -} */ - - - + p->bias = p->bias + (gradiente_percettrone * LRE); + //printf("\n"); +} /* ################# IMPORT EXPORT ################################ @@ -520,156 +473,28 @@ ReteNeurale *caricaReteNeurale(const char *filename) - - - - -/* funzioni[indice_layer] = (double *)malloc(sizeof(double) * rete.layers[indice_layer].size); - for(int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone ++) { - //Se è il livello output in ogni caso deve fare sigmoide - if(indice_layer == rete.size-1) - funzioni[indice_layer][indice_percettrone] = funzione_attivazione(rete.layers[indice_layer].percettroni[indice_percettrone], funzioni[indice_layer-1], 2); - else - funzioni[indice_layer][indice_percettrone] = funzione_attivazione(rete.layers[indice_layer].percettroni[indice_percettrone], funzioni[indice_layer-1], tipo_funzione); - } */ - -/* double sigmoide_byte(Percettrone, byte *, int); -double sigmoide_double(Percettrone, double *, int); -double *funzioni_attivazione_layer_byte(Layer, byte *); -double *funzioni_attivazione_layer_double(Layer, double *); */ -/* void correggi_layer_interni(ReteNeurale *, double **, double **); -void correggi_layer_input(Layer *, double **, double **, byte *, int); */ -/* // Questa funzione calcola tutte le funzioni di attivazione dei percettroni del layer che prende dei byte come inputs -double *funzioni_attivazione_layer_byte(Layer layer, byte *inputs) +void debug(double valore) { - - double *funzioni = (double *)malloc(sizeof(double) * layer.size); - - for (int i = 0; i < layer.size; i++) - { - funzioni[i] = sigmoide_byte(layer.percettroni[i], inputs, layer.percettroni[i].size); - // printf("\tsigmoide layer input %f\n", funzioni[i]); - } - - return funzioni; + printf("valore: %f\n", valore); } -// Questa funzione calcola tutte le funzioni di attivazione dei percettroni del layer che prende dei double come inputs (le sigmoidi del livello precedente) -double *funzioni_attivazione_layer_double(Layer layer, double *inputs) +void debug_matrice(ReteNeurale *rete_neurale, double **matrice) { - - double *funzioni = (double *)malloc(sizeof(double) * layer.size); - - for (int i = 0; i < layer.size; i++) + for (int count = 0; count < rete_neurale->size; count++) { - funzioni[i] = sigmoide_double(layer.percettroni[i], inputs, layer.percettroni[i].size); - // printf("\tsigmoide layer %d: %f\n", i, funzioni[i]); - } - - return funzioni; -} - */ -/* // Questa funzione prende la matrice dei gradienti e la matrice delle sigmoidi per correggere tutti i layer tranne quello di ingresso -void correggi_layer_interni(ReteNeurale *rete, double **gradienti, double **sigmoidi) -{ - - for (int indice_layer = rete->size - 1; indice_layer > 0; indice_layer--) - { - for (int indice_percettrone = 0; indice_percettrone < rete->layers[indice_layer].size; indice_percettrone++) - { // Numero percettroni - - for (int indice_peso = 0; indice_peso < rete->layers[indice_layer].percettroni[indice_percettrone].size; indice_peso++) - { // Numero pesi - gradienti[indice_layer][indice_percettrone] = gradienti[rete->size - 1][0] * (sigmoidi[indice_layer][indice_percettrone] * (1 - sigmoidi[indice_layer][indice_percettrone])); - rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso] += (gradienti[indice_layer][indice_percettrone] * LRE * sigmoidi[indice_layer - 1][indice_percettrone]); - // rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso] += (gradienti[rete->size-1][0] * LRE * sigmoidi[indice_layer-1][indice_percettrone]); - } - rete->layers[indice_layer].percettroni[indice_percettrone].bias += (gradienti[indice_layer][indice_percettrone] * LRE); - // printf("bias: %f\n", rete->layers[indice_layer].percettroni[indice_percettrone].bias); - } - } -} -// Questa funzione prende tutti i parametri della precedente + gli input passati dal dataset per correggere il layer di ingresso -void correggi_layer_input(Layer *layer, double **gradienti, double **sigmoidi, byte *inputs, int n_layers) -{ - // L'indice del layer d'ingresso che prende byte per input - int indice_layer = 0; - for (int indice_percettrone = 0; indice_percettrone < layer->size; indice_percettrone++) - { // Numero percettroni - for (int indice_peso = 0; indice_peso < layer->percettroni->size; indice_peso++) - { // Numero pesi - - gradienti[indice_layer][indice_percettrone] = gradienti[n_layers - 1][0] * (sigmoidi[indice_layer][indice_percettrone] * (1 - sigmoidi[indice_layer][indice_percettrone])); - layer->percettroni[indice_percettrone].pesi[indice_peso] += (gradienti[indice_layer][indice_percettrone] * LRE * inputs[indice_peso]); - // layer->percettroni[indice_percettrone].pesi[indice_peso] += (gradienti[n_layers-1][0] * LRE * inputs[indice_peso]); - } - layer->percettroni[indice_percettrone].bias += (gradienti[n_layers - 1][0] * LRE); - } -} - */ -/* -// Questa funzione viene usata per il primo livello perchè ha un vettore di byte (unsigned char) in input -double sigmoide_byte(Percettrone p, byte *valori, int n_input) -{ - - double sommatoria = 0.0; - // printf("valori: [%d][%d]", valori[0], valori[1]); - // printf("pesi: [%f][%f]", p.pesi[0], p.pesi[1]); - - for (int i = 0; i < n_input; i++) - { - sommatoria += ((double)valori[i] * p.pesi[i]); - } - // printf("sommatoria= %f\n", sommatoria); - double funzione = sommatoria + p.bias; - double potenza_e = exp(-funzione); - // printf("potenza_e= %f\n", potenza_e); - // formula sigmoide - double risultato = 1.0 / (1.0 + potenza_e); - // printf("risultato= %f\n", risultato); - return risultato; -} - -// Questa funzione viene usata per gli altri livelli dove gli input sono double, ossia i valori della sigmoide dei livelli precedenti -double sigmoide_double(Percettrone p, double *valori, int n_input) -{ - double sommatoria = 0.0; - for (int i = 0; i < n_input; i++) - { - sommatoria += (valori[i] * p.pesi[i]); - } - - double funzione = sommatoria + p.bias; - // printf("sommatoria= %f\n", sommatoria); - double potenza_e = exp(-funzione); - // printf("potenza_e= %f\n", potenza_e); - // formula sigmoide - double risultato = 1.0 / (1.0 + potenza_e); - // printf("risultato= %f\n", risultato); - - return risultato; -} - */ - - -//void discesa_gradiente(ReteNeurale, double **, double **, int); -/* void discesa_gradiente(ReteNeurale rete, double **funzioni, double **gradienti, int tipo_derivata) -{ - for (int indice_layer = rete.size - 2; indice_layer >= 0; indice_layer--) - { - for (int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++) + for (int count_2 = 0; count_2 < rete_neurale->layers[count].size; count_2++) { - //In base al tipo di funzione scelto, avvio relu o sigmoidi - - double derivata_attivazione; - - if(tipo_derivata == 1) - derivata_attivazione = derivata_relu(funzioni[indice_layer][indice_percettrone]); - else - derivata_attivazione = derivata_sigmoide(funzioni[indice_layer][indice_percettrone]); - - // Passo anche l'indice del percettrone perchè corrisponde all'indice del peso del livello sopra - gradienti[indice_layer][indice_percettrone] = calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti, derivata_attivazione); + printf("[%d][%d]: %f\t", count, count_2, matrice[count][count_2]); } + printf("\n"); } -} */ \ No newline at end of file +} + +void debug_vettore(double *vettore, int size) +{ + for (int count_2 = 0; count_2 < size; count_2++) + { + printf("[%d]: %f\t", count_2, vettore[count_2]); + } + printf("\n"); +} diff --git a/prova_passaggio_parametri b/prova_passaggio_parametri new file mode 100755 index 0000000000000000000000000000000000000000..e10872c8a27a99c24fd5ef3032922eb8133a643a GIT binary patch literal 15672 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 UQNKPH