Advertisement
cesarsouza

Untitled

Jul 28th, 2011
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.45 KB | None | 0 0
  1. /// <summary>
  2. ///   Calculates partial derivatives for all weights of the network.
  3. /// </summary>
  4. ///
  5. /// <param name="input">The input vector.</param>
  6. /// <param name="desiredOutput">Desired output vector.</param>
  7. /// <param name="outputIndex">The current output location (index) in the desired output vector.</param>
  8. ///
  9. /// <returns>Returns summary squared error of the last layer.</returns>
  10. ///
  11. private double CalculateDerivatives(double[] input, double[] desiredOutput, int outputIndex)
  12. {
  13.     // assume, that all neurons of the network have the same activation function
  14.     IActivationFunction function = network[0][0].ActivationFunction;
  15.  
  16.     double[] previousLayerOutput;
  17.  
  18.     // Start by the output layer first
  19.     int outputLayerIndex = network.LayersCount - 1;
  20.     ActivationLayer outputLayer = network[outputLayerIndex];
  21.  
  22.     // If we have only one single layer, the previous layer outputs is given by the input layer
  23.     previousLayerOutput = (outputLayerIndex == 0) ? input : network[outputLayerIndex - 1].Output;
  24.  
  25.     // Assume single output neuron
  26.     ActivationNeuron outputNeuron = outputLayer[outputIndex];
  27.     double[] neuronWeightDerivatives = weightDerivatives[outputLayerIndex][outputIndex];
  28.  
  29.     double output = outputNeuron.Output;
  30.     double e = desiredOutput[outputIndex] - output;
  31.     double derivative = function.Derivative2(output);
  32.  
  33.     // Set derivative for each weight in the neuron
  34.     for (int i = 0; i < previousLayerOutput.Length; i++)
  35.         neuronWeightDerivatives[i] = derivative * previousLayerOutput[i];
  36.  
  37.     // Set derivative for the current threshold (bias) term
  38.     thresholdsDerivatives[outputLayerIndex][outputIndex] = derivative;
  39.  
  40.  
  41.     // Now, proceed to the hidden layers
  42.     for (int layerIndex = network.LayersCount - 2; layerIndex >= 0; layerIndex--)
  43.     {
  44.         int nextLayerIndex = layerIndex + 1;
  45.  
  46.         ActivationLayer layer = network[layerIndex];
  47.         ActivationLayer nextLayer = network[nextLayerIndex];
  48.  
  49.         // If we are in the first layer, the previous layer is just the input layer
  50.         previousLayerOutput = (layerIndex == 0) ? input : network[layerIndex - 1].Output;
  51.  
  52.         // Now, we will compute the derivatives for the current layer applying the chain
  53.         //  rule. To apply the chain-rule, we will make use of the previous derivatives
  54.         //  computed for the inner layers (forming a calculation chain, hence the name).
  55.  
  56.         // So, for each neuron in the current layer:
  57.         for (int neuronIndex = 0; neuronIndex < layer.NeuronsCount; neuronIndex++)
  58.         {
  59.             ActivationNeuron neuron = layer[neuronIndex];
  60.  
  61.             neuronWeightDerivatives = weightDerivatives[layerIndex][neuronIndex];
  62.  
  63.             double[] layerDerivatives = thresholdsDerivatives[layerIndex];
  64.             double[] nextLayerDerivatives = thresholdsDerivatives[layerIndex + 1];
  65.  
  66.             double sum = 0;
  67.  
  68.             // The chain-rule can be stated as (f(w*g(x))' = f'(w*g(x)) * w*g'(x)
  69.             //
  70.             // We will start computing the second part of the product. Since the g'
  71.             //  derivatives have already been computed in the previous computation,
  72.             //  we will be summing all previous function derivatives and weighting
  73.             //  them using their connection weight (sinapses).
  74.             //
  75.             // So, for each neuron in the next layer:
  76.             for (int j = 0; j < nextLayerDerivatives.Length; j++)
  77.             {
  78.                 // retrieve the weight connecting the output of the current
  79.                 //   neuron and the activation function of the next neuron.
  80.                 double weight = nextLayer[j][neuronIndex];
  81.  
  82.                 // accumulate the sinapse weight * next layer derivative
  83.                 sum += weight * nextLayerDerivatives[j];
  84.             }
  85.  
  86.             // Continue forming the chain-rule statement
  87.             derivative = sum * function.Derivative2(neuron.Output);
  88.  
  89.             // Set derivative for each weight in the neuron
  90.             for (int i = 0; i < previousLayerOutput.Length; i++)
  91.                 neuronWeightDerivatives[i] = derivative * previousLayerOutput[i];
  92.  
  93.             // Set derivative for the current threshold
  94.             layerDerivatives[neuronIndex] = derivative;
  95.  
  96.             // The threshold derivatives also gather the derivatives for
  97.             // the layer, and thus can be re-used in next calculations.
  98.         }
  99.     }
  100.  
  101.     // return error
  102.     return e;
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement