integrazione mnist

This commit is contained in:
2025-02-13 21:17:57 +01:00
parent 7c7fcedbaa
commit 55b0e97546
19 changed files with 70119 additions and 54 deletions

View File

@@ -74,40 +74,3 @@ void salva_dataset(const char *filename, Dataset *set)
fclose(file); fclose(file);
} }
/* 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;
}
Dataset cavalli;
cavalli.size = 1;
cavalli.istanze = (Istanza *)malloc(sizeof(Istanza) * cavalli.size);
int indice_cavalli = 0;
// 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++)
{
if (set.istanze[i].categoria == 7)
{
cavalli.size++;
cavalli.istanze[indice_cavalli] = set.istanze[i];
cavalli.istanze = (Istanza *)realloc(cavalli.istanze, sizeof(Istanza) * cavalli.size);
printf("n: %d. Categoria: %d\n", indice_cavalli, cavalli.istanze[indice_cavalli].categoria);
indice_cavalli++;
}
}
salva_dataset("cavalli.bin", &cavalli);
} */

Binary file not shown.

View File

@@ -1,10 +1,11 @@
#include "percettroni.h"
#include <time.h> #include <time.h>
#include "percettroni.h"
#include "mnist/mnist_manager.h"
#define NUM_LAYERS 4 #define NUM_LAYERS 4
#define PERCETTRONI_LAYER_0 32 #define PERCETTRONI_LAYER_0 32
#define INPUT_LAYER_0 3072 #define INPUT_LAYER_0 N_PIXEL
#define PERCETTRONI_LAYER_1 16 #define PERCETTRONI_LAYER_1 16
#define INPUT_LAYER_1 32 #define INPUT_LAYER_1 32
#define PERCETTRONI_LAYER_2 8 #define PERCETTRONI_LAYER_2 8
@@ -26,7 +27,8 @@ void main() {
srand(time(NULL)); srand(time(NULL));
Dataset *set_appoggio = get_dataset("cifar-10-batches/test_batch.bin"); Dataset *set_appoggio = get_dataset("mnist/t10k-images.idx3-ubyte", "mnist/t10k-labels.idx1-ubyte");
if(set_appoggio == NULL) if(set_appoggio == NULL)
return; return;
Dataset set = *set_appoggio; Dataset set = *set_appoggio;
@@ -77,7 +79,7 @@ void main() {
for(int indice_set = 0; indice_set < set.size; indice_set++) { for(int indice_set = 0; indice_set < set.size; indice_set++) {
//printf("\timmagine: %d\n", indice_set); printf("\timmagine: %d\n", indice_set);
double **sigmoidi = (double **)malloc(sizeof(double*) * NUM_LAYERS); double **sigmoidi = (double **)malloc(sizeof(double*) * NUM_LAYERS);
@@ -110,6 +112,8 @@ void main() {
{ {
corrette++; corrette++;
} }
printf("\timmagine: %d post calcoli, indovinate: %d\n", indice_set, corrette);
} }
printf("\tRisposte corrette: %d\n", corrette); printf("\tRisposte corrette: %d\n", corrette);

97
mnist/mnist_manager.h Normal file
View File

@@ -0,0 +1,97 @@
#include <stdlib.h>
#include <stdio.h>
#define N_PIXEL 784 // Immagine 28x28
// 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 *, 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_mnist, char *path_categoria)
{
Dataset *set = (Dataset *)malloc(sizeof(Dataset));
FILE *file;
FILE *categorie;
Istanza istanza;
Istanza *istanze = (Istanza *)malloc(sizeof(Istanza));
file = fopen(path_mnist, "rb");
if (file == NULL) {
printf("Errore nella funzione fopen() nelle immagini\n");
return NULL;
}
categorie = fopen(path_categoria, "rb");
if (file == NULL) {
printf("Errore nella funzione fopen() nelle categorie\n");
return NULL;
}
int numero_righe = 0;
//printf("Scorro il while %d\n", fread(istanze[numero_righe].categoria, sizeof(byte), 2, categorie));
// Fino a quando questo fread restituisce 1 significa che il file contiene ancora roba
while (fread(istanze[numero_righe].immagine, sizeof(byte), N_PIXEL, file) == N_PIXEL)
{
if(fread(&istanze[numero_righe].categoria, sizeof(byte), 1, categorie) == 1) {
numero_righe++;
istanze = (Istanza *)realloc(istanze, sizeof(Istanza) * (numero_righe + 1));
}
}
// Dataset set;
(*set).size = numero_righe;
(*set).istanze = istanze;
fclose(file);
return set;
}
void salva_dataset(const char *filename, Dataset *set)
{
FILE *file = fopen(filename, "wb");
if (!file)
{
perror("Errore nell'apertura del file");
exit(EXIT_FAILURE);
}
for (int indice_istanze = 0; indice_istanze < set->size; indice_istanze++)
{
fwrite(&set->istanze[indice_istanze].categoria, sizeof(byte), 1, file);
fwrite(&set->istanze[indice_istanze].immagine, sizeof(byte), N_PIXEL, file);
}
fclose(file);
}
/* void main() {
Dataset *set = get_dataset("t10k-images.idx3-ubyte", "t10k-labels.idx1-ubyte");
if(set == NULL) {
printf("Nullo esco\n");
return;
}
for(int i = 0; i < set->size; i++) {
printf("immagine %d - valore rappresentato: %d\n", i, set->istanze[i].categoria);
}
} */

10000
mnist/mnist_test.csv Normal file

File diff suppressed because it is too large Load Diff

60000
mnist/mnist_train.csv Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h> #include <math.h>
#include "dataset_manager.h"
// 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;
double LRE = 0.2; double LRE = 0.2;
double soglia_sigmoide = 0.5; double soglia_sigmoide = 0.5;
@@ -158,14 +163,9 @@ void correggi_layer_interni(ReteNeurale *rete, double **gradienti, double **sigm
for(int indice_percettrone = 0; indice_percettrone < rete->layers[indice_layer].size; indice_percettrone++) {//Numero percettroni 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 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])); //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]);
rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso] += (gradienti[indice_layer][indice_percettrone] * LRE * sigmoidi[indice_layer-1][indice_percettrone]); rete->layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso] += (gradienti[rete->size-1][0] * 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); 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); //printf("bias: %f\n", rete->layers[indice_layer].percettroni[indice_percettrone].bias);
@@ -180,10 +180,11 @@ void correggi_layer_input(Layer *layer, double **gradienti, double **sigmoidi, b
for(int indice_percettrone = 0; indice_percettrone < layer->size; indice_percettrone++) {//Numero percettroni 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 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])); //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].pesi[indice_peso] += (gradienti[indice_layer][indice_percettrone] * LRE * inputs[indice_peso]);
layer->percettroni[indice_percettrone].pesi[indice_peso] += (gradienti[n_layers-1][0] * LRE * inputs[indice_peso]);
} }
layer->percettroni[indice_percettrone].bias += (gradienti[indice_layer][indice_percettrone] * LRE); layer->percettroni[indice_percettrone].bias += (gradienti[n_layers-1][0] * LRE);
} }
} }