private double CalculateError( double[] desiredOutput )
{
double error = 0;
int layersCount = network.Layers.Length;
// assume, that all neurons of the network have the same activation function
IActivationFunction function = ( network.Layers[0].Neurons[0] as ActivationNeuron ).ActivationFunction;
// calculate error values for the last layer first
ActivationLayer layer = network.Layers[layersCount - 1] as ActivationLayer;
double[] layerDerivatives = neuronErrors[layersCount - 1];
for ( int i = 0; i < layer.Neurons.Length; i++ )
{
double output = layer.Neurons[i].Output;
double e = output - desiredOutput[i];
layerDerivatives[i] = e * function.Derivative2( output );
error += ( e * e );
}
// calculate error values for other layers
for ( int j = layersCount - 2; j >= 0; j-- )
{
layer = network.Layers[j] as ActivationLayer;
layerDerivatives = neuronErrors[j];
ActivationLayer layerNext = network.Layers[j + 1] as ActivationLayer;
double[] nextDerivatives = neuronErrors[j + 1];
// for all neurons of the layer
for ( int i = 0, n = layer.Neurons.Length; i < n; i++ )
{
double sum = 0.0;
for ( int k = 0; k < layerNext.Neurons.Length; k++ )
{
sum += nextDerivatives[k] * layerNext.Neurons[k].Weights[i];
}
layerDerivatives[i] = sum * function.Derivative2( layer.Neurons[i].Output );
}
}
// return squared error of the last layer divided by 2
return error / 2.0;
}