private void CreateNeurons(int numInputs, int numHiddenNeurons) { hiddenNeurons = new BDN[numHiddenNeurons]; for (int i = 0; i < hiddenNeurons.Length; i++) { hiddenNeurons[i] = new BDN(numInputs); } outputNeuron = new BDN(numHiddenNeurons); }
public double Classify(double[] pattern) { double[] hiddenNeuronActivations = new double[hiddenNeurons.Length]; double[] hiddenNeuronOutputs = new double[hiddenNeurons.Length]; for (int j = 0; j < hiddenNeurons.Length; j++) { BDN hiddenNeuron = hiddenNeurons[j]; double activation = hiddenNeuron.Activate(pattern); hiddenNeuronActivations[j] = activation; hiddenNeuronOutputs[j] = Sigmoid(activation); } double outputNeuronActivation = outputNeuron.Activate(hiddenNeuronOutputs); double outputNeuronOutput = Sigmoid(outputNeuronActivation); return(outputNeuronOutput); }
public double Train(double[][] trainData, int[] targets, double trainRate, double targetError, int maxEpochs, int maxRestarts) { // Random used for initialising input weights Random random = new Random(); // Initialise neurons for first training attempt InitNeurons(random); int epoch = 0; int restarts = 0; error = 0.0; do { // For each training pattern, run a forward and backward pass for (int i = 0; i < trainData.Length; i++) { double[] pattern = trainData[i]; double patternTarget = targets[i]; // Forward pass double[] hiddenNeuronActivations = new double[hiddenNeurons.Length]; double[] hiddenNeuronOutputs = new double[hiddenNeurons.Length]; for (int j = 0; j < hiddenNeurons.Length; j++) { BDN hiddenNeuron = hiddenNeurons[j]; double activation = hiddenNeuron.Activate(pattern); hiddenNeuronActivations[j] = activation; hiddenNeuronOutputs[j] = Sigmoid(activation); } double outputNeuronActivation = outputNeuron.Activate(hiddenNeuronOutputs); double outputNeuronOutput = Sigmoid(outputNeuronActivation); // Add squared pattern error to total error error += Math.Pow(patternTarget - outputNeuronOutput, 2); // Backward pass double outputDelta = (patternTarget - outputNeuronOutput) * SigmoidDeriv(outputNeuronActivation); outputNeuron.AdjustWeights(trainRate, outputDelta, hiddenNeuronOutputs); for (int j = 0; j < hiddenNeurons.Length; j++) { BDN hiddenNeuron = hiddenNeurons[j]; double hiddenDelta = outputDelta * outputNeuron.Weight(j + 1) * SigmoidDeriv(hiddenNeuronActivations[j]); hiddenNeuron.AdjustWeights(trainRate, hiddenDelta, pattern); } } // Square root the average error for a conservative estimate error = Math.Sqrt(error / trainData.Length); if (++epoch >= maxEpochs) { // If we run out of attempts, finish now if (restarts >= maxRestarts) { return(error); } // Otherwise, restart the network for another attempt InitNeurons(random); epoch = 0; restarts += 1; } } while (error > targetError); return(error); }