为什么我的神经网络没有发展?使用NEAT增强型拓扑的神经进化

问题描述

我正在开发一个项目,以发展神经网络来相互玩囚徒困境游戏。我使用的是NEAT-python实现(see website here),可通过示例下载。我的代码基于其中之一-我已定制文件以适合我的任务。这是我的代码

import os
import pandas as pd
import neat


pathdata_ratiocoop = 'pergenerationcoop.xlsx'
pathdata_averageint = 'pergenerationint.xlsx'
pathdata_gamecoop = 'gamecoop.xlsx'

#changing variable
runs_per_net = 50
generations = 10000

#static variable
cooperate = 1.0
defect = 0.0
reactive_inputs=[]

#counters
total_payoff = 0.0

    #ratio per generation
num_coop_moves = 0.0
total_moves = 0.0
ratio_coop = 0.0
total_intelligence = 0.0
intelligence_counter = 0.0
generation_ratio=[]
average_int=[]
ratio=[]

    #ratio over whole game
grand_total_moves = 0.0
grand_num_coop = 0.0
grand_ratio = 0.0

current_gen = 1

def update_inputs(inputs1,inputs2):
    global reactive_inputs
    reactive_inputs = [inputs1,inputs2]


def eval_genome(genome,genome2,config):

    global total_moves
    global grand_total_moves
    global num_coop_moves
    global grand_num_coop
    global ratio_coop
    global total_intelligence
    global intelligence_counter

    nets=[]
    #net = neat.nn.FeedForwardNetwork.create(genome,config)
    #net2 = neat.nn.FeedForwardNetwork.create(genome2,config)
    net = neat.nn.RecurrentNetwork.create(genome,config)
    net2 = neat.nn.RecurrentNetwork.create(genome2,config)

    nets.append(net)
    nets.append(net2)
    
    fitness = 0.0
    last_move_of_player1 = 0.0
    last_move_of_player2 = 0.0

    runs = 0
    
    for runs in range(runs_per_net):
        if runs == 0:
            #in first round,reset total payoff and players cooperate for first move
            total_payoff = 0.0
            update_inputs([1.0,1.0],[1.0,1.0])
            
        outputs=[]
        payoff = 0

        #run each net and store their outputs
        for index,net in enumerate(nets):
            inputs = reactive_inputs[index]
            action = net.activate(inputs)
            output = action[0]
            outputs.append(output)
        #END OF FOR LOOP
        
        #determine if move is cooperate/defect
        if outputs[0] > 0.5:
            last_move_of_player1 = cooperate
            num_coop_moves += 1
            grand_num_coop += 1
        else:
            last_move_of_player1 = defect
        
        if outputs[1] > 0.5:
            last_move_of_player2 = cooperate
            num_coop_moves += 1
            grand_num_coop += 1
        else:
            last_move_of_player2 = defect

        #increment counter for ratio calculation
        total_moves += 2
        grand_total_moves += 2

        #update inputs for next run
        input1 =[last_move_of_player1,last_move_of_player2]
        input2 = [last_move_of_player2,last_move_of_player1]
        update_inputs(input1,input2)

        #PAYOFF MATRIX
        if outputs[0] > 0.5 and outputs[1] > 0.5:
            payoff = 2.0
        elif outputs[0] > 0.5 and outputs[1] < 0.5:
            payoff = 0.0
        elif outputs[0] < 0.5 and outputs[1] > 0.5:
            payoff = 3.0
        elif outputs[0] < 0.5 and outputs[1] < 0.5:
            payoff = 1.0

        total_payoff += payoff

    #END OF FOR LOOP - running nets against each other for number of runs
    intelligence = genome.size()[0]
    total_intelligence += intelligence
#print("total intelligence "+ str(total_intelligence))
    intelligence_counter += 1
    fitness = (total_payoff/(runs+1)) - (0.01*intelligence)
    return fitness

def eval_genomes(genomes,config):
    global total_moves 
    global num_coop_moves 
    global generation_ratio

    global grand_total_moves
    global grand_num_coop

    global total_intelligence
    global intelligence_counter
    global average_int
    global ratio

    global current_gen

    #reset variables for each generation
    total_moves = 0.0
    num_coop_moves = 0.0
    total_intelligence = 0.0
    intelligence_counter = 0.0

    for genome_id,genome in genomes:
        genome1 = genome
        total_fitness = 0.0

        for genome_id,genome2 in genomes:
            total_fitness += eval_genome(genome1,config)
        
        genome.fitness = total_fitness
    #end of for loop to run the generation

    average_intelligence = total_intelligence/intelligence_counter
    average_int.append(average_intelligence)

    #calculate per generation ratio of coop moves
    if num_coop_moves == 0.0:
        ratio_coop = 0.0
    else:
        ratio_coop = (num_coop_moves/total_moves)*100
    generation_ratio.append(ratio_coop)

    #calculate per game ratio of coop moves
    if current_gen == generations:
        if grand_num_coop == 0.0:
            grand_ratio = 0.0
        else:
            grand_ratio = (grand_num_coop/grand_total_moves)*100
        ratio.append(grand_ratio)
        save_game_results()
        save_generation_results()
        save_intelligence_results()
    current_gen += 1

def save_generation_results():
    try:
        existing_data = pd.read_excel(pathdata_ratiocoop)
        data = pd.DataFrame(generation_ratio)
        x = [existing_data,data]
        existing_data = pd.concat(x,axis=1)
        writer=pd.ExcelWriter(pathdata_ratiocoop,engine='xlsxwriter' )
        existing_data.to_excel(writer,sheet_name='Sheet1',index = False)
    except Exception as e:
        data = pd.DataFrame(generation_ratio)
        writer=pd.ExcelWriter(pathdata_ratiocoop,engine='xlsxwriter' )
        data.to_excel(writer,index = False)
    writer.save() 

def save_intelligence_results():
    try:
        existing_data = pd.read_excel(pathdata_averageint)
        data = pd.DataFrame(average_int)
        x = [existing_data,axis=1)
        writer=pd.ExcelWriter(pathdata_averageint,index = False)
    except Exception as e:
        data = pd.DataFrame(average_int)
        writer=pd.ExcelWriter(pathdata_averageint,index = False)
    writer.save() 

def save_game_results():
    try:
        existing_data = pd.read_excel(pathdata_gamecoop)
        data = pd.DataFrame(ratio)
        x = [existing_data,axis=1)
        writer=pd.ExcelWriter(pathdata_gamecoop,index = False)
    except Exception as e:
        data = pd.DataFrame(ratio)
        writer=pd.ExcelWriter(pathdata_gamecoop,index = False)
    writer.save() 


def run():

    local_dir = os.path.dirname(__file__)
    config_path = os.path.join(local_dir,'config-Feedforward') 
    config = neat.Config(neat.DefaultGenome,neat.DefaultReproduction,neat.DefaultSpeciesSet,neat.DefaultStagnation,config_path)

    pop = neat.Population(config)

    winner = pop.run(eval_genomes,generations)


if __name__ == '__main__':
    run()

我将大多数配置文件设置设为认,但是更改了输入,隐藏和输出节点的数量以及节点,连接和权重的突变率:

fitness_criterion     = max
fitness_threshold     = 60.0
no_fitness_termination = True
pop_size              = 50
reset_on_extinction   = False

[DefaultGenome]
#network parameters
num_inputs              = 2
num_hidden              = 0
num_outputs             = 1

initial_connection      = full_direct
Feed_forward            = False

#connection enable options
enabled_default         = True
enabled_mutate_rate     = 0.01

#genome compatibility options
compatibility_disjoint_coefficient    = 1.0
compatibility_weight_coefficient      = 0.6

#connection & node add/remove rates
conn_add_prob           = 0.02
conn_delete_prob        = 0.02
node_add_prob           = 0.02
node_delete_prob        = 0.02

#node activation options
activation_default      = sigmoid
activation_options      = sigmoid
activation_mutate_rate  = 0.0

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

#node bias options
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

#node response options
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

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


[DefaultSpeciesSet]
compatibility_threshold = 3.0

[DefaultStagnation]
species_fitness_func = mean
max_stagnation  = 1000

[DefaultReproduction]
elitism            = 0
survival_threshold = 0.2

我的适应度函数基于网是否选择合作还是在每转弯时出现缺陷(确定为输出> 0.5或

在我看来,网络并没有发展,我尝试根据文档更改大多数配置文件设置,但结果始终没有改变。

另外值得注意的是,我的停滞数字很高,因为如果停滞数字降低,人口将立即灭绝-当其设置为30时,灭绝将在33代左右发生,这进一步表明他们没有进化。

我希望有人能找出原因,因为我已经用尽了所有想法,但事情可能无法正常工作,并且关于这一特定问题的在线文档也很少。如果您有任何想法,我会尝试一切!另外,我必须使用NEAT作为特定的遗传算法,因为这是专门针对此问题的研究的一部分。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)