Пример #1
0
def neural_network_visualizer(genome, config):
    """
    Download and process given neural network into a display-ready image

    :param genomes: chosen genome to be visualized
    :type genomes: neat.Population

    :param config: configuration of the genome to be visualized
    :type config: neat.ConfigParameter

    :return: None
    """

    # Global Variable
    global neural_net_image

    visualize.draw_net(config,
                       genome,
                       False,
                       fmt='png',
                       filename='best_neural_net')

    img = Image.open('best_neural_net.png')
    img = img.convert("RGBA")
    datas = img.getdata()

    # Remove White Pixels (Background)
    newData = []
    for item in datas:
        if item[0] == 255 and item[1] == 255 and item[2] == 255:
            newData.append((255, 255, 255, 0))
        else:
            newData.append(item)

    img.putdata(newData)

    # Resize
    resize = True
    basewidth = 200
    current_t = time.time()
    while resize:
        wpercent = (basewidth / float(img.size[0]))
        hsize = int((float(img.size[1]) * float(wpercent)))
        if hsize < (GAME_WIN_HEIGHT - 200):
            resize = False
            img = img.resize((basewidth, hsize), Image.ANTIALIAS)
            break

        if current_t - time.time() > 10:
            break

        basewidth -= 1

    img.save("best_neural_net.png", "PNG")

    # To Display is Ready
    neural_net_image = pygame.image.load('best_neural_net.png')
def run_experiment(config_file, trial_id, n_generations, out_dir, view_results=False, save_results=True):
    """
    The function to run the experiment against hyper-parameters 
    defined in the provided configuration file.
    The winner genome will be rendered as a graph as well as the
    important statistics of neuroevolution process execution.
    Arguments:
        config_file: the path to the file with experiment 
                    configuration
    """
    # set random seed
    seed = int(time.time())
    random.seed(seed)

    # Load configuration.
    config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                         neat.DefaultSpeciesSet, neat.DefaultStagnation,
                         config_file)

    # Create the population, which is the top-level object for a NEAT run.
    p = neat.Population(config)

    # Add a stdout reporter to show progress in the terminal.
    #p.add_reporter(neat.StdOutReporter(True))
    stats = neat.StatisticsReporter()
    p.add_reporter(stats)

    # Run for up to N generations.
    best_genome = p.run(eval_genomes, n=n_generations)

    # Check if the best genome is a winning Sinle-Pole balancing controller 
    #net = neat.nn.FeedForwardNetwork.create(best_genome, config)

    # Find best genome complexity
    complexity = len(best_genome.connections) + len(best_genome.nodes) + 4 # four input nodes

    # Test if solution was found
    best_genome_fitness = best_genome.fitness # cart.eval_fitness(net, max_bal_steps=max_balancing_steps_num)#
    solution_found = (best_genome_fitness >= config.fitness_threshold)
    if solution_found:
        print("Trial: %2d\tgeneration: %d\tfitness: %f\tcomplexity: %d\tseed: %d" % (trial_id, p.generation, best_genome_fitness, complexity, seed))
    else:
        print("Trial: %2d\tFAILED\t\tfitness: %f\tcomplexity: %d\tseed: %d" % (trial_id, best_genome_fitness, complexity, seed))

    # Visualize the experiment results
    if save_results:
        node_names = {-1:'x', -2:'dot_x', -3:'θ', -4:'dot_θ', 0:'action_1', 1:'action_2'}
        visualize.draw_net(config, best_genome, view=view_results, node_names=node_names, directory=out_dir, fmt='svg')
        visualize.plot_stats(stats, ylog=False, view=view_results, filename=os.path.join(out_dir, 'avg_fitness.svg'))
        visualize.plot_species(stats, view=view_results, filename=os.path.join(out_dir, 'speciation.svg'))

    return solution_found, p.generation, complexity, best_genome_fitness
Пример #3
0
def neural_network_visualizer(genome, config):
    """
	Download and process given neural network into a display-ready image

	:param genomes: chosen genome to be visualized
	:type genomes: neat.Population

	:param config: configuration of the genome to be visualized
	:type config: neat.ConfigParameter

	:return: None
	"""

    # Global Variable
    global neural_net_image

    node_names = {0: 'Jump', -1: 'Bottom P', -2: 'Top P', -3: 'Bird'}
    visualize.draw_net(config,
                       genome,
                       False,
                       fmt='png',
                       filename='best_neural_net',
                       node_names=node_names)

    img = Image.open('best_neural_net.png')
    img = img.convert("RGBA")
    datas = img.getdata()

    # Remove White Pixels (Background)
    newData = []
    for item in datas:
        if item[0] == 255 and item[1] == 255 and item[2] == 255:
            newData.append((255, 255, 255, 0))
        else:
            newData.append(item)

    img.putdata(newData)
    img.save("best_neural_net.png", "PNG")

    # To Display is Ready
    neural_net_image = pygame.image.load('best_neural_net.png')
Пример #4
0
def run_experiment(config_file,
                   trial_id,
                   n_generations,
                   out_dir,
                   view_results=False,
                   save_results=True):
    """
    The function to run XOR experiment against hyper-parameters 
    defined in the provided configuration file.
    The winner genome will be rendered as a graph as well as the
    important statistics of neuroevolution process execution.
    Arguments:
        config_file:    the path to the file with experiment 
                        configuration
        trial_id:       the id of current trial run
        n_generations:  the number of evolutionary generations
        out_dir:        the directory to store experiment outputs
        view_results:   the flag to control whether to view result visualizations
        save_results:   the flag to control whether to save resulting stats into files
    """
    # set random seed
    seed = int(time.time())
    random.seed(seed)

    # Load configuration.
    config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction,
                         neat.DefaultSpeciesSet, neat.DefaultStagnation,
                         config_file)

    # Create the population, which is the top-level object for a NEAT run.
    p = neat.Population(config)

    # Add a stdout reporter to show progress in the terminal.
    #p.add_reporter(neat.StdOutReporter(True))
    stats = neat.StatisticsReporter()
    p.add_reporter(stats)

    # Run for up to n_generations generations.
    best_genome = p.run(eval_genomes, n_generations)

    # Check if the best genome is an adequate XOR solver
    net = neat.nn.FeedForwardNetwork.create(best_genome, config)
    best_genome_fitness = best_genome.fitness  # eval_fitness(net)

    # Find best genome complexity
    complexity = len(best_genome.connections) + len(
        best_genome.nodes) + 2  # two input nodes

    solution_found = best_genome_fitness > config.fitness_threshold
    if solution_found:
        print(
            "Trial: %2d\tgeneration: %d\tfitness: %f\tcomplexity: %d\tseed: %d"
            % (trial_id, p.generation, best_genome_fitness, complexity, seed))
    else:
        print("Trial: %2d\tFAILED\t\tfitness: %f\tcomplexity: %d\tseed: %d" %
              (trial_id, best_genome_fitness, complexity, seed))

    # Visualize the experiment results
    if save_results:
        node_names = {-1: 'A', -2: 'B', 0: 'A XOR B'}
        visualize.draw_net(config,
                           best_genome,
                           view=view_results,
                           node_names=node_names,
                           directory=out_dir)
        visualize.plot_stats(stats,
                             ylog=False,
                             view=view_results,
                             filename=os.path.join(out_dir, 'avg_fitness.svg'))
        visualize.plot_species(stats,
                               view=view_results,
                               filename=os.path.join(out_dir,
                                                     'speciation.svg'))

    return solution_found, p.generation, complexity, best_genome_fitness
Пример #5
0
def run(config_path):
    """
	Use given configuration path and variables to start teaching the AI to play the game
	Then visualize the data with the genome containing highest fitness

	:param config_path: path to the neural 
	:type config_path: int / range[0 -> 99]

	:return: None
	"""

    # Global Variables
    global hs_genopt_popopt
    global gen

    # -------------------------------------------------------------------------
    # Load Configuration
    # -------------------------------------------------------------------------
    config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction,
                                neat.DefaultSpeciesSet, neat.DefaultStagnation,
                                config_path)

    # Create Population
    p = neat.Population(config)

    # Add StdOut Reporter (Displays Progress in Terminal)
    p.add_reporter(neat.StdOutReporter(True))
    stats = neat.StatisticsReporter()
    p.add_reporter(stats)
    """ Save Population in Generation x
	x = 3
	p.add_reporter(neat.Checkpointer(x))
	"""

    # Handle Generation Count of 0
    if hs_genopt_popopt[1] < 1:
        print('Generations set to 1 instead of 0.')
        hs_genopt_popopt[1] = 1

    # Save HighScore Gen. Option and Pop. Option with Pickle
    with open(os.path.join("utils", "hs_genopt_popopt.txt"),
              "wb") as fp:  # Save Pickle
        pickle.dump(hs_genopt_popopt, fp)

    # Reset Gen Count
    gen = 0

    # Run Up to [Gen. Option] Generations
    winner = p.run(main_ai, hs_genopt_popopt[1])  # We Save Best Genome

    # -------------------------------------------------------------------------
    # Visualize Neural Network, Statistics, and Species
    # -------------------------------------------------------------------------
    node_names = {
        0: 'Jump',
        -1: 'Bottom Pipe Height',
        -2: 'Top Pipe Height',
        -3: 'Bird Height'
    }
    visualize.draw_net(config,
                       winner,
                       False,
                       fmt='png',
                       filename='best_neural_net',
                       node_names=node_names)

    # Only Draw if More Than 1 Gen
    if hs_genopt_popopt[1] > 1:
        visualize.plot_stats(stats, ylog=False, view=False)
        visualize.plot_species(stats, view=False)
    """ Load and Run Saved Checkpoint
Пример #6
0
def main_ai(genomes, config):
    """
	Play game for AI

	:param genomes: use different neural networks to play the game
	:type genomes: neat.Population[]

	:param config: use different neural networks to play the game
	:type config: neat.ConfigParameter

	:return: None
	"""

    # Global Variables
    global FPS
    global gen
    global neural_net_image

    # -------------------------------------------------------------------------
    # AI Systen: Neural Network Display
    # -------------------------------------------------------------------------
    neural_network_visualizer(genomes[0][1], config)

    # Set Birds "Connected" To Its Genome and NN
    nets = []
    ge = []
    birds = []
    for _, g in genomes:
        net = neat.nn.FeedForwardNetwork.create(g, config)
        nets.append(net)
        birds.append(Bird(230, 350))
        g.fitness = 0
        ge.append(g)

    # Set Variables
    base = Base(730)
    pipes = [Pipe(600)]
    win = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
    clock = pygame.time.Clock()

    # Reset Score and Add One Gen
    score = 0
    gen += 1

    # Draw Neural Net Once
    ge_save = ge[0]

    # -------------------------------------------------------------------------
    # Game: Main Game
    # -------------------------------------------------------------------------
    run = True
    while run:
        clock.tick(FPS)  # Allow only for FPS Frames per Second
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                # Save last iteration
                node_names = {
                    0: 'Jump',
                    -1: 'Bottom Pipe Height',
                    -2: 'Top Pipe Height',
                    -3: 'Bird Height'
                }
                visualize.draw_net(
                    config,
                    genomes[0][1],
                    False,
                    fmt='png',
                    filename='best_neural_net',
                    node_names=node_names)  # Save last iteration

                # Remove Special Vis Files
                try:
                    os.remove('speciation.svg')
                    os.remove('avg_fitness.svg')
                except Exception as e:
                    pass
                run = False

                pygame.quit()
                quit()

        pipe_ind = 0
        if len(birds) > 0:
            if len(pipes) > 1 and birds[
                    0].x > pipes[0].x + pipes[0].PIPE_TOP.get_width():
                pipe_ind = 1

        else:
            run = False
            break

        # -------------------------------------------------------------------------
        # AI Systen: Bird Jump
        # -------------------------------------------------------------------------
        for x, bird in enumerate(birds):
            bird.move()  # Move each bird
            ge[x].fitness += 0.1

            # Inputs: Bird Height, Top Pipe Height, Bottom Pipe Height
            outputs = nets[x].activate(
                (bird.y, abs(bird.y - pipes[pipe_ind].height),
                 abs(bird.y - pipes[pipe_ind].bottom)))

            # TanH Function | y > 0.5
            if outputs[0] > 0.5:
                bird.jump()

        # -------------------------------------------------------------------------
        # System: Pipes
        # -------------------------------------------------------------------------
        add_pipe = False
        rem = []
        for pipe in pipes:
            for x, bird in enumerate(birds):
                # Bird / Pipe Collision
                if pipe.collide(bird):
                    ge[x].fitness -= 2
                    birds.pop(x)
                    nets.pop(x)
                    ge.pop(x)

                    # -------------------------------------------------------------------------
                    # AI Systen: Neural Network Display
                    # -------------------------------------------------------------------------
                    if ge != [] and ge[
                            0] != ge_save:  # Visualize new alive bird
                        neural_network_visualizer(ge[0], config)
                        ge_save = ge[0]

                if not pipe.passed and pipe.x < bird.x:
                    pipe.passed = True
                    add_pipe = True

            # Pipe Outside Screen
            if pipe.x + pipe.PIPE_TOP.get_width() < 0:
                rem.append(pipe)

            # Move Pipes
            pipe.move()

        # Add New Pipe and 1 to Score
        if add_pipe:
            score += 1  # All birds have same x pos

            if score == 50:
                print("Perfect bird out here")

            for g in ge:
                g.fitness += 2

            pipes.append(Pipe(600))

        # Remove Outside Pipes To Not Render Them
        for r in rem:
            pipes.remove(r)

        # -------------------------------------------------------------------------
        # System: Base / Top Collision
        # -------------------------------------------------------------------------
        for x, bird in enumerate(birds):
            if bird.y + bird.img.get_height() >= 730 or bird.y < 0:
                ge[x].fitness -= 2
                birds.pop(x)
                nets.pop(x)
                ge.pop(x)

                # -------------------------------------------------------------------------
                # AI Systen: Neural Network Display
                # -------------------------------------------------------------------------
                if ge != [] and ge[0] != ge_save:  # Visualize new alive bird
                    neural_network_visualizer(ge[0], config)
                    ge_save = ge[0]

        # Animate Base
        base.move()

        # -------------------------------------------------------------------------
        # Draw To Screen
        # -------------------------------------------------------------------------
        draw_window_ai(win, birds, pipes, base, score, gen, len(birds),
                       genomes, config)
Пример #7
0
def draw_window_ai(win, birds, pipes, base, score, gen, birds_alive, genomes,
                   config):
    """
	Draw game using given parameters (AI Game)

	:param win: window to draw on
	:type win: UI.Window

	:param birds: bird to draw
	:type birds: Bird[]

	:param pipes: pipes to draw
	:type pipes: Pipe[]

	:param base: base to draw
	:type base: Base

	:param score: score to draw
	:type score: int [0 -> infiniti]

	:param gen: generations to draw
	:type gen: int [1 -> 99]

	:param birds_alive: draw how many birds are alive
	:type birds_alive: int [1 -> 99]

	:param genomes: visualize neural net when menu button is pressed
	:type genomes: neat.Population[]

	:param config: visualize neural net when menu button is pressed
	:type config: neat.ConfigParameter

	:return: None
	"""

    # Draw Background
    win.blit(BG_IMG, (0, 0))

    # Draw All Pipes
    for pipe in pipes:
        pipe.draw(win)

    # Draw Current Score
    text = STAT_FONT.render("Score: " + str(score), 1, (255, 255, 255))
    win.blit(text, (WIN_WIDTH - 10 - text.get_width(), 10))

    # Draw Current Generation
    text = STAT_FONT.render("Gen: " + str(gen), 1, (255, 255, 255))
    win.blit(text, (10, 10))

    # Draw Current Number of Birds Alive
    text = STAT_FONT.render("Alive: " + str(birds_alive), 1, (255, 255, 255))
    win.blit(text, (10, 50))

    # Return To Menu if Menu Button Pressed
    if button2.update():
        # Save last iteration
        node_names = {
            0: 'Jump',
            -1: 'Bottom Pipe Height',
            -2: 'Top Pipe Height',
            -3: 'Bird Height'
        }
        visualize.draw_net(config,
                           genomes[0][1],
                           False,
                           fmt='png',
                           filename='best_neural_net',
                           node_names=node_names)

        # Remove Special Vis Files
        try:
            os.remove('speciation.svg')
            os.remove('avg_fitness.svg')
        except Exception as e:
            pass

        # Go Back To Menu
        menu()

    # Draw Base and Birds
    base.draw(win)
    for bird in birds:
        bird.draw(win)

    # Draw Top Neural Network
    text = STAT_FONT_SMALL.render("Best NN: ", 1, (255, 255, 255))
    win.blit(text, (10, WIN_HEIGHT - 70 - neural_net_image.get_height() -
                    text.get_height()))

    # Draw Neural Network
    win.blit(neural_net_image,
             (10, WIN_HEIGHT - 70 -
              neural_net_image.get_height()))  # 70 accounts for base

    # Update the Current Display
    pygame.display.update()