Example #1
0
def run():
    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'xor2_config'))

    # For spiking networks
    config.output_nodes = 2

    pop = population.Population(config)
    pop.epoch(eval_fitness, 500)

    winner = pop.most_fit_genomes[-1]
    print 'Number of evaluations: %d' % winner.ID

    # Verify network output against training data.
    print '\nBest network output:'
    net = iznn.create_phenotype(winner)
    for inputData, outputData in zip(INPUTS, OUTPUTS):
        for j in range(MAX_TIME):
            output = net.advance([x * 10 for x in inputData])
            if output != [False, False]:
                break
        if output[0] and not output[1]:  # Network answered 1
            print "%r expected %d got 1" % (inputData, outputData)
        elif not output[0] and output[1]:  # Network answered 0
            print "%r expected %d got 0" % (inputData, outputData)
        else:
            print "%r expected %d got ?" % (inputData, outputData)

    # Visualize the winner network and plot statistics.
    visualize.plot_stats(pop.most_fit_genomes, pop.avg_fitness_scores)
    visualize.plot_species(pop.species_log)
    visualize.draw_net(winner, view=True)
Example #2
0
def run():
    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'xor2_config'))

    # For this network, we use two output neurons and use the difference between
    # the "time to first spike" to determine the network response.  There are
    # probably a great many different choices one could make for an output encoding,
    # and this choice may not be the best for tackling a real problem.
    config.output_nodes = 2

    pop = population.Population(config)
    pop.run(eval_fitness, 200)

    print('Number of evaluations: {0}'.format(pop.total_evaluations))

    # Display the winning genome.
    winner = pop.statistics.best_genome()
    print('\nBest genome:\n{!s}'.format(winner))

    # Show output of the most fit genome against training data.
    winner = pop.statistics.best_genome()
    print('\nBest genome:\n{!s}'.format(winner))
    print('\nBest network output:')
    net = iznn.create_phenotype(winner, *iz_params)
    dt = iz_params[-1]
    for inputData, outputData in zip(xor_inputs, xor_outputs):
        neuron_data = {}
        for i, n in net.neurons.items():
            neuron_data[i] = []

        # Reset the network, apply the XOR inputs, and run for the maximum allowed time.
        net.reset()
        net.set_inputs(inputData)
        t0 = None
        t1 = None
        v0 = None
        v1 = None
        num_steps = int(max_time / dt)
        for j in range(num_steps):
            t = dt * j
            output = net.advance()

            # Capture the time and neuron membrane potential for later use if desired.
            for i, n in net.neurons.items():
                neuron_data[i].append((t, n.v))

            # Remember time and value of the first output spikes from each neuron.
            if t0 is None and output[0] > 0:
                t0, v0 = neuron_data[net.outputs[0]][-2]

            if t1 is None and output[1] > 0:
                t1, v1 = neuron_data[net.outputs[1]][-2]

        response = compute_output(t0, t1)
        print(inputData, response)
Example #3
0
def run():
    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'xor2_config'))

    # For this network, we use two output neurons and use the difference between
    # the "time to first spike" to determine the network response.  There are
    # probably a great many different choices one could make for an output encoding,
    # and this choice may not be the best for tackling a real problem.
    config.output_nodes = 2

    pop = population.Population(config)
    pop.run(eval_fitness, 200)

    print('Number of evaluations: {0}'.format(pop.total_evaluations))

    # Visualize the winner network and plot statistics.
    winner = pop.statistics.best_genome()
    node_names = {0: 'A', 1: 'B', 2: 'Out1', 3: 'Out2'}
    visualize.draw_net(winner, view=True, node_names=node_names)
    visualize.plot_stats(pop.statistics)
    visualize.plot_species(pop.statistics)

    # Verify network output against training data.
    print('\nBest network output:')
    net = iznn.create_phenotype(winner, *iz_params)
    sum_square_error, simulated = simulate(winner)

    # Create a plot of the traces out to the max time for each set of inputs.
    plt.figure(figsize=(12, 12))
    for r, (inputData, outputData, t0, t1, v0, v1, neuron_data) in enumerate(simulated):
        response = compute_output(t0, t1)
        print("{0!r} expected {1:.3f} got {2:.3f}".format(inputData, outputData, response))

        axes = plt.subplot(4, 1, r + 1)
        plt.title("Traces for XOR input {{{0:.1f}, {1:.1f}}}".format(*inputData), fontsize=12)
        for i, s in neuron_data.items():
            if i in net.outputs:
                t, v = zip(*s)
                plt.plot(t, v, "-", label="neuron {0:d}".format(i))

        # Circle the first peak of each output.
        circle0 = patches.Ellipse((t0, v0), 1.0, 10.0, color='r', fill=False)
        circle1 = patches.Ellipse((t1, v1), 1.0, 10.0, color='r', fill=False)
        axes.add_artist(circle0)
        axes.add_artist(circle1)

        plt.ylabel("Potential (mv)", fontsize=10)
        plt.ylim(-100, 50)
        plt.tick_params(labelsize=8)
        plt.grid()

    plt.xlabel("Time (in ms)", fontsize=10)
    plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
    plt.savefig("traces.png", dpi=90)
    plt.show()
def run():
    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'xor2_config'))

    # For this network, we use two output neurons and use the difference between
    # the "time to first spike" to determine the network response.  There are
    # probably a great many different choices one could make for an output encoding,
    # and this choice may not be the best for tackling a real problem.
    config.output_nodes = 2

    pop = population.Population(config)
    pop.run(eval_fitness, 200)

    print('Number of evaluations: {0}'.format(pop.total_evaluations))

    # Display the winning genome.
    winner = pop.statistics.best_genome()
    print('\nBest genome:\n{!s}'.format(winner))

    # Show output of the most fit genome against training data.
    winner = pop.statistics.best_genome()
    print('\nBest genome:\n{!s}'.format(winner))
    print('\nBest network output:')

    # Create a network of "fast spiking" Izhikevich neurons, simulation time step 0.25 millisecond.
    net = iznn.create_phenotype(winner, **neuron_params)
    for inputData, outputData in zip(xor_inputs, xor_outputs):
        neuron_data = {}
        for i, n in net.neurons.items():
            neuron_data[i] = []

        # Reset the network, apply the XOR inputs, and run for the maximum allowed time.
        net.reset()
        net.set_inputs(inputData)
        t0 = None
        t1 = None
        num_steps = int(max_time / dt)
        for j in range(num_steps):
            t = dt * j
            output = net.advance(dt)

            # Capture the time and neuron membrane potential for later use if desired.
            for i, n in net.neurons.items():
                neuron_data[i].append((t, n.v))

            # Remember time and value of the first output spikes from each neuron.
            if t0 is None and output[0] > 0:
                t0, v0 = neuron_data[net.outputs[0]][-2]

            if t1 is None and output[1] > 0:
                t1, v1 = neuron_data[net.outputs[1]][-2]

        response = compute_output(t0, t1)
        print(inputData, response)
def run():
    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'xor2_config'))

    # For this network, we use two output neurons and use the difference between
    # the "time to first spike" to determine the network response.  There are
    # probably a great many different choices one could make for an output encoding,
    # and this choice may not be the best for tackling a real problem.
    config.output_nodes = 2

    pop = population.Population(config)
    pop.epoch(eval_fitness, 200)

    winner = pop.most_fit_genomes[-1]
    print('Number of evaluations: %d' % winner.ID)

    # Visualize the winner network and plot statistics.
    visualize.plot_stats(pop.most_fit_genomes, pop.avg_fitness_scores)
    visualize.plot_species(pop.species_log)
    visualize.draw_net(winner, view=True)

    # Verify network output against training data.
    print('\nBest network output:')
    net = iznn.create_phenotype(winner, *iz_params)
    error, simulated = simulate(winner)

    # Create a plot of the traces out to the max time for each set of inputs.
    plt.figure(figsize=(12,12))
    for r, (inputData, outputData, t0, t1, neuron_data) in enumerate(simulated):
        response = compute_output(t0, t1)
        print("%r expected %.3f got %.3f" % (inputData, outputData, response))

        plt.subplot(4, 1, r + 1)
        plt.title("Traces for XOR input {%.1f, %.1f}" % inputData, fontsize=12)
        for i, s in neuron_data.items():
            if i not in net.inputs:
                t, v = zip(*s)
                plt.plot(t, v, "-", label="neuron %d" % i)

        plt.ylabel("Potential (mv)", fontsize=10)
        plt.ylim(-100, 50)
        plt.tick_params(axis='both', labelsize=8)
        plt.grid()

    plt.xlabel("Time (in ms)", fontsize=10)
    plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
    plt.savefig("traces.png", dpi=90)
    plt.show()
Example #6
0
def eval_fitness(population):
    for chromosome in population:
        brain = iznn.create_phenotype(chromosome)
        error = 0.0
        for i, input in enumerate(INPUTS):
            for j in range(MAX_TIME):
                output = brain.advance([x * 10 for x in input])
                if output != [False, False]:
                    break
            if output[0] and not output[1]:  # Network answered 1
                error += (1 - OUTPUTS[i])**2
            elif not output[0] and output[1]:  # Network answered 0
                error += (0 - OUTPUTS[i])**2
            else:  # No answer or ambiguous
                error += 1
        chromosome.fitness = 1 - math.sqrt(error / len(OUTPUTS))
        if not chromosome.fitness:
            chromosome.fitness = 0.00001
Example #7
0
def eval_fitness(chromosomes):
    for chromo in chromosomes:
        net = iznn.create_phenotype(chromo)
        error = 0.0
        for inputData, outputData in zip(INPUTS, OUTPUTS):
            for j in range(MAX_TIME):
                output = net.advance([x * 10 for x in inputData])
                if output != [False, False]:
                    break
            if output[0] and not output[1]:  # Network answered 1
                error += (1 - outputData) ** 2
            elif not output[0] and output[1]:  # Network answered 0
                error += (0 - outputData) ** 2
            else:
                # No answer or ambiguous
                error += 1
        chromo.fitness = 1 - math.sqrt(error / len(OUTPUTS))
        if not chromo.fitness:
            chromo.fitness = 0.00001
Example #8
0
    def simulate(genome):
        # Create a network of Izhikevich neurons based on the given genome.
        net = iznn.create_phenotype(genome, **iznn.THALAMO_CORTICAL_PARAMS)
        dt = 0.25
        sum_square_error = 0.0
        simulated = []
        for inputData, outputData in zip(xor_inputs, xor_outputs):
            neuron_data = {}
            for i, n in net.neurons.items():
                neuron_data[i] = []

            # Reset the network, apply the XOR inputs, and run for the maximum allowed time.
            net.reset()
            net.set_inputs(inputData)
            t0 = None
            t1 = None
            v0 = None
            v1 = None
            num_steps = int(max_time / dt)
            for j in range(num_steps):
                t = dt * j
                output = net.advance(dt)

                # Capture the time and neuron membrane potential for later use if desired.
                for i, n in net.neurons.items():
                    neuron_data[i].append((t, n.v))

                # Remember time and value of the first output spikes from each neuron.
                if t0 is None and output[0] > 0:
                    t0, v0 = neuron_data[net.outputs[0]][-2]

                if t1 is None and output[1] > 0:
                    t1, v1 = neuron_data[net.outputs[1]][-2]

            response = compute_output(t0, t1)
            sum_square_error += (response - outputData) ** 2

            simulated.append(
                (inputData, outputData, t0, t1, v0, v1, neuron_data))

        return sum_square_error, simulated
Example #9
0
    def simulate(genome):
        # Create a network of Izhikevich neurons based on the given genome.
        net = iznn.create_phenotype(genome, **iznn.THALAMO_CORTICAL_PARAMS)
        dt = 0.25
        sum_square_error = 0.0
        simulated = []
        for inputData, outputData in zip(xor_inputs, xor_outputs):
            neuron_data = {}
            for i, n in net.neurons.items():
                neuron_data[i] = []

            # Reset the network, apply the XOR inputs, and run for the maximum allowed time.
            net.reset()
            net.set_inputs(inputData)
            t0 = None
            t1 = None
            v0 = None
            v1 = None
            num_steps = int(max_time / dt)
            for j in range(num_steps):
                t = dt * j
                output = net.advance(dt)

                # Capture the time and neuron membrane potential for later use if desired.
                for i, n in net.neurons.items():
                    neuron_data[i].append((t, n.v))

                # Remember time and value of the first output spikes from each neuron.
                if t0 is None and output[0] > 0:
                    t0, v0 = neuron_data[net.outputs[0]][-2]

                if t1 is None and output[1] > 0:
                    t1, v1 = neuron_data[net.outputs[1]][-2]

            response = compute_output(t0, t1)
            sum_square_error += (response - outputData)**2

            simulated.append(
                (inputData, outputData, t0, t1, v0, v1, neuron_data))

        return sum_square_error, simulated
Example #10
0
def evaluate_population(population):

    twelve_degrees = 0.2094384  #radians
    num_steps = 10**5
    MAX_TIME = 100
    spikes = 0

    for chromo in population:

        #refnet = refnn.create_phenotype(chromo)
        brain = iznn.create_phenotype(chromo)

        # initial conditions (as used by Stanley)
        x = random.randint(0, 4799) / 1000.0 - 2.4
        x_dot = random.randint(0, 1999) / 1000.0 - 1.0
        theta = random.randint(0, 399) / 1000.0 - 0.2
        theta_dot = random.randint(0, 2999) / 1000.0 - 1.5
        #x = 0.0
        #x_dot = 0.0
        #theta = 0.0
        #theta_dot = 0.0

        fitness = 0

        for trials in xrange(num_steps):

            # maps into [0,1]
            #inputs = [(x + 2.4)/4.8,
            inputs = [(x + 2.4) / 4.8, (x_dot + 0.75) / 1.5,
                      (theta + twelve_degrees) / 0.41, (theta_dot + 1.0) / 2.0]

            # a normalizacao so acontece para estas condicoes iniciais
            # nada garante que a evolucao do sistema leve a outros
            # valores de x, x_dot e etc... (Portuguese)
            # the normalization only happens for these initial conditions
            # no guarantee that the evolution of the system takes other
            # values of x, x_dot and etc...

            #ref_action = refnet.pactivate(inputs)
            for j in range(MAX_TIME):
                #   action = brain.advance(inputs)
                output = brain.advance([i * 10 for i in inputs])
                #action = brain.advance(inputs)
                #output = brain.advance([i * 20 for i in inputs])
                if output[0] == True:
                    break
            if output[0] == False:
                action = 0
            else:
                action = 1

#[0.011440711571233664, -0.08630150913576802, 1.0056547273034697, 1.8375648386104453] [False]

# Apply action to the simulated cart-pole
            x, x_dot, theta, theta_dot = cart_pole(action, x, x_dot, theta,
                                                   theta_dot)
            #x, x_dot, theta, theta_dot = cart_pole(action[0], x, x_dot, theta, theta_dot)

            #if action == 1:
            #	print inputs,output,action
            spikes += action

            # Check for failure.  If so, return steps
            # the number of steps indicates the fitness: higher = better
            fitness += 1
            if (abs(x) >= 2.4 or abs(theta) >= twelve_degrees):
                #if abs(theta) > twelve_degrees: # Igel (p. 5) uses theta criteria only
                # the cart/pole has run/inclined out of the limits
                break

        chromo.fitness = fitness
    print 'Spikes:', spikes, ', Firing rate:', spikes / MAX_TIME, '(spikes/ms)'
Example #11
0
def run():
    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'xor2_config'))

    # For this network, we use two output neurons and use the difference between
    # the "time to first spike" to determine the network response.  There are
    # probably a great many different choices one could make for an output encoding,
    # and this choice may not be the best for tackling a real problem.
    config.output_nodes = 2

    pop = population.Population(config)
    pop.run(eval_fitness, 200)

    print('Number of evaluations: {0}'.format(pop.total_evaluations))

    # Visualize the winner network and plot statistics.
    winner = pop.statistics.best_genome()
    node_names = {0: 'A', 1: 'B', 2: 'Out1', 3: 'Out2'}
    visualize.draw_net(winner, view=True, node_names=node_names)
    visualize.plot_stats(pop.statistics)
    visualize.plot_species(pop.statistics)

    # Verify network output against training data.
    print('\nBest network output:')
    net = iznn.create_phenotype(winner, *iz_params)
    sum_square_error, simulated = simulate(winner)

    # Create a plot of the traces out to the max time for each set of inputs.
    plt.figure(figsize=(12, 12))
    for r, (inputData, outputData, t0, t1, v0, v1,
            neuron_data) in enumerate(simulated):
        response = compute_output(t0, t1)
        print("{0!r} expected {1:.3f} got {2:.3f}".format(
            inputData, outputData, response))

        axes = plt.subplot(4, 1, r + 1)
        plt.title(
            "Traces for XOR input {{{0:.1f}, {1:.1f}}}".format(*inputData),
            fontsize=12)
        for i, s in neuron_data.items():
            if i in net.outputs:
                t, v = zip(*s)
                plt.plot(t, v, "-", label="neuron {0:d}".format(i))

        # Circle the first peak of each output.
        circle0 = patches.Ellipse((t0, v0), 1.0, 10.0, color='r', fill=False)
        circle1 = patches.Ellipse((t1, v1), 1.0, 10.0, color='r', fill=False)
        axes.add_artist(circle0)
        axes.add_artist(circle1)

        plt.ylabel("Potential (mv)", fontsize=10)
        plt.ylim(-100, 50)
        plt.tick_params(labelsize=8)
        plt.grid()

    plt.xlabel("Time (in ms)", fontsize=10)
    plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
    plt.savefig("traces.png", dpi=90)
    plt.show()
Example #12
0
def test_iznn_evolve():
    """This is a stripped-down copy of the XOR2 spiking example."""

    # Network inputs and expected outputs.
    xor_inputs = ((0, 0), (0, 1), (1, 0), (1, 1))
    xor_outputs = (0, 1, 1, 0)

    # Maximum amount of simulated time (in milliseconds) to wait for the network to produce an output.
    max_time = 50.0

    def compute_output(t0, t1):
        '''Compute the network's output based on the "time to first spike" of the two output neurons.'''
        if t0 is None or t1 is None:
            # If one of the output neurons failed to fire within the allotted time,
            # give a response which produces a large error.
            return -1.0
        else:
            # If the output neurons fire within 1.0 milliseconds of each other,
            # the output is 1, and if they fire more than 11 milliseconds apart,
            # the output is 0, with linear interpolation between 1 and 11 milliseconds.
            response = 1.1 - 0.1 * abs(t0 - t1)
            return max(0.0, min(1.0, response))

    def simulate(genome):
        # Create a network of Izhikevich neurons based on the given genome.
        net = iznn.create_phenotype(genome, **iznn.THALAMO_CORTICAL_PARAMS)
        dt = 0.25
        sum_square_error = 0.0
        simulated = []
        for inputData, outputData in zip(xor_inputs, xor_outputs):
            neuron_data = {}
            for i, n in net.neurons.items():
                neuron_data[i] = []

            # Reset the network, apply the XOR inputs, and run for the maximum allowed time.
            net.reset()
            net.set_inputs(inputData)
            t0 = None
            t1 = None
            v0 = None
            v1 = None
            num_steps = int(max_time / dt)
            for j in range(num_steps):
                t = dt * j
                output = net.advance(dt)

                # Capture the time and neuron membrane potential for later use if desired.
                for i, n in net.neurons.items():
                    neuron_data[i].append((t, n.v))

                # Remember time and value of the first output spikes from each neuron.
                if t0 is None and output[0] > 0:
                    t0, v0 = neuron_data[net.outputs[0]][-2]

                if t1 is None and output[1] > 0:
                    t1, v1 = neuron_data[net.outputs[1]][-2]

            response = compute_output(t0, t1)
            sum_square_error += (response - outputData) ** 2

            simulated.append(
                (inputData, outputData, t0, t1, v0, v1, neuron_data))

        return sum_square_error, simulated

    def eval_fitness(genomes):
        for genome in genomes:
            sum_square_error, simulated = simulate(genome)
            genome.fitness = 1 - sum_square_error

    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'test_configuration'))

    # TODO: This is a little hackish, but will a user ever want to do it?
    # If so, provide a convenience method on Config for it.
    for i, tc in enumerate(config.type_config['DefaultStagnation']):
        if tc[0] == 'species_fitness_func':
            config.type_config['DefaultStagnation'][i] = (tc[0], 'median')

    # For this network, we use two output neurons and use the difference between
    # the "time to first spike" to determine the network response.  There are
    # probably a great many different choices one could make for an output encoding,
    # and this choice may not be the best for tackling a real problem.
    config.output_nodes = 2

    pop = population.Population(config)
    pop.run(eval_fitness, 10)

    print('Number of evaluations: {0}'.format(pop.total_evaluations))

    # Visualize the winner network and plot statistics.
    winner = pop.statistics.best_genome()

    # Verify network output against training data.
    print('\nBest network output:')
    net = iznn.create_phenotype(winner, **iznn.RESONATOR_PARAMS)
    sum_square_error, simulated = simulate(winner)

    repr(winner)
    str(winner)
    for g in winner.node_genes:
        repr(g)
        str(g)
    for g in winner.conn_genes:
        repr(g)
        str(g)
Example #13
0
def test_iznn_evolve():
    """This is a stripped-down copy of the XOR2 spiking example."""

    # Network inputs and expected outputs.
    xor_inputs = ((0, 0), (0, 1), (1, 0), (1, 1))
    xor_outputs = (0, 1, 1, 0)

    # Maximum amount of simulated time (in milliseconds) to wait for the network to produce an output.
    max_time = 50.0

    def compute_output(t0, t1):
        '''Compute the network's output based on the "time to first spike" of the two output neurons.'''
        if t0 is None or t1 is None:
            # If one of the output neurons failed to fire within the allotted time,
            # give a response which produces a large error.
            return -1.0
        else:
            # If the output neurons fire within 1.0 milliseconds of each other,
            # the output is 1, and if they fire more than 11 milliseconds apart,
            # the output is 0, with linear interpolation between 1 and 11 milliseconds.
            response = 1.1 - 0.1 * abs(t0 - t1)
            return max(0.0, min(1.0, response))

    def simulate(genome):
        # Create a network of Izhikevich neurons based on the given genome.
        net = iznn.create_phenotype(genome, **iznn.THALAMO_CORTICAL_PARAMS)
        dt = 0.25
        sum_square_error = 0.0
        simulated = []
        for inputData, outputData in zip(xor_inputs, xor_outputs):
            neuron_data = {}
            for i, n in net.neurons.items():
                neuron_data[i] = []

            # Reset the network, apply the XOR inputs, and run for the maximum allowed time.
            net.reset()
            net.set_inputs(inputData)
            t0 = None
            t1 = None
            v0 = None
            v1 = None
            num_steps = int(max_time / dt)
            for j in range(num_steps):
                t = dt * j
                output = net.advance(dt)

                # Capture the time and neuron membrane potential for later use if desired.
                for i, n in net.neurons.items():
                    neuron_data[i].append((t, n.v))

                # Remember time and value of the first output spikes from each neuron.
                if t0 is None and output[0] > 0:
                    t0, v0 = neuron_data[net.outputs[0]][-2]

                if t1 is None and output[1] > 0:
                    t1, v1 = neuron_data[net.outputs[1]][-2]

            response = compute_output(t0, t1)
            sum_square_error += (response - outputData)**2

            simulated.append(
                (inputData, outputData, t0, t1, v0, v1, neuron_data))

        return sum_square_error, simulated

    def eval_fitness(genomes):
        for genome in genomes:
            sum_square_error, simulated = simulate(genome)
            genome.fitness = 1 - sum_square_error

    # Load the config file, which is assumed to live in
    # the same directory as this script.
    local_dir = os.path.dirname(__file__)
    config = Config(os.path.join(local_dir, 'test_configuration'))

    # TODO: This is a little hackish, but will a user ever want to do it?
    # If so, provide a convenience method on Config for it.
    for i, tc in enumerate(config.type_config['DefaultStagnation']):
        if tc[0] == 'species_fitness_func':
            config.type_config['DefaultStagnation'][i] = (tc[0], 'median')

    # For this network, we use two output neurons and use the difference between
    # the "time to first spike" to determine the network response.  There are
    # probably a great many different choices one could make for an output encoding,
    # and this choice may not be the best for tackling a real problem.
    config.output_nodes = 2

    pop = population.Population(config)
    pop.run(eval_fitness, 10)

    print('Number of evaluations: {0}'.format(pop.total_evaluations))

    # Visualize the winner network and plot statistics.
    winner = pop.statistics.best_genome()

    # Verify network output against training data.
    print('\nBest network output:')
    net = iznn.create_phenotype(winner, **iznn.RESONATOR_PARAMS)
    sum_square_error, simulated = simulate(winner)

    repr(winner)
    str(winner)
    for g in winner.node_genes:
        repr(g)
        str(g)
    for g in winner.conn_genes:
        repr(g)
        str(g)