aggiornato readme e documentazione con ai

This commit is contained in:
2026-03-27 17:07:20 +01:00
parent 7aac8ceac2
commit 4b652b4e4d
7 changed files with 430 additions and 137 deletions
+174 -123
View File
@@ -1,42 +1,54 @@
# 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.
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
Questo progetto implementa una rete neurale fully-connected con:
- **Attivazione**: funzione sigmoide
- **Addestramento**: backpropagation con discesa del gradiente
- **Predizione**: softmax per classificazione multi-classe
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
├── 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_pesi.bin # Pesi pre-addestrati
── rete_mnist.bin # Pesi salvati dopo l'addestramento
└── AGENTS.md # Guida per agenti di codifica
```
## Compilazione
## 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)
Modifica `percettroni.h`:
- Commenta: `// #include "mnist/mnist_manager.h"`
- Decommenta: `#include "xor_manager.h"`
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
@@ -47,153 +59,192 @@ gcc -o classificatore_xor classificatore.c -lm
gcc -o visualizzatore visualizzatore.c -lalleg -lm
```
## Componenti Principali
## Configurazione dell'Addestramento
### 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:**
### Parametri Modificabili in `classificatore.c`
```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
#define EPOCHE 500 // Numero massimo di epoche di addestramento
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%
}
// inizializza_rete_neurale(numero_input, numero_layers, percettroni_iniziali, percettroni_finali)
ReteNeurale rete = inizializza_rete_neurale(N_INPUTS, 2, 32, 10);
// ...
}
```
### Manager Dataset
**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)
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
**Architettura automatica:** I layer intermedi riducono progressivamente i neuroni secondo la formula:
```
neuroni_layer[i] = percettroni_iniziali * ((numero_layers - i) / numero_layers)
```
#### 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:
### Costanti Modificabili in `percettroni.h`
```c
// Per MNIST
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)
// Per XOR (testing rapido)
// #include "xor_manager.h"
// Per CIFAR-10
// #include "cifar-10/cifar10_manager.h"
```
## Costanti Principali
**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)
- `LRE = 0.1`: learning rate
- `soglia_sigmoide = 0.5`: soglia per predizione binaria
- `EPOCHE`: numero epoche addestramento
## Processo di Addestramento
## Debugging
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 pesi
stampa_pesi_rete(&rete);
# Ispezione dettagliata dei pesi
// Decommenta in classificatore.c: stampa_pesi_rete(rete);
# Controllo memory leak
valgrind --leak-check=full ./classificatore_mnist
# Monitoraggio training
// Modifica addestra() per stampare errore per epoca
# Monitoraggio performance
time ./classificatore_mnist
```
## Note Tecniche
## Best Practice per l'Addestramento
- **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)
### 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
## Esempio Output Training
### 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
```
Layer 0 -> percettroni: 256
Layer 1 -> percettroni: 230
...
Layer 9 -> percettroni: 10
Rete neurale da 123456 parametri
Risposte corrette: 85%
Risposte corrette: 92%
...
```
### 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
## Requisiti di Sistema
- GCC o compilatore C compatibile
- Libreria math (`-lm`)
- Allegro (solo per visualizzatore)
- **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.
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.