【问题标题】:Python NEAT not learning further after a certain pointPython NEAT 在某一点之后没有进一步学习
【发布时间】:2021-03-07 15:10:40
【问题描述】:

似乎我的程序试图学习到某个点,然后它就满足了,并且完全停止改进和改变。通过我的测试,它通常最多会达到 -5 的值,然后无论我让它运行多长时间,它都会保持在那里。结果集也没有变化。

只是为了跟踪它,我制作了自己的日志记录工具,看看哪个做得最好。 1 和 0 数组指的是 AI 做出正确选择的频率 (1),以及 AI 做出错误选择的频率 (0)。

我的目标是让 AI 重复一个高于 0.5 然后低于 0.5 的模式,不一定要找到奇数。这只是一个小测试,看看我是否可以让 AI 在一些基本数据上正常工作,然后再做一些更高级的事情。

但不幸的是,它不起作用,我不确定为什么。

代码:

import os
import neat

def main(genomes, config):
    networks = []
    ge = []
    choices = []

    for _, genome in genomes:
        network = neat.nn.FeedForwardNetwork.create(genome, config)
        networks.append(network)

        genome.fitness = 0
        ge.append(genome)

        choices.append([])

    for x in range(25):
        for i, genome in enumerate(ge):
            output = networks[i].activate([x])

            # print(str(x) + " - " + str(i) + " chose " + str(output[0]))
            if output[0] > 0.5:
                if x % 2 == 0:
                    ge[i].fitness += 1
                    choices[i].append(1)
                else:
                    ge[i].fitness -= 5
                    choices[i].append(0)
            else:
                if not x % 2 == 0:
                    ge[i].fitness += 1
                    choices[i].append(1)
                else:
                    ge[i].fitness -= 5
                    choices[i].append(0)
                    pass
            
            # Optional death function, if I use this there are no winners at any point.
            # if ge[i].fitness <= 20:
            #     ge[i].fitness -= 100
            #     ge.pop(i)
            #     choices.pop(i)
            #    networks.pop(i)
    if len(ge) > 0:
        fittest = -1
        fitness = -999999
        for i, genome in enumerate(ge):
            if ge[i].fitness > fitness:
                fittest = i
                fitness = ge[i].fitness

        print("Best: " + str(fittest) + " with fitness " + str(fitness))
        print(str(choices[fittest]))
    else:
        print("Done with no best.")

def run(config_path):
    config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet,
                                neat.DefaultStagnation, config_path)

    pop = neat.Population(config)

    #pop.add_reporter(neat.StdOutReporter(True))
    #stats = neat.StatisticsReporter()
    #pop.add_reporter(stats)

    winner = pop.run(main, 100)

if __name__ == "__main__":
    local_dir = os.path.dirname(__file__)
    config_path = os.path.join(local_dir, "config-feedforward.txt")
    run(config_path)

整洁的配置:

[NEAT]
fitness_criterion     = max
fitness_threshold     = 100000
pop_size              = 5000
reset_on_extinction   = False

[DefaultGenome]
# node activation options
activation_default      = tanh
activation_mutate_rate  = 0.0
activation_options      = tanh

# node aggregation options
aggregation_default     = sum
aggregation_mutate_rate = 0.0
aggregation_options     = sum

# node bias options
bias_init_mean          = 0.0
bias_init_stdev         = 1.0
bias_max_value          = 30.0
bias_min_value          = -30.0
bias_mutate_power       = 0.5
bias_mutate_rate        = 0.7
bias_replace_rate       = 0.1

# genome compatibility options
compatibility_disjoint_coefficient = 1.0
compatibility_weight_coefficient   = 0.5

# connection add/remove rates
conn_add_prob           = 0.5
conn_delete_prob        = 0.5

# connection enable options
enabled_default         = True
enabled_mutate_rate     = 0.1

feed_forward            = True
initial_connection      = full

# node add/remove rates
node_add_prob           = 0.2
node_delete_prob        = 0.2

# network parameters
num_hidden              = 0
num_inputs              = 1
num_outputs             = 1

# node response options
response_init_mean      = 1.0
response_init_stdev     = 0.0
response_max_value      = 30.0
response_min_value      = -30.0
response_mutate_power   = 0.0
response_mutate_rate    = 0.0
response_replace_rate   = 0.0

# connection weight options
weight_init_mean        = 0.0
weight_init_stdev       = 1.0
weight_max_value        = 30
weight_min_value        = -30
weight_mutate_power     = 0.5
weight_mutate_rate      = 0.8
weight_replace_rate     = 0.1

[DefaultSpeciesSet]
compatibility_threshold = 3.0

[DefaultStagnation]
species_fitness_func = max
max_stagnation       = 20
species_elitism      = 2

[DefaultReproduction]
elitism            = 2
survival_threshold = 0.2

【问题讨论】:

    标签: python machine-learning genetic-algorithm neat


    【解决方案1】:

    很抱歉告诉您,这种方法行不通。请记住,神经网络通常是通过进行矩阵乘法然后用 0 取最大值(这称为 RELU)构建的,因此在每一层基本上都是线性的,并且有一个截止值(不,选择像 sigmoid 这样的不同激活不会有帮助) .您希望网络产生 >.5, <.5>.5, <.5 ... relu neat href="https://stackoverflow.com/questions/56380303/keras-making-a-neural-network-to-find-a-numbers-modulus" target="_blank" rel="nofollow">Keras: Making a neural network to find a number's modulus

    您可以使用 NEAT 取得的唯一真正进步是为网络提供更多功能作为输入,例如给它x%2 作为输入,它会很快学会,尽管这显然是“作弊”。

    【讨论】:

    • 也是一种作弊,但我认为添加sin() 作为激活函数可能会有所帮助
    猜你喜欢
    • 2016-02-13
    • 2020-06-17
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多