Advertisement
cesarsouza

Untitled

Jul 28th, 2011
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.07 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