diff --git a/cifar-10-batches/batches.meta.txt b/cifar-10-batches/batches.meta.txt
index cc82768..fa30c22 100644
--- a/cifar-10-batches/batches.meta.txt
+++ b/cifar-10-batches/batches.meta.txt
@@ -8,4 +8,3 @@ frog
horse
ship
truck
-
diff --git a/cifar-10-batches/readme.html b/cifar-10-batches/readme.html
deleted file mode 100644
index e377ade..0000000
--- a/cifar-10-batches/readme.html
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/classificatore_singolo b/classificatore_singolo
new file mode 100755
index 0000000..082dc53
Binary files /dev/null and b/classificatore_singolo differ
diff --git a/classificatore_singolo.c b/classificatore_singolo.c
new file mode 100644
index 0000000..d744719
--- /dev/null
+++ b/classificatore_singolo.c
@@ -0,0 +1,124 @@
+#include "visualizzatore.h"
+
+#define NUM_LAYERS 5
+
+#define PERCETTRONI_LAYER_0 256
+#define INPUT_LAYER_0 3072
+#define PERCETTRONI_LAYER_1 128
+#define INPUT_LAYER_1 256
+#define PERCETTRONI_LAYER_2 64
+#define INPUT_LAYER_2 128
+#define PERCETTRONI_LAYER_3 10
+#define INPUT_LAYER_3 64
+#define PERCETTRONI_LAYER_4 1
+#define INPUT_LAYER_4 10
+
+#define MAX_EPOCHE 100
+
+//Scelgo quale categoria voglio identificare. La 7 sono i cavalli. La rete mi dirà per ogni immagine se è un cavallo o no
+#define CATEGORIA 7
+byte get_out_corretto(byte);
+void stampa_layer_indirizzo(Layer*);
+
+void main() {
+ srand(time(NULL));
+
+ /* init_allegro();
+
+ // Carica la prima immagine
+ load_current_image(set);
+
+ while (!key[KEY_ESC]) {
+ draw_interface();
+ handle_input(set);
+ rest(10);
+ }
+
+ destroy_bitmap(buffer);
+ destroy_bitmap(image);
+ allegro_exit(); */
+
+ Dataset *set_appoggio = get_dataset("cifar-10-batches/data_batch_1.bin");
+ if(set_appoggio == NULL)
+ return;
+ Dataset set = *set_appoggio;
+ free(set_appoggio);
+
+ ReteNeurale rete_neurale = inizializza_rete_neurale(NUM_LAYERS);
+ //inizializzo layer 0
+ rete_neurale.layers[0] = inizializza_layer(PERCETTRONI_LAYER_0, INPUT_LAYER_0);
+ //inizializzo layer 1
+ rete_neurale.layers[1] = inizializza_layer(PERCETTRONI_LAYER_1, INPUT_LAYER_1);
+ //inizializzo layer 2
+ rete_neurale.layers[2] = inizializza_layer(PERCETTRONI_LAYER_2, INPUT_LAYER_2);
+ //inizializzo layer 3
+ rete_neurale.layers[3] = inizializza_layer(PERCETTRONI_LAYER_3, INPUT_LAYER_3);
+ //inizializzo layer ULTIMO
+ rete_neurale.layers[4] = inizializza_layer(PERCETTRONI_LAYER_4, INPUT_LAYER_4);
+
+ printf("Numero immagini: %d\n",set.size);
+
+ //ADDESTRAMENTO
+ for(int i = 0; i < MAX_EPOCHE; i++) {
+ printf("Epoca %d\n", i);
+
+ int corrette = 0;
+
+ for(int indice_set = 0; indice_set < 100; indice_set++) {
+
+ //printf("\timmagine: %d\n", indice_set);
+
+ double **sigmoidi = (double **)malloc(sizeof(double*) * NUM_LAYERS);
+
+ sigmoidi[0] = (double*)malloc(sizeof(double) * PERCETTRONI_LAYER_0);
+ sigmoidi[0] = funzioni_attivazione_layer_byte(rete_neurale.layers[0], set.istanze[indice_set].immagine);
+
+ for(int j = 1; j < NUM_LAYERS; j++) {
+ sigmoidi[j] = (double*)malloc(sizeof(double) * rete_neurale.layers[j].size);
+ sigmoidi[j] = funzioni_attivazione_layer_double(rete_neurale.layers[j], sigmoidi[j-1]);
+ }
+
+ byte output_corretto = get_out_corretto(set.istanze[indice_set].categoria);
+
+ //Se prevede male
+ if(previsione(sigmoidi[NUM_LAYERS-1][0]) != output_corretto) {
+
+ double **gradienti = (double**)malloc(sizeof(double*) * NUM_LAYERS);
+
+ for(int indice_layer = 0; indice_layer < NUM_LAYERS; indice_layer++) {
+ gradienti[indice_layer] = (double*)malloc(sizeof(double) * rete_neurale.layers[indice_layer].size);
+ }
+
+ gradienti[NUM_LAYERS-1][0] = output_corretto - sigmoidi[NUM_LAYERS-1][0];
+
+ correggi_layer_interni(&rete_neurale, gradienti, sigmoidi);
+ correggi_layer_input(&rete_neurale.layers[0], gradienti, sigmoidi, set.istanze[indice_set].immagine, NUM_LAYERS);
+ }
+ else
+ {
+ //printf("immagine: %d categoria: %d, risposta_esatta: %d, previsione: %d\n", indice_set, set.istanze[indice_set].categoria, output_corretto, previsione(*sigmoide_out));
+ corrette++;
+ }
+ }
+ printf("\tRisposte corrette: %d\n", corrette);
+ }
+}
+
+//Questa funzione ritorna 1 se la categoria è quella che voglio individuare, altrimenti 0
+byte get_out_corretto(byte categoria) {
+ if(categoria == CATEGORIA)
+ return 1;
+ else
+ return 0;
+}
+
+void stampa_layer_indirizzo(Layer *layer) {
+ for(int i = 0; i < layer->size; i++) {
+ printf("Percettrone %d ->", i);
+ for(int j = 0; j < layer->percettroni->size; j++) {
+ printf("\t peso %d, valore: %f",j, layer->percettroni[i].pesi[j]);
+ layer->percettroni[i].pesi[j] += 1;
+ }
+ printf("\n");
+ }
+}
\ No newline at end of file
diff --git a/dataset_manager.h b/dataset_manager.h
new file mode 100644
index 0000000..3c8c7dd
--- /dev/null
+++ b/dataset_manager.h
@@ -0,0 +1,74 @@
+#include
+#include
+
+#define N_PIXEL 3072 //1024 pixel * 3 (R, G, B)
+
+//Siccome il char è un byte che rappresenta il valore tra 0 e 255. Per evitare confusioni definisco il tipo "byte" come in Java
+typedef unsigned char byte;
+
+// Singola istanza del dataset.
+typedef struct {
+ byte categoria;
+ byte immagine[N_PIXEL];
+} Istanza;
+
+//Questo tipo fornisce il vettore delle istanze e il size (dimensione) del vettore
+typedef struct {
+ int size;
+ Istanza *istanze;
+} Dataset;
+
+Dataset* get_dataset(char *);
+
+//Questo metodo legge il file in questione e restituisce un puntatore a Dataset se il file esiste, altrimenti NULL
+//Ritorna un puntatore perchè in questo caso posso gestire il ritorno NULL.
+Dataset* get_dataset(char *path) {
+
+ Dataset *set = (Dataset *) malloc(sizeof(Dataset));
+ FILE *file;
+ Istanza istanza;
+ Istanza *istanze = (Istanza *)malloc(sizeof(Istanza));
+
+ file = fopen(path, "rb");
+ if(file == NULL)
+ return NULL;
+
+ int numero_righe = 0;
+
+ //Fino a quando questo fread restituisce 1 significa che il file contiene ancora roba
+ while(fread(&istanze[numero_righe].categoria, sizeof(byte), 1, file) == 1) {
+ if(fread(istanze[numero_righe].immagine, sizeof(byte), N_PIXEL, file) == N_PIXEL) {
+ numero_righe ++;
+ istanze = (Istanza *)realloc(istanze, sizeof(Istanza) * (numero_righe + 1));
+ //printf("Caricata nel sistema riga %d\n", numero_righe);
+ }
+ }
+
+ //Dataset set;
+ (*set).size = numero_righe;
+ (*set).istanze = istanze;
+
+ fclose(file);
+
+ return set;
+}
+
+/* void main() {
+ char *path = "cifar-10-batches/data_batch_1.bin";
+
+ //Carico il dataset e controllo che non sia nullo
+ Dataset *dataset = get_dataset(path);
+ if(dataset == NULL) {
+ printf("Oggetto dataset nullo\n");
+ return;
+ }
+
+ //Lo copio in una seconda variabile per non dover mettere sempre * davanti al nome e libero la memoria occupata dal puntatore
+ Dataset set = *dataset;
+ free(dataset);
+
+ //Stampa di debug
+ for(int i = 0; i < set.size; i++) {
+ printf("n: %d. Categoria: %d\n", i, (int)set.istanze[i].categoria);
+ }
+} */
\ No newline at end of file
diff --git a/percettroni.h b/percettroni.h
index f1810de..bf9c990 100644
--- a/percettroni.h
+++ b/percettroni.h
@@ -8,40 +8,108 @@
In output ci sono 10 percettroni, ognuno di essi è associato ad una categoria del CIFAR10. Alla fine dell'addestramento, la previsione sarà
data dal percettrone di output che avrà il valore 1 rispetto agli altri 9.
*/
-#include
-#include
-#define INPUT_LIV1 3072
-#define INPUT_LIV2 256
-#define INPUT_LIV3 128
+#include
+#include "dataset_manager.h"
double LRE = 0.2;
+double soglia_sigmoide = 0.5;
typedef struct {
double *pesi;
double bias;
- double lre;
+ int size;
} Percettrone;
-double randomico();
-void inzializza_percettrone(Percettrone*, int);
-double funzione_sigmoide(Percettrone, int[], int);
+typedef struct {
+ Percettrone *percettroni;
+ int size;
+} Layer;
+typedef struct {
+ Layer *layers;
+ int size;
+} ReteNeurale;
+
+double randomico();
+
+Percettrone inzializza_percettrone(int);
+ReteNeurale inizializza_rete_neurale(int);
+Layer inizializza_layer(int, int);
+
+double sigmoide_byte(Percettrone, byte*, int);
+double sigmoide_double(Percettrone, double*, int);
+double *funzioni_attivazione_layer_byte(Layer, byte*);
+double *funzioni_attivazione_layer_double(Layer, double*);
+
+void correggi_layer_interni(ReteNeurale*, double**, double**);
+void correggi_layer_input(Layer*, double**, double**, byte*, int);
+
+int previsione(double);
+
+//Questa funzione genera un valore reale random compreso nell'intervallo [-1, 1]
double randomico() {
// Genero numeri nell'intervallo [-1,1]
return ((double)(rand() % 101 * 0.01 * 2 ) -1);
}
-void inizializza_percettrone(Percettrone *p, int n_pesi) {
- p->pesi = (double*)malloc(sizeof(double) * n_pesi );
+//Questa funzione inizializza il percettrone allocando la memoria in base al numero dei pesi che voglio ed inizializza il loro valore usando randomico()
+Percettrone inizializza_percettrone(int n_pesi) {
+ Percettrone p;
+ p.pesi = (double*) malloc(sizeof(double) * n_pesi);
for(int i = 0; i < n_pesi; i++)
- p->pesi[i] = randomico();
+ p.pesi[i] = randomico();
- p->bias = randomico();
- p->lre = LRE;
+ p.bias = randomico();
+
+ p.size = n_pesi;
+
+ return p;
}
-double funzione_sigmoide(Percettrone p, int valori[], int n_input) {
+//Questa funzione inizializza una rete neurale. Diamo il numero di layer desiderato e restituisce un ReteNeurale
+ReteNeurale inizializza_rete_neurale(int n_layers) {
+ ReteNeurale r;
+ r.layers = (Layer*)malloc(sizeof(Layer) * n_layers);
+ r.size = n_layers;
+
+ return r;
+}
+
+//Questa funzione serve ad inizializzare il singolo layer con il numero di percettroni che vogliamo
+//Ogni percettrone a sua volta viene automaticamente inizializzato con il numero di pesi che vogliamo e coi valori di partenza
+Layer inizializza_layer(int n_percettroni, int n_pesi) {
+ Layer layer;
+ layer.percettroni = (Percettrone *)malloc(sizeof(Percettrone) * n_percettroni);
+
+ for(int i = 0; i < n_percettroni; i++) {
+ layer.percettroni[i] = inizializza_percettrone(n_pesi);
+ }
+
+ layer.size = n_percettroni;
+
+ return layer;
+}
+
+//Questa funzione viene usata per il primo livello perchè ha un vettore di byte (unsigned char) in input
+double sigmoide_byte(Percettrone p, byte *valori, int n_input) {
+
+ double sommatoria = 0.0;
+ for(int i = 0; i < n_input; i++) {
+ sommatoria += ((double)valori[i] * p.pesi[i]);
+ }
+ //printf("sommatoria= %f\n", sommatoria);
+ double funzione = sommatoria + p.bias;
+ double potenza_e = exp(-funzione);
+ //printf("potenza_e= %f\n", potenza_e);
+ //formula sigmoide
+ double risultato = 1 / ( 1 + potenza_e);
+ //printf("risultato= %f\n", risultato);
+ return risultato;
+}
+
+//Questa funzione viene usata per gli altri livelli dove gli input sono double, ossia i valori della sigmoide dei livelli precedenti
+double sigmoide_double(Percettrone p, double *valori, int n_input) {
double sommatoria = 0.0;
for(int i = 0; i < n_input; i++) {
@@ -49,10 +117,106 @@ double funzione_sigmoide(Percettrone p, int valori[], int n_input) {
}
double funzione = sommatoria + p.bias;
+ //printf("sommatoria= %f\n", sommatoria);
double potenza_e = exp(-funzione);
-
+ //printf("potenza_e= %f\n", potenza_e);
//formula sigmoide
double risultato = 1 / ( 1 + potenza_e);
+ //printf("risultato= %f\n", risultato);
return risultato;
-}
\ No newline at end of file
+}
+
+//Questa funzione calcola tutte le funzioni di attivazione dei percettroni del layer che prende dei byte come inputs
+double *funzioni_attivazione_layer_byte(Layer layer, byte *inputs) {
+
+ double *funzioni = (double*)malloc(sizeof(double) * layer.size);
+
+ for(int i = 0; i < layer.size; i++) {
+ funzioni[i] = sigmoide_byte(layer.percettroni[i], inputs, layer.percettroni[i].size);
+ }
+
+ return funzioni;
+}
+
+//Questa funzione calcola tutte le funzioni di attivazione dei percettroni del layer che prende dei double come inputs (le sigmoidi del livello precedente)
+double *funzioni_attivazione_layer_double(Layer layer, double *inputs) {
+
+ double *funzioni = (double*)malloc(sizeof(double) * layer.size);
+
+ for(int i = 0; i < layer.size; i++) {
+ funzioni[i] = sigmoide_double(layer.percettroni[i], inputs, layer.percettroni[i].size);
+ }
+
+ return funzioni;
+}
+
+//Questa funzione restituisce il valore 0,1 in base alla soglia di attivazione della funzione sigmoide
+int previsione(double valore) {
+ if(valore >= soglia_sigmoide)
+ return 1;
+ else
+ return 0;
+}
+
+void correggi_layer_interni(ReteNeurale *rete, double **gradienti, double **sigmoidi) {
+
+ for(int indice_layer = rete->size-1; indice_layer > 0; indice_layer--) {
+ for(int indice_percettrone = 0; indice_percettrone < rete->layers[indice_layer].size; indice_percettrone++) {//Numero percettroni
+
+ for(int indice_peso = 0; indice_peso < rete->layers[indice_layer].percettroni[indice_percettrone].size; indice_peso++) {//Numero pesi
+ gradienti[indice_layer][indice_percettrone] = gradienti[rete->size-1][0] * (sigmoidi[indice_layer][indice_percettrone] * (1 - sigmoidi[indice_layer][indice_percettrone]));
+
+ rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso] -= (gradienti[indice_layer][indice_percettrone] * LRE * sigmoidi[indice_layer-1][indice_percettrone]);
+
+ //if(indice_layer == 3)
+ // printf("qui ci arrivo layer: %d, percettrone: %d, input:%d, peso: %f\n", indice_layer, indice_percettrone, indice_peso, rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso]);
+
+ //printf("gradiente applicato %f, sigmoide %f\n", gradienti[indice_layer][indice_percettrone], sigmoidi[indice_layer][indice_percettrone]);
+ }
+ rete->layers[indice_layer].percettroni[indice_percettrone].bias -= (gradienti[indice_layer][indice_percettrone] * LRE);
+ //printf("bias: %f\n", rete->layers[indice_layer].percettroni[indice_percettrone].bias);
+ }
+ }
+}
+
+void correggi_layer_input(Layer *layer, double **gradienti, double **sigmoidi, byte *inputs, int n_layers) {
+ //L'indice del layer d'ingresso che prende byte per input
+ int indice_layer = 0;
+ for(int indice_percettrone = 0; indice_percettrone < layer->size; indice_percettrone++) {//Numero percettroni
+ for(int indice_peso = 0; indice_peso < layer->percettroni->size; indice_peso++) { //Numero pesi
+
+ gradienti[indice_layer][indice_percettrone] = gradienti[n_layers-1][0] * (sigmoidi[indice_layer][indice_percettrone] * (1 - sigmoidi[indice_layer][indice_percettrone]));
+ layer->percettroni[indice_percettrone].pesi[indice_peso] -= (gradienti[indice_layer][indice_percettrone] * LRE * inputs[indice_peso]);
+ }
+ layer->percettroni[indice_percettrone].bias -= (gradienti[indice_layer][indice_percettrone] * LRE);
+ }
+}
+
+
+
+
+
+
+/* void correggi_pesi_layer(Percettrone[], int, int, double**, double[], double[]);
+void correggi_pesi_layer_uno(Percettrone[], int, int, double**, byte[], double[]);
+
+void correggi_pesi_layer(Percettrone percettroni_layer[], int size_percettroni, int size_inputs, double **gradienti, double inputs[], double gradienti_bias[]) {
+ for(int i = 0; i < size_percettroni; i++) {
+ // Non termina questo for
+ for(int j = 0; j < size_inputs; j++) {
+ percettroni_layer[i].pesi[j] -= LRE * gradienti[i][j] * inputs[j];
+ }
+ percettroni_layer[i].bias -= LRE * gradienti_bias[i];
+ }
+}
+
+void correggi_pesi_layer_uno(Percettrone percettroni_layer[], int size_percettroni, int size_inputs, double **gradienti, byte inputs[], double gradienti_bias[]) {
+
+ for(int i = 0; i < size_percettroni; i++) {
+ for(int j = 0; j < size_inputs; j++) {
+ percettroni_layer[i].pesi[j] -= LRE * gradienti[i][j] * inputs[j];
+ }
+ percettroni_layer[i].bias -= LRE * gradienti_bias[i];
+ }
+} */
diff --git a/rete_cifar10.c b/rete_cifar10.c
deleted file mode 100644
index 4937428..0000000
--- a/rete_cifar10.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include
-#include
-#include "percettroni.h"
-
-#define PERCETTRONI_1 256
-#define PERCETTRONI_2 128
-#define PERCETTRONI_OUT 10
-
-void main() {
- srand(time(NULL));
-
- Percettrone livello_uno[PERCETTRONI_1];
- Percettrone livello_due[PERCETTRONI_2];
- Percettrone livello_out[PERCETTRONI_OUT];
-
- for(int i = 0; i < PERCETTRONI_1; i++) {
- inizializza_percettrone(&livello_uno[i], INPUT_LIV1);
- if(i < PERCETTRONI_2) {
- inizializza_percettrone(&livello_due[i], INPUT_LIV2);
- if(i < PERCETTRONI_OUT)
- inizializza_percettrone(&livello_out[i], INPUT_LIV3);
- }
- }
-
- for(int i = 0; i < PERCETTRONI_1; i++) {
- printf("\nPercettrone esterno %d: w78: %f, bias: %f",i, livello_uno[i].pesi[77], livello_uno[i].bias);
- if(i < PERCETTRONI_2) {
- printf("\n\tPercettrone interno %d: w78: %f, bias: %f", i, livello_due[i].pesi[77], livello_due[i].bias);
- if(i < PERCETTRONI_OUT)
- printf("\n\t\tPercettrone output %d: w78: %f, bias: %f", i, livello_out[i].pesi[77], livello_out[i].bias);
- }
- }
-}
\ No newline at end of file
diff --git a/rete_neurale b/rete_neurale
new file mode 100755
index 0000000..fb620de
Binary files /dev/null and b/rete_neurale differ
diff --git a/rete_neurale.c b/rete_neurale.c
new file mode 100644
index 0000000..9a865cc
--- /dev/null
+++ b/rete_neurale.c
@@ -0,0 +1,162 @@
+#include
+#include
+#include "percettroni.h"
+
+#define PERCETTRONI_1 256
+#define PERCETTRONI_2 128
+#define PERCETTRONI_OUT 10
+
+#define MAX_EPOCHE 1
+
+double** alloca_memoria_bidimensionale(int, int);
+
+void main()
+{
+ srand(time(NULL));
+
+ Percettrone livello_uno[PERCETTRONI_1];
+ Percettrone livello_due[PERCETTRONI_2];
+ Percettrone livello_out[PERCETTRONI_OUT];
+
+ for (int i = 0; i < PERCETTRONI_1; i++)
+ {
+ inizializza_percettrone(&livello_uno[i], INPUT_LIV1);
+ if (i < PERCETTRONI_2)
+ {
+ inizializza_percettrone(&livello_due[i], INPUT_LIV2);
+ if (i < PERCETTRONI_OUT)
+ inizializza_percettrone(&livello_out[i], INPUT_LIV3);
+ }
+ }
+
+ Dataset *set_appoggio = get_dataset("cifar-10-batches/data_batch_1.bin");
+ if (set_appoggio == NULL)
+ return;
+
+ Dataset dataset = *set_appoggio;
+ free(set_appoggio);
+
+ // Ciclo esterno per contare le epoche
+ for (int indice_epoca = 0; indice_epoca < MAX_EPOCHE; indice_epoca++)
+ {
+
+ // Ciclo interno per contare tutte le istanze del dataset da analizzare nell'epoca corrente
+ for (int indice_dataset = 0; indice_dataset < dataset.size; indice_dataset++)
+ {
+
+ // Qui memorizzo tutte le sigmoidi della rete
+ double sigmoidi_livello_uno[PERCETTRONI_1];
+ double sigmoidi_livello_due[PERCETTRONI_2];
+ double sigmoidi_livello_out[PERCETTRONI_OUT];
+
+ // Livello 1
+ // Ho 256 percettroni da riempire
+ for (int i = 0; i < PERCETTRONI_1; i++)
+ sigmoidi_livello_uno[i] = funzione_sigmoide_primo_livello(livello_uno[i], dataset.istanze[indice_dataset].immagine, INPUT_LIV1);
+
+ // Livello 2
+ // Ho 128 percettroni da riempire
+ for (int i = 0; i < PERCETTRONI_2; i++)
+ sigmoidi_livello_due[i] = funzione_sigmoide(livello_due[i], sigmoidi_livello_uno, INPUT_LIV2);
+
+ // Livello OUT
+ // Ho 10 percettroni da riempire
+ for (int i = 0; i < PERCETTRONI_OUT; i++)
+ {
+ sigmoidi_livello_out[i] = funzione_sigmoide(livello_out[i], sigmoidi_livello_due, INPUT_LIV3);
+ printf("Sigmoide %d: %f\n", i, sigmoidi_livello_out[i]);
+ }
+
+ // Determinare l'errore e la previsione
+ // Ho 10 percettroni in uscita, la previsione è che uno sarà 1 mentre tutti gli altri 0.
+ // Il percettrone con 1 è quello di indice dataset.istanze[indice_dataset].categoria
+ int indice_corretto = dataset.istanze[indice_dataset].categoria;
+
+ double errori[PERCETTRONI_OUT];
+
+ printf("Fino a qui ci arrivo 1\n");
+
+ double **gradienti_out = alloca_memoria_bidimensionale(PERCETTRONI_OUT, INPUT_LIV3);
+ double gradienti_bias_out[PERCETTRONI_OUT];
+
+ double **gradienti_2 = alloca_memoria_bidimensionale(PERCETTRONI_2, INPUT_LIV2);
+ double gradienti_bias_2[PERCETTRONI_2];
+
+ double **gradienti_1 = alloca_memoria_bidimensionale(PERCETTRONI_1, INPUT_LIV1);
+ double gradienti_bias_1[PERCETTRONI_1];
+
+ // Per ogni percettrone di uscita vedo se ha commesso errore e mi calcolo il gradiente
+ for (int i = 0; i < PERCETTRONI_OUT; i++)
+ {
+ // Se la i corrisponde all'indice corretto, la previsione dovrebbe essere 1, se non lo è c'è errore
+ if (i == indice_corretto)
+ {
+ if (prevedi(sigmoidi_livello_out[i]) != 1)
+ { // Errore
+ errori[i] = 1 - sigmoidi_livello_out[i];
+
+ for (int j = 0; j < INPUT_LIV3; j++)
+ gradienti_out[i][j] = errori[i] * sigmoidi_livello_out[i] * (1 - sigmoidi_livello_out[i]) /* * sigmoidi_livello_due[j] */;
+ gradienti_bias_out[i] = errori[i] * sigmoidi_livello_out[i] * (1 - sigmoidi_livello_out[i]);
+
+ //Qui potrei moltiplicarmi i pesi per i gradienti quindi correggere il livello output
+
+ for (int j = 0; j < PERCETTRONI_2; j++)
+ {
+ for (int k = 0; k < INPUT_LIV2; k++)
+ gradienti_2[j][k] = gradienti_out[i][j] * sigmoidi_livello_due[j] * (1 - sigmoidi_livello_due[j]);
+ gradienti_bias_2[j] = gradienti_out[i][j] * sigmoidi_livello_due[j] * (1 - sigmoidi_livello_due[j]);
+
+ //Qui potrei moltiplicarmi i pesi per i gradienti quindi correggere il livello due
+
+ for (int y = 0; y < PERCETTRONI_1; y++)
+ {
+ for (int z = 0; z < INPUT_LIV1; z++)
+ gradienti_1[y][z] = gradienti_out[i][j] * gradienti_2[j][y] * sigmoidi_livello_uno[y] * (1 - sigmoidi_livello_uno[y]);
+ gradienti_bias_1[y] = gradienti_out[i][j] * gradienti_2[j][y] * sigmoidi_livello_uno[y] * (1 - sigmoidi_livello_uno[y]);
+
+ //Qui potrei moltiplicarmi i pesi per i gradienti quindi correggere il livello uno
+ }
+ }
+ }
+ }
+ else
+ {
+ // Qui determino quando deve valere zero
+ }
+ }
+
+ printf("Fino a qui ci arrivo 2\n");
+ /*
+ Devo dichiarare i gradienti col malloc
+ */
+ correggi_pesi_layer(livello_out, PERCETTRONI_OUT, INPUT_LIV3, gradienti_out, sigmoidi_livello_due, gradienti_bias_out);
+ printf("Fino a qui ci arrivo 3\n");
+ correggi_pesi_layer(livello_due, PERCETTRONI_2, INPUT_LIV2, gradienti_2, sigmoidi_livello_uno, gradienti_bias_2);
+ printf("Fino a qui ci arrivo 4\n");
+ correggi_pesi_layer_uno(livello_uno, PERCETTRONI_1, INPUT_LIV1, gradienti_1, dataset.istanze[indice_dataset].immagine, gradienti_bias_1);
+ printf("Fino a qui ci arrivo 5\n");
+ }
+ }
+
+ // Stampa di debug
+ /* for(int i = 0; i < PERCETTRONI_1; i++) {
+ printf("\nPercettrone esterno %d: w78: %f, bias: %f",i, livello_uno[i].pesi[77], livello_uno[i].bias);
+ if(i < PERCETTRONI_2) {
+ printf("\n\tPercettrone interno %d: w78: %f, bias: %f", i, livello_due[i].pesi[77], livello_due[i].bias);
+ if(i < PERCETTRONI_OUT)
+ printf("\n\t\tPercettrone output %d: w78: %f, bias: %f", i, livello_out[i].pesi[77], livello_out[i].bias);
+ }
+ }*/
+
+ printf("\r");
+}
+
+double** alloca_memoria_bidimensionale(int x, int y) {
+ double **vettore = (double **)malloc(sizeof(double*) * x);
+
+ for(int i = 0; i < x; i++)
+ vettore[i] = (double *)malloc(sizeof(double) * y);
+
+ return vettore;
+}
\ No newline at end of file
diff --git a/tempCodeRunnerFile.c b/tempCodeRunnerFile.c
new file mode 100644
index 0000000..a27cc13
--- /dev/null
+++ b/tempCodeRunnerFile.c
@@ -0,0 +1 @@
+printf("qui ci arrivo else\n");
\ No newline at end of file
diff --git a/visualizzatore b/visualizzatore
new file mode 100755
index 0000000..8496919
Binary files /dev/null and b/visualizzatore differ
diff --git a/visualizzatore.h b/visualizzatore.h
new file mode 100644
index 0000000..ded1525
--- /dev/null
+++ b/visualizzatore.h
@@ -0,0 +1,75 @@
+#include
+#include "percettroni.h"
+
+#define IMAGE_WIDTH 32
+#define IMAGE_HEIGHT 32
+#define SCALE_FACTOR 2
+
+BITMAP *buffer;
+BITMAP *image;
+
+void init_allegro() {
+ allegro_init();
+ install_keyboard();
+ install_mouse();
+ set_color_depth(32);
+ set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0);
+ buffer = create_bitmap(800,600);
+ image = create_bitmap(IMAGE_WIDTH, IMAGE_HEIGHT);
+ show_mouse(screen);
+}
+
+void load_current_image(Dataset *set) {
+ int indice = rand()%set->size;
+ for (int y = 0; y < IMAGE_HEIGHT; y++) {
+ for (int x = 0; x < IMAGE_WIDTH; x++) {
+ int r = set->istanze[indice].immagine[y * IMAGE_WIDTH + x];
+ int g = set->istanze[indice].immagine[1024 + y * IMAGE_WIDTH + x];
+ int b = set->istanze[indice].immagine[2048 + y * IMAGE_WIDTH + x];
+ putpixel(image, x, y, makecol(r, g, b));
+ }
+ }
+}
+
+void draw_interface() {
+ clear_to_color(buffer, makecol(255, 255, 255));
+
+ // Calcola la posizione per centrare l'immagine ingrandita
+ int scaled_width = IMAGE_WIDTH * SCALE_FACTOR;
+ int scaled_height = IMAGE_HEIGHT * SCALE_FACTOR;
+ int image_x = (800 - scaled_width) / 2;
+ int image_y = (600 - scaled_height) / 2 - 20; // Sposta leggermente sopra per fare spazio al pulsante
+
+ // Disegna l'immagine ingrandita
+ stretch_blit(image, buffer, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, image_x, image_y, scaled_width, scaled_height);
+
+ // Disegna il pulsante "prossima"
+ int button_width = 150;
+ int button_height = 40;
+ int button_x = (800 - button_width) / 2;
+ int button_y = 600 - 60; // Posizione in basso
+ rectfill(buffer, button_x, button_y, button_x + button_width, button_y + button_height, makecol(200, 200, 200));
+ textout_centre_ex(buffer, font, "prossima", button_x + button_width / 2, button_y + 10, makecol(0, 0, 0), -1);
+
+ // Copia il buffer sullo schermo
+ blit(buffer, screen, 0, 0, 0, 0, 800, 600);
+}
+
+void handle_input(Dataset *set) {
+ if (mouse_b & 1) {
+ int mx = mouse_x;
+ int my = mouse_y;
+
+ // Coordinate del pulsante
+ int button_width = 150;
+ int button_height = 40;
+ int button_x = (800 - button_width) / 2;
+ int button_y = 600 - 60;
+
+ // Controlla se il clic è avvenuto sul pulsante
+ if (mx >= button_x && mx <= button_x + button_width && my >= button_y && my <= button_y + button_height) {
+ load_current_image(set);
+ rest(200); // Debounce
+ }
+ }
+}
\ No newline at end of file