public void TrainGeneration(double[][] inputs, double[][] outputs) { //Cross Over 80% Of Nets & Randomize 10% int OneTenthPopulation = NeuralNets.Length / 10; for (int i = OneTenthPopulation; i < NeuralNets.Length; i++) { GeneticNeuralNetwork CurrentNet = NeuralNets[i]; if (i < 9 * OneTenthPopulation) { CurrentNet.CrossOverAndMutate(NeuralNets[i % OneTenthPopulation], MutationRate, Rand); } else { CurrentNet.Initialize(Rand); } } //Calculate Fitnesses & Sort Parallel.For(0, NeuralNets.Length, j => { CalculateFitness(NeuralNets[j], inputs, outputs); }); Array.Sort(NeuralNets, (a, b) => a.Fitness.CompareTo(b.Fitness)); BestNetwork = NeuralNets[0]; GenerationCount++; }
private void CalculateFitness(GeneticNeuralNetwork neuralNetwork, double[][] inputs, double[][] desiredOutputs) { double MeanAbsoluteError = 0; for (int i = 0; i < inputs.Length; i++) { double Output = neuralNetwork.Compute(inputs[i])[0]; MeanAbsoluteError += Math.Pow(desiredOutputs[i][0] - Output, 2); } neuralNetwork.Fitness = MeanAbsoluteError / inputs.Length; }
public Genetics(Random rand, NeuralNetwork modelNetwork, int populationCount, double mutationRate = 0.05) { //Store Neural Network Data Rand = rand; MutationRate = mutationRate; //Get Network Layer Neuron Counts NeuralNets = new GeneticNeuralNetwork[populationCount]; for (int i = 0; i < populationCount; i++) { NeuralNets[i] = new GeneticNeuralNetwork(modelNetwork); } }
public void CrossOverAndMutate(GeneticNeuralNetwork BetterNetwork, double MutationRate, Random Rand) { Parallel.For(0, NeuralLayers.Count, i => { //Cross Over The Neurons From Each Layer At Given Cut Off Point int Flip = Rand.Next(2); int CutPoint = Rand.Next(NeuralLayers[i].NeuronLength); for (int j = Flip == 0 ? 0 : CutPoint; j < (Flip == 0 ? CutPoint : NeuralLayers[i].NeuronLength); j++) { //Get The Neurons Neuron CurrentNeuron = NeuralLayers[i][j]; Neuron BetterNetworkNeuron = BetterNetwork.NeuralLayers[i][j]; for (int h = 0; h < CurrentNeuron.InputDendrites.Length; h++) { CurrentNeuron.InputDendrites[h] = BetterNetworkNeuron.InputDendrites[h]; } CurrentNeuron.BiasValue = (BetterNetworkNeuron.BiasValue + CurrentNeuron.BiasValue) / 2; } //Mutate The Crossed Over Neurons for (int j = 0; j < NeuralLayers[i].NeuronLength; j++) { ActivationFunc activationFunc = NeuralLayers[i].ActivationFunc; Neuron CurrentNeuron = NeuralLayers[i][j]; for (int h = 0; h < CurrentNeuron.InputDendrites.Length; h++) { if (Rand.NextDouble() < MutationRate) { Mutate(activationFunc, ref CurrentNeuron.InputDendrites[h], Rand); } } //Mutate The Bias if (Rand.NextDouble() < MutationRate) { Mutate(activationFunc, ref CurrentNeuron.BiasValue, Rand); } } }); }