reinizio a metterci mano per completarlo 2
This commit is contained in:
+83
-22
@@ -5,27 +5,26 @@
|
||||
|
||||
char *file_pesi = "rete_pesi.bin";
|
||||
|
||||
//#include "mnist/mnist_manager.h"
|
||||
// #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 "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";
|
||||
// char *file_immagini = "cifar-10/data_batch_5.bin";
|
||||
//char *file_immagini = "cifar-10/test_batch.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";
|
||||
// char *file_immagini = "cifar-10/data_batch_5.bin";
|
||||
// char *file_immagini = "cifar-10/test_batch.bin";
|
||||
|
||||
#include "xor_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 = 1.414;
|
||||
double LRE = 0.5;
|
||||
double soglia_sigmoide = 0.5;
|
||||
|
||||
typedef struct
|
||||
@@ -61,7 +60,7 @@ double **elabora_gradienti(ReteNeurale, double, double **);
|
||||
void discesa_gradiente(ReteNeurale, double **, double **);
|
||||
double calcola_gradiente_disceso(ReteNeurale, int, int, double **);
|
||||
|
||||
void aggiorna_pesi(ReteNeurale*, double**, double**, Istanza);
|
||||
void aggiorna_pesi(ReteNeurale *, double **, double **, Istanza);
|
||||
void correggi_pesi_percettrone_double(Percettrone *, int, double **, double);
|
||||
void correggi_pesi_percettrone_byte(Percettrone *, Istanza, double, int);
|
||||
|
||||
@@ -146,6 +145,7 @@ ReteNeurale inizializza_rete_neurale(int numero_layers, int numero_percettroni_i
|
||||
################# PREVISIONI ################################
|
||||
*/
|
||||
|
||||
// Da eseguire a mano 2
|
||||
double **elabora_gradienti(ReteNeurale rete_neurale, double gradiente_errore, double **sigmoidi)
|
||||
{
|
||||
double **gradienti = (double **)malloc(sizeof(double *) * rete_neurale.size);
|
||||
@@ -164,6 +164,7 @@ double **elabora_gradienti(ReteNeurale rete_neurale, double gradiente_errore, do
|
||||
return gradienti;
|
||||
}
|
||||
|
||||
// Invocata da elabora_sigmoidi()
|
||||
double sigmoide(Percettrone p, double *valori)
|
||||
{
|
||||
double sommatoria = 0.0;
|
||||
@@ -174,32 +175,48 @@ double sigmoide(Percettrone p, double *valori)
|
||||
}
|
||||
|
||||
sommatoria += p.bias;
|
||||
|
||||
//Sigmoide
|
||||
double risultato = 1.0 / (1.0 + exp(-sommatoria));
|
||||
//ReLU
|
||||
//double risultato = sommatoria > 0 ? sommatoria : 0.0f;
|
||||
|
||||
// printf(" sommatoria %f -> %f\n",sommatoria, risultato);
|
||||
|
||||
return risultato;
|
||||
}
|
||||
|
||||
// Invocata da elabora_gradienti()
|
||||
double derivata_sigmoide(double valore)
|
||||
{
|
||||
return (valore * (1.0 - valore));
|
||||
//Sigmoide
|
||||
double derivata = valore * (1.0 - valore);
|
||||
//ReLU
|
||||
//double derivata = valore > 0 ? 1.0f : 0.0f;
|
||||
|
||||
return derivata;
|
||||
}
|
||||
|
||||
int previsione(double valore)
|
||||
{
|
||||
//Sigmoide
|
||||
if (valore >= soglia_sigmoide)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
//ReLU
|
||||
//return valore > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
// Invocata da elabora_gradienti()
|
||||
void discesa_gradiente(ReteNeurale rete, double **sigmoidi, double **gradienti)
|
||||
{
|
||||
for (int indice_layer = rete.size - 2; indice_layer >= 0; indice_layer--)
|
||||
{
|
||||
for (int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++)
|
||||
{
|
||||
double derivata_attivazione = sigmoidi[indice_layer][indice_percettrone] * (1.0 - sigmoidi[indice_layer][indice_percettrone]);
|
||||
double derivata_attivazione = derivata_sigmoide(sigmoidi[indice_layer][indice_percettrone]);
|
||||
double gradiente_disceso = calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti);
|
||||
|
||||
gradienti[indice_layer][indice_percettrone] = gradiente_disceso * derivata_attivazione;
|
||||
@@ -207,17 +224,19 @@ void discesa_gradiente(ReteNeurale rete, double **sigmoidi, double **gradienti)
|
||||
}
|
||||
}
|
||||
|
||||
// Invocata da discesa_gradienti()
|
||||
double calcola_gradiente_disceso(ReteNeurale rete, int livello, int indice_peso, double **gradienti)
|
||||
{
|
||||
double sommatoria = 0.0;
|
||||
for (int indice_percettrone = 0; indice_percettrone < rete.layers[livello].size; indice_percettrone++)
|
||||
{
|
||||
sommatoria += (gradienti[livello][indice_peso] * rete.layers[livello].percettroni[indice_percettrone].pesi[indice_peso]);
|
||||
sommatoria += (gradienti[livello][indice_percettrone] * rete.layers[livello].percettroni[indice_percettrone].pesi[indice_peso]);
|
||||
}
|
||||
|
||||
return sommatoria;
|
||||
}
|
||||
|
||||
// Da eseguire a mano 1
|
||||
double **elabora_sigmoidi(ReteNeurale rete, Istanza istanza)
|
||||
{
|
||||
double **sigmoidi = (double **)malloc(sizeof(double *) * rete.size);
|
||||
@@ -300,13 +319,52 @@ void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradie
|
||||
// Determino il gradiente del peso
|
||||
double gradiente_peso = gradiente_percettrone * (double)input.dati[indice_peso];
|
||||
|
||||
// Modifico il peso Qui si impalla perchè per qualche ragione arriva size elevatissimo
|
||||
// Modifico il peso
|
||||
p->pesi[indice_peso] += (gradiente_peso * LRE);
|
||||
}
|
||||
|
||||
p->bias += (gradiente_percettrone * LRE);
|
||||
}
|
||||
|
||||
/*
|
||||
################### ADDESTRAMENTO #########################
|
||||
*/
|
||||
//Elabora un'epoca. Restituisce 1 se ha dato il 100% di previsioni corrette
|
||||
byte addestra(ReteNeurale *rete_neurale, Dataset set)
|
||||
{
|
||||
int corrette = 0;
|
||||
double errore_totale = 0.0;
|
||||
|
||||
//Per ogni istanza del dataset
|
||||
for (int indice_set = 0; indice_set < set.size; indice_set++)
|
||||
{
|
||||
double **sigmoidi = elabora_sigmoidi(*rete_neurale, set.istanze[indice_set]);
|
||||
|
||||
byte output_corretto = set.istanze[indice_set].classificazione;
|
||||
int previsto = previsione(sigmoidi[rete_neurale->size - 1][0]);
|
||||
printf("\tPrevisto: %d, corretto: %d\n", previsto, output_corretto);
|
||||
if (previsto == output_corretto) {
|
||||
corrette++;
|
||||
}
|
||||
else {
|
||||
// Derivata funzione di perdita
|
||||
double gradiente_errore = (output_corretto - sigmoidi[rete_neurale->size - 1][0]);
|
||||
errore_totale += pow(gradiente_errore, 2);
|
||||
|
||||
double **gradienti = elabora_gradienti(*rete_neurale, gradiente_errore, sigmoidi);
|
||||
|
||||
aggiorna_pesi(rete_neurale, sigmoidi, gradienti, set.istanze[indice_set]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Errore: %f, risposte corrette: %d%\n", errore_totale, (corrette * 100) / set.size);
|
||||
|
||||
if(corrette == set.size)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
################# IMPORT EXPORT ################################
|
||||
*/
|
||||
@@ -399,16 +457,19 @@ ReteNeurale *caricaReteNeurale(const char *filename)
|
||||
return rete;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
################ STAMPE ############################
|
||||
*/
|
||||
void stampa_pesi_rete(ReteNeurale rete) {
|
||||
for(int indice_layer = 0; indice_layer < rete.size; indice_layer++) {
|
||||
void stampa_pesi_rete(ReteNeurale rete)
|
||||
{
|
||||
for (int indice_layer = 0; indice_layer < rete.size; indice_layer++)
|
||||
{
|
||||
printf("\nLivello %d", indice_layer);
|
||||
for(int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++) {
|
||||
for (int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++)
|
||||
{
|
||||
printf("\n\tPercettrone %d", indice_percettrone);
|
||||
for(int indice_peso = 0; indice_peso < rete.layers[indice_layer].percettroni[indice_percettrone].size; indice_peso++) {
|
||||
for (int indice_peso = 0; indice_peso < rete.layers[indice_layer].percettroni[indice_percettrone].size; indice_peso++)
|
||||
{
|
||||
printf("\n\t\tPeso %d: %f", indice_peso, rete.layers[indice_layer].percettroni[indice_percettrone].pesi[indice_peso]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user