/// <summary> /// Trains the Neural Network by feeding forward, then back propgating /// </summary> public void Train(double[] inputs, double[] targetOutputs) { double[] actualOutputs = RunNetwork(inputs); var outputNeuronLayer = Neurons.Length - 1; var outputNeurons = Neurons[outputNeuronLayer]; var errorTotal = 0.0; for (int n = 0; n < outputNeurons.Length; n++) { errorTotal += .5 * (targetOutputs[n] - actualOutputs[n]) * (targetOutputs[n] - actualOutputs[n]); } TotalError = errorTotal; for (int l = Neurons.Length - 1; l > 0; l--) { var layerPrev = Neurons[l - 1]; var layer = Neurons[l]; for (int n = 0; n < layer.Length; n++) { var neuron = layer[n]; if (l == outputNeuronLayer) { neuron.Delta = -1 * (targetOutputs[n] - neuron.Output) * ActivatorFunction.ExecuteDerivative(neuron.Output); } else { var layerNext = Neurons[l + 1]; var wDeltaSum = 0.0; for (int w = 0; w < layerNext.Length; w++) { wDeltaSum = layerNext[w].Delta; } var derivedPart = ActivatorFunction.ExecuteDerivative(neuron.Output); neuron.Delta = -1 * derivedPart * wDeltaSum; } for (int w = 0; w < neuron.Weights.Length; w++) { var wPrime = neuron.Weights[w] - LearningRate * neuron.Delta * layerPrev[w].Output; neuron.Weights[w] = wPrime; } neuron.BiasWeight = neuron.BiasWeight - LearningRate * neuron.Delta; } } }