# Classificatore di Immagini con Rete Neurale Implementazione in C di una rete neurale from-scratch per la classificazione di immagini sui dataset MNIST e CIFAR-10. ## Panoramica Questo progetto implementa una rete neurale fully-connected con: - **Attivazione**: funzione sigmoide - **Addestramento**: backpropagation con discesa del gradiente - **Predizione**: softmax per classificazione multi-classe ## Struttura del Progetto ``` . ├── classificatore.c # Programma principale ├── percettroni.h # Libreria core della rete neurale (header-only) ├── xor_manager.h # Manager dataset XOR (4 campioni, test rapido) ├── mnist/ │ └── mnist_manager.h # Manager dataset MNIST (28x28 pixel) ├── cifar-10/ │ └── cifar10_manager.h # Manager dataset CIFAR-10 (32x32 RGB) ├── visualizzatore.c # Visualizzatore immagini (richiede Allegro) └── rete_pesi.bin # Pesi pre-addestrati ``` ## Compilazione ### Classificatore MNIST (default) ```bash gcc -o classificatore_mnist classificatore.c -lm ./classificatore_mnist ``` ### Test XOR (validazione rapida) Modifica `percettroni.h`: - Commenta: `// #include "mnist/mnist_manager.h"` - Decommenta: `#include "xor_manager.h"` ```bash gcc -o classificatore_xor classificatore.c -lm ./classificatore_xor ``` ### Visualizzatore ```bash gcc -o visualizzatore visualizzatore.c -lalleg -lm ``` ## Componenti Principali ### percettroni.h Libreria header-only che implementa la rete neurale completa. **Strutture dati:** - `Percettrone`: singolo neurone con pesi, bias e dimensione - `Layer`: strato di percettroni - `ReteNeurale`: rete completa con array di layer **Funzioni principali:** ```c // Inizializzazione ReteNeurale inizializza_rete_neurale(int numero_input, int numero_layers, int numero_percettroni_iniziali, int numero_percettroni_finali); // Forward propagation double **elabora_sigmoidi(ReteNeurale *rete, Istanza istanza); // Backpropagation double **elabora_gradienti(ReteNeurale *rete, byte output_corretto, double **sigmoidi); void aggiorna_pesi(ReteNeurale *rete, double **sigmoidi, double **gradienti, Istanza istanza); // Predizione int previsione_softmax(double *output, int size); // Persistenza void salvaReteNeurale(const char *filename, ReteNeurale *rete); ReteNeurale *caricaReteNeurale(const char *filename); ``` **Architettura dinamica:** I layer intermedi riducono progressivamente i percettroni secondo la formula: ``` percettroni = percettroni_iniziali * (layer_rimanenti / layer_totali) ``` ### classificatore.c Programma principale che configura e addestra la rete. ```c #define EPOCHE 50 void main() { // Rete: 784 input (MNIST), 10 layer, 256 percettroni iniziali, 10 output ReteNeurale rete = inizializza_rete_neurale(N_INPUTS, 10, 256, 10); Dataset mnist = *get_dataset(); for(int epoca = 0; epoca < EPOCHE; epoca++) { if (addestra(&rete, mnist)) break; // Stop se accuratezza 100% } } ``` ### Manager Dataset Ogni manager definisce: - `N_INPUTS`: dimensione input (es. 784 per MNIST 28x28) - `Istanza`: struct con `classificazione` e `dati[]` - `Dataset`: struct con array di istanze e dimensione - `get_dataset()`: funzione che carica i dati #### xor_manager.h Dataset semplice per test (4 campioni): - Input: 2 valori binari - Output: 1 valore (XOR) - Perfetto per verificare convergenza #### mnist/mnist_manager.h Dataset MNIST: - Input: 784 pixel (28×28) - Output: 10 classi (cifre 0-9) - Formato IDX: header binario + pixel raw - Supporta train (60k) e test (10k) set #### cifar-10/cifar10_manager.h Dataset CIFAR-10: - Input: 3072 valori (32×32 RGB) - Output: 10 classi (oggetti) - Formato binario: label + pixel RGB ## Configurazione Dataset In `percettroni.h`, includi il manager desiderato: ```c // Per MNIST #include "mnist/mnist_manager.h" // Per XOR (testing) // #include "xor_manager.h" // Per CIFAR-10 // #include "cifar-10/cifar10_manager.h" ``` ## Costanti Principali - `LRE = 0.1`: learning rate - `soglia_sigmoide = 0.5`: soglia per predizione binaria - `EPOCHE`: numero epoche addestramento ## Debugging ```bash # Ispezione pesi stampa_pesi_rete(&rete); # Controllo memory leak valgrind --leak-check=full ./classificatore_mnist # Monitoraggio training // Modifica addestra() per stampare errore per epoca ``` ## Note Tecniche - **Normalizzazione**: input byte (0-255) convertiti in double (0.0-1.0) - **Inizializzazione**: pesi casuali in [-1, 1] - **Attivazione**: sigmoide con formula `1/(1+e^(-x))` - **Softmax**: usato solo sull'output per probabilità multi-classe - **Prestazioni**: training CPU-intensive (minuti per epoca su MNIST) ## Esempio Output Training ``` Layer 0 -> percettroni: 256 Layer 1 -> percettroni: 230 ... Layer 9 -> percettroni: 10 Rete neurale da 123456 parametri Risposte corrette: 85% Risposte corrette: 92% ... ``` ## Requisiti - GCC o compilatore C compatibile - Libreria math (`-lm`) - Allegro (solo per visualizzatore) ## Licenza Progetto didattico - Implementazione from-scratch per scopi educativi.