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