/// <summary> /// Calculates error values for all neurons of the network /// </summary> /// /// <param name="desiredOutput">Desired output vector</param> /// /// <returns>Returns summary squared error of the last layer divided by 2</returns> /// private double CalculateError(double[] desiredOutput) { // current and the next layers ActivationLayer layer, layerNext; // current and the next errors arrays double[] errors, errorsNext; // error values double error = 0, e, sum; // neuron's output value double output; // layers count int layersCount = network.LayersCount; // assume, that all neurons of the network have the same activation function IActivationFunction function = network[0][0].ActivationFunction; // calculate error values for the last layer first layer = network[layersCount - 1]; errors = neuronErrors[layersCount - 1]; for (int i = 0, n = layer.NeuronsCount; i < n; i++) { output = layer[i].Output; // error of the neuron e = desiredOutput[i] - output; // error multiplied with activation function's derivative errors[i] = e * function.Derivative2(output); // squre the error and sum it error += (e * e); } // calculate error values for other layers for (int j = layersCount - 2; j >= 0; j--) { layer = network[j]; layerNext = network[j + 1]; errors = neuronErrors[j]; errorsNext = neuronErrors[j + 1]; // for all neurons of the layer for (int i = 0, n = layer.NeuronsCount; i < n; i++) { sum = 0.0; // for all neurons of the next layer for (int k = 0, m = layerNext.NeuronsCount; k < m; k++) { sum += errorsNext[k] * layerNext[k][i]; } errors[i] = sum * function.Derivative2(layer[i].Output); } } // return squared error of the last layer divided by 2 return(error / 2.0); }
/// <summary> /// Calculates error values for all neurons of the network. /// </summary> /// /// <param name="desiredOutput">Desired output vector.</param> /// /// <returns>Returns summary squared error of the last layer divided by 2.</returns> /// 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); }
/// <summary> /// Runs learning iteration /// </summary> /// /// <param name="input">input vector</param> /// <param name="output">desired output vector</param> /// /// <returns>Returns squared error divided by 2</returns> /// /// <remarks>Runs one learning iteration and updates neuron's /// weights.</remarks> /// public double Run(double[] input, double[] output) { // compute output of network double[] networkOutput = network.Compute(input); // get the only layer of the network ActivationLayer layer = network[0]; // get activation function of the layer IActivationFunction activationFunction = layer[0].ActivationFunction; // summary network absolute error double error = 0.0; // update weights of each neuron for (int j = 0, k = layer.NeuronsCount; j < k; j++) { // get neuron of the layer ActivationNeuron neuron = layer[j]; // calculate neuron's error double e = output[j] - networkOutput[j]; // get activation function's derivative double functionDerivative = activationFunction.Derivative2(networkOutput[j]); // update weights for (int i = 0, n = neuron.InputsCount; i < n; i++) { neuron[i] += learningRate * e * functionDerivative * input[i]; } // update threshold value neuron.Threshold += learningRate * e * functionDerivative; // sum error error += (e * e); } return(error / 2); }