diff --git a/__pycache__/visualize.cpython-36.pyc b/__pycache__/visualize.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..820f6e2409a620aa5c5826b4e14a0adc6e2499b4 Binary files /dev/null and b/__pycache__/visualize.cpython-36.pyc differ diff --git a/ai-part-b-master b/ai-part-b-master new file mode 160000 index 0000000000000000000000000000000000000000..7d1282b7852f205d0eab5ad6c1a48222e04d42ab --- /dev/null +++ b/ai-part-b-master @@ -0,0 +1 @@ +Subproject commit 7d1282b7852f205d0eab5ad6c1a48222e04d42ab diff --git a/config b/config new file mode 100644 index 0000000000000000000000000000000000000000..e2c73de79d885cfa3bbd080c991bfedf8fc04152 --- /dev/null +++ b/config @@ -0,0 +1,64 @@ +# NEAT configuration for the bit-sequence memory experiment. + +# The `NEAT` section specifies parameters particular to the NEAT algorithm +# or the experiment itself. This is the only required section. +[NEAT] +fitness_criterion = max +fitness_threshold = 600.0 +pop_size = 100 +reset_on_extinction = 0 + +[DefaultGenome] +num_inputs = 4 +num_hidden = 1 +num_outputs = 1 +initial_connection = partial_direct 0.5 +feed_forward = True +compatibility_disjoint_coefficient = 1.0 +compatibility_weight_coefficient = 0.6 +conn_add_prob = 0.2 +conn_delete_prob = 0.2 +node_add_prob = 0.2 +node_delete_prob = 0.2 +activation_default = sigmoid +activation_options = sigmoid +activation_mutate_rate = 0.0 +aggregation_default = sum +aggregation_options = sum +aggregation_mutate_rate = 0.0 +bias_init_mean = 0.0 +bias_init_stdev = 1.0 +bias_replace_rate = 0.1 +bias_mutate_rate = 0.7 +bias_mutate_power = 0.5 +bias_max_value = 30.0 +bias_min_value = -30.0 +response_init_mean = 1.0 +response_init_stdev = 0.0 +response_replace_rate = 0.0 +response_mutate_rate = 0.0 +response_mutate_power = 0.0 +response_max_value = 30.0 +response_min_value = -30.0 + +weight_max_value = 30 +weight_min_value = -30 +weight_init_mean = 0.0 +weight_init_stdev = 1.0 +weight_mutate_rate = 0.8 +weight_replace_rate = 0.1 +weight_mutate_power = 0.5 +enabled_default = True +enabled_mutate_rate = 0.01 + +[DefaultSpeciesSet] +compatibility_threshold = 3.0 + +[DefaultStagnation] +species_fitness_func = max +max_stagnation = 20 + +[DefaultReproduction] +elitism = 2 +survival_threshold = 0.2 + diff --git a/tensTest.py b/tensTest.py new file mode 100644 index 0000000000000000000000000000000000000000..88916fd2825801c50212b553ed48f14a5181395f --- /dev/null +++ b/tensTest.py @@ -0,0 +1,39 @@ +from itertools import cycle +from numpy.random import randint,choice +import sys +import neat +import os +import random + +GENERATION = 0 +MAX_FITNESS = 0 +BEST_GENOME = 0 + +def eval_genomes(genomes, config): + i = 0 + global SCORE + global GENERATION, MAX_FITNESS, BEST_GENOME + + GENERATION += 1 + for genome_id, genome in genomes: + + genome.fitness = random.randint(1,10) + print("Gen : %d Genome # : %d Fitness : %f Max Fitness : %f"%(GENERATION,i,genome.fitness, MAX_FITNESS)) + if genome.fitness >= MAX_FITNESS: + MAX_FITNESS = genome.fitness + BEST_GENOME = genome + SCORE = 0 + i+=1 + + +config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction, + neat.DefaultSpeciesSet, neat.DefaultStagnation, + 'config') + +pop = neat.Population(config) +stats = neat.StatisticsReporter() +pop.add_reporter(stats) + +winner = pop.run(eval_genomes, 30) + +print(winner) \ No newline at end of file diff --git a/visualize.py b/visualize.py new file mode 100644 index 0000000000000000000000000000000000000000..3bae1a2a8ed7c4bb15b6ee488f964880992a3b91 --- /dev/null +++ b/visualize.py @@ -0,0 +1,197 @@ +from __future__ import print_function + +import copy +import warnings + +import graphviz +import matplotlib.pyplot as plt +import numpy as np + + +def plot_stats(statistics, ylog=False, view=False, filename='avg_fitness.svg'): + """ Plots the population's average and best fitness. """ + if plt is None: + warnings.warn("This display is not available due to a missing optional dependency (matplotlib)") + return + + generation = range(len(statistics.most_fit_genomes)) + best_fitness = [c.fitness for c in statistics.most_fit_genomes] + avg_fitness = np.array(statistics.get_fitness_mean()) + stdev_fitness = np.array(statistics.get_fitness_stdev()) + + plt.plot(generation, avg_fitness, 'b-', label="average") + plt.plot(generation, avg_fitness - stdev_fitness, 'g-.', label="-1 sd") + plt.plot(generation, avg_fitness + stdev_fitness, 'g-.', label="+1 sd") + plt.plot(generation, best_fitness, 'r-', label="best") + + plt.title("Population's average and best fitness") + plt.xlabel("Generations") + plt.ylabel("Fitness") + plt.grid() + plt.legend(loc="best") + if ylog: + plt.gca().set_yscale('symlog') + + plt.savefig(filename) + if view: + plt.show() + + plt.close() + + +def plot_spikes(spikes, view=False, filename=None, title=None): + """ Plots the trains for a single spiking neuron. """ + t_values = [t for t, I, v, u, f in spikes] + v_values = [v for t, I, v, u, f in spikes] + u_values = [u for t, I, v, u, f in spikes] + I_values = [I for t, I, v, u, f in spikes] + f_values = [f for t, I, v, u, f in spikes] + + fig = plt.figure() + plt.subplot(4, 1, 1) + plt.ylabel("Potential (mv)") + plt.xlabel("Time (in ms)") + plt.grid() + plt.plot(t_values, v_values, "g-") + + if title is None: + plt.title("Izhikevich's spiking neuron model") + else: + plt.title("Izhikevich's spiking neuron model ({0!s})".format(title)) + + plt.subplot(4, 1, 2) + plt.ylabel("Fired") + plt.xlabel("Time (in ms)") + plt.grid() + plt.plot(t_values, f_values, "r-") + + plt.subplot(4, 1, 3) + plt.ylabel("Recovery (u)") + plt.xlabel("Time (in ms)") + plt.grid() + plt.plot(t_values, u_values, "r-") + + plt.subplot(4, 1, 4) + plt.ylabel("Current (I)") + plt.xlabel("Time (in ms)") + plt.grid() + plt.plot(t_values, I_values, "r-o") + + if filename is not None: + plt.savefig(filename) + + if view: + plt.show() + plt.close() + fig = None + + return fig + + +def plot_species(statistics, view=False, filename='speciation.svg'): + """ Visualizes speciation throughout evolution. """ + if plt is None: + warnings.warn("This display is not available due to a missing optional dependency (matplotlib)") + return + + species_sizes = statistics.get_species_sizes() + num_generations = len(species_sizes) + curves = np.array(species_sizes).T + + fig, ax = plt.subplots() + ax.stackplot(range(num_generations), *curves) + + plt.title("Speciation") + plt.ylabel("Size per Species") + plt.xlabel("Generations") + + plt.savefig(filename) + + if view: + plt.show() + + plt.close() + + +def draw_net(config, genome, view=False, filename=None, node_names=None, show_disabled=True, prune_unused=False, + node_colors=None, fmt='svg'): + """ Receives a genome and draws a neural network with arbitrary topology. """ + # Attributes for network nodes. + if graphviz is None: + warnings.warn("This display is not available due to a missing optional dependency (graphviz)") + return + + if node_names is None: + node_names = {} + + assert type(node_names) is dict + + if node_colors is None: + node_colors = {} + + assert type(node_colors) is dict + + node_attrs = { + 'shape': 'circle', + 'fontsize': '9', + 'height': '0.2', + 'width': '0.2'} + + dot = graphviz.Digraph(format=fmt, node_attr=node_attrs) + + inputs = set() + for k in config.genome_config.input_keys: + inputs.add(k) + name = node_names.get(k, str(k)) + input_attrs = {'style': 'filled', 'shape': 'box', 'fillcolor': node_colors.get(k, 'lightgray')} + dot.node(name, _attributes=input_attrs) + + outputs = set() + for k in config.genome_config.output_keys: + outputs.add(k) + name = node_names.get(k, str(k)) + node_attrs = {'style': 'filled', 'fillcolor': node_colors.get(k, 'lightblue')} + + dot.node(name, _attributes=node_attrs) + + if prune_unused: + connections = set() + for cg in genome.connections.values(): + if cg.enabled or show_disabled: + connections.add((cg.in_node_id, cg.out_node_id)) + + used_nodes = copy.copy(outputs) + pending = copy.copy(outputs) + while pending: + new_pending = set() + for a, b in connections: + if b in pending and a not in used_nodes: + new_pending.add(a) + used_nodes.add(a) + pending = new_pending + else: + used_nodes = set(genome.nodes.keys()) + + for n in used_nodes: + if n in inputs or n in outputs: + continue + + attrs = {'style': 'filled', + 'fillcolor': node_colors.get(n, 'white')} + dot.node(str(n), _attributes=attrs) + + for cg in genome.connections.values(): + if cg.enabled or show_disabled: + #if cg.input not in used_nodes or cg.output not in used_nodes: + # continue + input, output = cg.key + a = node_names.get(input, str(input)) + b = node_names.get(output, str(output)) + style = 'solid' if cg.enabled else 'dotted' + color = 'green' if cg.weight > 0 else 'red' + width = str(0.1 + abs(cg.weight / 5.0)) + dot.edge(a, b, _attributes={'style': style, 'color': color, 'penwidth': width}) + + dot.render(filename, view=view) + + return dot