//Costruttore, si occupa dell'allenamento vero e proprio. public RPropPlus(FFANN ffann, double[][] stdDataset) { int epochs = 0; double[][][] delta = new double[ffann.NumLayers - 1][][]; //Matrice delta che conterrà le correzione dei pesi da applicare alla fine della propagazione. desired_output = new double[ffann.NumPercept[ffann.NumLayers - 1]]; dterr = new double[ffann.NumLayers - 1][]; //inizializzazione di delta[][][]. for (int i = 0; i < ffann.NumLayers - 1; i++) { delta[i] = new double[ffann.NumPercept[i]][]; } for (int j = 0; j < delta.Length; j++) { for (int i = 0; i < delta[j].Length; i++) //Calcolo il numero totale di sinapsi nella rete. { delta[j][i] = new double[ffann.NumPercept[j + 1]]; } } //Fine inizializzazione delta[][][]. //Inizializzo ed azzero la matrice dterr. for (int i = 0; i < ffann.NumLayers - 1; i++) { dterr[i] = new double[ffann.NumPercept[i]]; for (int z = 0; z < ffann.NumPercept[i]; z++) { dterr[i][z] = 0; } } //Fine azzeramento. do //Scorro le epoche in cui la rete si allenerà. { for (int i = 0; i < stdDataset.Length; i++) //Scorro tutti i samples nel dataset. { Error = 0; ffann.Predict(stdDataset[i]); //Calcolo le uscite della rete dato il sample i. //Copio i valori desiderati in un vettore comodo e calcolo l'Errore Quadratico Medio. for (int j = 0; j < ffann.NumPercept[ffann.NumLayers - 1]; j++) { desired_output[j] = stdDataset[i][ffann.NumPercept[0] + j]; Error += 0.5 * Math.Pow(ffann.layer[ffann.NumLayers - 1].perceptron[j].getAction() - desired_output[j], 2); } //End //Calcolo i delta dei pesi sinaptici. for (int j = ffann.NumLayers - 2; j >= 0; j--) //Scorro la rete dal penultimo layer al primo, per avere accesso diretto ai pesi sinaptici da correggere. { for (int k = 0; k < ffann.NumPercept[j]; k++) // Scorro i percettroni dello strato j. { for (int q = 0; q < ffann.NumPercept[j + 1]; q++) // Scorro le sinapsi. { delta[j][k][q] = Delta(ffann, j, k, q); } } } //Setto i nuovi pesi applicando i delta dei pesi sinaptici. for (int j = 0; j < ffann.NumLayers - 1; j++) { for (int k = 0; k < ffann.NumPercept[j]; k++) { for (int q = 0; q < ffann.NumPercept[j + 1]; q++) { ffann.layer[j].perceptron[k].setSynapsys(ffann.layer[j].perceptron[k].getSynapsys(q) + delta[j][k][q], q); } } } //è necessario azzerare dterr per ogni sample analizzato. for (int j = 0; j < dterr.Length; j++) { for (int z = 0; z < dterr[j].Length; z++) { dterr[j][z] = 0; } } //Fine azzeramento. } //Stampa l'errore quadratico medio se if è true. if (epochs % 1000 == 0) { Console.WriteLine("\nErrore Quadratico Medio: " + Error + "\n"); } epochs++; if (Error <= 0.00001) { Console.Write("\nEpoche: " + epochs + "\n"); } } while ((epochs != 100000) && (Error >= 0.00001)); }