lavoro ancora alle nuove formule
This commit is contained in:
Binary file not shown.
@@ -71,6 +71,7 @@ void main() {
|
|||||||
|
|
||||||
//gradienti è un array bidimensionale, la prima dimensione identifica il layer, la seconda il percettrone nel layer
|
//gradienti è un array bidimensionale, la prima dimensione identifica il layer, la seconda il percettrone nel layer
|
||||||
//gradienti[indice_layer][indice_percettrone]
|
//gradienti[indice_layer][indice_percettrone]
|
||||||
|
//Questo vettore identifica i gradienti dei percettroni
|
||||||
double **gradienti = (double**)malloc(sizeof(double*) * NUM_LAYERS);
|
double **gradienti = (double**)malloc(sizeof(double*) * NUM_LAYERS);
|
||||||
|
|
||||||
//Alloco la dimensione per ogni layer
|
//Alloco la dimensione per ogni layer
|
||||||
@@ -88,7 +89,27 @@ void main() {
|
|||||||
- gradiente dell'errore retropropagato = peso del ne
|
- gradiente dell'errore retropropagato = peso del ne
|
||||||
|
|
||||||
*/
|
*/
|
||||||
gradienti[NUM_LAYERS-1][0] = (output_corretto - sigmoidi[NUM_LAYERS-1][0]);
|
|
||||||
|
double gradiente_errore = (output_corretto - sigmoidi[NUM_LAYERS-1][0]);
|
||||||
|
double derivata_sigmoide_out = sigmoidi[NUM_LAYERS-1][0] * (1 - sigmoidi[NUM_LAYERS-1][0]);
|
||||||
|
|
||||||
|
gradienti[NUM_LAYERS-1][0] = gradiente_errore * derivata_sigmoide_out;
|
||||||
|
|
||||||
|
//Ricorda di partire dal penultimo layer in quanto l'ultimo è già fatto
|
||||||
|
discesa_gradiente(rete_neurale, sigmoidi, gradienti);
|
||||||
|
|
||||||
|
/* A questo punto ho tutti i gradienti dei percettroni, non mi resta che trovare i gradienti dei pesi e correggerli
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Applico la correzione dal penultimo layer andando indietro fino al secondo (il primo si fa diverso)
|
||||||
|
for(int indice_layer = NUM_LAYERS - 2; indice_layer > 0; indice_layer--) {
|
||||||
|
//Applico la correzione a tutti i percettroni del layer dal primo a seguire
|
||||||
|
for(int indice_percettrone = 0; indice_percettrone <= rete_neurale.layers[indice_layer].size; indice_percettrone++) {
|
||||||
|
correggi_pesi_percettrone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//gradienti[NUM_LAYERS-1][0] = (output_corretto - sigmoidi[NUM_LAYERS-1][0]);
|
||||||
errore_totale += gradienti[NUM_LAYERS-1][0];
|
errore_totale += gradienti[NUM_LAYERS-1][0];
|
||||||
|
|
||||||
correggi_layer_interni(&rete_neurale, gradienti, sigmoidi);
|
correggi_layer_interni(&rete_neurale, gradienti, sigmoidi);
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ double *funzioni_attivazione_layer_double(Layer, double*);
|
|||||||
void correggi_layer_interni(ReteNeurale*, double**, double**);
|
void correggi_layer_interni(ReteNeurale*, double**, double**);
|
||||||
void correggi_layer_input(Layer*, double**, double**, byte*, int);
|
void correggi_layer_input(Layer*, double**, double**, byte*, int);
|
||||||
|
|
||||||
|
double calcola_gradiente_layer(ReteNeurale, int, int, double**);
|
||||||
|
void discesa_gradiente(ReteNeurale, double**, double**);
|
||||||
|
|
||||||
int previsione(double);
|
int previsione(double);
|
||||||
|
|
||||||
void salvaReteNeurale(const char*, ReteNeurale*);
|
void salvaReteNeurale(const char*, ReteNeurale*);
|
||||||
@@ -211,7 +214,6 @@ void correggi_layer_interni(ReteNeurale *rete, double **gradienti, double **sigm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Questa funzione prende tutti i parametri della precedente + gli input passati dal dataset per correggere il layer di ingresso
|
//Questa funzione prende tutti i parametri della precedente + gli input passati dal dataset per correggere il layer di ingresso
|
||||||
void correggi_layer_input(Layer *layer, double **gradienti, double **sigmoidi, byte *inputs, int n_layers) {
|
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
|
//L'indice del layer d'ingresso che prende byte per input
|
||||||
@@ -227,6 +229,39 @@ void correggi_layer_input(Layer *layer, double **gradienti, double **sigmoidi, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void discesa_gradiente(ReteNeurale rete, double **sigmoidi, double **gradienti) {
|
||||||
|
//For che scorre i layer dal penultimo al primo QUINI SIZE -2
|
||||||
|
for(int indice_layer = rete.size -2; indice_layer >= 0; indice_layer--) {
|
||||||
|
//printf("Mi trovo nel layer %d, ho %d percettroni\n", indice_layer, rete.layers[indice_layer].size);
|
||||||
|
|
||||||
|
//For che scorre i percettroni del layer partendo dal primo
|
||||||
|
//Per ogni percettrone mi devo prendere il gradiente disceso dal livello sopra e moltiplicarlo per la derivata di attivazione
|
||||||
|
for(int indice_percettrone = 0; indice_percettrone < rete.layers[indice_layer].size; indice_percettrone++) {
|
||||||
|
|
||||||
|
double derivata_attivazione = sigmoidi[indice_layer][indice_percettrone] * (1 - sigmoidi[indice_layer][indice_percettrone]);
|
||||||
|
//Passo anche l'indice del percettrone perchè corrisponde all'indice del peso del livello sopra
|
||||||
|
double gradiente_disceso = calcola_gradiente_layer(rete, indice_layer + 1, indice_percettrone, gradienti);
|
||||||
|
|
||||||
|
|
||||||
|
gradienti[indice_layer][indice_percettrone] = gradiente_disceso * derivata_attivazione;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double calcola_gradiente_disceso(ReteNeurale rete, int livello, int indice_peso, double **gradienti) {
|
||||||
|
//printf("Qui ci arrivo\n");
|
||||||
|
double sommatoria = 0.0;
|
||||||
|
//printf("Layer %d: N_percettroni: %d\n", livello, rete.layers[livello].size);
|
||||||
|
//Calcolo la sommatoria dei gradienti dei percettroni per i pesi
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sommatoria;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Una volta finito il ciclo delle epoche viene salvato lo stato della rete neurale
|
//Una volta finito il ciclo delle epoche viene salvato lo stato della rete neurale
|
||||||
void salvaReteNeurale(const char *filename, ReteNeurale *rete) {
|
void salvaReteNeurale(const char *filename, ReteNeurale *rete) {
|
||||||
FILE *file = fopen(filename, "wb");
|
FILE *file = fopen(filename, "wb");
|
||||||
|
|||||||
BIN
visualizzatore
BIN
visualizzatore
Binary file not shown.
Reference in New Issue
Block a user