GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Finish xor evolution experiment. · CBenoit/NEToolKit@f38eb9f

This repository was archived by the owner on Jul 1, 2021. It is now read-only.

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • NEToolKitExamples/src
    • random_evolution.cpp
    • xor_experiment.cpp
  • NEToolKit
    • include/netkit/neat
      • genome.h
      • neat.h
      • species.h
    • src/neat
      • neat.cpp
      • species.cpp
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎NEToolKit/include/netkit/neat/genome.h‎

Copy file name to clipboardExpand all lines: NEToolKit/include/netkit/neat/genome.h
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class genome {
7777
gene new_gene = get_gene_from_parents(*this, *oya1_gene_it, other, *oya2_gene_it);
7878

7979
// randomly disable the gene if a parent has it disabled
80-
new_gene.enabled = (oya1_gene_it->enabled && oya2_gene_it->enabled) || rand() % 2 == 0;
80+
new_gene.enabled = (oya1_gene_it->enabled && oya2_gene_it->enabled) || rand() % 10 == 0;
8181

8282
offspring.add_gene(std::move(new_gene));
8383

@@ -87,14 +87,14 @@ class genome {
8787
} else if (oya1_gene_it->innov_num < oya2_gene_it->innov_num) { // keep genes sorted by innovation number
8888
if (this->m_fitness >= other.m_fitness) {
8989
gene new_gene(*oya1_gene_it);
90-
new_gene.enabled = oya1_gene_it->enabled || rand() % 2 == 0;
90+
new_gene.enabled = oya1_gene_it->enabled || rand() % 10 == 0;
9191
offspring.add_gene(std::move(new_gene));
9292
}
9393
++oya1_gene_it;
9494
} else {
9595
if (other.m_fitness >= this->m_fitness) {
9696
gene new_gene(*oya2_gene_it);
97-
new_gene.enabled = oya2_gene_it->enabled || rand() % 2 == 0;
97+
new_gene.enabled = oya2_gene_it->enabled || rand() % 10 == 0;
9898
offspring.add_gene(std::move(new_gene));
9999
}
100100
++oya2_gene_it;
@@ -106,7 +106,7 @@ class genome {
106106
if (this->m_fitness >= other.m_fitness) {
107107
while (oya1_gene_it != this->m_genes.cend()) {
108108
gene new_gene(*oya1_gene_it);
109-
new_gene.enabled = oya1_gene_it->enabled || rand() % 2 == 0;
109+
new_gene.enabled = oya1_gene_it->enabled || rand() % 10 == 0;
110110
offspring.add_gene(std::move(new_gene));
111111
++oya1_gene_it;
112112
}
@@ -115,7 +115,7 @@ class genome {
115115
if (other.m_fitness >= this->m_fitness) {
116116
while (oya2_gene_it != other.m_genes.cend()) {
117117
gene new_gene(*oya2_gene_it);
118-
new_gene.enabled = oya2_gene_it->enabled || rand() % 2 == 0;
118+
new_gene.enabled = oya2_gene_it->enabled || rand() % 10 == 0;
119119
offspring.add_gene(std::move(new_gene));
120120
++oya2_gene_it;
121121
}
Collapse file

‎NEToolKit/include/netkit/neat/neat.h‎

Copy file name to clipboardExpand all lines: NEToolKit/include/netkit/neat/neat.h
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class neat {
3939

4040
std::optional<species*> find_appropriate_species_for(const genome& geno);
4141

42+
const genome& get_best_genome() const;
43+
4244
private:
4345
void helper_speciate();
4446

Collapse file

‎NEToolKit/include/netkit/neat/species.h‎

Copy file name to clipboardExpand all lines: NEToolKit/include/netkit/neat/species.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class species {
3131
unsigned int get_expected_offsprings() const { return m_expected_offsprings; }
3232
genome_id_t select_one_genitor() const;
3333
bool empty() const { return m_members.empty(); }
34+
size_t number_of_members() const { return m_members.size(); }
3435

3536
void sort_by_fitness();
3637
void update_stats();
Collapse file

‎NEToolKit/src/neat/neat.cpp‎

Copy file name to clipboardExpand all lines: NEToolKit/src/neat/neat.cpp
+13-1Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ void netkit::neat::epoch() {
114114
}
115115

116116
auto next_generation_pop_size = static_cast<unsigned int>(m_population.size()); // TODO: dynamic population?
117-
std::cout << next_generation_pop_size << " " << total_expected_offsprings << " " << next_generation_pop_size - total_expected_offsprings << std::endl;
118117

119118
// Need to make up for lost floating point precision in offsprings assignation
120119
// by giving the missing offsprings to the current best species.
@@ -180,6 +179,19 @@ std::optional<netkit::species*> netkit::neat::find_appropriate_species_for(const
180179
return {};
181180
}
182181

182+
const netkit::genome& netkit::neat::get_best_genome() const {
183+
double best_fitness_so_far = std::numeric_limits<double>::min();
184+
const genome* champion = nullptr;
185+
for (const genome& geno : m_population.get_all_genomes()) {
186+
if (geno.get_fitness() > best_fitness_so_far) {
187+
best_fitness_so_far = geno.get_fitness();
188+
champion = &geno;
189+
}
190+
}
191+
192+
return *champion;
193+
}
194+
183195
void netkit::neat::helper_speciate() {
184196
genome_id_t geno_id = 0;
185197
for (const genome& geno : m_population.get_all_genomes()) {
Collapse file

‎NEToolKit/src/neat/species.cpp‎

Copy file name to clipboardExpand all lines: NEToolKit/src/neat/species.cpp
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ void netkit::species::init_for_next_gen(genome new_representant) {
168168
m_summed_fitnesses = 0;
169169
++m_age;
170170

171-
std::cout << "Init specie " << m_id << std::endl;
172171
delete m_representant;
173172
m_representant = new genome(std::move(new_representant));
174173

Collapse file

‎NEToolKitExamples/src/random_evolution.cpp‎

Copy file name to clipboardExpand all lines: NEToolKitExamples/src/random_evolution.cpp
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void run_random_evolution() {
1010
netkit::parameters params;
1111
params.initial_population_size = 10;
1212
params.compatibility_threshold = 1;
13-
netkit::neat neat(std::move(params));
13+
netkit::neat neat(params);
1414
neat.init();
1515

1616
for (unsigned int gen = 0; gen < 10; ++gen) {
Collapse file

‎NEToolKitExamples/src/xor_experiment.cpp‎

Copy file name to clipboardExpand all lines: NEToolKitExamples/src/xor_experiment.cpp
+84-21Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@
1111

1212
#include "xor_experiment.h"
1313

14+
void print_species_stats(const netkit::species& spec);
15+
void rate_xor_population(netkit::neat& neat);
16+
void print_xor_network_results(netkit::network& net);
17+
18+
std::vector<std::vector<netkit::neuron_value_t>> inputs_per_run = {
19+
{0, 0},
20+
{1, 0},
21+
{0, 1},
22+
{1, 1}
23+
};
24+
25+
std::vector<netkit::neuron_value_t> expected_output_per_run = {0, 1, 1, 0};
26+
1427
void xor_network_test() {
1528
std::cout << "Starting the (handmade) example xor network..." << std::endl;
1629

@@ -32,20 +45,7 @@ void xor_network_test() {
3245
std::cout << "Neural network created." << std::endl;
3346
std::cout << net << std::endl;
3447

35-
std::vector<std::vector<netkit::neuron_value_t>> inputs_per_run = {
36-
{0, 0},
37-
{1, 0},
38-
{0, 1},
39-
{1, 1}
40-
};
41-
42-
for (auto& inputs : inputs_per_run) {
43-
std::cout << "==================" << std::endl;
44-
std::cout << inputs[0] << " xor " << inputs[1] << std::endl;
45-
net.load_inputs(inputs);
46-
net.activate_until_relaxation();
47-
std::cout << "Result: " << net.get_outputs()[0] << std::endl;
48-
}
48+
print_xor_network_results(net);
4949

5050
std::cout << "\nPerforming the same with a network generated from a genome..." << std::endl;
5151

@@ -70,13 +70,7 @@ void xor_network_test() {
7070
netkit::network gennet = genome.generate_network();
7171
std::cout << gennet << std::endl;
7272

73-
for (auto& inputs : inputs_per_run) {
74-
std::cout << "==================" << std::endl;
75-
std::cout << inputs[0] << " xor " << inputs[1] << std::endl;
76-
gennet.load_inputs(inputs);
77-
gennet.activate_until_relaxation();
78-
std::cout << "Result: " << gennet.get_outputs()[0] << std::endl;
79-
}
73+
print_xor_network_results(gennet);
8074

8175
std::cout << "\nBenchmark: how much does it takes to activate the xor network 100 000 times?" << std::endl;
8276
std::cout << "Running the benchmark..." << std::endl;
@@ -94,4 +88,73 @@ void xor_network_test() {
9488

9589
void run_xor_experiment() {
9690
std::cout << "Starting the xor evolution experiment..." << std::endl;
91+
92+
netkit::parameters params;
93+
params.number_of_inputs = 2;
94+
params.number_of_outputs = 1;
95+
netkit::neat neat(params);
96+
neat.init();
97+
98+
std::cout << "\n\n======== Here's the initial generation's population. =========" << std::endl;
99+
rate_xor_population(neat);
100+
for (netkit::species &spec : neat.get_all_species()) {
101+
spec.update_stats();
102+
print_species_stats(spec);
103+
}
104+
105+
// go for a 100 generations evolution.
106+
for (unsigned int gen = 1; gen <= 100; ++gen) {
107+
neat.epoch(); // go to next generation
108+
109+
std::cout << "\n\n======== Here's the generation " << gen << "'s population. =========" << std::endl;
110+
rate_xor_population(neat);
111+
for (netkit::species &spec : neat.get_all_species()) {
112+
spec.update_stats();
113+
print_species_stats(spec);
114+
}
115+
}
116+
117+
const netkit::genome& best_geno = neat.get_best_genome();
118+
std::cout << "\nHere's the best genome produced:" << std::endl;
119+
std::cout << best_geno << std::endl;
120+
netkit::network net = best_geno.generate_network();
121+
print_xor_network_results(net);
97122
}
123+
124+
// ===== local functions =====
125+
126+
void print_species_stats(const netkit::species& spec) {
127+
std::cout << "<species: id = " << spec.get_id() << ", age = " << spec.get_age()
128+
<< ", age of last improvement = " << spec.get_age_of_last_improvement()
129+
<< "\n\tavg fitness = " << spec.get_avg_fitness()
130+
<< ", best fitness = " << spec.get_best_fitness()
131+
<< ", best fitness ever = " << spec.get_best_fitness_ever()
132+
<< "\n\tnumber of members = " << spec.number_of_members() << ">" << std::endl;
133+
}
134+
135+
void rate_xor_population(netkit::neat& neat) {
136+
std::vector<size_t> runs = {0, 1, 2, 3};
137+
while (neat.has_more_organisms_to_process()) {
138+
netkit::organism org = neat.generate_and_get_next_organism();
139+
netkit::network& net = org.get_network();
140+
141+
double fitness = 0;
142+
for (auto run : runs) {
143+
net.load_inputs(inputs_per_run[run]);
144+
net.activate_until_relaxation();
145+
fitness += 1 - std::abs(net.get_outputs()[0] - expected_output_per_run[run]);
146+
}
147+
148+
org.set_fitness(fitness);
149+
}
150+
}
151+
152+
void print_xor_network_results(netkit::network& net) {
153+
for (auto& inputs : inputs_per_run) {
154+
std::cout << "==================" << std::endl;
155+
std::cout << inputs[0] << " xor " << inputs[1] << std::endl;
156+
net.load_inputs(inputs);
157+
net.activate_until_relaxation();
158+
std::cout << "Result: " << net.get_outputs()[0] << std::endl;
159+
}
160+
}

0 commit comments

Comments
0 (0)
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.