# 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. Questo progetto educativo dimostra i principi fondamentali del deep learning in modo trasparente e accessibile. 📖 **[Documentazione Completa della Libreria percettroni.h](percettroni_documentation.md)** ## Panoramica Questa implementazione supporta reti neurali feedforward completamente connesse con: - **Architettura dinamica**: Numero variabile di layer e neuroni per layer - **Funzioni di attivazione**: Sigmoide, ReLU o gradino (configurabile) - **Addestramento**: Backpropagation con discesa del gradiente stocastica - **Classificazione**: Softmax per problemi multi-classe - **Inizializzazione**: Strategia He per prevenire vanishing/exploding gradients ## Struttura del Progetto ``` . ├── classificatore.c # Programma principale di addestramento ├── percettroni.h # Libreria core della rete neurale (header-only) ├── percettroni_documentation.md # Documentazione completa della libreria ├── 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_mnist.bin # Pesi salvati dopo l'addestramento └── AGENTS.md # Guida per agenti di codifica ``` ## Compilazione e Esecuzione ### Classificatore MNIST (default) ```bash # Compila il classificatore gcc -o classificatore_mnist classificatore.c -lm # Esegue l'addestramento ./classificatore_mnist ``` ### Test XOR (validazione rapida) Per verificare rapidamente che la rete converga correttamente: 1. Modifica `percettroni.h`: - Commenta: `// #include "mnist/mnist_manager.h"` - Decommenta: `#include "xor_manager.h"` 2. Compila ed esegui: ```bash gcc -o classificatore_xor classificatore.c -lm ./classificatore_xor ``` ### Visualizzatore ```bash gcc -o visualizzatore visualizzatore.c -lalleg -lm ``` ## Configurazione dell'Addestramento ### Parametri Modificabili in `classificatore.c` ```c #define EPOCHE 500 // Numero massimo di epoche di addestramento void main() { // inizializza_rete_neurale(numero_input, numero_layers, percettroni_iniziali, percettroni_finali) ReteNeurale rete = inizializza_rete_neurale(N_INPUTS, 2, 32, 10); // ... } ``` **Parametri della rete neurale:** - `numero_input`: Dimensione dell'input (784 per MNIST, 3072 per CIFAR-10) - `numero_layers`: Numero totale di layer nella rete - `percettroni_iniziali`: Numero di neuroni nel primo layer nascosto - `percettroni_finali`: Numero di neuroni nell'ultimo layer (output) **Architettura automatica:** I layer intermedi riducono progressivamente i neuroni secondo la formula: ``` neuroni_layer[i] = percettroni_iniziali * ((numero_layers - i) / numero_layers) ``` ### Costanti Modificabili in `percettroni.h` ```c float LRE = 0.01; // Learning Rate (tasso di apprendimento) float soglia_sigmoide = 0.5; // Soglia per classificazione binaria #define TOLLERANZA 99.5 // Accuratezza % per arresto anticipato #define FUNZIONE_ATTIVAZIONE 1 // 0=sigmoide, 1=ReLU, 2=gradino char *file_pesi = "rete_mnist.bin"; // File per salvataggio pesi ``` ### Selezione del Dataset In `percettroni.h`, includi solo il manager del dataset desiderato: ```c // Per MNIST (attivo di default) #include "mnist/mnist_manager.h" // Per XOR (testing rapido) // #include "xor_manager.h" // Per CIFAR-10 // #include "cifar-10/cifar10_manager.h" ``` **Requisiti dei dataset:** - **MNIST**: File `t10k-images.idx3-ubyte` e `t10k-labels.idx1-ubyte` nella cartella `mnist/` - **CIFAR-10**: File binari appropriati nella cartella `cifar-10/` - **XOR**: Nessun file esterno richiesto (dataset hardcoded) ## Processo di Addestramento L'addestramento segue questo flusso completo: 1. **Inizializzazione**: Creazione della rete con pesi casuali (inizializzazione He) 2. **Ciclo per epoca**: Fino a `EPOCHE` massime o raggiungimento della `TOLLERANZA` 3. **Forward propagation**: Calcolo delle predizioni per ogni istanza 4. **Calcolo accuratezza**: Percentuale di predizioni corrette 5. **Backpropagation**: Calcolo dei gradienti dell'errore 6. **Aggiornamento pesi**: Discesa del gradiente stocastica 7. **Arresto anticipato**: Se accuratezza ≥ `TOLLERANZA` (99.5%) 8. **Salvataggio**: Scrittura dei pesi finali su `rete_mnist.bin` ### Output di Esempio ``` Layer 0 -> percettroni: 32 Layer 1 -> percettroni: 10 Rete neurale da 25354 parametri EPOCA 0 Risposte corrette: 12.34% EPOCA 1 Risposte corrette: 45.67% ... EPOCA 25 Risposte corrette: 99.60% ``` ## Caratteristiche Avanzate ### Funzioni di Attivazione Supportate **ReLU (default - più efficiente):** - Formula: `f(x) = max(0, x)` - Vantaggi: Nessun vanishing gradient, computazionalmente efficiente **Sigmoide:** - Formula: `f(x) = 1 / (1 + e^(-x))` - Uso: Tradizionale per output binari, ma soffre di vanishing gradient **Gradino:** - Formula: `f(x) = 1 se x > 0, altrimenti 0` - Limitazione: Non differenziabile, non utilizzabile con backpropagation ### Gestione della Memoria - **Allocazione dinamica**: Tutti gli array sono allocati dinamicamente - **Pulizia automatica**: La memoria viene liberata correttamente dopo ogni epoca - **Persistenza**: Supporto per salvataggio/caricamento di reti addestrate ### Debugging e Analisi ```bash # Ispezione dettagliata dei pesi // Decommenta in classificatore.c: stampa_pesi_rete(rete); # Controllo memory leak valgrind --leak-check=full ./classificatore_mnist # Monitoraggio performance time ./classificatore_mnist ``` ## Best Practice per l'Addestramento ### Scelta dell'Architettura - **Reti profonde** (>5 layer): Richiedono più dati e tempo di addestramento - **Reti larghe**: Più neuroni per layer aumentano la capacità ma anche l'overfitting - **Architettura a imbuto**: Riduzione progressiva dei neuroni è generalmente efficace ### Ottimizzazione degli Iperparametri - **Learning Rate**: - Troppo alto (>0.1): Instabilità, divergenza - Troppo basso (<0.001): Convergenza lenta - Valore consigliato: 0.01 (default) - **Numero di epoche**: Dipende dalla complessità del dataset - XOR: 100-500 epoche sufficienti - MNIST: 500+ epoche per buone prestazioni ### Prevenzione dell'Overfitting - **Arresto anticipato**: Implementato con soglia del 99.5% - **Dataset adeguato**: Utilizzare set di training/test separati - **Architettura semplice**: Evitare reti troppo complesse per il dataset ## Requisiti di Sistema - **Compilatore**: GCC o qualsiasi compilatore C standard - **Librerie**: math (`-lm`) obbligatoria, Allegro opzionale (solo visualizzatore) - **Memoria**: Dipende dall'architettura della rete (MNIST richiede ~100MB) - **Dataset**: MNIST (~11MB), CIFAR-10 (~160MB) ## Note Tecniche Importanti - **Normalizzazione input**: I valori pixel (0-255) vengono convertiti automaticamente in (0.0-1.0) - **Precisione**: Utilizzo di `float` per tutti i calcoli (bilancio tra precisione e memoria) - **Performance**: Implementazione CPU-only, ottimizzata per chiarezza piuttosto che velocità - **Determinismo**: Il seed random è basato su `time(NULL)`, quindi ogni esecuzione è diversa ## Risoluzione Problemi Comuni **"Errore nell'apertura del file"**: - Verifica che i file del dataset siano nella posizione corretta - Controlla i permessi di lettura **Addestramento troppo lento**: - Riduci il numero di layer/neuroni - Usa il dataset XOR per test rapidi - Verifica che il learning rate non sia troppo basso **Accuratezza bassa**: - Aumenta il numero di epoche - Prova architetture diverse - Verifica la qualità del dataset **Memory leak**: - Assicurati di usare `valgrind` per identificare problemi - La libreria gestisce correttamente la memoria in condizioni normali ## Estensioni Future - **Batch training**: Implementazione della discesa del gradiente mini-batch - **Regularizzazione**: Dropout, L1/L2 regularization - **Ottimizzatori avanzati**: Adam, RMSprop - **Convoluzioni**: Supporto per reti neurali convoluzionali (CNN) ## Licenza Progetto didattico - Implementazione from-scratch per scopi educativi. Libero da utilizzare per apprendimento e ricerca. --- 💡 **Suggerimento**: Consulta la [documentazione completa](percettroni_documentation.md) per comprendere le formule matematiche, gli algoritmi implementati e le proprietà teoriche di questa implementazione di rete neurale.