diff --git a/addestratore.sh b/addestratore.sh new file mode 100755 index 0000000..b73cc9f --- /dev/null +++ b/addestratore.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +contatore=0 + +while [ $contatore -lt 10 ] +do + echo "Parto con l'addestramento" + ./classificatore_singolo_mnist >> ciclo_addestramento_$contatore.txt + contatore=`expr $contatore + 1` + echo "Fine ciclo addestramento $contatore" + sleep 2m +done diff --git a/ciclo_addestramento_0.txt b/ciclo_addestramento_0.txt new file mode 100644 index 0000000..02f2d86 --- /dev/null +++ b/ciclo_addestramento_0.txt @@ -0,0 +1,200 @@ +Caricate impostazioni rete neurale da file +Numero elementi nel dataset: 60000 +Epoca 0 +Errore: 0.036221, risposte corrette: 96% +Epoca 1 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 0:31 +Errore: 0.036884, risposte corrette: 95% +Epoca 2 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 1:3 +Errore: 0.035890, risposte corrette: 96% +Epoca 3 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 1:34 +Errore: 0.036380, risposte corrette: 96% +Epoca 4 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 2:5 +Errore: 0.036256, risposte corrette: 95% +Epoca 5 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 2:37 +Errore: 0.036077, risposte corrette: 96% +Epoca 6 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 3:8 +Errore: 0.036191, risposte corrette: 95% +Epoca 7 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 3:40 +Errore: 0.036500, risposte corrette: 96% +Epoca 8 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 4:11 +Errore: 0.036235, risposte corrette: 96% +Epoca 9 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 4:43 +Errore: 0.035910, risposte corrette: 96% +Epoca 10 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 5:14 +Errore: 0.036595, risposte corrette: 96% +Epoca 11 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 5:45 +Errore: 0.036101, risposte corrette: 96% +Epoca 12 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 6:17 +Errore: 0.037006, risposte corrette: 95% +Epoca 13 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 6:48 +Errore: 0.036310, risposte corrette: 96% +Epoca 14 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 7:20 +Errore: 0.036653, risposte corrette: 95% +Epoca 15 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 7:51 +Errore: 0.036671, risposte corrette: 95% +Epoca 16 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 8:23 +Errore: 0.036005, risposte corrette: 96% +Epoca 17 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 8:54 +Errore: 0.035876, risposte corrette: 96% +Epoca 18 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 9:25 +Errore: 0.036562, risposte corrette: 95% +Epoca 19 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 9:57 +Errore: 0.035936, risposte corrette: 96% +Epoca 20 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 10:28 +Errore: 0.036783, risposte corrette: 95% +Epoca 21 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 11:0 +Errore: 0.036031, risposte corrette: 96% +Epoca 22 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 11:31 +Errore: 0.036080, risposte corrette: 95% +Epoca 23 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 12:2 +Errore: 0.036065, risposte corrette: 96% +Epoca 24 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 12:34 +Errore: 0.036156, risposte corrette: 96% +Epoca 25 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 13:5 +Errore: 0.035987, risposte corrette: 96% +Epoca 26 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 13:37 +Errore: 0.036270, risposte corrette: 96% +Epoca 27 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 14:8 +Errore: 0.035895, risposte corrette: 96% +Epoca 28 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 14:40 +Errore: 0.036890, risposte corrette: 95% +Epoca 29 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 15:11 +Errore: 0.037329, risposte corrette: 95% +Epoca 30 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 15:42 +Errore: 0.036398, risposte corrette: 95% +Epoca 31 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 16:14 +Errore: 0.035868, risposte corrette: 96% +Epoca 32 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 16:45 +Errore: 0.036742, risposte corrette: 96% +Epoca 33 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 17:17 +Errore: 0.036120, risposte corrette: 96% +Epoca 34 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 17:48 +Errore: 0.035737, risposte corrette: 96% +Epoca 35 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 18:20 +Errore: 0.035885, risposte corrette: 96% +Epoca 36 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 18:51 +Errore: 0.036042, risposte corrette: 96% +Epoca 37 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 19:22 +Errore: 0.036020, risposte corrette: 96% +Epoca 38 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 19:54 +Errore: 0.035933, risposte corrette: 96% +Epoca 39 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 20:25 +Errore: 0.036811, risposte corrette: 95% +Epoca 40 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 20:57 +Errore: 0.036528, risposte corrette: 95% +Epoca 41 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 21:28 +Errore: 0.036102, risposte corrette: 96% +Epoca 42 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 22:0 +Errore: 0.036159, risposte corrette: 96% +Epoca 43 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 22:31 +Errore: 0.037031, risposte corrette: 95% +Epoca 44 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 23:2 +Errore: 0.036231, risposte corrette: 96% +Epoca 45 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 23:34 +Errore: 0.037214, risposte corrette: 95% +Epoca 46 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 24:5 +Errore: 0.035984, risposte corrette: 96% +Epoca 47 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 24:37 +Errore: 0.036427, risposte corrette: 95% +Epoca 48 +Tempo dall'epoca precedente: 0:31 +Tempo dall'inizio: 25:8 +Errore: 0.035916, risposte corrette: 96% +Epoca 49 +Tempo dall'epoca precedente: 0:32 +Tempo dall'inizio: 25:40 +Errore: 0.036036, risposte corrette: 96% diff --git a/classificatore_singolo b/classificatore_singolo deleted file mode 100755 index d10d990..0000000 Binary files a/classificatore_singolo and /dev/null differ diff --git a/classificatore_singolo.c b/classificatore_singolo.c index 4a16460..77c0d68 100644 --- a/classificatore_singolo.c +++ b/classificatore_singolo.c @@ -5,7 +5,7 @@ #define CATEGORIA 7 #define NUM_LAYERS 7 #define PERCETTRONI_LAYER_0 128 -#define MAX_EPOCHE 10 +#define MAX_EPOCHE 50 byte get_out_corretto(byte); void stampa_layer_indirizzo(Layer *); @@ -17,7 +17,7 @@ void main() srand(time(NULL)); - Dataset *set_appoggio = get_dataset(file_immagini);//get_dataset(file_immagini, file_label); + Dataset *set_appoggio = get_dataset(file_immagini, file_label); //get_dataset(file_immagini); if (set_appoggio == NULL) return; @@ -116,4 +116,4 @@ void stampa_tempo(time_t tempo_epoche[], int i) printf("Tempo dall'epoca precedente: %d:%d\n", minuti_epoca, secondi_epoca); printf("Tempo dall'inizio: %d:%d\n", minuti_totali, secondi_totali); } -} \ No newline at end of file +} diff --git a/classificatore_singolo_mnist b/classificatore_singolo_mnist new file mode 100755 index 0000000..a8d1425 Binary files /dev/null and b/classificatore_singolo_mnist differ diff --git a/deep_seek b/deep_seek deleted file mode 100755 index a167f8a..0000000 Binary files a/deep_seek and /dev/null differ diff --git a/deep_seek.c b/deep_seek.c deleted file mode 100644 index c22f2dc..0000000 --- a/deep_seek.c +++ /dev/null @@ -1,304 +0,0 @@ -#include -#include -#include -#include -#include "cifar-10/cifar10_manager.h" - -// Costanti configurabili -#define N_LAYERS 3 // Numero di layer (input, hidden, output) -#define N_NEURONI_HIDDEN 128 // Numero di neuroni nei layer nascosti -#define N_NEURONI_OUTPUT 10 // Numero di neuroni nel layer di output (10 classi) -#define N_EPOCHE 10 // Numero di epoche di addestramento -#define LEARNING_RATE 0.01 // Tasso di apprendimento -#define N_INPUTS 3072 // Dimensioni di un'immagine CIFAR-10 (32x32x3) - -// Strutture dati -/* typedef unsigned char byte; - -typedef struct { - byte classificazione; - byte dati[N_INPUTS]; -} Istanza; - -typedef struct { - int size; - Istanza *istanze; -} Dataset; */ - -typedef struct { - double *pesi; - double bias; - int size; -} Percettrone; - -typedef struct { - Percettrone *percettroni; - int size; -} Layer; - -typedef struct { - Layer *layers; - int size; -} ReteNeurale; - -double sigmoide(double); -double relu(double); -double relu_derivata(double); -double softmax(double*, int, int); -ReteNeurale crea_rete(); -double *prevedi(ReteNeurale*, byte*); -void allena(ReteNeurale*, Dataset*); -void salva_rete(ReteNeurale*, const char*); -ReteNeurale carica_rete(const char*); -void carica_immagini_casuali(Dataset*, byte[][N_INPUTS], byte*); -void fai_previsioni(ReteNeurale*, byte[][N_INPUTS], byte*); -void backpropagation(ReteNeurale*, byte*, byte, double*); -double *forward_pass(ReteNeurale*, byte*); - -// Funzioni di utilità -double sigmoide(double x) { - return 1.0 / (1.0 + exp(-x)); -} - -double relu(double x) { - return x > 0 ? x : 0; -} - -double relu_derivata(double x) { - return x > 0 ? 1 : 0; -} - -double softmax(double *x, int index, int size) { - double max = x[0]; - for (int i = 1; i < size; i++) { - if (x[i] > max) max = x[i]; - } - double sum = 0.0; - for (int i = 0; i < size; i++) { - sum += exp(x[i] - max); - } - return exp(x[index] - max) / sum; -} - -// Inizializzazione della rete -ReteNeurale crea_rete() { - ReteNeurale rete; - rete.size = N_LAYERS; - rete.layers = (Layer *)malloc(N_LAYERS * sizeof(Layer)); - - // Layer di input (non ha pesi, solo pass-through) - rete.layers[0].size = N_INPUTS; - rete.layers[0].percettroni = NULL; - - // Layer nascosto - rete.layers[1].size = N_NEURONI_HIDDEN; - rete.layers[1].percettroni = (Percettrone *)malloc(N_NEURONI_HIDDEN * sizeof(Percettrone)); - for (int i = 0; i < N_NEURONI_HIDDEN; i++) { - rete.layers[1].percettroni[i].size = N_INPUTS; - rete.layers[1].percettroni[i].pesi = (double *)malloc(N_INPUTS * sizeof(double)); - for (int j = 0; j < N_INPUTS; j++) { - rete.layers[1].percettroni[i].pesi[j] = ((double)rand() / RAND_MAX) * 2 - 1; // Pesi casuali tra -1 e 1 - } - rete.layers[1].percettroni[i].bias = ((double)rand() / RAND_MAX) * 2 - 1; // Bias casuale tra -1 e 1 - } - - // Layer di output - rete.layers[2].size = N_NEURONI_OUTPUT; - rete.layers[2].percettroni = (Percettrone *)malloc(N_NEURONI_OUTPUT * sizeof(Percettrone)); - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - rete.layers[2].percettroni[i].size = N_NEURONI_HIDDEN; - rete.layers[2].percettroni[i].pesi = (double *)malloc(N_NEURONI_HIDDEN * sizeof(double)); - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - rete.layers[2].percettroni[i].pesi[j] = ((double)rand() / RAND_MAX) * 2 - 1; // Pesi casuali tra -1 e 1 - } - rete.layers[2].percettroni[i].bias = ((double)rand() / RAND_MAX) * 2 - 1; // Bias casuale tra -1 e 1 - } - - return rete; -} - -// Funzione per la previsione -double *prevedi(ReteNeurale *rete, byte *input) { - double *output = (double *)malloc(N_NEURONI_OUTPUT * sizeof(double)); - // Implementazione del forward pass - // (Da completare) - return output; -} - -// Funzione per l'addestramento -void allena(ReteNeurale *rete, Dataset *dataset) { - printf("Sono dentro l'allenamento\n"); - for (int epoca = 0; epoca < N_EPOCHE; epoca++) { - printf("Epoca %d\n", epoca); - for (int i = 0; i < dataset->size; i++) { - byte *input = dataset->istanze[i].dati; - byte target = dataset->istanze[i].classificazione; - - // Forward pass - double *output_final = forward_pass(rete, input); - - // Backpropagation - backpropagation(rete, input, target, output_final); - - free(output_final); - } - } -} - -// Forward pass -double *forward_pass(ReteNeurale *rete, byte *input) { - double *output_hidden = (double *)malloc(N_NEURONI_HIDDEN * sizeof(double)); - double *output_final = (double *)malloc(N_NEURONI_OUTPUT * sizeof(double)); - - // Layer nascosto - for (int i = 0; i < N_NEURONI_HIDDEN; i++) { - double somma = 0.0; - for (int j = 0; j < N_INPUTS; j++) { - somma += input[j] * rete->layers[1].percettroni[i].pesi[j]; - } - somma += rete->layers[1].percettroni[i].bias; - output_hidden[i] = relu(somma); // Applica ReLU - } - - // Layer di output - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - double somma = 0.0; - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - somma += output_hidden[j] * rete->layers[2].percettroni[i].pesi[j]; - } - somma += rete->layers[2].percettroni[i].bias; - output_final[i] = somma; // Non applica softmax qui, verrà fatto durante la loss - } - - free(output_hidden); - return output_final; -} - -// Backpropagation -void backpropagation(ReteNeurale *rete, byte *input, byte target, double *output_final) { - // Calcola la softmax e la loss (cross-entropy) - double softmax_output[N_NEURONI_OUTPUT]; - double sum_exp = 0.0; - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - sum_exp += exp(output_final[i]); - } - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - softmax_output[i] = exp(output_final[i]) / sum_exp; - } - - // Gradiente della loss rispetto all'output - double grad_output[N_NEURONI_OUTPUT]; - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - grad_output[i] = softmax_output[i] - (i == target ? 1 : 0); - } - - // Gradiente rispetto ai pesi e bias del layer di output - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - rete->layers[2].percettroni[i].pesi[j] -= LEARNING_RATE * grad_output[i] * output_final[j]; - } - rete->layers[2].percettroni[i].bias -= LEARNING_RATE * grad_output[i]; - } - - // Gradiente rispetto ai pesi e bias del layer nascosto - double grad_hidden[N_NEURONI_HIDDEN]; - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - grad_hidden[j] = 0.0; - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - grad_hidden[j] += grad_output[i] * rete->layers[2].percettroni[i].pesi[j]; - } - grad_hidden[j] *= relu_derivata(output_final[j]); // Derivata di ReLU - } - - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - for (int k = 0; k < N_INPUTS; k++) { - rete->layers[1].percettroni[j].pesi[k] -= LEARNING_RATE * grad_hidden[j] * input[k]; - } - rete->layers[1].percettroni[j].bias -= LEARNING_RATE * grad_hidden[j]; - } -} - -// Serializzazione della rete -void salva_rete(ReteNeurale *rete, const char *filename) { - FILE *file = fopen(filename, "wb"); - if (file == NULL) { - perror("Errore nell'apertura del file"); - return; - } - fwrite(rete, sizeof(ReteNeurale), 1, file); - fclose(file); -} - -// Deserializzazione della rete -ReteNeurale carica_rete(const char *filename) { - FILE *file = fopen(filename, "rb"); - if (file == NULL) { - perror("Errore nell'apertura del file"); - exit(1); - } - ReteNeurale rete; - fread(&rete, sizeof(ReteNeurale), 1, file); - fclose(file); - return rete; -} - -// Funzione per caricare 4 immagini casuali dal dataset -void carica_immagini_casuali(Dataset *dataset, byte immagini[4][N_INPUTS], byte *etichette) { - for (int i = 0; i < 4; i++) { - int indice_casuale = rand() % dataset->size; // Sceglie un'immagine casuale - for (int j = 0; j < N_INPUTS; j++) { - immagini[i][j] = dataset->istanze[indice_casuale].dati[j]; // Copia i dati dell'immagine - } - etichette[i] = dataset->istanze[indice_casuale].classificazione; // Copia l'etichetta - } -} - -// Funzione per fare previsioni su 4 immagini -void fai_previsioni(ReteNeurale *rete, byte immagini[4][N_INPUTS], byte *etichette) { - for (int i = 0; i < 4; i++) { - double *output = prevedi(rete, immagini[i]); // Passa l'immagine attraverso la rete - int previsione = 0; - double max_prob = output[0]; - for (int j = 1; j < N_NEURONI_OUTPUT; j++) { - if (output[j] > max_prob) { - max_prob = output[j]; - previsione = j; - } - } - printf("Immagine %d: Etichetta vera = %d, Previsione = %d\n", i + 1, etichette[i], previsione); - free(output); // Libera la memoria allocata per l'output - } -} - -int main() { - srand(time(NULL)); - - printf("Mi appresto a caricare la rete\n"); - // Creazione della rete - ReteNeurale rete = crea_rete(); - - printf("Mi appresto a caricare il dataset\n"); - // Caricamento del dataset (da implementare) - Dataset *dataset; - dataset = get_dataset("cifar-10/data_batch_1.bin"); - - printf("Mi appresto ad allenare\n"); - // Addestramento della rete - allena(&rete, dataset); - - // Salvataggio della rete - salva_rete(&rete, "rete_neurale.bin"); - - // Caricamento di 4 immagini casuali - byte immagini[4][N_INPUTS]; - byte etichette[4]; - carica_immagini_casuali(dataset, immagini, etichette); - - // Previsioni sulle immagini - fai_previsioni(&rete, immagini, etichette); - - // Liberazione della memoria - // (Da implementare) - - return 0; -} \ No newline at end of file diff --git a/deep_seek_singolo b/deep_seek_singolo deleted file mode 100755 index 455e7d9..0000000 Binary files a/deep_seek_singolo and /dev/null differ diff --git a/deep_seek_singolo.c b/deep_seek_singolo.c deleted file mode 100644 index 1332ecb..0000000 --- a/deep_seek_singolo.c +++ /dev/null @@ -1,229 +0,0 @@ -#include -#include -#include -#include -#include - -//#include "cifar-10/cifar10_manager.h" -#include "mnist/mnist_manager.h" - -// Costanti configurabili -#define N_LAYERS 3 // Numero di layer (input, hidden, output) -#define N_NEURONI_HIDDEN 128 // Numero di neuroni nei layer nascosti -#define N_NEURONI_OUTPUT 1 // Un solo neurone di output (binario) -#define N_EPOCHE 100 // Numero di epoche di addestramento -#define LEARNING_RATE 0.01 // Tasso di apprendimento -#define N_INPUTS 784 // Dimensioni di un'immagine CIFAR-10 (32x32x3) - -typedef struct { - double *pesi; - double bias; - int size; -} Percettrone; - -typedef struct { - Percettrone *percettroni; - int size; -} Layer; - -typedef struct { - Layer *layers; - int size; -} ReteNeurale; - - -double sigmoide(double); -double relu(double); -double relu_derivata(double); -double softmax(double*, int, int); -ReteNeurale crea_rete(); -int prevedi(ReteNeurale*, byte*); -void allena(ReteNeurale*, Dataset*); -void salva_rete(ReteNeurale*, const char*); -ReteNeurale carica_rete(const char*); -void carica_immagini_casuali(Dataset*, byte[][N_INPUTS], byte*); -void fai_previsioni(ReteNeurale*, byte[][N_INPUTS], byte*); -void backpropagation(ReteNeurale*, byte*, byte, double); -double forward_pass(ReteNeurale*, byte*); - - -// Funzioni di utilità -double sigmoide(double x) { - return 1.0 / (1.0 + exp(-x)); -} - -double sigmoide_derivata(double x) { - return sigmoide(x) * (1 - sigmoide(x)); -} - -double relu(double x) { - return x > 0 ? x : 0; -} - -double relu_derivata(double x) { - return x > 0 ? 1 : 0; -} - -// Inizializzazione della rete -ReteNeurale crea_rete() { - ReteNeurale rete; - rete.size = N_LAYERS; - rete.layers = (Layer *)malloc(N_LAYERS * sizeof(Layer)); - - // Layer di input (non ha pesi, solo pass-through) - rete.layers[0].size = N_INPUTS; - rete.layers[0].percettroni = NULL; - - // Layer nascosto - rete.layers[1].size = N_NEURONI_HIDDEN; - rete.layers[1].percettroni = (Percettrone *)malloc(N_NEURONI_HIDDEN * sizeof(Percettrone)); - for (int i = 0; i < N_NEURONI_HIDDEN; i++) { - rete.layers[1].percettroni[i].size = N_INPUTS; - rete.layers[1].percettroni[i].pesi = (double *)malloc(N_INPUTS * sizeof(double)); - for (int j = 0; j < N_INPUTS; j++) { - rete.layers[1].percettroni[i].pesi[j] = ((double)rand() / RAND_MAX) * 2 - 1; // Pesi casuali tra -1 e 1 - } - rete.layers[1].percettroni[i].bias = ((double)rand() / RAND_MAX) * 2 - 1; // Bias casuale tra -1 e 1 - } - - // Layer di output - rete.layers[2].size = N_NEURONI_OUTPUT; - rete.layers[2].percettroni = (Percettrone *)malloc(N_NEURONI_OUTPUT * sizeof(Percettrone)); - for (int i = 0; i < N_NEURONI_OUTPUT; i++) { - rete.layers[2].percettroni[i].size = N_NEURONI_HIDDEN; - rete.layers[2].percettroni[i].pesi = (double *)malloc(N_NEURONI_HIDDEN * sizeof(double)); - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - rete.layers[2].percettroni[i].pesi[j] = ((double)rand() / RAND_MAX) * 2 - 1; // Pesi casuali tra -1 e 1 - } - rete.layers[2].percettroni[i].bias = ((double)rand() / RAND_MAX) * 2 - 1; // Bias casuale tra -1 e 1 - } - - return rete; -} - -// Forward pass -double forward_pass(ReteNeurale *rete, byte *input) { - double *output_hidden = (double *)malloc(N_NEURONI_HIDDEN * sizeof(double)); - double output_final; - - // Layer nascosto - for (int i = 0; i < N_NEURONI_HIDDEN; i++) { - double somma = 0.0; - for (int j = 0; j < N_INPUTS; j++) { - somma += input[j] * rete->layers[1].percettroni[i].pesi[j]; - } - somma += rete->layers[1].percettroni[i].bias; - output_hidden[i] = relu(somma); // Applica ReLU - } - - // Layer di output - double somma = 0.0; - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - somma += output_hidden[j] * rete->layers[2].percettroni[0].pesi[j]; - } - somma += rete->layers[2].percettroni[0].bias; - output_final = sigmoide(somma); // Applica sigmoide - - free(output_hidden); - return output_final; -} - -// Backpropagation -void backpropagation(ReteNeurale *rete, byte *input, byte target, double output_final) { - // Gradiente della loss (binary cross-entropy) - double grad_output = output_final - target; - - // Gradiente rispetto ai pesi e bias del layer di output - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - rete->layers[2].percettroni[0].pesi[j] -= LEARNING_RATE * grad_output * output_final * (1 - output_final) * input[j]; - } - rete->layers[2].percettroni[0].bias -= LEARNING_RATE * grad_output * output_final * (1 - output_final); - - // Gradiente rispetto ai pesi e bias del layer nascosto - double grad_hidden[N_NEURONI_HIDDEN]; - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - grad_hidden[j] = grad_output * output_final * (1 - output_final) * rete->layers[2].percettroni[0].pesi[j]; - grad_hidden[j] *= relu_derivata(output_final); // Derivata di ReLU - } - - for (int j = 0; j < N_NEURONI_HIDDEN; j++) { - for (int k = 0; k < N_INPUTS; k++) { - rete->layers[1].percettroni[j].pesi[k] -= LEARNING_RATE * grad_hidden[j] * input[k]; - } - rete->layers[1].percettroni[j].bias -= LEARNING_RATE * grad_hidden[j]; - } -} - -// Addestramento -void allena(ReteNeurale *rete, Dataset *dataset) { - for (int epoca = 0; epoca < N_EPOCHE; epoca++) { - printf("Epoca %d\n", epoca+1); - for (int i = 0; i < dataset->size; i++) { - byte *input = dataset->istanze[i].dati; - byte target = (dataset->istanze[i].classificazione == 7) ? 1 : 0; // 1 per cavalli, 0 per il resto - - // Forward pass - double output_final = forward_pass(rete, input); - - // Backpropagation - backpropagation(rete, input, target, output_final); - } - printf("Epoca %d completata\n", epoca + 1); - } -} - -// Funzione per fare previsioni -int prevedi(ReteNeurale *rete, byte *input) { - double output_final = forward_pass(rete, input); - return (output_final >= 0.5) ? 2 : 0; // 2 per cavalli, 0 per il resto -} - -// Funzione per caricare 4 immagini casuali dal dataset -void carica_immagini_casuali(Dataset *dataset, byte immagini[4][N_INPUTS], byte *etichette) { - for (int i = 0; i < 4; i++) { - int indice_casuale = rand() % dataset->size; // Sceglie un'immagine casuale - for (int j = 0; j < N_INPUTS; j++) { - immagini[i][j] = dataset->istanze[indice_casuale].dati[j]; // Copia i dati dell'immagine - } - etichette[i] = dataset->istanze[indice_casuale].classificazione; // Copia l'etichetta - } -} - -// Funzione per fare previsioni su 4 immagini -void fai_previsioni(ReteNeurale *rete, byte immagini[4][N_INPUTS], byte *etichette) { - for (int i = 0; i < 4; i++) { - int previsione = prevedi(rete, immagini[i]); - printf("Immagine %d: Etichetta vera = %d, Previsione = %d\n", i + 1, etichette[i], previsione); - } -} - -int main() { - srand(time(NULL)); - - // Creazione della rete - ReteNeurale rete = crea_rete(); - - // Caricamento del dataset (da implementare) - Dataset *dataset; - dataset = get_dataset("mnist/train-images.idx3-ubyte", "mnist/train-labels.idx1-ubyte"); - // dataset = carica_dataset("cifar10.bin"); - - // Addestramento della rete - allena(&rete, dataset); - - // Salvataggio della rete - // salva_rete(&rete, "rete_neurale.bin"); - - // Caricamento di 4 immagini casuali - byte immagini[4][N_INPUTS]; - byte etichette[4]; - carica_immagini_casuali(dataset, immagini, etichette); - - // Previsioni sulle immagini - fai_previsioni(&rete, immagini, etichette); - - // Liberazione della memoria - // (Da implementare) - - return 0; -} \ No newline at end of file diff --git a/percettroni.h b/percettroni.h index 6950d6e..602b2ae 100644 --- a/percettroni.h +++ b/percettroni.h @@ -3,14 +3,16 @@ #include char *file_pesi = "rete_pesi.bin"; + +#include "mnist/mnist_manager.h" /* char *file_immagini = "mnist/t10k-images.idx3-ubyte"; char *file_label = "mnist/t10k-labels.idx1-ubyte"; */ -/* char *file_immagini = "mnist/train-images.idx3-ubyte"; -char *file_label = "mnist/train-labels.idx1-ubyte"; */ +char *file_immagini = "mnist/train-images.idx3-ubyte"; +char *file_label = "mnist/train-labels.idx1-ubyte"; -// #include "mnist/mnist_manager.h" -#include "cifar-10/cifar10_manager.h"; -char *file_immagini = "cifar-10/data_batch_1.bin"; + +//#include "cifar-10/cifar10_manager.h"; +//char *file_immagini = "cifar-10/data_batch_1.bin"; // char *file_immagini = "cifar-10/data_batch_2.bin"; // char *file_immagini = "cifar-10/data_batch_3.bin"; // char *file_immagini = "cifar-10/data_batch_4.bin"; diff --git a/rete_neurale.bin b/rete_neurale.bin deleted file mode 100644 index 297b9fe..0000000 Binary files a/rete_neurale.bin and /dev/null differ diff --git a/rete_pesi.bin b/rete_pesi.bin new file mode 100644 index 0000000..014e0dc Binary files /dev/null and b/rete_pesi.bin differ