pusho per testare nel threadripper

This commit is contained in:
2025-02-08 19:15:34 +01:00
parent 8f360421f2
commit 7c242fabfa
12 changed files with 617 additions and 52 deletions

View File

@@ -8,4 +8,3 @@ frog
horse
ship
truck

View File

@@ -1 +0,0 @@
<meta HTTP-EQUIV="REFRESH" content="0; url=http://www.cs.toronto.edu/~kriz/cifar.html">

BIN
classificatore_singolo Executable file

Binary file not shown.

124
classificatore_singolo.c Normal file
View File

@@ -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");
}
}

74
dataset_manager.h Normal file
View File

@@ -0,0 +1,74 @@
#include <stdlib.h>
#include <stdio.h>
#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);
}
} */

View File

@@ -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<stdlib.h>
#include <math.h>
#define INPUT_LIV1 3072
#define INPUT_LIV2 256
#define INPUT_LIV3 128
#include <math.h>
#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;
}
}
//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];
}
} */

View File

@@ -1,33 +0,0 @@
#include <stdio.h>
#include <time.h>
#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);
}
}
}

BIN
rete_neurale Executable file

Binary file not shown.

162
rete_neurale.c Normal file
View File

@@ -0,0 +1,162 @@
#include <stdio.h>
#include <time.h>
#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;
}

1
tempCodeRunnerFile.c Normal file
View File

@@ -0,0 +1 @@
printf("qui ci arrivo else\n");

BIN
visualizzatore Executable file

Binary file not shown.

75
visualizzatore.h Normal file
View File

@@ -0,0 +1,75 @@
#include <allegro.h>
#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
}
}
}