-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Hi. I was editing the example code provided in the documentation into an XOR task as an exercise for myself, and I noticed that sometimes the program freezes at a random iterations. I made the simulation loop print out the current iteration, and sometimes it would freeze at iteration 15, another time - 59, another - 72, etc. Here is the code to reproduce the error:
use neat::rand::Rng;
use neat::*;
const INPUT_SIZE: usize = 2;
const OUTPUT_SIZE: usize = 1;
#[derive(Clone, RandomlyMutable, DivisionReproduction)]
struct MyAgentDNA {
network: NeuralNetworkTopology<INPUT_SIZE, OUTPUT_SIZE>,
}
impl GenerateRandom for MyAgentDNA {
fn gen_random(rng: &mut impl rand::Rng) -> Self {
Self {
network: NeuralNetworkTopology::new(0.01, 3, rng),
}
}
}
struct MyAgent {
network: NeuralNetwork<INPUT_SIZE, OUTPUT_SIZE>,
}
impl From<&MyAgentDNA> for MyAgent {
fn from(value: &MyAgentDNA) -> Self {
Self {
network: NeuralNetwork::from(&value.network),
}
}
}
fn fitness(dna: &MyAgentDNA) -> f32 {
// task: XOR
// Example:
// input A > 0.5 && input B > 0.5 -> output must be 0
// input A < 0.5 && input B < 0.5 -> output must be 0
// input A > 0.5 && input B < 0.5 -> output must be 1
// input A < 0.5 && input B > 0.5 -> output must be 1
let agent = MyAgent::from(dna);
let mut rng = rand::thread_rng();
let mut fitness: f32 = 0.0;
let max_iter = 100;
for _ in 0..max_iter {
let a = rng.r#gen::<f32>();
let b = rng.r#gen::<f32>();
let a_enabled = a > 0.5;
let b_enabled = b > 0.5;
let expected_result: f32 = match a_enabled != b_enabled {
true => 1.0,
false => 0.0,
};
let predictions = agent.network.predict([a, b]);
let prediction = predictions[0];
// Distance between the expected result and the prediction will be
// deducted from fitness
let mistake: f32 = (expected_result - prediction).abs();
fitness += 1.0 - (mistake);
}
return fitness / (max_iter as f32); // Normalize fitness
}
impl Prunable for MyAgentDNA {}
fn main() {
let mut rng = rand::thread_rng();
let mut sim = GeneticSim::new(
Vec::gen_random(&mut rng, 100),
fitness,
division_pruning_nextgen,
);
// simulate 100 generations
for iteration in 0..1000 {
println!("Doing iteration {iteration}");
sim.next_generation();
}
// display fitness results
let fits: Vec<f32> = sim.genomes.iter().map(fitness).collect();
let comparator = |a: &&f32, b: &&f32| a.partial_cmp(b).unwrap();
dbg!(&fits, fits.iter().max_by(comparator));
// Test out the best genome
let best_genome = &sim.genomes[fits.iter().max_index()];
let best_agent = MyAgent::from(best_genome);
let preds_x = [[0.1, 0.1], [0.8, 0.1], [0.1, 0.8], [0.8, 0.8]];
for x_set in preds_x {
let result = best_agent.network.predict(x_set)[0];
println!("X: {x_set:?}, Y: {result}");
}
}Does anyone have any idea as to why this happens and how to fix it?
Metadata
Metadata
Assignees
Labels
No labels