Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Neural evolution algorithms implementation (CNE, NEAT, HyperNEAT) #686

Closed
wants to merge 72 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
dc27518
change .gitignore to ignore .DS_Store
BangLiu May 17, 2016
88788d6
create gene.hpp, add ne_test.cpp, and created or modified multiple CM…
BangLiu May 20, 2016
6ab9add
Created gene.happ, add tests and changed or created CMakeLists.txt
BangLiu May 20, 2016
ca73f95
Add aDepth to NeuronGene.
BangLiu May 20, 2016
30ec0ba
implement CNE, haven't finish.
BangLiu May 28, 2016
7fdd7ca
delete blank files
BangLiu May 28, 2016
e4fbabd
finished genome.hpp, revised gene.hpp
BangLiu Jun 7, 2016
3c8aa62
modified gene.hpp
BangLiu Jun 7, 2016
cbb79a2
implemented CNE skeleton; more genome and population functions.
BangLiu Jun 9, 2016
65f093d
implemented XOR test case; need debugging; one heart function -- CNE:…
BangLiu Jun 10, 2016
eb16ce2
solved most bugs for testing XOR
BangLiu Jun 11, 2016
c6976ac
further solved some bugs in code.
BangLiu Jun 11, 2016
8919bb9
Solved bugs. Need to fulfill Reproduce() to finish CNE.
BangLiu Jun 12, 2016
ee548b6
CNE algorithm finished. XOR test passes. Need to revise coding style …
BangLiu Jun 12, 2016
faf47a2
Create Species class.
BangLiu Jun 19, 2016
adc45b2
Revised LinkGene and related file for NEAT
BangLiu Jun 20, 2016
95c2e53
revised sortSpecies()
BangLiu Jun 21, 2016
1ee07a0
add aAdjustedFitness to genome
BangLiu Jun 21, 2016
39ef07b
fix bug in CNE Reproduce()
BangLiu Jun 21, 2016
74fb4a0
Implemented neat mutations, replace size_t by ssize_t
BangLiu Jun 24, 2016
d0883f4
Implemented crossover, some bug exist
BangLiu Jun 26, 2016
a605eef
Revise Crossover, solve bugs, more functions implementations.
BangLiu Jun 26, 2016
e059af0
revised neat functions. In paper,disabled links also consider for cro…
BangLiu Jun 27, 2016
6c11f32
neat almost finished. Need debugging,need revise coding style, need t…
BangLiu Jun 28, 2016
3c10995
NEAT finished, but has bugs. XOR not pass.
BangLiu Jun 29, 2016
57d4165
In progress of debugging. Add lots of printf ... Will clear them afte…
BangLiu Jun 30, 2016
6a770ec
seems bugs solved. keep printf. Seems information such as species siz…
BangLiu Jun 30, 2016
cce115b
solve more bugs
BangLiu Jun 30, 2016
2a9899c
solved more. But still have problem.
BangLiu Jun 30, 2016
1a2cfd8
solved CalcAverageRank bug. Still have more.
BangLiu Jun 30, 2016
dacc2e6
currently seems no bug. Previously we removed stale species even when…
BangLiu Jun 30, 2016
2a4c715
revised WeightDiff
BangLiu Jun 30, 2016
6f901a1
Removed redundant members in species, population. haven't remove in g…
BangLiu Jul 1, 2016
a80f5f7
Further cleaned some code.
BangLiu Jul 1, 2016
3db85fd
changed the place where we should set the childGenome's NumInput, Num…
BangLiu Jul 1, 2016
8168779
changed neuron_gene, genome's activation. Still need to revise neat.
BangLiu Jul 2, 2016
554a279
Revised MutateAddLink.
BangLiu Jul 2, 2016
1fe7d73
solved some bugs about activation.
BangLiu Jul 7, 2016
ff45785
Add Cart Pole test. Result not good. Fitness doesn't improve.
BangLiu Jul 10, 2016
48e15c4
Solved more bugs.
BangLiu Jul 13, 2016
fc982b9
Fixed a bug in task. Removed adjustFitness. Problems maybe the parame…
BangLiu Jul 16, 2016
66b0f41
further revised something.
BangLiu Jul 17, 2016
109f05b
Passed Cart Pole problem. Revised neat, task.
BangLiu Jul 20, 2016
8054f00
Implemented test MountainCar, not pass yet.
BangLiu Jul 21, 2016
5ef61fe
Seems passed Mountain Car.. in 1 iteration
BangLiu Jul 21, 2016
f213dd8
Revised a bug in TaskMountainCar Action()
BangLiu Jul 21, 2016
f234ebd
added Success() for tasks.
BangLiu Jul 21, 2016
96ccef5
Finished double pole. Non-Markov have bug.
BangLiu Aug 3, 2016
24f9baf
revised non-markov, still have bug
BangLiu Aug 3, 2016
4decb0e
revised neat MutateAddLink. Non-Markov still have bug.
BangLiu Aug 3, 2016
c46436e
revised neat, clean genome before evaluate.
BangLiu Aug 4, 2016
000d6aa
Merge pull request #1 from mlpack/master
BangLiu Aug 5, 2016
2599077
revised a bug in Activate()
BangLiu Aug 5, 2016
408b40f
fix conflict
BangLiu Aug 5, 2016
0fc792c
changed header file in ne_test
BangLiu Aug 5, 2016
847db95
solved compile bug
BangLiu Aug 5, 2016
10b99ab
change ssize_t, size_t to int. Windows doesn't support ssize_t
BangLiu Aug 6, 2016
da55507
revised comment style, bracket style etc. Have strange compile error.
BangLiu Aug 8, 2016
beb8ba8
rebuild, solved compile problem. Add default constructors back. Witho…
BangLiu Aug 8, 2016
3b66431
Revised the style of all current code
BangLiu Aug 10, 2016
9480379
revised some tiny styles
BangLiu Aug 11, 2016
4483fc8
Revised NeuronGene to add aCoordinate. Tests all previous testings an…
BangLiu Aug 13, 2016
190e639
Revised neat.hpp. NeuronInnovation considers activation function type…
BangLiu Aug 13, 2016
4cd0054
Implemented first version of Hyperneat.
BangLiu Aug 15, 2016
668fa6e
revised HyperNEAT. No inheritance.
BangLiu Aug 16, 2016
62d5885
Solved bugs. Implemented XOR test. Not pass. Need debug.
BangLiu Aug 16, 2016
e176571
in the progress of debugging XOR test
BangLiu Aug 18, 2016
dec32ac
Find important bug in Activate()! revised. Still not pass hyperneat xor.
BangLiu Aug 19, 2016
bc178c3
small change.
BangLiu Aug 19, 2016
432331b
Solved the duplicated link bug. Changed MutateAddNeuron. Still not pa…
BangLiu Aug 21, 2016
0944516
Make the new neuron type random when add new neuron. Still not pass xor.
BangLiu Aug 26, 2016
d66bb14
Revised naming style
BangLiu Aug 29, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/mlpack/methods/ne/genome.hpp
Expand Up @@ -205,7 +205,6 @@ class Genome {
// Calculate Neuron depth.
ssize_t NeuronDepth(ssize_t id) {
// TODO: if contains loop in network.

// Find all links that output to this neuron id.
std::vector<int> inputLinksIndex;
for (ssize_t i=0; i<NumLink(); ++i) {
Expand All @@ -224,6 +223,7 @@ class Genome {
for (ssize_t i=0; i<inputLinksIndex.size(); ++i) {
depths[i] = NeuronDepth(aLinkGenes[inputLinksIndex[i]].FromNeuronId());
}

ssize_t maxInputDepth = *(std::max_element(std::begin(depths),
std::end(depths)));
return (maxInputDepth + 1);
Expand Down Expand Up @@ -291,6 +291,7 @@ class Genome {
neuronIdToIndex.insert(std::pair<ssize_t, ssize_t>(aNeuronGenes[i].Id(), i));
}

printf("aDepth is %d \n", aDepth);
// Activate layer by layer.
for (ssize_t i=0; i<aDepth; ++i) {
// Loop links to calculate neurons' input sum.
Expand Down
104 changes: 80 additions & 24 deletions src/mlpack/methods/ne/neat.hpp
Expand Up @@ -132,22 +132,26 @@ class NEAT {
// Whether mutate or not.
double p = mlpack::math::Random();
if (p > mutateAddLinkProb) return;

printf("addlink 1\n");
// Select from neuron
ssize_t fromNeuronIdx = mlpack::math::RandInt(0, genome.aNeuronGenes.size());
ssize_t fromNeuronId = genome.aNeuronGenes[fromNeuronIdx].Id();

printf("addlink 2\n");
// Select to neuron which cannot be input.
printf("genome num input is: %d\n", genome.NumInput());
ssize_t toNeuronIdx = mlpack::math::RandInt(genome.NumInput(), genome.aNeuronGenes.size());
printf("toNeuronIdx is: %d\n", toNeuronIdx);
printf("num of neuron is : %d\n", genome.aNeuronGenes.size());
ssize_t toNeuronId = genome.aNeuronGenes[toNeuronIdx].Id();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have to make sure, that fromNeuronIdx != toNeuronIdx.


if (fromNeuronId == toNeuronId) return;
printf("addlink 3\n");
// Check link already exist or not.
ssize_t linkIdx = IsLinkExist(genome, fromNeuronId, toNeuronId);
if (linkIdx != -1) {
genome.aLinkGenes[linkIdx].Enabled(true);
return;
}

printf("addlink 4\n");
// Check innovation already exist or not.
ssize_t innovIdx = CheckLinkInnovation(fromNeuronId, toNeuronId);
if (innovIdx != -1) {
Expand All @@ -159,7 +163,7 @@ class NEAT {
genome.AddLink(linkGene);
return;
}

printf("addlink 5\n");
// If new link and new innovation, create it, push new innovation.
LinkInnovation linkInnov = AddLinkInnovation(fromNeuronId, toNeuronId);
LinkGene linkGene(fromNeuronId,
Expand Down Expand Up @@ -293,74 +297,80 @@ class NEAT {
// If not, we will need to change CrossoverLinkAndNeuron, and Disjoint, and WeightDiff.
void CrossoverLinkAndNeuron(Genome& momGenome, Genome& dadGenome, Genome& childGenome) {
// Add input and output neuron genes to child genome.
printf("crossover 0\n");
for (ssize_t i=0; i<(momGenome.NumInput() + momGenome.NumOutput()); ++i) {
childGenome.aNeuronGenes.push_back(momGenome.aNeuronGenes[i]);
printf("crossover 0.5\n");
}

childGenome.NumInput(momGenome.NumInput());
childGenome.NumOutput(momGenome.NumOutput());
childGenome.GenomeDepth();

printf("crossover 1\n");
// Iterate to add link genes and neuron genes to child genome.
for (ssize_t i=0; i<momGenome.NumLink(); ++i) {
ssize_t innovId = momGenome.aLinkGenes[i].InnovationId();
ssize_t idx = dadGenome.GetLinkIndex(innovId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the names of the genomes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

bool linkContainedInDad = (idx != -1);
double randNum = mlpack::math::Random();

printf("crossover 2\n");
if (!linkContainedInDad) { // exceed or disjoint
childGenome.AddLink(momGenome.aLinkGenes[i]);

printf("crossover 3\n");
// Add from neuron
ssize_t idxInChild = childGenome.GetNeuronIndex(momGenome.aLinkGenes[i].FromNeuronId());
ssize_t idxInParent = momGenome.GetNeuronIndex(momGenome.aLinkGenes[i].FromNeuronId());
if (idxInChild == -1) {
childGenome.AddHiddenNeuron(momGenome.aNeuronGenes[idxInParent]);
}

printf("crossover 4\n");
// Add to neuron
idxInChild = childGenome.GetNeuronIndex(momGenome.aLinkGenes[i].ToNeuronId());
idxInParent = momGenome.GetNeuronIndex(momGenome.aLinkGenes[i].ToNeuronId());
if (idxInChild == -1) {
childGenome.AddHiddenNeuron(momGenome.aNeuronGenes[idxInParent]);
}

printf("crossover 5\n");
continue;
}

if (linkContainedInDad && randNum < 0.5) {
childGenome.AddLink(momGenome.aLinkGenes[i]);

printf("crossover 6\n");
// Add from neuron
ssize_t idxInChild = childGenome.GetNeuronIndex(momGenome.aLinkGenes[i].FromNeuronId());
ssize_t idxInParent = momGenome.GetNeuronIndex(momGenome.aLinkGenes[i].FromNeuronId());
if (idxInChild == -1) {
childGenome.AddHiddenNeuron(momGenome.aNeuronGenes[idxInParent]);
}

printf("crossover 7\n");
// Add to neuron
idxInChild = childGenome.GetNeuronIndex(momGenome.aLinkGenes[i].ToNeuronId());
idxInParent = momGenome.GetNeuronIndex(momGenome.aLinkGenes[i].ToNeuronId());
if (idxInChild == -1) {
childGenome.AddHiddenNeuron(momGenome.aNeuronGenes[idxInParent]);
}

printf("crossover 8\n");
continue;
}

printf("crossover 9\n");
if (linkContainedInDad && randNum >= 0.5) {
childGenome.AddLink(dadGenome.aLinkGenes[idx]);

printf("crossover 10\n");
// Add from neuron TODO: make it a function?? check whether crossover is correct.
ssize_t idxInChild = childGenome.GetNeuronIndex(dadGenome.aLinkGenes[idx].FromNeuronId());
ssize_t idxInParent = dadGenome.GetNeuronIndex(dadGenome.aLinkGenes[idx].FromNeuronId());
if (idxInChild == -1) {
childGenome.AddHiddenNeuron(dadGenome.aNeuronGenes[idxInParent]);
}

printf("crossover 11\n");
// Add to neuron
idxInChild = childGenome.GetNeuronIndex(dadGenome.aLinkGenes[idx].ToNeuronId());
idxInParent = dadGenome.GetNeuronIndex(dadGenome.aLinkGenes[idx].ToNeuronId());
if (idxInChild == -1) {
childGenome.AddHiddenNeuron(dadGenome.aNeuronGenes[idxInParent]);
}

printf("crossover 12\n");
continue;
}
}
Expand Down Expand Up @@ -518,7 +528,9 @@ class NEAT {

averageRank = averageRank / speciesSize; // smaller is better.
speciesAverageRank.push_back(averageRank);
printf("size speciesAverage is %d \n", speciesAverageRank.size());
}
printf("size speciesAverage is %d \n", speciesAverageRank.size());
}

// Remove weak species.
Expand Down Expand Up @@ -565,24 +577,30 @@ class NEAT {
// NOTICE: how we organize different mutations is kind of flexible.
void Mutate(Genome& genome) {
// NOTICE: we can change mutate rates here. Randomly let mutate rates be bigger or smaller.

printf("mutate 1\n");
// Mutate weights.
MutateWeight(genome, aMutateWeightProb, aPerturbWeightProb, aMutateWeightSize);

printf("mutate 2\n");
// Mutate link. TODO: check link mutate implementation is correct or not.
double p = aMutateAddLinkProb;
while (p > 0) { // so p can be bigger than 1 and mutate can happen multiple times.
if (mlpack::math::Random() < p) {
printf("mutate 3\n");
MutateAddLink(genome, aMutateAddLinkProb);
printf("mutate 4\n");
}
--p;
}

// Mutate neuron
printf("mutate 5\n");
p = aMutateAddNeuronProb;
printf("mutate 6\n");
while (p > 0) {
if (mlpack::math::Random() < p) {
printf("mutate 7\n");
MutateAddNeuron(genome, aMutateAddNeuronProb);
printf("mutate 8\n");
}
--p;
}
Expand All @@ -591,7 +609,9 @@ class NEAT {
p = aMutateEnabledProb;
while (p > 0) {
if (mlpack::math::Random() < p) {
printf("mutate 9\n");
MutateEnableDisable(genome, true, aMutateEnabledProb);
printf("mutate 10\n");
}
--p;
}
Expand All @@ -600,7 +620,9 @@ class NEAT {
p = aMutateDisabledProb;
while (p > 0) {
if (mlpack::math::Random() < p) {
printf("mutate 11\n");
MutateEnableDisable(genome, false, aMutateDisabledProb);
printf("mutate 12\n");
}
--p;
}
Expand All @@ -609,18 +631,31 @@ class NEAT {
// Breed child for a species.
// NOTICE: can have different ways to breed a child.
void BreedChild(Species& species, Genome& childGenome, double crossoverProb) {
printf("breed 1\n");
double p = mlpack::math::Random();
ssize_t speciesSize = species.aGenomes.size();
printf("species size is %d \n", speciesSize);
printf("breed 2\n");
if (speciesSize == 0)
return;

if (p < crossoverProb) {
ssize_t idx1 = mlpack::math::RandInt(0, speciesSize);
ssize_t idx2 = mlpack::math::RandInt(0, speciesSize);
printf("idx1 is %d\n", idx1);
printf("idx2 is %d\n", idx2);
printf("breed 3\n");
Crossover(species.aGenomes[idx1], species.aGenomes[idx2], childGenome);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to do a crossover using the same genomes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revised.

printf("breed 4\n");
} else {
ssize_t idx = mlpack::math::RandInt(0, speciesSize);
printf("breed 5\n");
childGenome = species.aGenomes[idx];
printf("breed 6\n");
}

printf("breed 7\n");
Mutate(childGenome);
printf("breed 8\n");
}


Expand All @@ -633,31 +668,46 @@ class NEAT {
void Reproduce() {
// Remove stale species.
RemoveStaleSpecies(aPopulation);

printf("hehe 0\n"); // DEBUG
// Remove weak genomes in each species.
CullSpecies(aPopulation, aCullSpeciesPercentage);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, is this a technique to avoid local minima? Truncating each species by 50% sounds like an counterproductive idea. Maybe I missed a reference in the NEAT paper?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I referred to this implementation which seems performs good on Mario game:
http://pastebin.com/ZZmSNaHX
And truncating species by 50%, or by only one left are also come from this.
Actually I am now in the progress of reviewing other implementation ideas, such as the neat-python. The NEAT's implementation seems are all quite different for different packages. I am trying to come up with a progress which combines the goodness of different packages.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the information, maybe it's a good idea, but it sounds counterproductive to me. I think it should work without, since RemoveStaleSpecies should remove old species anyway.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My current plan is keep the functions, but when we do the Reproduce(), we need further decision about whether to use it. Organizing these steps in Reproduce() are flexible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, since there is a parameter (aCullSpeciesPercentage) it's super easy to disable the function.

printf("hehe 1\n"); // DEBUG

// Remove weak species.
RemoveWeakSpecies(aPopulation);

if (aPopulation.NumSpecies() > 10) {
RemoveWeakSpecies(aPopulation);
}
printf("hehe 2\n"); // DEBUG
// Breed children in each species.
std::vector<double> speciesAverageRank;
CalcSpeciesAverageRank(aPopulation, speciesAverageRank);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding https://groups.yahoo.com/neo/groups/neat/conversations/topics/2203 we don't use the adjusted fitness.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you mean, as we are calculation the average fitness of species, we doesn't need to use the adjustedFitness, because it likes we average it for twice, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think that's what Stanley is trying to explain.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I now removed all adjustedFitness, even in the genome class.

printf("size speciesAverageRank is %d \n", speciesAverageRank.size());
printf("hehe 3\n"); // DEBUG
double totalAverageRank = std::accumulate(speciesAverageRank.begin(), speciesAverageRank.end(), 0);
printf("size speciesAverageRank is %d \n", speciesAverageRank.size());
printf("hehe 3-0\n");
std::vector<Genome> childGenomes;
printf("hehe 3-01\n");
for (ssize_t i=0; i<aPopulation.aSpecies.size(); ++i) {
// number of child genomes by this species.
printf("hehe 3-02\n");
printf("size species is %d \n", aPopulation.aSpecies.size());
printf("size speciesAverageRank is %d \n", speciesAverageRank.size());
ssize_t numBreed = std::floor(speciesAverageRank[i] * aPopulationSize / totalAverageRank) - 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the right position, I would go with offspring here.


printf("hehe 3-1\n"); // DEBUG
for (ssize_t j=0; j<numBreed; ++j) {
Genome genome; //!!!!!!!!!!!!!
printf("num of species is %d \n", aPopulation.aSpecies.size());
BreedChild(aPopulation.aSpecies[i], genome, aCrossoverRate);
childGenomes.push_back(genome);
}
printf("hehe 3-2\n"); // DEBUG
}
printf("hehe 4\n"); // DEBUG

// Keep the best in each species.
CullSpeciesToOne(aPopulation);
printf("hehe 5\n"); // DEBUG

// Random choose species and breed child until reach population size.
while (childGenomes.size() + aPopulation.aSpecies.size() < aPopulationSize) {
Expand All @@ -666,11 +716,13 @@ class NEAT {
BreedChild(aPopulation.aSpecies[speciesIndex], genome, aCrossoverRate);
childGenomes.push_back(genome);
}
printf("hehe 6\n"); // DEBUG

// Speciate genomes into new species.
for (ssize_t i=0; i<childGenomes.size(); ++i) {
AddGenomeToSpecies(aPopulation, childGenomes[i]);
}
printf("hehe 7\n"); // DEBUG

// Reassign genome IDs.
aPopulation.ReassignGenomeId();
Expand All @@ -680,7 +732,9 @@ class NEAT {
void Evaluate() {
for (ssize_t i=0; i<aPopulation.NumSpecies(); ++i) {
for (ssize_t j=0; j<aPopulation.aSpecies[i].SpeciesSize(); ++j) {
printf("start eval fitness\n");
double fitness = aTask.EvalFitness(aPopulation.aSpecies[i].aGenomes[j]);
printf("end eval fitness\n");
aPopulation.aSpecies[i].aGenomes[j].Fitness(fitness);
}

Expand All @@ -706,7 +760,9 @@ class NEAT {
// Repeat
while (generation < aMaxGeneration) {
// Evaluate all genomes in population.
printf("start evaluate\n");
Evaluate();
printf("end evaluate\n");

// Output some information.
printf("Generation: %zu\tBest fitness: %f\n", generation, aPopulation.BestFitness());
Expand Down
2 changes: 1 addition & 1 deletion src/mlpack/methods/ne/population.hpp
Expand Up @@ -39,7 +39,7 @@ class Population {
// Parametric constructor.
Population(Genome& seedGenome, ssize_t populationSize) {
aPopulationSize = populationSize;
aNumSpecies = 0;
aNumSpecies = 1;
aBestFitness = DBL_MAX;
Species species(seedGenome, populationSize);
aSpecies.push_back(species); // NOTICE: we don't speciate.
Expand Down
2 changes: 2 additions & 0 deletions src/mlpack/methods/ne/tasks.hpp
Expand Up @@ -51,7 +51,9 @@ class TaskXor {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, using an arma::mat object to store the input is a better representation. This way, we can use all kinds of already implemented methods to preprocess the data.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zoq Reasonable. I will revise it then.

double fitness = 0;
for (int i=0; i<4; ++i) {
printf("start activate\n");
genome.Activate(inputs[i]);
printf("end activate\n");
double output = genome.Output()[0];
//fitness += FitnissFunction::Error(output, outputs[i]); incorrect
fitness += pow((output - outputs[i]), 2); // TODO: revise.
Expand Down
2 changes: 1 addition & 1 deletion src/mlpack/tests/ne_test.cpp
Expand Up @@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(NECneXorTest)
params.aMutateRate = 0.1;
params.aMutateSize = 0.02;
params.aElitePercentage = 0.2;
params.aMaxGeneration = 1000;
params.aMaxGeneration = 500;

// Construct seed genome for xor task.
ssize_t id = 0;
Expand Down