public void TestAddSynapseMutator() { var mutator = new AddSynapseMutator(innovations); var mutatedGenotype = new Genotype(genotype); var mutationResults = new MutationResults(); mutator.Mutate(mutatedGenotype, mutationResults); Assert.AreEqual(1, mutationResults.addedSynapses); // Compare gene counts Assert.AreEqual(mutatedGenotype.NeuronCount, genotype.NeuronCount); Assert.AreEqual(1, mutatedGenotype.SynapseCount - genotype.SynapseCount); // Compare innovation ids var aN = new [] { 0, 1, 2 }; var bN = mutatedGenotype.NeuronGenes.Select(g => g.InnovationId); Assert.That(aN.SequenceEqual(bN)); var aS = new [] { 3, 4, 5, 6 }; var bS = mutatedGenotype.SynapseGenes.Select(g => g.InnovationId); Assert.That(aS.SequenceEqual(bS)); }
public void Mutate(Genotype genotype, MutationResults results) { var neuronIndexA = Random.Range(0, genotype.NeuronCount); var neuronGeneA = genotype.NeuronGenes.ElementAt(neuronIndexA); var candidates = new List<NeuronGene>(genotype.NeuronGenes); candidates.Shuffle(); NeuronGene neuronGeneB = default(NeuronGene); bool foundNeuron = false; for (var i = 0; i < candidates.Count; i++) { neuronGeneB = candidates[i]; var exists = genotype.SynapseGenes.Any(s => neuronGeneA.InnovationId == s.fromNeuronId && neuronGeneB.InnovationId == s.toNeuronId); if (!exists) { foundNeuron = true; break; } } if (foundNeuron) { var synapseInnovationId = innovations.GetSynapseInnovationId(neuronGeneA.InnovationId, neuronGeneB.InnovationId); var synapseGene = new SynapseGene(synapseInnovationId, neuronGeneA.InnovationId, neuronGeneB.InnovationId, true); var synapseGenes = new GeneList<SynapseGene>(genotype.SynapseGenes); synapseGenes.Add(synapseGene); genotype.SynapseGenes = synapseGenes; results.addedSynapses += 1; } }
public void Init() { var innovations = new InnovationCollection(); var neuronGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetInitialNeuronInnovationId(i); return(new NeuronGene(inId, NeuronType.HiddenNeuron)); }).ToGeneList(); var synapseGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetSynapseInnovationId(i, i + 1); return(new SynapseGene(inId, i, i + 1, true)); }).ToGeneList(); var protoGenotype = new Genotype(neuronGenes, synapseGenes); var phenotypes = Enumerable.Range(0, 100).Select(_ => { var gt = Genotype.FromPrototype(protoGenotype); var pt = new Phenotype(gt); return(pt); }).ToArray(); var distanceMetric = new NEAT.DistanceMetric(0.0f, 0.0f, 35.0f); var speciation = new NEAT.Speciation(10, 50.0f, 0.2f, distanceMetric); species = speciation.Speciate(new NEAT.Specie[0], phenotypes); }
public void Mutate(Genotype genotype, MutationResults results) { var prunedSynapses = genotype.SynapseGenes .Where(_ => Random.value < p) .Where(g => !g.isEnabled) .ToList(); var synapseGenes = genotype.SynapseGenes.Except(prunedSynapses) .ToGeneList(); genotype.SynapseGenes = synapseGenes; // An orphan is a neuron with no connecting synapses // For each neuron: check if any synapse connects to it // Exclude IO neurons var orphanedNeurons = genotype.HiddenNeurons.Where(g => synapseGenes.None(s => s.fromNeuronId == g.InnovationId || s.toNeuronId == g.InnovationId)).ToList(); var neuronGenes = genotype.NeuronGenes.Except(orphanedNeurons) .ToGeneList(); genotype.NeuronGenes = neuronGenes; results.orphanedNeurons += orphanedNeurons.Count; results.prunedSynapses += prunedSynapses.Count; }
public void Init() { var innovations = new InnovationCollection(); var neuronGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetInitialNeuronInnovationId(i); return new NeuronGene(inId, NeuronType.HiddenNeuron); }).ToGeneList(); var synapseGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetSynapseInnovationId(i, i + 1); return new SynapseGene(inId, i, i + 1, true); }).ToGeneList(); var protoGenotype = new Genotype(neuronGenes, synapseGenes); var phenotypes = Enumerable.Range(0, 100).Select(_ => { var gt = Genotype.FromPrototype(protoGenotype); var pt = new Phenotype(gt); return pt; }).ToArray(); var distanceMetric = new NEAT.DistanceMetric(0.0f, 0.0f, 35.0f); var speciation = new NEAT.Speciation(10, 50.0f, 0.2f, distanceMetric); species = speciation.Speciate(new NEAT.Specie[0], phenotypes); }
public Specie(int speciesId, Genotype representative, int age, int bestAge, float pastBestAdjustedFitness) : base() { this.speciesId = speciesId; this.representative = representative; this.age = age; this.bestAge = bestAge; this.pastBestAdjustedFitness = pastBestAdjustedFitness; }
public void TestGenotype_RoundTripJSON() { var json = "{\"neurons\":[{\"innovation\":0,\"type\":4,\"mean\":0.5,\"sigma\":0,\"a\":0.5,\"b\":0.5,\"c\":0.5,\"d\":0.5},{\"innovation\":1,\"type\":4,\"mean\":0.5,\"sigma\":0,\"a\":0.5,\"b\":0.5,\"c\":0.5,\"d\":0.5},{\"innovation\":2,\"type\":4,\"mean\":0.5,\"sigma\":0,\"a\":0.5,\"b\":0.5,\"c\":0.5,\"d\":0.5}],\"synapses\":[{\"innovation\":0,\"weight\":0.5,\"from\":0,\"to\":1,\"enabled\":true},{\"innovation\":1,\"weight\":0.5,\"from\":0,\"to\":1,\"enabled\":true},{\"innovation\":2,\"weight\":0.5,\"from\":0,\"to\":1,\"enabled\":true}]}"; var deserializedGenotype = Genotype.FromJSON(JSON.Deserialize(json)); var serializedGenotype = JSON.Serialize(deserializedGenotype.ToJSON()); Assert.AreEqual(json, serializedGenotype, "JSON can convert round-trip"); }
public void TestGenotype_FromJSON() { var json = "{\"neurons\":[{\"innovation\":0,\"type\":4,\"mean\":0.5,\"sigma\":0,\"a\":0.5,\"b\":0.5,\"c\":0.5,\"d\":0.5},{\"innovation\":1,\"type\":4,\"mean\":0.5,\"sigma\":0,\"a\":0.5,\"b\":0.5,\"c\":0.5,\"d\":0.5},{\"innovation\":2,\"type\":4,\"mean\":0.5,\"sigma\":0,\"a\":0.5,\"b\":0.5,\"c\":0.5,\"d\":0.5}],\"synapses\":[{\"innovation\":0,\"weight\":0.5,\"from\":0,\"to\":1,\"enabled\":true},{\"innovation\":1,\"weight\":0.5,\"from\":0,\"to\":1,\"enabled\":true},{\"innovation\":2,\"weight\":0.5,\"from\":0,\"to\":1,\"enabled\":true}]}"; var deserializedGenotype = Genotype.FromJSON(JSON.Deserialize(json)); var comparer = new GenotypeEqualityComparer(); Assert.That(comparer.Equals(genotype, deserializedGenotype)); }
public Genotype(Genotype other) { this.neuronGenes = other.NeuronGenes .Select(g => new NeuronGene(g)) .ToGeneList(); this.synapseGenes = other.SynapseGenes .Select(g => new SynapseGene(g)) .ToGeneList(); }
public void TestGenotype_Clone() { var clonedGenotype = new Genotype(genotype); Assert.AreNotSame(genotype, clonedGenotype); Assert.AreNotSame(genotype.NeuronGenes, clonedGenotype.NeuronGenes); Assert.AreNotSame(genotype.SynapseGenes, clonedGenotype.SynapseGenes); var comparer = new GenotypeEqualityComparer(); Assert.That(comparer.Equals(genotype, clonedGenotype)); }
public void Init() { var neuronGenes = Enumerable.Range(0, 3) .Select(i => new NeuronGene(i, NeuronType.HiddenNeuron)) .ToGeneList(); var synapseGenes = Enumerable.Range(0, 3) .Select(i => new SynapseGene(i, 0, 1, true, 0.5f)) .ToGeneList(); genotype = new Genotype(neuronGenes, synapseGenes); }
public void Mutate(Genotype genotype, MutationResults results) { var innovationIds = genotype.NeuronGenes.InnovationIds; for (int i = 0; i < innovationIds.Count; i++) { if (Random.value < p) { var innovationId = innovationIds[i]; genotype.NeuronGenes[innovationId] = NeuronGene.Random(innovationId); results.replacedNeurons++; } } }
public static Genotype FromPrototype(Genotype protoGenotype) { var neuronGenes = protoGenotype.NeuronGenes .Select(g => NeuronGene.FromPrototype(g)) .ToGeneList(); var synapseGenes = protoGenotype.SynapseGenes .Select(g => SynapseGene.FromPrototype(g)) .ToGeneList(); return(new Genotype(neuronGenes, synapseGenes)); }
public void Mutate(Genotype genotype, MutationResults results) { var innovationIds = genotype.SynapseGenes.InnovationIds; for (int i = 0; i < innovationIds.Count; i++) { if (Random.value < p) { var synapseGene = genotype.SynapseGenes[innovationIds[i]]; synapseGene.weight = Mathf.Clamp01(RandomHelper.NextCauchy(synapseGene.weight, mutationScale)); genotype.SynapseGenes[synapseGene.InnovationId] = synapseGene; results.perturbedSynapses++; } } }
public void Mutate(Genotype genotype, MutationResults results) { var innovationIds = genotype.SynapseGenes.InnovationIds; for (int i = 0; i < innovationIds.Count; i++) { if (Random.value < p) { var synapseGene = genotype.SynapseGenes[innovationIds[i]]; synapseGene.isEnabled = !synapseGene.isEnabled; genotype.SynapseGenes[synapseGene.InnovationId] = synapseGene; results.toggledSynapses++; } } }
public void Mutate(Genotype genotype, MutationResults results) { var innovationIds = genotype.SynapseGenes.InnovationIds; for (int i = 0; i < innovationIds.Count; i++) { if (Random.value < p) { var synapseGene = genotype.SynapseGenes[innovationIds[i]]; synapseGene.weight = Random.value; genotype.SynapseGenes[synapseGene.InnovationId] = synapseGene; results.replacedSynapses++; } } }
public void Mutate(Genotype genotype, MutationResults results) { // We require a synapse to split if (genotype.SynapseCount == 0) { return; } // Pick a synapse at random var synapseIndex = Random.Range(0, genotype.SynapseCount); var synapseGene = genotype.SynapseGenes.ElementAt(synapseIndex); // Generate an innovation id for the operation var innovationId = innovations.GetNeuronInnovationId( synapseGene.fromNeuronId, synapseGene.toNeuronId, synapseGene.InnovationId ); // If the genotype already contains the innovation id, bail if (genotype.Contains(innovationId)) { return; } var neuronGene = NeuronGene.Random(innovationId); var neuronGenes = new GeneList <NeuronGene>(genotype.NeuronGenes); neuronGenes.Add(neuronGene); genotype.NeuronGenes = neuronGenes; var synapseGenes = new GeneList <SynapseGene>(genotype.SynapseGenes); var synapseGene1 = new SynapseGene(innovationId + 0, synapseGene.fromNeuronId, neuronGene.InnovationId, true, 0.5f); synapseGenes.Add(synapseGene1); var synapseGene2 = new SynapseGene(innovationId + 1, neuronGene.InnovationId, synapseGene.toNeuronId, true, 0.5f); synapseGenes.Add(synapseGene2); genotype.SynapseGenes = synapseGenes; results.addedNeurons += 1; results.addedSynapses += 2; }
public void TestPerturbSynapseMutator() { var mutator = new PerturbSynapseMutator(1.0f, 0.25f); var mutatedGenotype = new Genotype(genotype); var mutationResults = new MutationResults(); mutator.Mutate(mutatedGenotype, mutationResults); Assert.AreEqual(3, mutationResults.perturbedSynapses); // Compare gene counts var comparer = new GenotypeShapeEqualityComparer(); Assert.That(comparer.Equals(mutatedGenotype, genotype)); }
public Genotype Crossover(Phenotype a, Phenotype b) { if (a == b) { return(new Genotype(a.Genotype)); } var aGenotype = new Genotype(a.Genotype); var bGenotype = new Genotype(b.Genotype); var newNeuronGenes = CrossoverGenes <NeuronGene>(aGenotype.NeuronGenes, bGenotype.NeuronGenes, a.AdjustedFitness, b.AdjustedFitness); var newSynapseGenes = CrossoverGenes <SynapseGene>(aGenotype.SynapseGenes, bGenotype.SynapseGenes, a.AdjustedFitness, b.AdjustedFitness); return(new Genotype(newNeuronGenes, newSynapseGenes)); }
public void TestReplaceSynapseMutator() { var mutator = new ReplaceSynapseMutator(1.0f); var mutatedGenotype = new Genotype(genotype); var mutationResults = new MutationResults(); mutator.Mutate(mutatedGenotype, mutationResults); Assert.AreEqual(mutationResults.replacedSynapses, 3); // Compare gene counts var comparer = new GenotypeShapeEqualityComparer(); Assert.That(comparer.Equals(mutatedGenotype, genotype)); }
public void TestMutationCollection() { var genotypes = Enumerable.Range(0, 100).Select(_ => Genotype.FromPrototype(protoGenotype)).ToArray(); var mutations = new NEAT.MutationCollection(); mutations.Add(0.75f, new NEAT.AddNeuronMutator(innovations)); mutations.Add(0.25f, new NEAT.AddSynapseMutator(innovations)); var results = mutations.Mutate(genotypes); Assert.AreEqual(75, results.addedNeurons, 75 * 0.15f); Assert.AreEqual(175, results.addedSynapses, 175 * 0.25f); }
public void Mutate(Genotype genotype, MutationResults results) { // We require a synapse to split if (genotype.SynapseCount == 0) { return; } // Pick a synapse at random var synapseIndex = Random.Range(0, genotype.SynapseCount); var synapseGene = genotype.SynapseGenes.ElementAt(synapseIndex); // Generate an innovation id for the operation var innovationId = innovations.GetNeuronInnovationId( synapseGene.fromNeuronId, synapseGene.toNeuronId, synapseGene.InnovationId ); // If the genotype already contains the innovation id, bail if (genotype.Contains(innovationId)) { return; } var neuronGene = NeuronGene.Random(innovationId); var neuronGenes = new GeneList<NeuronGene>(genotype.NeuronGenes); neuronGenes.Add(neuronGene); genotype.NeuronGenes = neuronGenes; var synapseGenes = new GeneList<SynapseGene>(genotype.SynapseGenes); var synapseGene1 = new SynapseGene(innovationId + 0, synapseGene.fromNeuronId, neuronGene.InnovationId, true, 0.5f); synapseGenes.Add(synapseGene1); var synapseGene2 = new SynapseGene(innovationId + 1, neuronGene.InnovationId, synapseGene.toNeuronId, true, 0.5f); synapseGenes.Add(synapseGene2); genotype.SynapseGenes = synapseGenes; results.addedNeurons += 1; results.addedSynapses += 2; }
public void Init() { var innovations = new InnovationCollection(); var neuronGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetInitialNeuronInnovationId(i); return(new NeuronGene(inId, NeuronType.HiddenNeuron)); }).ToGeneList(); var synapseGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetSynapseInnovationId(i, i + 1); return(new SynapseGene(inId, i, i + 1, true)); }).ToGeneList(); protoGenotype = new Genotype(neuronGenes, synapseGenes); }
public MutationResults Mutate(Genotype[] genotypes) { var orderedMutators = mutators.OrderBy(m => m.Key); var results = new MutationResults(); foreach (var genotype in genotypes) { foreach (var p_mutator in orderedMutators) { var p = p_mutator.Key; var mutator = p_mutator.Value; if (Random.value < p) { mutator.Mutate(genotype, results); break; } } } return results; }
public void TestPerturbNeuronMutator() { var mutator = new PerturbNeuronMutator(1.0f, 0.25f); var mutatedGenotype = new Genotype(genotype); var mutationResults = new MutationResults(); mutator.Mutate(mutatedGenotype, mutationResults); Assert.AreEqual(3, mutationResults.perturbedNeurons); // Compare gene counts var comparer = new GenotypeShapeEqualityComparer(); Assert.That(comparer.Equals(mutatedGenotype, genotype)); }
public void Init() { var innovations = new InnovationCollection(); var neuronGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetInitialNeuronInnovationId(i); return new NeuronGene(inId, NeuronType.HiddenNeuron); }).ToGeneList(); var synapseGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetSynapseInnovationId(i, i + 1); return new SynapseGene(inId, i, i + 1, true); }).ToGeneList(); genotype = new Genotype(neuronGenes, synapseGenes); }
public void Mutate(Genotype genotype, MutationResults results) { var innovationIds = genotype.NeuronGenes.InnovationIds; for (int i = 0; i < innovationIds.Count; i++) { if (Random.value < p) { var neuronGene = genotype.NeuronGenes[innovationIds[i]]; neuronGene.a = Mathf.Clamp01(RandomHelper.NextCauchy(neuronGene.a, mutationScale)); neuronGene.b = Mathf.Clamp01(RandomHelper.NextCauchy(neuronGene.b, mutationScale)); neuronGene.c = Mathf.Clamp01(RandomHelper.NextCauchy(neuronGene.c, mutationScale)); neuronGene.d = Mathf.Clamp01(RandomHelper.NextCauchy(neuronGene.d, mutationScale)); neuronGene.mean = Mathf.Clamp01(RandomHelper.NextCauchy(neuronGene.mean, mutationScale)); neuronGene.sigma = Mathf.Clamp01(RandomHelper.NextCauchy(neuronGene.sigma, mutationScale)); genotype.NeuronGenes[neuronGene.InnovationId] = neuronGene; results.perturbedNeurons++; } } }
public void TestSpecie() { var specie = new Specie(13, protoGenotype, 0, 0, 0.0f); for (int i = 0; i < 100; i++) { var gt = Genotype.FromPrototype(protoGenotype); var pt = new Phenotype(gt); specie.Add(pt); } foreach (var pt in specie) { pt.AdjustedFitness = 1.0f / (float)specie.Count; } Assert.AreEqual(0.0f, specie.MeanFitness, 0.001f); Assert.AreEqual(0.01f, specie.MeanAdjustedFitness, 0.001f); Assert.AreEqual(100, specie.Count); }
public void Init() { var neuronGenesA = Enumerable.Range(0, 3) .Select(i => new NeuronGene(i, NeuronType.HiddenNeuron)) .ToGeneList(); var synapseGenesA = Enumerable.Range(0, 3) .Select(i => new SynapseGene(i, 0, 1, true, 0.5f)) .ToGeneList(); genotypeA = new Genotype(neuronGenesA, synapseGenesA); genotypeB = new Genotype(genotypeA); var neuronGenesC = Enumerable.Range(0, 3) .Select(i => new NeuronGene(i, NeuronType.HiddenNeuron)) .ToGeneList(); var synapseGenesC = Enumerable.Range(0, 3) .Select(i => new SynapseGene(i + 1, -1, 1, true, 0.0f)) .ToGeneList(); genotypeC = new Genotype(neuronGenesC, synapseGenesC); }
public void Mutate(Genotype genotype, MutationResults results) { var neuronIndexA = Random.Range(0, genotype.InputNeurons.Count); var neuronGeneA = genotype.InputNeurons[neuronIndexA]; var validNeurons = genotype.OutputNeurons .Where(_ => Random.value < p) .Where(neuronGeneB => genotype.SynapseGenes.None(s => neuronGeneA.InnovationId == s.fromNeuronId && neuronGeneB.InnovationId == s.toNeuronId)); foreach (var neuronGeneB in validNeurons) { var synapseInnovationId = innovations.GetSynapseInnovationId(neuronGeneA.InnovationId, neuronGeneB.InnovationId); var synapseGene = SynapseGene.Random(synapseInnovationId, neuronGeneA.InnovationId, neuronGeneB.InnovationId, true); var synapseGenes = new GeneList<SynapseGene>(genotype.SynapseGenes); synapseGenes.Add(synapseGene); genotype.SynapseGenes = synapseGenes; results.addedSynapses += 1; } }
public void Init() { var innovations = new InnovationCollection(); var neuronGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetInitialNeuronInnovationId(i); return new NeuronGene(inId, NeuronType.HiddenNeuron); }).ToGeneList(); var synapseGenes = Enumerable.Range(0, 3).Select(i => { var inId = innovations.GetSynapseInnovationId(i, i + 1); return new SynapseGene(inId, i, i + 1, true); }).ToGeneList(); var protoGenotype = new Genotype(neuronGenes, synapseGenes); phenotypes = Enumerable.Range(0, 100).Select(_ => { var gt = Genotype.FromPrototype(protoGenotype); var pt = new Phenotype(gt); return pt; }).ToArray(); }
public void Mutate(Genotype genotype, MutationResults results) { var neuronIndexA = Random.Range(0, genotype.NeuronCount); var neuronGeneA = genotype.NeuronGenes.ElementAt(neuronIndexA); var candidates = new List <NeuronGene>(genotype.NeuronGenes); candidates.Shuffle(); NeuronGene neuronGeneB = default(NeuronGene); bool foundNeuron = false; for (var i = 0; i < candidates.Count; i++) { neuronGeneB = candidates[i]; var exists = genotype.SynapseGenes.Any(s => neuronGeneA.InnovationId == s.fromNeuronId && neuronGeneB.InnovationId == s.toNeuronId); if (!exists) { foundNeuron = true; break; } } if (foundNeuron) { var synapseInnovationId = innovations.GetSynapseInnovationId(neuronGeneA.InnovationId, neuronGeneB.InnovationId); var synapseGene = new SynapseGene(synapseInnovationId, neuronGeneA.InnovationId, neuronGeneB.InnovationId, true); var synapseGenes = new GeneList <SynapseGene>(genotype.SynapseGenes); synapseGenes.Add(synapseGene); genotype.SynapseGenes = synapseGenes; results.addedSynapses += 1; } }
public void TestAddSynapseMutator() { var mutator = new AddSynapseMutator(innovations); var mutatedGenotype = new Genotype(genotype); var mutationResults = new MutationResults(); mutator.Mutate(mutatedGenotype, mutationResults); Assert.AreEqual(1, mutationResults.addedSynapses); // Compare gene counts Assert.AreEqual(mutatedGenotype.NeuronCount, genotype.NeuronCount); Assert.AreEqual(1, mutatedGenotype.SynapseCount - genotype.SynapseCount); // Compare innovation ids var aN = new []{0, 1, 2}; var bN = mutatedGenotype.NeuronGenes.Select(g => g.InnovationId); Assert.That(aN.SequenceEqual(bN)); var aS = new []{3, 4, 5, 6}; var bS = mutatedGenotype.SynapseGenes.Select(g => g.InnovationId); Assert.That(aS.SequenceEqual(bS)); }
public void Mutate(Genotype genotype, MutationResults results) { var neuronIndexA = Random.Range(0, genotype.InputNeurons.Count); var neuronGeneA = genotype.InputNeurons[neuronIndexA]; var validNeurons = genotype.OutputNeurons .Where(_ => Random.value < p) .Where(neuronGeneB => genotype.SynapseGenes.None(s => neuronGeneA.InnovationId == s.fromNeuronId && neuronGeneB.InnovationId == s.toNeuronId)); foreach (var neuronGeneB in validNeurons) { var synapseInnovationId = innovations.GetSynapseInnovationId(neuronGeneA.InnovationId, neuronGeneB.InnovationId); var synapseGene = SynapseGene.Random(synapseInnovationId, neuronGeneA.InnovationId, neuronGeneB.InnovationId, true); var synapseGenes = new GeneList <SynapseGene>(genotype.SynapseGenes); synapseGenes.Add(synapseGene); genotype.SynapseGenes = synapseGenes; results.addedSynapses += 1; } }
public void TestMultipointCrossover() { var innovationIdsA = new int[] { 1, 2, 3, 4, 5, 8 }; var neuronGenesA = innovationIdsA.Select(i => new NeuronGene(i, NeuronType.HiddenNeuron)).ToGeneList(); var innovationIdsB = new int[] { 1, 2, 3, 4, 5, 6, 7, 9, 10 }; var neuronGenesB = innovationIdsB.Select(i => new NeuronGene(i, NeuronType.HiddenNeuron)).ToGeneList(); var expectedInnovationIds = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var genotypeA = new Genotype(neuronGenesA, new GeneList <SynapseGene>(0)); var genotypeB = new Genotype(neuronGenesB, new GeneList <SynapseGene>(0)); var phenotypeA = new Phenotype(genotypeA); var phenotypeB = new Phenotype(genotypeB); var crossover = new MultipointCrossover(); var offspring = crossover.Crossover(phenotypeA, phenotypeB); var offspringInnovationIds = offspring.NeuronGenes.Select(g => g.InnovationId).ToArray(); Assert.AreEqual(expectedInnovationIds, offspringInnovationIds); }
public void TestMultipointCrossover() { var innovationIdsA = new int[]{1, 2, 3, 4, 5, 8}; var neuronGenesA = innovationIdsA.Select(i => new NeuronGene(i, NeuronType.HiddenNeuron)).ToGeneList(); var innovationIdsB = new int[]{1, 2, 3, 4, 5, 6, 7, 9, 10}; var neuronGenesB = innovationIdsB.Select(i => new NeuronGene(i, NeuronType.HiddenNeuron)).ToGeneList(); var expectedInnovationIds = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; var genotypeA = new Genotype(neuronGenesA, new GeneList<SynapseGene>(0)); var genotypeB = new Genotype(neuronGenesB, new GeneList<SynapseGene>(0)); var phenotypeA = new Phenotype(genotypeA); var phenotypeB = new Phenotype(genotypeB); var crossover = new MultipointCrossover(); var offspring = crossover.Crossover(phenotypeA, phenotypeB); var offspringInnovationIds = offspring.NeuronGenes.Select(g => g.InnovationId).ToArray(); Assert.AreEqual(expectedInnovationIds, offspringInnovationIds); }
public Phenotype(Genotype genotype) { this.genotype = genotype; }
public bool MeasureDistance(Genotype a, Genotype b, float threshold) { return(MeasureDistance(a, b) <= threshold); }
IEnumerator Start() { var logPath = string.Format("logs_{0}", DateTime.Now.Ticks); Debug.LogFormat("Logging to {0}", logPath); if (!Directory.Exists(logPath)) { Directory.CreateDirectory(logPath); } elitesLog = File.CreateText(Path.Combine(logPath, "elites.csv")); populationLog = File.CreateText(Path.Combine(logPath, "populations.csv")); generationLog = File.CreateText(Path.Combine(logPath, "generations.csv")); speciesLog = File.CreateText(Path.Combine(logPath, "species.csv")); var populationSize = 100; var innovations = new InnovationCollection(); var mutations = new MutationCollection(); mutations.Add(0.01f, new AddNeuronMutator(innovations)); // 0.1% mutations.Add(0.05f, new AddSynapseMutator(innovations)); // 1% mutations.Add(0.05f, new ToggleSynapseMutator(0.125f)); mutations.Add(0.20f, new PerturbNeuronMutator(0.5f, 0.25f)); // 98% vvv mutations.Add(0.20f, new PerturbSynapseMutator(0.5f, 0.25f)); mutations.Add(0.20f, new ReplaceNeuronMutator(0.5f)); mutations.Add(0.20f, new ReplaceSynapseMutator(0.5f)); var eliteSelector = new EliteSelector(); var crossover = new MultipointCrossover(); var offspringSelector = new OffspringSelector(crossover); var distanceMetric = new DistanceMetric(2.0f, 2.0f, 1.0f); var speciation = new Speciation(10, 6.0f, 0.3f, distanceMetric); var neuronGenes = new []{ new NeuronGene(innovations.GetInitialNeuronInnovationId(0), NeuronType.UpperNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(1), NeuronType.LowerNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(2), NeuronType.PositionNeuron), new NeuronGene(innovations.GetInitialNeuronInnovationId(3), NeuronType.SpeedNeuron), }.ToGeneList(); var synapseGenes = new GeneList<SynapseGene>(); var protoGenotype = new Genotype(neuronGenes, synapseGenes); var genotypes = new GenotypeStream(protoGenotype) .Take(populationSize).ToArray(); var species = new Specie[0]; var generation = 0; var elitePhenotypes = new List<Phenotype>(); var offspringPhenotypes = genotypes.Select(gt => new Phenotype(gt)).ToList(); while (true) { yield return StartCoroutine(EvaluatePopulation(offspringPhenotypes)); var phenotypes = new List<Phenotype>(elitePhenotypes.Count + offspringPhenotypes.Count); phenotypes.AddRange(elitePhenotypes); phenotypes.AddRange(offspringPhenotypes); Assert.AreEqual(phenotypes.Count, populationSize, "Population size must remain constant"); var longest = phenotypes.OrderByDescending(pt => pt.BestDuration).First(); Debug.LogFormat("[{0}] Fitness: {1}, Duration: {2}s ({3}, {4}) (Longest)", generation, longest.MeanFitness, longest.MeanDuration, longest.Genotype.NeuronCount, longest.Genotype.SynapseCount); var best = phenotypes.OrderByDescending(pt => pt.Fitness).First(); Debug.LogFormat("[{0}] Fitness: {1}, Duration: {2}s ({3}, {4}) (Best)", generation, best.MeanFitness, best.MeanDuration, best.Genotype.NeuronCount, best.Genotype.SynapseCount); elitesLog.WriteLine(string.Join(",", new string[]{ generation.ToString(), best.Fitness.ToString(), best.BestDuration.ToString(), JSON.Serialize(best.Genotype.ToJSON()), })); var meanComplexity = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.Complexity, (sum) => sum / (float)phenotypes.Count); var meanNeuronCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.NeuronCount, (sum) => sum / (float)phenotypes.Count); var meanSynapseCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Genotype.SynapseCount, (sum) => sum / (float)phenotypes.Count); var meanFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.Fitness, (sum) => sum / (float)phenotypes.Count); var stdevFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow(pt.Fitness - meanFitness, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevComplexity = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.Complexity - meanComplexity, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevNeuronCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.NeuronCount - meanNeuronCount, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); var stdevSynapseCount = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow((float)pt.Genotype.SynapseCount - meanSynapseCount, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); species = speciation.Speciate(species, phenotypes.ToArray()); Debug.LogFormat("[{0}] Species Count: {1} (Threshold: {2})", generation, species.Length, speciation.DistanceThreshold); var meanAdjustedFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + (float)pt.AdjustedFitness, (sum) => sum / (float)phenotypes.Count); // standard deviation: // take the square root of the average of the squared deviations of the values from their average value var stdevAdjustedFitness = phenotypes.Aggregate(0.0f, (sum, pt) => sum + Mathf.Pow(pt.AdjustedFitness - meanAdjustedFitness, 2.0f), (sum) => Mathf.Sqrt(sum / (float)phenotypes.Count)); generationLog.WriteLine(new []{ generation, best.Fitness, best.MeanDuration, meanAdjustedFitness, stdevAdjustedFitness, meanFitness, stdevFitness, meanComplexity, stdevComplexity, meanNeuronCount, stdevNeuronCount, meanSynapseCount, stdevSynapseCount }.Stringify()); foreach (var sp in species) { speciesLog.WriteLine(new []{ generation, sp.SpeciesId, sp.Count, sp.BestFitness, sp.MeanFitness, sp.MeanAdjustedFitness, sp.MeanComplexity, }.Stringify()); foreach (var pt in sp) { populationLog.WriteLine(new []{ generation, sp.SpeciesId, pt.Fitness, pt.AdjustedFitness, pt.BestDuration, pt.Genotype.Complexity, pt.Genotype.NeuronCount, pt.Genotype.SynapseCount, }.Stringify()); } } var eliteCount = species.Length; elitePhenotypes = eliteSelector.Select(species, eliteCount); var offspringCount = populationSize - elitePhenotypes.Count; var offspringGenotypes = offspringSelector.Select(species, offspringCount); var mutationResults = mutations.Mutate(offspringGenotypes); Debug.LogFormat("[{0}] Mutations: Added Neurons: {1}, Added Synapses: {2}, Perturbed Neurons: {3}, Perturbed Synapses: {4}, Replaced Neurons: {5}, Replaced Synapses: {6}, Toggled Synapses: {7}, Pruned Synapses: {8}, Orphaned Neurons: {9}", generation, mutationResults.addedNeurons, mutationResults.addedSynapses, mutationResults.perturbedNeurons, mutationResults.perturbedSynapses, mutationResults.replacedNeurons, mutationResults.replacedSynapses, mutationResults.toggledSynapses, mutationResults.prunedSynapses, mutationResults.orphanedNeurons); offspringPhenotypes = offspringGenotypes.Select(gt => new Phenotype(gt)).ToList(); generation++; // Flush these so we can preview results while it runs generationLog.Flush(); populationLog.Flush(); speciesLog.Flush(); } }
public bool MeasureDistance(Genotype a, Genotype b, float threshold) { return MeasureDistance(a, b) <= threshold; }
public float MeasureDistance(Genotype a, Genotype b) { var neuronCount = Mathf.Max(a.NeuronCount, b.NeuronCount); if (neuronCount == 0) { // Don't divide by zero neuronCount = 1; } var neuronDiff = 0.0f; var neuronExcess = 0.0f; var neuronDisjoint = 0.0f; foreach (var t in new GeneEnumerable<NeuronGene>(a.NeuronGenes, b.NeuronGenes)) { switch (t.First) { case HistoricalGeneTypes.Aligned: neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].a - b.NeuronGenes[t.Third].a); neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].b - b.NeuronGenes[t.Third].b); neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].c - b.NeuronGenes[t.Third].c); neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].d - b.NeuronGenes[t.Third].d); break; case HistoricalGeneTypes.DisjointA: case HistoricalGeneTypes.DisjointB: neuronDisjoint++; break; case HistoricalGeneTypes.ExcessA: case HistoricalGeneTypes.ExcessB: neuronExcess++; break; } } var synapseCount = Mathf.Max(a.SynapseCount, b.SynapseCount); if (synapseCount == 0) { // Don't divide by zero synapseCount = 1; } var synapseDiff = 0.0f; var synapseExcess = 0.0f; var synapseDisjoint = 0.0f; foreach (var t in new GeneEnumerable<SynapseGene>(a.SynapseGenes, b.SynapseGenes)) { switch (t.First) { case HistoricalGeneTypes.Aligned: synapseDiff += Mathf.Abs(a.SynapseGenes[t.Second].weight - b.SynapseGenes[t.Third].weight); break; case HistoricalGeneTypes.DisjointA: case HistoricalGeneTypes.DisjointB: synapseDisjoint++; break; case HistoricalGeneTypes.ExcessA: case HistoricalGeneTypes.ExcessB: synapseExcess++; break; } } neuronDiff /= (float)neuronCount; synapseDiff /= (float)synapseCount; return (excessCoeff * neuronExcess) + (excessCoeff * synapseExcess) + (disjointCoeff * neuronDisjoint) + (disjointCoeff * synapseDisjoint) + (mutationCoeff * neuronDiff) + (mutationCoeff * synapseDiff); }
public static Genotype FromPrototype(Genotype protoGenotype) { var neuronGenes = protoGenotype.NeuronGenes .Select(g => NeuronGene.FromPrototype(g)) .ToGeneList(); var synapseGenes = protoGenotype.SynapseGenes .Select(g => SynapseGene.FromPrototype(g)) .ToGeneList(); return new Genotype(neuronGenes, synapseGenes); }
public static NetworkPorts FromGenotype(NEAT.Genotype genotype) { var neuronGenes = genotype.NeuronGenes.ToList(); var synapseGenes = genotype.SynapseGenes.ToList(); var network = new Neural.Network(20ul); var upperNeurons = new Dictionary <int, IReceptiveField>(); var lowerNeurons = new Dictionary <int, IReceptiveField>(); var positionNeurons = new Dictionary <int, IReceptiveField>(); var speedNeurons = new Dictionary <int, IReceptiveField>(); foreach (var neuronGene in neuronGenes) { float a = NumberHelper.Scale(neuronGene.a, 0.02f, 0.1f); // 0.1 float b = NumberHelper.Scale(neuronGene.b, 0.2f, 0.25f); // 0.2 float c = NumberHelper.Scale(neuronGene.c, -65.0f, -50.0f); // -65.0 float d = NumberHelper.Scale(neuronGene.d, 0.05f, 8.0f); // 2.0 try { var id = (int)network.AddNeuron(Neural.IzhikevichConfig.Of(a, b, c, d)); var mean = 0.0f; var sigma = 0.0f; switch (neuronGene.type) { case NeuronType.UpperNeuron: mean = NumberHelper.Scale(neuronGene.mean, -180.0f, 180.0f); sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 180.0f); upperNeurons[id] = new SignReceptiveField(mean, sigma); break; case NeuronType.LowerNeuron: mean = NumberHelper.Scale(neuronGene.mean, -180.0f, 180.0f); sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 180.0f); lowerNeurons[id] = new SignReceptiveField(mean, sigma); break; case NeuronType.PositionNeuron: mean = NumberHelper.Scale(neuronGene.mean, -12.0f, 12.0f); sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 12.0f); positionNeurons[id] = new SignReceptiveField(mean, sigma); break; case NeuronType.SpeedNeuron: mean = NumberHelper.Scale(neuronGene.mean, -1.0f, 1.0f); sigma = NumberHelper.Scale(neuronGene.sigma, 0.0f, 1000.0f); speedNeurons[id] = new MulReceptiveField(mean, sigma); break; } } catch (Exception e) { Debug.LogException(e); } } // Connect each input neuron to the output neuron. foreach (var synapseGene in synapseGenes) { if (!synapseGene.isEnabled) { continue; } var fromNeuronId = neuronGenes.FindIndex(n => n.InnovationId == synapseGene.fromNeuronId); var toNeuronId = neuronGenes.FindIndex(n => n.InnovationId == synapseGene.toNeuronId); Assert.AreNotEqual(fromNeuronId, -1, "Must find from-neuron id"); Assert.AreNotEqual(toNeuronId, -1, "Must find to-neuron id"); float weight = NumberHelper.Scale(synapseGene.weight, -40.0f, 40.0f); try { network.AddSynapse((ulong)fromNeuronId, (ulong)toNeuronId, Neural.STDPConfig.Of(weight, -40.0f, 40.0f)); } catch (Exception e) { Debug.LogException(e); } } return(new NetworkPorts(network, upperNeurons, lowerNeurons, positionNeurons, speedNeurons)); }
public float MeasureDistance(Genotype a, Genotype b) { var neuronCount = Mathf.Max(a.NeuronCount, b.NeuronCount); if (neuronCount == 0) // Don't divide by zero { neuronCount = 1; } var neuronDiff = 0.0f; var neuronExcess = 0.0f; var neuronDisjoint = 0.0f; foreach (var t in new GeneEnumerable <NeuronGene>(a.NeuronGenes, b.NeuronGenes)) { switch (t.First) { case HistoricalGeneTypes.Aligned: neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].a - b.NeuronGenes[t.Third].a); neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].b - b.NeuronGenes[t.Third].b); neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].c - b.NeuronGenes[t.Third].c); neuronDiff += Mathf.Abs(a.NeuronGenes[t.Second].d - b.NeuronGenes[t.Third].d); break; case HistoricalGeneTypes.DisjointA: case HistoricalGeneTypes.DisjointB: neuronDisjoint++; break; case HistoricalGeneTypes.ExcessA: case HistoricalGeneTypes.ExcessB: neuronExcess++; break; } } var synapseCount = Mathf.Max(a.SynapseCount, b.SynapseCount); if (synapseCount == 0) // Don't divide by zero { synapseCount = 1; } var synapseDiff = 0.0f; var synapseExcess = 0.0f; var synapseDisjoint = 0.0f; foreach (var t in new GeneEnumerable <SynapseGene>(a.SynapseGenes, b.SynapseGenes)) { switch (t.First) { case HistoricalGeneTypes.Aligned: synapseDiff += Mathf.Abs(a.SynapseGenes[t.Second].weight - b.SynapseGenes[t.Third].weight); break; case HistoricalGeneTypes.DisjointA: case HistoricalGeneTypes.DisjointB: synapseDisjoint++; break; case HistoricalGeneTypes.ExcessA: case HistoricalGeneTypes.ExcessB: synapseExcess++; break; } } neuronDiff /= (float)neuronCount; synapseDiff /= (float)synapseCount; return((excessCoeff * neuronExcess) + (excessCoeff * synapseExcess) + (disjointCoeff * neuronDisjoint) + (disjointCoeff * synapseDisjoint) + (mutationCoeff * neuronDiff) + (mutationCoeff * synapseDiff)); }