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[indice_layer][indice_percettrone]
|
||||
//Questo vettore identifica i gradienti dei percettroni
|
||||
double **gradienti = (double**)malloc(sizeof(double*) * NUM_LAYERS);
|
||||
|
||||
//Alloco la dimensione per ogni layer
|
||||
@@ -88,7 +89,27 @@ void main() {
|
||||
- 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];
|
||||
|
||||
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_input(Layer*, double**, double**, byte*, int);
|
||||
|
||||
double calcola_gradiente_layer(ReteNeurale, int, int, double**);
|
||||
void discesa_gradiente(ReteNeurale, double**, double**);
|
||||
|
||||
int previsione(double);
|
||||
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
void salvaReteNeurale(const char *filename, ReteNeurale *rete) {
|
||||
FILE *file = fopen(filename, "wb");
|
||||
|
||||
BIN
visualizzatore
BIN
visualizzatore
Binary file not shown.
Reference in New Issue
Block a user