la discesa del gradiente porta i gradienti a nan e in seguito tutti i pesi

This commit is contained in:
2025-02-24 09:39:47 +01:00
parent a215e4785a
commit b8c5b82f72
3 changed files with 58 additions and 19 deletions

Binary file not shown.

View File

@@ -144,16 +144,16 @@ void main()
*/
aggiorna_pesi(rete_neurale, gradienti, funzioni_attivazione, set.istanze[indice_set]);
// Correggo il livello output
for (int indice_peso = 0; indice_peso < rete_neurale.layers[rete_neurale.size - 1].percettroni[0].size; indice_peso++)
/* for (int indice_peso = 0; indice_peso < rete_neurale.layers[rete_neurale.size - 1].percettroni[0].size; indice_peso++)
{
// Determino gradiente del peso
double gradiente_peso = gradienti[rete_neurale.size - 1][0] * funzioni_attivazione[rete_neurale.size - 2][indice_peso];
rete_neurale.layers[rete_neurale.size - 1].percettroni[0].pesi[indice_peso] += gradiente_peso * LRE;
}
rete_neurale.layers[rete_neurale.size - 1].percettroni[0].bias += gradienti[rete_neurale.size - 1][0] * LRE;
rete_neurale.layers[rete_neurale.size - 1].percettroni[0].bias += gradienti[rete_neurale.size - 1][0] * LRE; */

View File

@@ -53,9 +53,10 @@ double **elabora_funzioni_attivazione(ReteNeurale*, Istanza, int);
double *elabora_funzioni_attivazione_layer(Layer, double*, int);
double **discesa_gradiente(ReteNeurale, double **, double, int);
double *calcola_gradiente_output(Layer layer, double*, double, int);
double calcola_gradiente_disceso(ReteNeurale, int, int, double **, double);
void correggi_pesi_percettrone_double(Percettrone *, int, double **, double);
void correggi_pesi_percettrone_byte(Percettrone *, Istanza, double, int);
double calcola_gradiente_disceso(ReteNeurale, int, int, double**, double);
void aggiorna_pesi(ReteNeurale, double**, double**, Istanza);
void correggi_pesi_percettrone(Percettrone, double*, double);
//void correggi_pesi_percettrone_byte(Percettrone*, Istanza, double, int);
int previsione(double);
double sigmoide(double);
@@ -258,6 +259,8 @@ double *elabora_funzioni_attivazione_layer(Layer layer, double *inputs, int tipo
################# RETROPROPAGAZIONE ################################
*/
NON CALCOLA I GRADIENTI, PARTE DIRETTAMENTE NAN, VERIFICARE LA PRESENZA DI DATI IN FUNZIONI E LE FUNZIONI DI CALCOLO
double **discesa_gradiente(ReteNeurale rete, double **funzioni, double errore, int tipo_derivata) {
double **gradienti = (double**)malloc(sizeof(double*) * rete.size);
@@ -265,6 +268,8 @@ double **discesa_gradiente(ReteNeurale rete, double **funzioni, double errore, i
//Determino il gradiente di output a parte perchè non prende gradienti discesi dal livello superiore
gradienti[rete.size-1] = calcola_gradiente_output(rete.layers[rete.size-1], funzioni[rete.size-1], errore, tipo_derivata);
//printf("grad di testa %f, size %d\n", gradienti[rete.size-1][0], rete.size);
//Determino gli altri livelli
for (int indice_layer = rete.size - 2; indice_layer >= 0; indice_layer--)
{
@@ -280,10 +285,21 @@ double **discesa_gradiente(ReteNeurale rete, double **funzioni, double errore, i
else
derivata_attivazione = derivata_sigmoide(funzioni[indice_layer][indice_percettrone]);
// printf("derivata: %f, gradiente_disceso %f\n", derivata_attivazione, calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti, derivata_attivazione));
gradienti[indice_layer][indice_percettrone] = calcola_gradiente_disceso(rete, indice_layer + 1, indice_percettrone, gradienti, derivata_attivazione);
}
}
/* for (int count = 0; count < rete.size; count++)
{
for (int count_2 = 0; count_2 < rete.layers[count].size; count_2++)
{
printf("[%d][%d]: %f\t", count, count_2, gradienti[count][count_2]);
}
printf("\n");
} */
return gradienti;
}
@@ -324,24 +340,38 @@ double calcola_gradiente_disceso(ReteNeurale rete, int livello, int indice_peso,
################# PREVISIONE E CORREZIONI ################################
*/
void aggiorna_pesi(ReteNeurale *rete_neurale, double **gradienti, double **funzioni_attivazione, Istanza istanza) {
void aggiorna_pesi(ReteNeurale rete_neurale, double **gradienti, double **funzioni_attivazione, Istanza istanza) {
/* for (int xxx = 0; xxx < rete_neurale.size; xxx++)
{
for (int count = 0; count < rete_neurale.layers[xxx].size; count++)
{
for (int count_2 = 0; count_2 < rete_neurale.layers[xxx].percettroni[count].size; count_2++)
{
printf("[%d][%d]: %f\t", count, count_2, rete_neurale.layers[xxx].percettroni[count].pesi[count_2]);
}
printf("\n");
}
} */
// Applico la correzione dal penultimo layer andando indietro fino al secondo (il primo si fa diverso)
for (int indice_layer = rete_neurale->size - 2; indice_layer >= 0; indice_layer--)
for (int indice_layer = rete_neurale.size - 1; 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++)
{
// Devo prendere il gradiente del percettrone e moltiplicarlo con gli input associati ai pesi
if (indice_layer != 0)
if (indice_layer > 0)
{
correggi_pesi_percettrone_double(&rete_neurale.layers[indice_layer].percettroni[indice_percettrone], indice_layer, funzioni_attivazione, gradienti[indice_layer][indice_percettrone]);
//printf(" [%d][%d]: %f ", indice_layer, indice_percettrone, gradienti[indice_layer][indice_percettrone]);
correggi_pesi_percettrone(rete_neurale.layers[indice_layer].percettroni[indice_percettrone], funzioni_attivazione[indice_layer-1], gradienti[indice_layer][indice_percettrone]);
}
else
{
correggi_pesi_percettrone_byte(&rete_neurale.layers[0].percettroni[indice_percettrone], set.istanze[indice_set], gradienti[0][indice_percettrone], indice_percettrone);
correggi_pesi_percettrone(rete_neurale.layers[indice_layer].percettroni[indice_percettrone], get_double_from_bytes(istanza), gradienti[indice_layer][indice_percettrone]);
}
}
//printf("\n");
}
}
@@ -353,22 +383,31 @@ int previsione(double valore)
return 0;
}
void correggi_pesi_percettrone_double(Percettrone *p, int layer, double **input, double gradiente_percettrone)
{
/*
Al secondo giro diventa NAN
*/
for (int indice_peso = 0; indice_peso < p->size; indice_peso++)
void correggi_pesi_percettrone(Percettrone p, double *input, double gradiente_percettrone)
{
//printf("grad_perc: %f", gradiente_percettrone);
for (int indice_peso = 0; indice_peso < p.size; indice_peso++)
{
// Determino il gradiente del peso
double gradiente_peso = gradiente_percettrone * input[layer - 1][indice_peso];
double gradiente_peso = gradiente_percettrone * input[indice_peso];
//printf("indice[%d], gradiente percettrone %f, gradiente peso %f ", indice_peso, gradiente_percettrone, gradiente_peso);
// Modifico il peso
p->pesi[indice_peso] += (gradiente_peso * LRE);
p.pesi[indice_peso] += (gradiente_peso * LRE);
}
p->bias += (gradiente_percettrone * LRE);
p.bias += (gradiente_percettrone * LRE);
//printf("\n");
}
void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradiente_percettrone, int indice_percettrone)
/* void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradiente_percettrone, int indice_percettrone)
{
for (int indice_peso = 0; indice_peso < p->size; indice_peso++)
{
@@ -380,7 +419,7 @@ void correggi_pesi_percettrone_byte(Percettrone *p, Istanza input, double gradie
}
p->bias += (gradiente_percettrone * LRE);
}
} */