private double[] GetLayerError(TDerivative PWhichDeriv, int PWhichLayer, double[] POutput, double[] PNextLayerError) { int numneurons = layers[PWhichLayer].NumNeurons; int numneuronsnextlayer = layers[PWhichLayer + 1].NumNeurons; double[][] layerweights = weights[PWhichLayer + 1]; double[] error = new double[numneurons]; for (int i = 0; i < numneurons; i++) { error[i] = 0; for (int j = 0; j < numneuronsnextlayer; j++) { double curweight = layerweights[j][i]; double addtoerror = PNextLayerError[j] * curweight; if (PWhichDeriv != TDerivative.First) { addtoerror *= curweight; } error[i] += addtoerror; } double deriv = layers[PWhichLayer].FirstDerivative(POutput[i]); error[i] *= deriv; if (PWhichDeriv != TDerivative.First) { error[i] *= deriv; } } return(error); }
private double[][][] GetDerivativesFromOutputBatch(TDerivative PWhichDeriv, double[][][] POutput, double[][] PInput, double[][] PDesired) { double[][][] derivatives = ArrayInitOnePerWeight(); Utility.ZeroArray(derivatives); int numcases = POutput.GetLength(0); for (int i = 0; i < numcases; i++) { Utility.AddArrays(derivatives, GetDerivativesFromOutput(PWhichDeriv, POutput[i], PInput[i], PDesired[i])); } Utility.ScaleArray(derivatives, 1 / ((double)numcases)); return(derivatives); }
private double[] LastLayerError(TDerivative PWhichDeriv, double[] POutput, double[] PDesired) { int numneurons = layers[numlayers - 1].NumNeurons; double[] error = new double[numneurons]; for (int i = 0; i < numneurons; i++) { if (PWhichDeriv == TDerivative.First) { error[i] = POutput[i] - PDesired[i]; } else { error[i] = 1; } } return(error); }
private void CalculateDerivativesFromError(TDerivative PWhichDeriv, int PWhichLayer, double[][] PDerivatives, double[] PLayerError, double[] PPreviousOutputs) { int numneurons = layers[PWhichLayer].NumNeurons; int numneuronspreviouslayer = weights[PWhichLayer][0].GetLength(0); for (int i = 0; i < numneurons; i++) { for (int j = 0; j < numneuronspreviouslayer; j++) { PDerivatives[i][j] = PLayerError[i] * PPreviousOutputs[j]; if (PWhichDeriv != TDerivative.First) { PDerivatives[i][j] *= PPreviousOutputs[j]; } } PDerivatives[i][numneuronspreviouslayer] = PLayerError[i]; } }
private double[][][] GetDerivativesFromOutput(TDerivative PWhichDeriv, double[][] POutput, double[] PInput, double[] PDesired) { double[][][] derivatives = ArrayInitOnePerWeight(); double[] layererror = LastLayerError(PWhichDeriv, POutput[numlayers - 1], PDesired); double[] previousoutput = PInput; if (numlayers > 1) { previousoutput = POutput[numlayers - 2]; } CalculateDerivativesFromError(PWhichDeriv, numlayers - 1, derivatives[numlayers - 1], layererror, previousoutput); for (int i = numlayers - 2; i >= 0; i--) { layererror = GetLayerError(PWhichDeriv, i, POutput[i], layererror); previousoutput = PInput; if (i != 0) { previousoutput = POutput[i - 1]; } CalculateDerivativesFromError(PWhichDeriv, i, derivatives[i], layererror, previousoutput); } return(derivatives); }