问题描述
我正在开发一个项目,以发展神经网络来相互玩囚徒困境游戏。我使用的是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 (将#修改为@)