From 37c01285ca0da1ab2e7619bb70fd171293982f60 Mon Sep 17 00:00:00 2001 From: mirimatcode Date: Wed, 25 Mar 2026 18:25:38 +0100 Subject: [PATCH] Aggiunto qualche printf --- classificatore.c | 2 +- percettroni.h | 98 ++++++++++++++++++++++++++--------------------- visualizzatore | Bin 22400 -> 31664 bytes visualizzatore.c | 14 ++++--- 4 files changed, 64 insertions(+), 50 deletions(-) diff --git a/classificatore.c b/classificatore.c index 993ae15..9684e97 100644 --- a/classificatore.c +++ b/classificatore.c @@ -11,7 +11,7 @@ void main() { Dataset mnist = *get_dataset(file_immagini, file_label); for(int epoca = 0; epoca < EPOCHE; epoca++) { - //printf("\nEPOCA %d\n", epoca); + printf("\nEPOCA %d\n", epoca); if (addestra(&rete, mnist)) break; } diff --git a/percettroni.h b/percettroni.h index 7b37cb5..f3923ce 100644 --- a/percettroni.h +++ b/percettroni.h @@ -15,7 +15,7 @@ char *file_pesi = "rete_mnist.bin"; // char *file_immagini = "cifar-10/data_batch_5.bin"; // char *file_immagini = "cifar-10/test_batch.bin"; -//#include "xor_manager.h" +// #include "xor_manager.h" typedef unsigned char byte; @@ -44,7 +44,7 @@ typedef struct /* * Genera un valore casuale nell'intervallo [-1, 1] per inizializzare pesi e bias. - * Usa rand() modulo 101 (0-100) convertito in decimale (0.00-1.00), + * Usa rand() modulo 101 (0-100) convertito in decimale (0.00-1.00), * poi scalato a [-1, 1] moltiplicando per 2 e sottraendo 1. */ double randomico(); @@ -62,7 +62,7 @@ Percettrone inzializza_percettrone(int); * - numero_layers: quanti strati nascosti + strato di output * - numero_percettroni_iniziali: percettroni nel primo layer * - numero_percettroni_finali: percettroni nell'output (10 per MNIST, 1 per XOR) - * + * * I layer intermedi hanno numero decrescente di percettroni calcolato come: * numero_percettroni = numero_percettroni_iniziali * (layer_rimanenti / layer_totali) * Questo crea una piramide: molti neuroni in ingresso, pochi in uscita. @@ -102,12 +102,12 @@ void softmax(double *, int); /* * Forward propagation: calcola gli output di tutti i layer partendo dall'input. - * + * * Algoritmo: * 1. Converte i byte input (0-255) in double normalizzati (0.0-1.0) dividendo per 255 * 2. Per il primo layer: applica sigmoide a ogni percettrone usando gli input * 3. Per i layer successivi: usa gli output del layer precedente come input - * + * * Restituisce una matrice sigmoidi[layer][percettrone] con tutti i valori intermedi. * Questi valori servono poi per il calcolo dei gradienti (backpropagation). */ @@ -115,31 +115,31 @@ double **elabora_sigmoidi(ReteNeurale *, Istanza); /* * Calcola i gradienti dell'errore per ogni percettrone usando backpropagation. - * + * * Passaggi: * 1. GRADIENTI OUTPUT (ultimo layer): * - Se il percettrone corrisponde alla classe corretta: errore = 1 - output * - Altrimenti: errore = 0 - output * - Moltiplica errore per derivata_sigmoide(output) per ottenere il gradiente - * + * * 2. GRADIENTI NASCOSTI (layer precedenti): * - Usa discesa_gradiente() per propagare l'errore all'indietro * - Ogni neurone riceve la somma pesata dei gradienti dei neuroni successivi - * + * * Il gradiente indica quanto e in che direzione modificare i pesi per ridurre l'errore. */ double **elabora_gradienti(ReteNeurale *, byte, double **); /* * Propaga i gradienti dagli output verso i layer precedenti (backpropagation). - * + * * Per ogni layer (dall'ultimo al primo): * - Per ogni percettrone del layer corrente: * 1. Calcola derivata_sigmoide dell'output del percettrone * 2. Calcola gradiente_disceso: somma pesata dei gradienti del layer successivo * moltiplicati per i pesi delle connessioni * 3. Il gradiente finale = gradiente_disceso * derivata_sigmoide - * + * * Questo è l'algoritmo della "catena" di derivate (chain rule) del calcolo differenziale. */ void discesa_gradiente(ReteNeurale *, double **, double **); @@ -150,21 +150,21 @@ void discesa_gradiente(ReteNeurale *, double **, double **); * Questo è il "peso" dell'errore che deve essere corretto a questo livello. */ double calcola_gradiente_disceso(ReteNeurale *, int, int, double **); -//double trova_gradiente_errore_softmax(double *, int , int); +// double trova_gradiente_errore_softmax(double *, int , int); /* * Aggiorna tutti i pesi della rete usando i gradienti calcolati (discesa del gradiente). - * + * * Formula di aggiornamento: peso_nuovo = peso_vecchio + (gradiente * learning_rate) - * + * * Per l'ultimo layer: * - gradiente_peso = gradiente_percettrone * output_layer_precedente * - Aggiorna pesi e bias - * + * * Per i layer nascosti: * - Usa correggi_pesi_percettrone_double() per layer interni (input da double) * - Usa correggi_pesi_percettrone_byte() per primo layer (input da byte originale) - * + * * Il learning rate (LRE) controlla la "velocità" di apprendimento. */ void aggiorna_pesi(ReteNeurale *, double **, double **, Istanza); @@ -201,7 +201,7 @@ int previsione_softmax(double *, int); * - Numero di layer * - Per ogni layer: numero di percettroni * - Per ogni percettrone: numero di pesi, array pesi, bias - * + * * Il formato binario permette di ricaricare il modello addestrato * senza dover ripetere l'allenamento. */ @@ -210,7 +210,7 @@ void salvaReteNeurale(const char *, ReteNeurale *); /* * Carica una rete neurale da file binario. * Legge la struttura e alloca dinamicamente tutta la memoria necessaria. - * + * * Restituisce NULL se il file non esiste o c'è un errore di allocazione. */ ReteNeurale *caricaReteNeurale(const char *); @@ -274,18 +274,21 @@ ReteNeurale inizializza_rete_neurale(int numero_input, int numero_layers, int nu if (livello == numero_layers - 1) numero_percettroni_livello = numero_percettroni_finali; - else { - double frazione = (double) (numero_layers - livello) / (double) numero_layers; + else + { + double frazione = (double)(numero_layers - livello) / (double)numero_layers; numero_percettroni_livello = (int)((double)(numero_percettroni_iniziali * frazione)); } printf("Layer %d -> percettroni: %d\n", livello, numero_percettroni_livello); - if (livello == 0) { + if (livello == 0) + { r.layers[livello] = inizializza_layer(numero_percettroni_livello, numero_input); somma_parametri += (numero_percettroni_livello * numero_input); } - else { + else + { r.layers[livello] = inizializza_layer(numero_percettroni_livello, r.layers[livello - 1].size); somma_parametri += (numero_percettroni_livello * r.layers[livello - 1].size); } @@ -309,12 +312,15 @@ double **elabora_gradienti(ReteNeurale *rete_neurale, byte output_corretto, doub gradienti[indice_layer] = (double *)malloc(sizeof(double) * rete_neurale->layers[indice_layer].size); } - for(int indice_percettrone = 0; indice_percettrone < rete_neurale->layers[rete_neurale->size - 1].size; indice_percettrone++) { + for (int indice_percettrone = 0; indice_percettrone < rete_neurale->layers[rete_neurale->size - 1].size; indice_percettrone++) + { double gradiente_errore = 0.0; - if(indice_percettrone == output_corretto) { + if (indice_percettrone == output_corretto) + { gradiente_errore = 1 - sigmoidi[rete_neurale->size - 1][indice_percettrone]; } - else { + else + { gradiente_errore = 0 - sigmoidi[rete_neurale->size - 1][indice_percettrone]; } @@ -337,10 +343,10 @@ double sigmoide(Percettrone p, double *valori) sommatoria += p.bias; - //Sigmoide + // Sigmoide double risultato = 1.0 / (1.0 + exp(-sommatoria)); - //ReLU - //double risultato = sommatoria > 0 ? sommatoria : 0.0f; + // ReLU + // double risultato = sommatoria > 0 ? sommatoria : 0.0f; // printf(" sommatoria %f -> %f\n",sommatoria, risultato); @@ -349,19 +355,21 @@ double sigmoide(Percettrone p, double *valori) double derivata_sigmoide(double valore) { - double derivata = valore * (1.0 - valore); + double derivata = valore * (1.0 - valore); return derivata; } -void softmax(double *input, int size) { +void softmax(double *input, int size) +{ float max = input[0]; for (int i = 1; i < size; i++) if (input[i] > max) max = input[i]; - + float sum = 0.0f; - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) + { input[i] = expf(input[i] - max); sum += input[i]; } @@ -378,13 +386,15 @@ int previsione(double valore) return 0; } -int previsione_softmax(double *livello_percettroni, int size) { +int previsione_softmax(double *livello_percettroni, int size) +{ softmax(livello_percettroni, size); int max = 0; - - for(int i = 1; i < size; i++) { - if(livello_percettroni[i] > livello_percettroni[max]) + + for (int i = 1; i < size; i++) + { + if (livello_percettroni[i] > livello_percettroni[max]) max = i; } @@ -397,7 +407,7 @@ void discesa_gradiente(ReteNeurale *rete, double **sigmoidi, double **gradienti) { for (int indice_percettrone = 0; indice_percettrone < rete->layers[indice_layer].size; indice_percettrone++) { - double derivata_attivazione = derivata_sigmoide(sigmoidi[indice_layer][indice_percettrone]); + double derivata_attivazione = derivata_sigmoide(sigmoidi[indice_layer][indice_percettrone]); double gradiente_disceso = calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti); gradienti[indice_layer][indice_percettrone] = gradiente_disceso * derivata_attivazione; @@ -452,7 +462,8 @@ double **elabora_sigmoidi(ReteNeurale *rete, Istanza istanza) void aggiorna_pesi(ReteNeurale *rete_neurale, double **sigmoidi, double **gradienti, Istanza istanza) { - for(int indice_percettrone = 0; indice_percettrone < rete_neurale->layers[rete_neurale->size - 1].size; indice_percettrone++) { + for (int indice_percettrone = 0; indice_percettrone < rete_neurale->layers[rete_neurale->size - 1].size; indice_percettrone++) + { for (int indice_peso = 0; indice_peso < rete_neurale->layers[rete_neurale->size - 1].percettroni[indice_percettrone].size; indice_peso++) { @@ -514,25 +525,26 @@ char addestra(ReteNeurale *rete_neurale, Dataset set) byte output_corretto = set.istanze[indice_set].classificazione; double **sigmoidi = elabora_sigmoidi(rete_neurale, set.istanze[indice_set]); - + double *sigmoidi_softmax = (double *)malloc(sizeof(double) * rete_neurale->layers[rete_neurale->size - 1].size); memcpy(sigmoidi_softmax, sigmoidi[rete_neurale->size - 1], rete_neurale->layers[rete_neurale->size - 1].size * sizeof(double)); - + double **gradienti = elabora_gradienti(rete_neurale, output_corretto, sigmoidi); int previsto = previsione_softmax(sigmoidi_softmax, rete_neurale->layers[rete_neurale->size - 1].size); - if (previsto == output_corretto) { + if (previsto == output_corretto) + { corrette++; } aggiorna_pesi(rete_neurale, sigmoidi, gradienti, set.istanze[indice_set]); - for(int i = 0; i < rete_neurale->size; i++) + for (int i = 0; i < rete_neurale->size; i++) free(gradienti[i]); free(gradienti); - for(int i = 0; i < rete_neurale->size; i++) + for (int i = 0; i < rete_neurale->size; i++) free(sigmoidi[i]); free(sigmoidi); free(sigmoidi_softmax); @@ -542,7 +554,7 @@ char addestra(ReteNeurale *rete_neurale, Dataset set) printf("Risposte corrette: %d%%\n", percentuale); - if(percentuale >= TOLLERANZA) + if (percentuale >= TOLLERANZA) return 1; else return 0; diff --git a/visualizzatore b/visualizzatore index baf3aab0115362a7f9de35f63fcbd08d11c1d2f3..ae7838e495580c97463328ada0d5a2222a6a464e 100755 GIT binary patch literal 31664 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 literal 22400 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[indice_set].classificazione, prevedi(indice_set)); + printf("Immagine indice: %d, valore: %d. valore previsto: %d\n", indice_set, set->istanze[indice_set].classificazione, prevedi(indice_set)); // Itera su ogni pixel dell'immagine for (int y = 0; y < IMAGE_HEIGHT; y++) @@ -165,16 +165,18 @@ void evento_click_bottone(int indice_set) int prevedi(int indice_set) { - double **sigmoidi = elabora_sigmoidi(*rete_neurale, set->istanze[indice_set]); + double *sigmoidi_softmax = elabora_sigmoidi(rete_neurale, set->istanze[indice_set])[rete_neurale->size-1]; - byte output_corretto = get_out_corretto(set->istanze[indice_set].classificazione); + byte output_corretto = set->istanze[indice_set].classificazione; - return previsione(sigmoidi[rete_neurale->size - 1][0]); + int previsto = previsione_softmax(sigmoidi_softmax, rete_neurale->layers[rete_neurale->size - 1].size); + + return previsto; } -byte get_out_corretto(byte categoria) { +/* byte get_out_corretto(byte categoria) { if(categoria == CATEGORIA) return 1; else return 0; -} \ No newline at end of file +} */ \ No newline at end of file