Example #1
0
    def test_generation(self):
        genome1 = create_genome_structure(
            5, 2, modified_sigmoid_activation, NeatConfig(),
            InnovationNumberGeneratorSingleCore())

        genome2 = create_genome_structure(
            5, 2, modified_sigmoid_activation, NeatConfig(),
            InnovationNumberGeneratorSingleCore())

        agent1 = Agent(1, genome1)
        agent2 = Agent(2, genome2)
        members = [agent1, agent2]

        species = [
            Species(1,
                    genome2, [agent1, agent2],
                    max_species_fitness=10,
                    generation_max_species_fitness=3,
                    adjust_fitness=8)
        ]

        seed = 10
        generation = Generation(2, seed, members, species)

        self.assertEqual(2, generation.number)
        self.assertEqual(species, generation.species_list)
        self.assertEqual(members, generation.agents)
        self.assertEqual(seed, generation.seed)
    def test_mutate_add_connection(self):
        config = NeatConfig(connection_initial_min_weight=-3,
                            connection_initial_max_weight=3,
                            allow_recurrent_connections=True,
                            probability_mutate_add_connection=0.4,
                            mutate_connection_tries=2)

        self.genome.connections = []

        # Random values for with seed 1
        # rnd.uniform(0, 1) = 0.417022004702574 -> No mutation
        _, conn = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config)
        self.assertEqual(0, len(self.genome.connections))
        self.assertIsNone(conn)

        # Set higher config value, reset random
        config.probability_mutate_add_connection = 1
        self.rnd = np.random.RandomState(1)
        # Random values for with seed 1
        # rnd.uniform(0, 1) = 0.417022004702574 -> Mutate
        # rnd.randint(low=0,high=4) = 0
        # rnd.randint(low=0,high=2) = 0
        # rnd.uniform(low=-3, high=3) = -2.9993137510959307
        _, new_con1 = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config)
        self.assertEqual(1, len(self.genome.connections))
        self.assertEqual(4, new_con1.innovation_number)
        self.assertEqual(self.node_input1.innovation_number, new_con1.input_node)
        self.assertEqual(self.node_hidden1.innovation_number, new_con1.output_node)
        self.assertAlmostEqual(-2.9993137510959307, new_con1.weight, delta=0.0000000001)

        # Random values
        # rnd.uniform(0, 1) = 0.00011437481734488664 -> Mutate
        # rnd.randint(low=0,high=4) = 3
        # rnd.randint(low=0,high=2) = 0
        # rnd.uniform(low=-3, high=3) = -2.445968431387213
        _, new_con2 = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config)
        self.assertEqual(2, len(self.genome.connections))
        self.assertEqual(5, new_con2.innovation_number)
        self.assertEqual(self.node_output1.innovation_number, new_con2.input_node)
        self.assertEqual(self.node_hidden1.innovation_number, new_con2.output_node)
        self.assertAlmostEqual(-2.445968431387213, new_con2.weight, delta=0.0000000001)

        # Brute force - check if all nodes are connected after 1000 tries
        for _ in range(1000):
            _, _ = mutate_add_connection(self.genome, self.rnd, self.inn_generator, config)

        # Maximum connections with recurrent
        self.assertEqual(8, len(self.genome.connections))

        # Set recurrent to false
        config.allow_recurrent = False
        genome_feed_forward = Genome(1, self.nodes, connections=[])
        for _ in range(1000):
            genome_feed_forward, _ = mutate_add_connection(genome_feed_forward, self.rnd, self.inn_generator, config)
        # Maximum connections with recurrent=false
        self.assertEqual(5, len(genome_feed_forward.connections))
    def test_mutate_add_node(self):
        config = NeatConfig(probability_mutate_add_node=0.1, bias_initial_min=-3, bias_initial_max=3)
        genome, node, con1, con2 = mutate_add_node(self.genome, self.rnd, self.inn_generator, config)

        # Should not mutate
        self.assertEqual(self.genome, genome)
        self.assertIsNone(node)
        self.assertIsNone(con1)
        self.assertIsNone(con2)

        # Set probability high, and reset randomState
        config.probability_mutate_add_node = 1
        self.rnd = np.random.RandomState(1)
        self.node_output1.activation_function = modified_sigmoid_activation
        # Random values for with seed 1
        # rnd.uniform(0, 1) = 0.417022004702574 -> Mutate
        # rnd.randint(low=0,high=4) = 0 -> connection1
        # rnd.uniform(0, 1) = -0.9325573593386588 -> Take activation function of out node
        # rnd.uniform(-3, 3) = -2.23125331242386 -> Bias for new node

        node_size_before = len(self.genome.nodes)
        connections_size_before = len(self.connections)

        genome, node, con1, con2 = mutate_add_node(self.genome, self.rnd, self.inn_generator, config)
        # Check if 1 node and 2 connections were added
        self.assertEqual(genome, self.genome)
        self.assertEqual(node_size_before + 1, len(genome.nodes))
        self.assertEqual(connections_size_before + 2, len(genome.connections))

        # Check if old connection was disabled
        self.assertFalse(self.connection1.enabled)

        # Check the generated node
        self.assertEqual(NodeType.HIDDEN, node.node_type)
        self.assertEqual(modified_sigmoid_activation, node.activation_function)
        self.assertEqual(4, node.innovation_number)
        self.assertAlmostEqual(-2.23125331242386, node.bias, delta=0.0000000001)
        self.assertEqual(0.5, node.x_position)

        # Check 1 connection
        self.assertEqual(4, con1.innovation_number)
        self.assertEqual(self.connection1.input_node, con1.input_node)
        self.assertEqual(node.innovation_number, con1.output_node)
        self.assertEqual(1, con1.weight)
        self.assertTrue(con1.enabled)

        # Check 2 connection
        self.assertEqual(5, con2.innovation_number)
        self.assertEqual(node.innovation_number, con2.input_node)
        self.assertEqual(self.connection1.output_node, con2.output_node)
        self.assertEqual(self.connection1.weight, con2.weight)
        self.assertTrue(con2.enabled)
    def setUp(self) -> None:
        self.optimizer_single = NeatOptimizerSingleCore()
        self.callback = MockCallback()
        self.challenge = MockChallenge()

        self.optimizer_single.register_callback(self.callback)
        self.config = NeatConfig(population_size=150)
    def test_create_offspring_pairs(self):
        agent_id_generator = AgentIDGeneratorSingleCore()
        config = NeatConfig()

        rnd = np.random.RandomState(1)
        # First 10 random values
        # rnd.randint(3) = 1
        # rnd.randint(3) = 0
        # rnd.randint(3) = 0
        # rnd.randint(3) = 1
        # rnd.randint(3) = 1
        # rnd.randint(3) = 0
        # rnd.randint(3) = 0
        # rnd.randint(3) = 1

        tuple_list = ss.create_offspring_pairs(self.species1, 4,
                                               agent_id_generator,
                                               self.generation, rnd, config)

        # Test tuples
        agent_id_generator = AgentIDGeneratorSingleCore()
        self.assertEqual(4, len(tuple_list))
        self.assertEqual((self.agent2.id, self.agent1.id,
                          agent_id_generator.get_agent_id()), tuple_list[0])
        self.assertEqual((self.agent1.id, self.agent2.id,
                          agent_id_generator.get_agent_id()), tuple_list[1])
        self.assertEqual((self.agent2.id, self.agent1.id,
                          agent_id_generator.get_agent_id()), tuple_list[2])
        self.assertEqual((self.agent1.id, self.agent2.id,
                          agent_id_generator.get_agent_id()), tuple_list[3])
Example #6
0
    def test_config(self):
        config = NeatConfig(population_size=200,
                            connection_min_weight=-10,
                            connection_max_weight=10)

        self.assertEqual(200, config.population_size)
        self.assertEqual(-10, config.connection_min_weight)
        self.assertEqual(10, config.connection_max_weight)
Example #7
0
    def test_species(self):
        genome1 = create_genome_structure(5, 2, modified_sigmoid_activation, NeatConfig(),
                                          InnovationNumberGeneratorSingleCore())

        genome2 = create_genome_structure(5, 2, modified_sigmoid_activation, NeatConfig(),
                                          InnovationNumberGeneratorSingleCore())
        members = [Agent(1, genome1)]

        species = Species(1, genome2, members, max_species_fitness=10, generation_max_species_fitness=3,
                          adjust_fitness=8)

        self.assertEqual(genome2, species.representative)
        self.assertEqual(8, species.adjusted_fitness)
        self.assertEqual(10, species.max_species_fitness)
        self.assertEqual(3, species.generation_max_species_fitness)
        self.assertEqual(members, species.members)
        self.assertEqual(1, species.id_)
    def test_set_new_genome_bias(self):
        config = NeatConfig(bias_initial_min=-3, bias_initial_max=3)
        modified_genome = set_new_genome_bias(self.genome, self.rnd, config)

        # Input nodes should be skipped
        self.assertEqual(0, modified_genome.nodes[0].bias)
        self.assertEqual(0, modified_genome.nodes[1].bias)
        self.assertAlmostEqual(-0.4978679717845562, modified_genome.nodes[2].bias, delta=0.0000001)
        self.assertAlmostEqual(1.3219469606529488, modified_genome.nodes[3].bias, delta=0.0000001)
    def test_cross_over(self):
        node1_1 = Node(1, NodeType.INPUT, 1.1, step_activation, 0)
        node1_2 = Node(2, NodeType.INPUT, 1.2, step_activation, 0)
        node1_5 = Node(5, NodeType.OUTPUT, 1.5, step_activation, 1)
        node1_7 = Node(7, NodeType.HIDDEN, 1.7, step_activation, 0.5)
        nodes1 = [node1_1, node1_2, node1_5, node1_7]

        node2_1 = Node(1, NodeType.INPUT, 2.1, modified_sigmoid_activation, 0)
        node2_2 = Node(2, NodeType.INPUT, 2.2, modified_sigmoid_activation, 0)
        node2_4 = Node(4, NodeType.OUTPUT, 2.4, modified_sigmoid_activation, 1)
        node2_7 = Node(7, NodeType.HIDDEN, 2.7, modified_sigmoid_activation, 0.5)
        node2_8 = Node(8, NodeType.HIDDEN, 2.8, modified_sigmoid_activation, 0.5)
        nodes2 = [node2_1, node2_2, node2_4, node2_7, node2_8]

        connection1_1 = Connection(innovation_number=1, input_node=1, output_node=2, weight=1.2, enabled=False)
        connection1_2 = Connection(innovation_number=2, input_node=1, output_node=2, weight=1.2, enabled=True)
        connection1_4 = Connection(innovation_number=4, input_node=1, output_node=2, weight=1.2, enabled=True)
        connection1_7 = Connection(innovation_number=7, input_node=1, output_node=2, weight=1.2, enabled=False)
        connections1 = [connection1_1, connection1_2, connection1_4, connection1_7]

        connection2_1 = Connection(innovation_number=1, input_node=1, output_node=2, weight=1.2, enabled=False)
        connection2_2 = Connection(innovation_number=2, input_node=1, output_node=2, weight=1.2, enabled=True)
        connection2_3 = Connection(innovation_number=3, input_node=1, output_node=2, weight=1.2, enabled=True)
        connection2_5 = Connection(innovation_number=5, input_node=1, output_node=2, weight=1.2, enabled=True)
        connection2_7 = Connection(innovation_number=7, input_node=1, output_node=2, weight=1.2, enabled=False)
        connections2 = [connection2_1, connection2_2, connection2_3, connection2_5, connection2_7]

        more_fit_parent = Genome(1, nodes1, connections1)
        less_fit_parent = Genome(2, nodes2, connections2)

        config = NeatConfig(probability_enable_gene=0.31)
        # Random values:
        # 1 rnd.uniform(0, 1) = 0.417022004702574 -> First node (node1_1)
        # 1 rnd.uniform(0, 1) = 0.7203244934421581 -> Second node(node2_2)
        # 1 rnd.uniform(0, 1) = 0.00011437481734488664 -> First node (node7_1)

        # 1 rnd.uniform(0, 1) = 0.30233257263183977 -> Select first connection (connection1_1)
        # 1 rnd.uniform(0, 1) = 0.14675589081711304 -> Re-enable connection (connection1_1)
        # 1 rnd.uniform(0, 1) = 0.0923385947687978 -> Select first connection (connection1_2)
        # 1 rnd.uniform(0, 1) = 0.1862602113776709 -> Select first connection (connection1_7)
        # 1 rnd.uniform(0, 1) = 0.34556072704304774 -> Re-enable connection False (connection1_7)

        child_nodes, child_connections = cross_over(more_fit_parent, less_fit_parent, self.rnd, config)
        # Check nodes
        self.assertEqual(4, len(child_nodes))
        self.compare_nodes(node1_1, child_nodes[0])
        self.compare_nodes(node2_2, child_nodes[1])
        self.compare_nodes(node1_5, child_nodes[2])
        self.compare_nodes(node1_7, child_nodes[3])

        # Check connections
        self.assertEqual(4, len(child_connections))
        connection1_1.enabled = True
        self.compare_connections(connection1_1, child_connections[0])
        self.compare_connections(connection1_2, child_connections[1])
        self.compare_connections(connection1_4, child_connections[2])
        self.compare_connections(connection1_7, child_connections[3])
Example #10
0
    def evaluate(self, optimizer: NeatOptimizer, seed: int = None, **kwargs):
        time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")

        # Reporter for fitness values
        self.fitness_reporter = FitnessReporter()
        self.species_reporter = SpeciesReporter()
        self.time_reporter = TimeReporter()
        self.check_point_reporter = CheckPointReporter(
            "/tmp/breakout/{}/".format(time), "breakout", lambda _: True)

        # Register this class as callback
        optimizer.register_callback(self)

        optimizer.register_reporters(self.time_reporter, self.species_reporter,
                                     self.fitness_reporter,
                                     self.check_point_reporter)

        # Config
        config = NeatConfig(allow_recurrent_connections=False,
                            population_size=150,
                            compatibility_threshold=3,
                            weight_mutation_type="normal",
                            weight_mutation_normal_sigma=1.3,
                            connection_initial_min_weight=-1,
                            connection_initial_max_weight=1,
                            connection_min_weight=-15,
                            connection_max_weight=15,
                            bias_mutation_type="normal",
                            bias_mutation_normal_sigma=1.3,
                            bias_initial_min=-1,
                            bias_initial_max=1,
                            bias_min=-15,
                            bias_max=15,
                            compatibility_factor_disjoint_genes=1.0,
                            compatibility_factor_matching_genes=0.5,
                            probability_mutate_add_connection=0.5,
                            probability_mutate_add_node=0.2,
                            compatibility_genome_size_threshold=0)

        # Progressbar size
        self.progressbar_max = config.population_size

        # Create random seed, if none is specified
        if seed is None:
            seed = np.random.RandomState().randint(2**24)
        logger.info("Used Seed: {}".format(seed))

        # Create the challenge
        self.challenge = BreakoutChallenge()

        # Start evaluation
        optimizer.evaluate(amount_input_nodes=128,
                           amount_output_nodes=2,
                           activation_function=sigmoid_activation,
                           challenge=self.challenge,
                           config=config,
                           seed=seed)
Example #11
0
 def setUp(self) -> None:
     self.config = NeatConfig(population_size=10)
     self.generation = gs.create_initial_generation(
         3, 2, step_activation, InnovationNumberGeneratorSingleCore(),
         SpeciesIDGeneratorSingleCore(), AgentIDGeneratorSingleCore(),
         self.config, 1)
     for i, agent in zip(range(len(self.generation.agents)),
                         self.generation.agents):
         agent.fitness = i
    def test_create_initial_generation(self):
        config = NeatConfig(population_size=150,
                            connection_max_weight=10,
                            connection_min_weight=-10)

        generation1 = gs.create_initial_generation(
            10,
            3,
            step_activation,
            InnovationNumberGeneratorSingleCore(),
            SpeciesIDGeneratorSingleCore(),
            AgentIDGeneratorSingleCore(),
            config,
            seed=1)

        generation2 = gs.create_initial_generation(
            10,
            3,
            step_activation,
            InnovationNumberGeneratorSingleCore(),
            SpeciesIDGeneratorSingleCore(),
            AgentIDGeneratorSingleCore(),
            config,
            seed=1)

        self.assertEqual(0, generation1.number)
        self.assertEqual(0, generation2.number)
        self.assertEqual(150, len(generation1.agents))

        # Compare if generations and generated genomes are the same
        for agent1, agent2 in zip(generation1.agents, generation2.agents):
            self.assertEqual(agent1.genome.seed, agent2.genome.seed)

            for node1, node2, i in zip(agent1.genome.nodes,
                                       agent2.genome.nodes,
                                       range(len(agent1.genome.nodes))):
                self.assertEqual(node1.innovation_number,
                                 node2.innovation_number)
                self.assertEqual(i, node1.innovation_number)
                self.assertEqual(node1.bias, node2.bias)

                if node1.node_type != NodeType.INPUT:
                    self.assertNotAlmostEqual(0,
                                              node1.bias,
                                              delta=0.000000000001)

            # Check connection weights
            for connection1, connection2, i in zip(
                    agent1.genome.connections, agent2.genome.connections,
                    range(len(agent1.genome.connections))):
                self.assertEqual(connection1.weight, connection2.weight)
                self.assertEqual(connection1.innovation_number,
                                 connection2.innovation_number)
                self.assertEqual(i, connection1.innovation_number)
                self.assertNotAlmostEqual(0,
                                          connection1.weight,
                                          delta=0.000000000001)
Example #13
0
    def test_agent(self):
        genome = create_genome_structure(5, 2, modified_sigmoid_activation,
                                         NeatConfig(),
                                         InnovationNumberGeneratorSingleCore())
        agent = Agent(1, genome)

        self.assertEqual(1, agent.id)
        self.assertEqual(genome, agent.genome)
        self.assertIsNone(agent.neural_network)
        self.assertEqual(0, agent.fitness)
        self.assertEqual(0, agent.adjusted_fitness)
    def setUp(self) -> None:
        self.config = NeatConfig(population_size=7)
        self.inno_num_generator = InnovationNumberGeneratorSingleCore()
        self.species_id_generator = SpeciesIDGeneratorSingleCore()
        self.agent_id_generator = AgentIDGeneratorSingleCore()

        self.genome1 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome2 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome3 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome4 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome5 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome6 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome7 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)

        self.agent1 = Agent(1, self.genome1)
        self.agent1.fitness = 1
        self.agent2 = Agent(2, self.genome2)
        self.agent2.fitness = 2
        self.agent3 = Agent(3, self.genome3)
        self.agent3.fitness = 3
        self.agent4 = Agent(4, self.genome4)
        self.agent4.fitness = 4
        self.agent5 = Agent(5, self.genome5)
        self.agent5.fitness = 5
        self.agent6 = Agent(6, self.genome6)
        self.agent6.fitness = 6
        self.agent7 = Agent(7, self.genome7)
        self.agent7.fitness = 7

        self.species1 = Species(
            self.species_id_generator.get_species_id(), self.agent1.genome,
            [self.agent1, self.agent1, self.agent2, self.agent3])
        self.species2 = Species(self.species_id_generator.get_species_id(),
                                self.agent4.genome, [self.agent4, self.agent5])
        self.species3 = Species(self.species_id_generator.get_species_id(),
                                self.agent6.genome, [self.agent6, self.agent7])
    def test_set_new_genome_weights(self):
        original_genome = Genome(123,
                                 [Node(1, NodeType.INPUT, 1.1, step_activation, 0)],
                                 [Connection(124, 10, 20, 1.2, True),
                                  Connection("124124", 12, 22, 0.8, False)])

        config = NeatConfig(connection_initial_min_weight=-10, connection_initial_max_weight=10)
        new_genome = set_new_genome_weights(original_genome, np.random.RandomState(2), config=config)
        # First 3 random values
        # 1. -1.2801019571599248
        # 2. -9.481475363442174
        # 3. -1.293552147634463

        self.assertAlmostEqual(-1.2801019571599248, new_genome.connections[0].weight, delta=0.00000001)
        self.assertAlmostEqual(-9.481475363442174, new_genome.connections[1].weight, delta=0.00000001)
    def test_create_initial_generation_genome(self):
        genome = Genome(20, [
            Node("abc", NodeType.INPUT, 0.3, step_activation, 0),
            Node("def", NodeType.OUTPUT, 0.4, step_activation, 1)
        ], [
            Connection("x", "abc", "def", 1.0, True),
            Connection("y", "def", "abc", -5, True)
        ])

        generation = gs.create_initial_generation_genome(
            genome,
            InnovationNumberGeneratorSingleCore(),
            SpeciesIDGeneratorSingleCore(),
            AgentIDGeneratorSingleCore(),
            NeatConfig(population_size=3),
            seed=1)

        self.assertEqual(3, len(generation.agents))
        self.assertEqual(0, generation.number)
        self.assertEqual(1, len(generation.species_list))
        self.assertEqual(3, len(generation.species_list[0].members))
        self.assertEqual(1, generation.seed)

        # First three random numbers
        # 1 - 12710949
        # 2 - 4686059
        # 3 - 6762380
        self.assertEqual(12710949, generation.agents[0].genome.seed)
        self.assertEqual(4686059, generation.agents[1].genome.seed)
        self.assertEqual(6762380, generation.agents[2].genome.seed)

        for node1, node2, node3, i in zip(generation.agents[0].genome.nodes,
                                          generation.agents[1].genome.nodes,
                                          generation.agents[2].genome.nodes,
                                          range(3)):
            self.assertEqual(node1.innovation_number, node2.innovation_number)
            self.assertEqual(node2.innovation_number, node3.innovation_number)
            self.assertEqual(node3.innovation_number, i)

        for connection1, connection2, connection3, i in zip(
                generation.agents[0].genome.connections,
                generation.agents[1].genome.connections,
                generation.agents[2].genome.connections, range(3)):
            self.assertEqual(connection1.innovation_number,
                             connection2.innovation_number)
            self.assertEqual(connection2.innovation_number,
                             connection3.innovation_number)
            self.assertEqual(connection3.innovation_number, i)
    def test_create_genome_structure(self):

        config = NeatConfig()
        input_nodes = 100
        output_nodes = 50

        generated_structure = gs.create_genome_structure(
            amount_input_nodes=input_nodes,
            amount_output_nodes=output_nodes,
            activation_function=step_activation,
            config=config,
            generator=InnovationNumberGeneratorSingleCore())

        self.assertEqual(input_nodes + output_nodes,
                         len(generated_structure.nodes))
        self.assertEqual(input_nodes * output_nodes,
                         len(generated_structure.connections))

        for node, i in zip(generated_structure.nodes,
                           range(input_nodes + output_nodes)):
            self.assertEqual(i, node.innovation_number)
            self.assertEqual(step_activation, node.activation_function)
            self.assertEqual(0, node.bias)

            if i < input_nodes:
                self.assertEqual(NodeType.INPUT,
                                 node.node_type,
                                 msg="Value i={}".format(i))
                self.assertEqual(0, node.x_position)
            else:
                self.assertEqual(NodeType.OUTPUT,
                                 node.node_type,
                                 msg="Value i={}".format(i))
                self.assertEqual(1, node.x_position)

        for connection, i in zip(generated_structure.connections,
                                 range(input_nodes * output_nodes)):
            self.assertEqual(i, connection.innovation_number)
            self.assertEqual(0, connection.weight)
    def test_mutate_weights_uniform(self):

        config = NeatConfig(probability_weight_mutation=0.6,
                            probability_random_weight_mutation=0.5,
                            connection_min_weight=-4,
                            connection_max_weight=4,
                            connection_initial_min_weight=-3,
                            connection_initial_max_weight=3,
                            weight_mutation_type="uniform",
                            weight_mutation_uniform_max_change=1)

        # Random values for with seed 1
        # First connection
        # rnd.uniform(0, 1) = 0.417022004702574 -> Mutate yes
        # rnd.uniform(0, 1) = 0.7203244934421581 -> Perturb weight
        # rnd.uniform(-1, 1) = -0.9997712503653102 -> Value to be subtracted (and clamped)
        # Second connection
        # rnd.uniform(0, 1) = 0.30233257263183977 -> Mutate yes
        # rnd.uniform(0, 1) = 0.14675589081711304 -> Random weight
        # rnd.uniform(-3, 3) = -2.445968431387213 -> new random weight
        # Third connection
        # rnd.uniform(0, 1) = 0.1862602113776709 -> Mutate yes
        # rnd.uniform(0, 1) = 0.34556072704304774 -> Random weight
        # rnd.uniform(-3, 3) = -0.6193951546159804 -> new random weight
        # Fourth connection
        # rnd.uniform(0, 1) = 0.538816734003357 -> Mutate yes
        # rnd.uniform(0, 1) = 0.4191945144032948 -> Random weight
        # rnd.uniform(-3, 3) = 1.1113170023805568 -> new random weight

        con1_expected_weight = self.connection1.weight - 0.9997712503653102

        new_genome = mutate_weights(self.genome, self.rnd, config)

        # Same object
        self.assertEqual(self.genome, new_genome)
        self.assertAlmostEqual(con1_expected_weight, self.connection1.weight, delta=0.000000000001)
        self.assertAlmostEqual(-2.445968431387213, self.connection2.weight, delta=0.000000000001)
        self.assertAlmostEqual(-0.6193951546159804, self.connection3.weight, delta=0.000000000001)
        self.assertAlmostEqual(1.1113170023805568, self.connection4.weight, delta=0.000000000001)
    def test_mutate_weights_normal(self):
        config = NeatConfig(probability_weight_mutation=0.6,
                            probability_random_weight_mutation=0.5,
                            connection_min_weight=-3,
                            connection_max_weight=3,
                            weight_mutation_type="normal",
                            weight_mutation_normal_sigma=0.5)

        # Random values for with seed 1
        # First connection
        # rnd.uniform(0, 1) = 0.417022004702574 -> Mutate yes
        # rnd.uniform(0, 1) = 0.7203244934421581 -> Perturb weight
        # rnd.normal(scale=0.5) = -0.26408587613172785 -> Value to be subtracted (and clamped)
        # Second connection
        # rnd.uniform(0, 1) = 0.39676747423066994 -> Mutate yes
        # rnd.uniform(0, 1) = 0.538816734003357 -> Perturb weight
        # rnd.normal(scale=0.5) = -0.5364843110780853 -> Value to be subtracted (and clamped)
        # Third connection
        # rnd.uniform(0, 1) = 0.4191945144032948 -> Mutate yes
        # rnd.uniform(0, 1) = 0.6852195003967595 -> Perturb weight
        # rnd.normal(scale=0.5) = 0.15951954802854929 -> Value to be added (and clamped)
        # Fourth connection
        # rnd.uniform(0, 1) = 0.027387593197926163 -> Mutate yes
        # rnd.uniform(0, 1) = 0.6704675101784022 -> Perturb weight
        # rnd.normal(scale=0.5) = -0.12468518773870504 -> Value to be subtracted (and clamped)

        connection1_new_weight = self.connection1.weight - 0.26408587613172785
        connection2_new_weight = self.connection2.weight - 0.5364843110780853
        connection3_new_weight = self.connection3.weight + 0.15951954802854929
        connection4_new_weight = self.connection4.weight - 0.12468518773870504

        new_genome = mutate_weights(self.genome, self.rnd, config)

        # Same object
        self.assertEqual(self.genome, new_genome)
        self.assertAlmostEqual(connection1_new_weight, self.connection1.weight, delta=0.000000000001)
        self.assertAlmostEqual(connection2_new_weight, self.connection2.weight, delta=0.000000000001)
        self.assertAlmostEqual(connection3_new_weight, self.connection3.weight, delta=0.000000000001)
        self.assertAlmostEqual(connection4_new_weight, self.connection4.weight, delta=0.000000000001)
    def test_mutate_bias_uniform(self):
        config = NeatConfig(probability_bias_mutation=0.6,
                            bias_max=3,
                            bias_min=-3,
                            bias_initial_min=-2,
                            bias_initial_max=2,
                            probability_random_bias_mutation=0.5,
                            bias_mutation_uniform_max_change=1,
                            bias_mutation_type="uniform")

        # rnd.uniform(0, 1) = 0.417022004702574 -> Mutate
        # rnd.uniform(0, 1) = 0.7203244934421581 -> Perturb
        # rnd.uniform(-1, 1) = -0.9997712503653102 -> Substract form bias
        # rnd.uniform(0, 1) = 0.30233257263183977 -> Mutate
        # rnd.uniform(0, 1) = 0.14675589081711304 -> Random weight
        # rnd.uniform(-2, 2) = -1.6306456209248088 -> new random weight

        old_output_bias = self.node_output1.bias

        new_genome = mutate_bias(self.genome, self.rnd, config)
        self.assertAlmostEqual(old_output_bias - 0.9997712503653102, new_genome.nodes[2].bias, delta=0.000000001)
        self.assertAlmostEqual(-1.6306456209248088, new_genome.nodes[3].bias, delta=0.0000000001)
    def test_mutate_bias_normal(self):
        config = NeatConfig(probability_bias_mutation=0.6,
                            bias_max=3,
                            bias_min=-3,
                            bias_initial_min=-2,
                            bias_initial_max=2,
                            probability_random_bias_mutation=0.6,
                            bias_mutation_normal_sigma=1.0,
                            bias_mutation_type="normal")

        # rnd.uniform(0, 1) = 0.417022004702574 -> Mutate
        # rnd.uniform(0, 1) = 0.7203244934421581 -> Perturb
        # rnd.normal(scale=1) = -0.5281717522634557 -> Substract form bias
        # rnd.uniform(0, 1) = 0.39676747423066994 -> Mutate
        # rnd.uniform(0, 1) = 0.538816734003357 -> Random weight
        # rnd.uniform(-2, 2) = -0.3232219423868208 -> new random weight

        old_output_bias = self.node_output1.bias

        new_genome = mutate_bias(self.genome, self.rnd, config)
        self.assertAlmostEqual(old_output_bias - 0.5281717522634557, new_genome.nodes[2].bias, delta=0.000000001)
        self.assertAlmostEqual(-0.3232219423868208, new_genome.nodes[3].bias, delta=0.0000000001)
    def test_build_generation_from_genome(self):
        initial_genome = Genome(20, [
            Node(1, NodeType.INPUT, 0, step_activation, 0),
            Node(2, NodeType.OUTPUT, 0.4, step_activation, 1)
        ], [Connection(1, 1, 2, 1.0, True),
            Connection(2, 1, 2, -5, True)])

        rnd = np.random.RandomState(1)
        generation = gs._build_generation_from_genome(
            initial_genome, SpeciesIDGeneratorSingleCore(),
            AgentIDGeneratorSingleCore(), 19, rnd,
            NeatConfig(population_size=3))

        self.assertEqual(3, len(generation.agents))
        self.assertEqual(0, generation.number)
        self.assertEqual(1, len(generation.species_list))
        self.assertEqual(3, len(generation.species_list[0].members))
        self.assertEqual(19, generation.seed)

        # First three random numbers
        # 1 - 12710949
        # 2 - 4686059
        # 3 - 6762380
        self.assertEqual(12710949, generation.agents[0].genome.seed)
        self.assertEqual(4686059, generation.agents[1].genome.seed)
        self.assertEqual(6762380, generation.agents[2].genome.seed)

        # Check if every weight and bias is not equal to 0
        for agent, i in zip(generation.agents, range(len(generation.agents))):
            genome = agent.genome
            self.assertEqual(i, agent.id)
            for node in genome.nodes:
                # Input nodes can have bias 0
                if node.node_type == NodeType.INPUT:
                    continue
                self.assertNotAlmostEqual(0, node.bias, delta=0.00000000001)

            for conn in genome.connections:
                self.assertNotAlmostEqual(0, conn.weight, delta=0.00000000001)
Example #23
0
    def evaluate_fix_structure(self,
                               optimizer: NeatOptimizer,
                               seed: int = None):
        optimizer.register_callback(self)
        config = NeatConfig(allow_recurrent_connections=False,
                            population_size=150,
                            compatibility_threshold=3,
                            connection_min_weight=-5,
                            connection_max_weight=5,
                            bias_min=-5,
                            bias_max=5,
                            probability_mutate_add_node=0,
                            probability_mutate_add_connection=0)

        # Create random seed, if none is specified
        if seed is None:
            seed = np.random.RandomState().randint(2**24)
        logger.info("Used Seed: {}".format(seed))

        genome = Genome(0, [
            Node(0, NodeType.INPUT, 0, modified_sigmoid_activation, 0),
            Node(1, NodeType.INPUT, 0, modified_sigmoid_activation, 0),
            Node(2, NodeType.OUTPUT, 0, modified_sigmoid_activation, 1),
            Node(3, NodeType.HIDDEN, 0, modified_sigmoid_activation, 0.5),
            Node(4, NodeType.HIDDEN, 0, modified_sigmoid_activation, 0.5)
        ], [
            Connection(1, 0, 3, 0.1, True),
            Connection(2, 1, 3, 0.1, True),
            Connection(3, 0, 4, 0.1, True),
            Connection(4, 1, 4, 0.1, True),
            Connection(5, 3, 2, 0.1, True),
            Connection(6, 4, 2, 0.1, True)
        ])

        optimizer.evaluate_genome_structure(genome_structure=genome,
                                            challenge=ChallengeXOR(),
                                            config=config,
                                            seed=seed)
    def test_randomize_weight_bias(self):
        genome = Genome(20, [
            Node(1, NodeType.INPUT, 0.0, step_activation, 0),
            Node(2, NodeType.OUTPUT, 0.0, step_activation, 1)
        ], [Connection(3, 1, 2, 0, True),
            Connection(4, 2, 1, 0, True)])

        config = NeatConfig(bias_initial_min=1,
                            bias_initial_max=2,
                            connection_initial_min_weight=3,
                            connection_initial_max_weight=4)
        randomized_genome = gs._randomize_weight_bias(genome,
                                                      np.random.RandomState(1),
                                                      config)

        for node in randomized_genome.nodes:
            if node.node_type == NodeType.INPUT:
                self.assertEqual(0, node.bias)
            else:
                self.assertTrue(1 <= node.bias <= 2)

        for conn in randomized_genome.connections:
            self.assertTrue(3 <= conn.weight <= 4)
    def setUp(self) -> None:
        self.config = NeatConfig(compatibility_factor_matching_genes=1,
                                 compatibility_factor_disjoint_genes=2,
                                 compatibility_threshold=2.5,
                                 compatibility_genome_size_threshold=0,
                                 population_size=8)

        self.g1_nodes = [
            Node(1, NodeType.INPUT, 0, step_activation, 0),
            Node(2, NodeType.INPUT, 0, step_activation, 0),
            Node(3, NodeType.OUTPUT, 1.2, step_activation, 1),
            Node(4, NodeType.HIDDEN, 1.5, step_activation, 0.5),
            Node(6, NodeType.HIDDEN, 0.5, step_activation, 0.5),
            Node(7, NodeType.HIDDEN, 0.2, step_activation, 0.25)
        ]
        self.g1_connections = [
            Connection(1, 1, 3, 1.2, True),
            Connection(2, 2, 3, 0.5, False),
            Connection(3, 1, 4, -1.2, True),
            Connection(4, 4, 3, 0.2, True),
            Connection(5, 2, 6, 2.0, True),
            Connection(6, 6, 3, -1.1, False)
        ]
        self.g1 = Genome(1, self.g1_nodes, self.g1_connections)

        self.g2_nodes = [
            Node(1, NodeType.INPUT, 0, step_activation, 0),
            Node(2, NodeType.INPUT, 0, step_activation, 0),
            Node(3, NodeType.OUTPUT, 0.2, step_activation, 1),
            Node(4, NodeType.HIDDEN, 1.2, step_activation, 0.5),
            Node(5, NodeType.HIDDEN, 2.8, step_activation, 0.5)
        ]

        self.g2_connections = [
            Connection(1, 1, 3, 0.8, True),
            Connection(2, 2, 3, 1.5, True),
            Connection(3, 1, 4, 1.2, True),
            Connection(4, 4, 3, 3.2, True),
            Connection(6, 6, 3, -1.1, False),
            Connection(7, 6, 3, -0.1, False),
            Connection(8, 1, 4, -1.1, False)
        ]
        self.g2 = Genome(2, self.g2_nodes, self.g2_connections)

        self.agent1 = Agent(1, self.g1)
        self.agent1.fitness = 1
        self.agent2 = Agent(2, self.g2)
        self.agent2.fitness = 2

        # Add some more agents, and complete species
        self.inno_num_generator = InnovationNumberGeneratorSingleCore()
        self.species_id_generator = SpeciesIDGeneratorSingleCore()
        self.genome3 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome4 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome5 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome6 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome7 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)
        self.genome8 = gs.create_genome_structure(2, 1, step_activation,
                                                  self.config,
                                                  self.inno_num_generator)

        self.agent3 = Agent(3, self.genome3)
        self.agent3.fitness = 3
        self.agent4 = Agent(4, self.genome4)
        self.agent4.fitness = 4
        self.agent5 = Agent(5, self.genome5)
        self.agent5.fitness = 5
        self.agent6 = Agent(6, self.genome6)
        self.agent6.fitness = 6
        self.agent7 = Agent(7, self.genome7)
        self.agent7.fitness = 7
        self.agent8 = Agent(8, self.genome8)
        self.agent8.fitness = 8

        self.species1 = Species(self.species_id_generator.get_species_id(),
                                self.agent1.genome,
                                [self.agent1, self.agent2, self.agent3],
                                max_species_fitness=1.5,
                                generation_max_species_fitness=10)
        self.species2 = Species(self.species_id_generator.get_species_id(),
                                self.agent4.genome,
                                [self.agent4, self.agent5, self.agent6],
                                max_species_fitness=7,
                                generation_max_species_fitness=5)
        self.species3 = Species(self.species_id_generator.get_species_id(),
                                self.agent6.genome, [self.agent7, self.agent8],
                                max_species_fitness=0,
                                generation_max_species_fitness=6)

        self.generation = Generation(
            21,
            2,
            agents=[
                self.agent1, self.agent2, self.agent3, self.agent4,
                self.agent5, self.agent6, self.agent7, self.agent8
            ],
            species_list=[self.species1, self.species2, self.species3])
Example #26
0
    def evaluate(self, optimizer: NeatOptimizer, seed: int = None, **kwargs):
        time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        # Create reporter
        self.fitness_reporter = FitnessReporter()
        self.species_reporter = SpeciesReporter()
        self.time_reporter = TimeReporter()
        self.check_point_reporter = CheckPointReporter(
            "/tmp/xor/{}/".format(time), "xor_genome_", lambda _: False)

        # Register this class as callback and reporter
        optimizer.register_callback(self)
        optimizer.register_reporters(self.time_reporter, self.fitness_reporter,
                                     self.species_reporter,
                                     self.check_point_reporter)

        config = NeatConfig(allow_recurrent_connections=False,
                            population_size=150,
                            compatibility_threshold=3,
                            connection_min_weight=-15,
                            connection_max_weight=15,
                            bias_min=-15,
                            bias_max=15,
                            compatibility_factor_disjoint_genes=1.0,
                            compatibility_factor_matching_genes=0.5,
                            probability_mutate_add_connection=0.5,
                            probability_mutate_add_node=0.2)

        # config = NeatConfig(allow_recurrent_connections=False,
        #                     population_size=150,
        #                     compatibility_threshold=3,
        #                     connection_min_weight=-15,
        #                     connection_max_weight=15,
        #                     bias_min=-15,
        #                     bias_max=15,
        #                     compatibility_factor_disjoint_genes=1.0,
        #                     compatibility_factor_matching_genes=0.4,
        #                     probability_mutate_add_connection=0.05,
        #                     probability_mutate_add_node=0.03)

        # Specify the config
        # config = NeatConfig(allow_recurrent_connections=False,
        #                     population_size=400,
        #                     compatibility_threshold=3,
        #                     weight_mutation_type="normal",
        #                     weight_mutation_normal_sigma=1.3,
        #                     connection_initial_min_weight=-5,
        #                     connection_initial_max_weight=5,
        #                     connection_min_weight=-5,
        #                     connection_max_weight=5,
        #                     bias_mutation_type="normal",
        #                     bias_mutation_normal_sigma=1.3,
        #                     bias_initial_min=-1,
        #                     bias_initial_max=1,
        #                     bias_min=-5,
        #                     bias_max=5,
        #                     compatibility_factor_disjoint_genes=1.0,
        #                     compatibility_factor_matching_genes=0.4,
        #                     probability_mutate_add_connection=0.05,
        #                     probability_mutate_add_node=0.03,
        #                     compatibility_genome_size_threshold=10)

        # Create random seed, if none is specified
        if seed is None:
            seed = np.random.RandomState().randint(2**24)
        logger.info("Used Seed: {}".format(seed))

        optimizer.evaluate(amount_input_nodes=2,
                           amount_output_nodes=1,
                           activation_function=tanh_activation,
                           challenge=ChallengeXOR(),
                           config=config,
                           seed=seed)
 def setUp(self) -> None:
     self.config = NeatConfig(population_size=10)