namespace NeuralNetworkPCL { internal class NeuralNetwork { Neuron[] hiddenNeurons; Neuron[] outputNeurons; int nbInputs; int nbHidden; int nbOutputs; internal NeuralNetwork(int _nbInputs, int _nbHidden, int _nbOutput) { nbInputs = _nbInputs; nbHidden = _nbHidden; nbOutputs = _nbOutput; hiddenNeurons = new Neuron[nbHidden]; for (int i = 0; i < nbHidden; i++) { hiddenNeurons[i] = new Neuron(_nbInputs); } outputNeurons = new Neuron[nbOutputs]; for (int i = 0; i < nbOutputs; i++) { outputNeurons[i] = new Neuron(_nbHidden); } } internal double[] Evaluate(DataPoint _point) { foreach (Neuron n in hiddenNeurons) { n.Clear(); } foreach (Neuron n in outputNeurons) { n.Clear(); } double[] hiddenOutputs = new double[nbHidden]; for (int i = 0; i < nbHidden; i++) { hiddenOutputs[i] = hiddenNeurons[i].Evaluate(_point); } double[] outputs = new double[nbOutputs]; for (int outputNb = 0; outputNb < nbOutputs; outputNb++) { outputs[outputNb] = outputNeurons[outputNb].Evaluate(hiddenOutputs); } return outputs; } internal void AdjustWeights(DataPoint _point, double _learningRate) { // Deltas pour les sorties double[] outputDeltas = new double[nbOutputs]; for (int i = 0; i < nbOutputs; i++) { double output = outputNeurons[i].Output; double expectedOutput = _point.Outputs[i]; outputDeltas[i] = output * (1 - output) * (expectedOutput - output); } // Deltas pour les neurones cachés double[] hiddenDeltas = new double[nbHidden]; for (int i = 0; i < nbHidden; i++) { double hiddenOutput = hiddenNeurons[i].Output; double sum = 0.0; for (int j = 0; j < nbOutputs; j++) { sum += outputDeltas[j] * outputNeurons[j].Weight(i); } hiddenDeltas[i] = hiddenOutput * (1 - hiddenOutput) * sum; } double value; // Ajustement des poids des neurones de sortie for (int i = 0; i < nbOutputs; i++) { Neuron outputNeuron = outputNeurons[i]; for (int j = 0; j < nbHidden; j++) { value = outputNeuron.Weight(j) + _learningRate * outputDeltas[i] * hiddenNeurons[j].Output; outputNeuron.AdjustWeight(j, value); } // Et biais value = outputNeuron.Weight(nbHidden) + _learningRate * outputDeltas[i] * 1.0; outputNeuron.AdjustWeight(nbHidden, value); } // Ajustement des poids des neurones cachés for (int i = 0; i < nbHidden; i++) { Neuron hiddenNeuron = hiddenNeurons[i]; for (int j = 0; j < nbInputs; j++) { value = hiddenNeuron.Weight(j) + _learningRate * hiddenDeltas[i] * _point.Inputs[j]; hiddenNeuron.AdjustWeight(j, value); } // Et biais value = hiddenNeuron.Weight(nbInputs) + _learningRate * hiddenDeltas[i] * 1.0; hiddenNeuron.AdjustWeight(nbInputs, value); } } } }