private void CalculateGradient( double[] input )
{
// 1. calculate updates for the first layer
ActivationLayer layer = network.Layers[0] as ActivationLayer;
double[] weightErrors = neuronErrors[0];
double[][] layerWeightsDerivatives = weightsDerivatives[0];
double[] layerThresholdDerivatives = thresholdsDerivatives[0];
// So, for each neuron of the first layer:
for ( int i = 0; i < layer.Neurons.Length; i++ )
{
ActivationNeuron neuron = layer.Neurons[i] as ActivationNeuron;
double[] neuronWeightDerivatives = layerWeightsDerivatives[i];
// for each weight of the neuron:
for ( int j = 0; j < neuron.InputsCount; j++ )
{
neuronWeightDerivatives[j] += weightErrors[i] * input[j];
}
layerThresholdDerivatives[i] += weightErrors[i];
}
// 2. for all other layers
for ( int k = 1; k < network.Layers.Length; k++ )
{
layer = network.Layers[k] as ActivationLayer;
weightErrors = neuronErrors[k];
layerWeightsDerivatives = weightsDerivatives[k];
layerThresholdDerivatives = thresholdsDerivatives[k];
ActivationLayer layerPrev = network.Layers[k - 1] as ActivationLayer;
// for each neuron of the layer
for ( int i = 0; i < layer.Neurons.Length; i++ )
{
ActivationNeuron neuron = layer.Neurons[i] as ActivationNeuron;
double[] neuronWeightDerivatives = layerWeightsDerivatives[i];
// for each weight of the neuron
for ( int j = 0; j < layerPrev.Neurons.Length; j++ )
{
neuronWeightDerivatives[j] += weightErrors[i] * layerPrev.Neurons[j].Output;
}
layerThresholdDerivatives[i] += weightErrors[i];
}
}
}
}