250 lines
8.5 KiB
Markdown
250 lines
8.5 KiB
Markdown
# 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. |