Files
classificatore_immagini/README.md
T

5.1 KiB
Raw Blame History

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)

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"
gcc -o classificatore_xor classificatore.c -lm
./classificatore_xor

Visualizzatore

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:

// 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.

#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:

// 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

# 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.