public PerceptronLearning(IMultilayerNeuralNetwork network) { if (network.Layers.Length != 1) { throw new ArgumentException("Invalid nuaral network. It should have one layer only."); } this.network = network; }
// HalfSquared Euclidean Distance private double CalculateError(IMultilayerNeuralNetwork network, double[] expectedOutput) { double error = 0; int layersCount = network.Layers.Length; IActivationFunction function = network.Layers[0].Neurons[0].ActivationFunction; ILayer layer = network.Layers.Last(); double[] errors = neuronErrors.Last(); for (int i = 0, n = layer.Neurons.Length; i < n; i++) { double output = layer.Neurons[i].Output; double e = expectedOutput[i] - output; errors[i] = e * function.ComputeDerivative2(output); error += (e * e); } for (int j = layersCount - 2; j >= 0; j--) { layer = network.Layers[j]; ILayer layerNext = network.Layers[j + 1]; errors = neuronErrors[j]; double[] errorsNext = neuronErrors[j + 1]; for (int i = 0, n = layer.Neurons.Length; i < n; i++) { var sum = 0.0; for (int k = 0; k < layerNext.Neurons.Length; k++) { sum += errorsNext[k] * layerNext.Neurons[k].Weights[i]; } errors[i] = sum * function.ComputeDerivative2(layer.Neurons[i].Output); } } return(error / 2.0); }
private void UpdateNetwork(IMultilayerNeuralNetwork network) { for (int i = 0; i < network.Layers.Length; i++) { ILayer layer = network.Layers[i]; double[][] layerWeightsUpdates = weightsUpdates[i]; double[] layerThresholdUpdates = thresholdsUpdates[i]; for (int j = 0; j < layer.Neurons.Length; j++) { INeuron neuron = layer.Neurons[j]; double[] neuronWeightUpdates = layerWeightsUpdates[j]; for (int k = 0, s = neuron.Weights.Length; k < s; k++) { neuron.Weights[k] += neuronWeightUpdates[k]; } neuron.Threshold += layerThresholdUpdates[j]; } } }
public BackPropagationLearning(IMultilayerNeuralNetwork network) { this.network = network; // создание ошибкок и массивов дельт neuronErrors = new double[network.Layers.Length][]; weightsUpdates = new double[network.Layers.Length][][]; thresholdsUpdates = new double[network.Layers.Length][]; // инициализировать ошибки и массивы дельт для каждого слоя for (int i = 0; i < network.Layers.Length; i++) { ILayer layer = network.Layers[i]; neuronErrors[i] = new double[layer.Neurons.Length]; weightsUpdates[i] = new double[layer.Neurons.Length][]; thresholdsUpdates[i] = new double[layer.Neurons.Length]; for (int j = 0; j < layer.Neurons.Length; j++) { weightsUpdates[i][j] = new double[layer.Neurons[j].Weights.Length]; } } }
private void CalculateUpdates(IMultilayerNeuralNetwork network, double[] input) { INeuron neuron; double[] neuronWeightUpdates; double error; ILayer layer = network.Layers[0]; double[] errors = neuronErrors[0]; double[][] layerWeightsUpdates = weightsUpdates[0]; double[] layerThresholdUpdates = thresholdsUpdates[0]; for (int i = 0; i < layer.Neurons.Length; i++) { neuron = layer.Neurons[i]; error = errors[i]; neuronWeightUpdates = layerWeightsUpdates[i]; for (int j = 0; j < neuron.Weights.Length; j++) { neuronWeightUpdates[j] = LearningRate * ( Momentum * neuronWeightUpdates[j] + (1.0 - Momentum) * error * input[j] ); } layerThresholdUpdates[i] = LearningRate * ( Momentum * layerThresholdUpdates[i] + (1.0 - Momentum) * error ); } for (int k = 1; k < network.Layers.Length; k++) { ILayer layerPrev = network.Layers[k - 1]; layer = network.Layers[k]; errors = neuronErrors[k]; layerWeightsUpdates = weightsUpdates[k]; layerThresholdUpdates = thresholdsUpdates[k]; for (int i = 0; i < layer.Neurons.Length; i++) { neuron = layer.Neurons[i]; error = errors[i]; neuronWeightUpdates = layerWeightsUpdates[i]; for (int j = 0; j < neuron.Weights.Length; j++) { neuronWeightUpdates[j] = LearningRate * ( Momentum * neuronWeightUpdates[j] + (1.0 - Momentum) * error * layerPrev.Neurons[j].Output ); } layerThresholdUpdates[i] = LearningRate * ( Momentum * layerThresholdUpdates[i] + (1.0 - Momentum) * error ); } } }