diff --git a/AlphaGo/test_rl.py b/AlphaGo/test_rl.py new file mode 100644 index 0000000..0659de1 --- /dev/null +++ b/AlphaGo/test_rl.py @@ -0,0 +1,621 @@ +# coding:utf-8 + +import sys,numpy,os,scipy.signal,threading,time,random +import tensorflow as tf +sys.path.append('../../pythonModules') +import wgenv,common,wgfeature,wgsdata + +## HELPER FUNCTIONS + +# Copies one set of variables to another. +# Used to set worker network parameters to those of global network. +def update_target_graph(from_scope,to_scope): + from_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, from_scope) + to_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, to_scope) + op_holder = [] + for from_var,to_var in zip(from_vars,to_vars): + op_holder.append(to_var.assign(from_var)) + return op_holder + +def process_observation(obj_main): + wgfeature.calUpdateFeature(obj_main) + np_mapFeature = obj_main.dic_metadata['np_mapFeature'] + np_mapFeature = numpy.swapaxes(np_mapFeature,0, 1) + np_mapFeature = numpy.swapaxes(np_mapFeature, 1, 2) + np_bopFeature = obj_main.dic_metadata['np_bopFeature'] + return np_mapFeature[numpy.newaxis,:,:,:],np_bopFeature[numpy.newaxis,:] + +def normalized_columns_initializer(std=1.0): + def _initializer(shape, dtype=None, partition_info=None): + out = numpy.random.randn(*shape).astype(numpy.float32) + out *= std / numpy.sqrt(numpy.square(out).sum(axis=0, keepdims=True)) + return tf.constant(out) + return _initializer + +# Discounting function used to calculate discounted returns. +def discount(x, gamma): + return scipy.signal.lfilter([1], [1, -gamma], x[::-1], axis=0)[::-1] + +# +def calScore(obj_main,flag_rlaicolor): + try: + l_values = wgsdata.getSdataValue(obj_main.dic_metadata) + l_scores = [l_values[0],120-l_values[2],l_values[1]] if flag_rlaicolor == 0 else [l_values[2],120-l_values[0],l_values[3]] + return l_scores + except Exception as e: + print('error in test_rl.py -> calScore() : ' + str(e)) + raise +class AC_Network(): + def __init__(self, scope, trainer, nonspatial_size,map_size,dict_actionsepc): + with tf.variable_scope(scope): + # get size of features from action_spec and observation_spec + self.inputs_nonspatial = tf.placeholder(shape=[None, nonspatial_size], dtype=tf.float32) + self.inputs_spatial_screen = tf.placeholder(shape=[None, map_size[0],map_size[1],map_size[2]],dtype=tf.float32) + + # Architecture here follows Atari-net Agent described in [1] Section 4.3 + self.nonspatial_dense = tf.layers.dense(inputs=self.inputs_nonspatial,units=32,activation=tf.tanh) + self.screen_conv1 = tf.layers.conv2d(inputs=self.inputs_spatial_screen,filters=16,kernel_size=[8,8],strides=[4,4],padding='valid',activation=tf.nn.relu) + self.screen_conv2 = tf.layers.conv2d(inputs=self.screen_conv1,filters=32,kernel_size=[4,4],strides=[2,2],padding='valid',activation=tf.nn.relu) + + # According to [1]: "The results are concatenated and sent through a linear layer with a ReLU activation." + screen_output_length = 1 + for dim in self.screen_conv2.get_shape().as_list()[1:]: + screen_output_length *= dim + + self.latent_vector = tf.layers.dense( + inputs=tf.concat([self.nonspatial_dense, tf.reshape(self.screen_conv2,shape=[-1,screen_output_length])], axis=1),units=256,activation=tf.nn.relu) + + # Output layers for policy and value estimations + # 1 policy network for base actions + # 16 policy networks for arguments + # - All modeled independently + # - Spatial arguments have the x and y values modeled independently as well + # 1 value network + self.policy_arg = dict() + for key,value in dict_actionsepc.items(): + self.policy_arg[key] = tf.layers.dense(inputs=self.latent_vector,units=value,activation=tf.nn.softmax,kernel_initializer=normalized_columns_initializer(0.01)) + + self.value = tf.layers.dense(inputs=self.latent_vector,units=1,kernel_initializer=normalized_columns_initializer(1.0)) + + # Only the worker network need ops for loss functions and gradient updating. + if scope != 'global': + self.actions_arg = dict() + self.actions_onehot_arg = dict() + for key, value in dict_actionsepc.items(): + self.actions_arg[key] = tf.placeholder(shape=[None],dtype=tf.int32) + self.actions_onehot_arg[key] = tf.one_hot(self.actions_arg[key],value,dtype=tf.float32) + + self.target_v = tf.placeholder(shape=[None],dtype=tf.float32) + self.advantages = tf.placeholder(shape=[None],dtype=tf.float32) + + + self.responsible_outputs_arg = dict() + + for key, value in dict_actionsepc.items(): + self.responsible_outputs_arg[key] = tf.reduce_sum(self.policy_arg[key] * self.actions_onehot_arg[key], [1]) + # tf_c1 = tf.assign(self.responsible_outputs_arg[key],1) + # #shape = tf.shape(self.responsible_outputs_arg[key]) + # shape = self.screen_conv2.get_shape() + # tf_c1= tf.constant(1,shape=self.screen_conv2.get_shape()) + # self.responsible_outputs_arg[key] = tf.where(tf.equal(self.responsible_outputs_arg[key],0),tf_c1,self.responsible_outputs_arg[key]) + + # Loss functions + self.value_loss = 0.5 * tf.reduce_sum(tf.square(self.target_v - tf.reshape(self.value,[-1]))) + + self.entropy_arg = dict() + for key, value in dict_actionsepc.items(): + self.entropy_arg[key] = -tf.reduce_sum(self.policy_arg[key] * tf.log(tf.clip_by_value(self.policy_arg[key],1e-20,1.))) + + self.entropy = 0 + for key, value in dict_actionsepc.items(): + self.entropy += self.entropy_arg[key] + + self.policy_loss_arg = dict() + for key, value in dict_actionsepc.items(): + self.policy_loss_arg[key] = - tf.reduce_sum(tf.log(tf.clip_by_value(self.responsible_outputs_arg[key], 1e-20, 1.0)) * self.advantages) + + self.policy_loss = 0 + for key, value in dict_actionsepc.items(): + self.policy_loss += self.policy_loss_arg[key] + + self.loss = 0.5 * self.value_loss + self.policy_loss - self.entropy * 0.01 + + # Get gradients from local network using local losses + self.local_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope) + # self.gradients - gradients of loss wrt local_vars + self.gradients = tf.gradients(self.loss,self.local_vars) + self.var_norms = tf.global_norm(self.local_vars) + self.grads,self.grad_norms = tf.clip_by_global_norm(self.gradients,0.5) # old=40 2018年09月10日修改,梯度太大 + + # Apply local gradients to global network + self.global_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'global') + self.apply_grads = trainer.apply_gradients(zip(self.grads,self.global_vars)) + + +## WORKER AGENT +class Worker(): + def __init__(self, name, trainer, model_path,log_path, global_episodes,flag_rlaicolor,dic_mainparas,flag_testai = False): + self.name = "worker_" + str(name) + self.number = name + self.model_path = model_path + self.flag_rlaicolor = flag_rlaicolor + self.trainer = trainer + self.global_episodes = global_episodes + self.increment = self.global_episodes.assign_add(1) + self.episode_rewards = [] + self.episode_lengths = [] + self.episode_mean_values = [] + self.episode_winnums = [] + self.l_actkeys = ['remain_scores','defeat_scores','city_scores'] + self.dict_episode_scores = {'remain_scores':[],'defeat_scores':[],'city_scores':[]} #分数 + self.dict_episode_actnums = {} #动作数 + + self.summary_writer = tf.summary.FileWriter(log_path) # 修改,由外部传入 + self.flag_testai = flag_testai # 是否测试ai + self.testai_freq = 500 # 测试ai的频率 + self.testai_runnums = 20 # 测试50场的平均胜率 + self.episode_test_winrates = [] #测试的平均胜率 + self.episode_test_winscores = [] #测试的平均净胜分 + self.prob_dec_fn = lambda x : 1.0/(0.0009*x+1.1) + print('Initializing environment #{}...'.format(self.number)) + self.env = wgenv.ENV(dic_mainparas = dic_mainparas,flag_rlaicolor=flag_rlaicolor) + # 初始化保存动作执行变量 + self.num_whats = self.env.getWhatNums() + for i in range(self.num_whats): + self.dict_episode_actnums[i] = [] + print('initlize static map feature...') + wgfeature.cfunRegister(self.env.obj_main) + wgfeature.calOneTimeFeature(self.env.obj_main) + wgfeature.calUpdateFeature(self.env.obj_main) + print('initlize static map feature done...') + # Create the local copy of the network and the tensorflow op to copy global paramters to local network + self.nonspatial_size = self.env.obj_main.dic_metadata['np_bopFeature'].shape[0] + tmp_map_size = self.env.obj_main.dic_metadata['np_mapFeature'].shape + self.map_size = (tmp_map_size[1],tmp_map_size[2],tmp_map_size[0]) + self.l_action_keys = ['who','what','how'] + dict_actionsepc ={self.l_action_keys[0]:self.env.getWhoNums(),self.l_action_keys[1]:self.env.getWhatNums(),self.l_action_keys[2]:self.env.getHowNums()} + self.local_AC = AC_Network(self.name, trainer, self.nonspatial_size,self.map_size,dict_actionsepc) + self.update_local_ops = update_target_graph('global', self.name) + + def train(self, rollout, sess, gamma, bootstrap_value): + try: + rollout = numpy.array(rollout) + s_np_mapFeature,s_np_bopFeature = rollout[:, 0],rollout[:,1] + np_l_chooseArg, rewards = rollout[:,2],rollout[:,3] + s1_np_mapFeature, s1_np_bopFeature = rollout[:,4],rollout[:,5] + episode_end, values = rollout[:,6],rollout[:,7] + + actions_arg_stack = dict() + for l_chooseArg in np_l_chooseArg: + for i in range(len(self.l_action_keys)): + key = self.l_action_keys[i] + if key not in actions_arg_stack: + actions_arg_stack[key] = [] + actions_arg_stack[key].append(l_chooseArg[i]) + + # Here we take the rewards and values from the rollout, and use them to calculate the advantage and discounted returns + # The advantage function uses generalized advantage estimation from [2] + self.rewards_plus = numpy.asarray(rewards.tolist() + [bootstrap_value]) + discounted_rewards = discount(self.rewards_plus, gamma)[:-1] + self.value_plus = numpy.asarray(values.tolist() + [bootstrap_value]) + advantages = rewards + gamma * self.value_plus[1:] - self.value_plus[:-1] + advantages = discount(advantages, gamma) + + # Update the global network using gradients from loss + # Generate network statistics to periodically save + feed_dict = {self.local_AC.target_v: discounted_rewards, + self.local_AC.inputs_spatial_screen: numpy.stack(s_np_mapFeature).reshape(-1, self.map_size[0],self.map_size[1],self.map_size[2]), + self.local_AC.inputs_nonspatial: numpy.stack(s_np_bopFeature).reshape(-1, self.nonspatial_size), + self.local_AC.advantages: advantages} + + for key,value in actions_arg_stack.items(): + feed_dict[self.local_AC.actions_arg[key]] = value + + v_l, p_l, e_l, g_n, v_n, _ = sess.run([self.local_AC.value_loss, + self.local_AC.policy_loss, + self.local_AC.entropy, + self.local_AC.grad_norms, + self.local_AC.var_norms, + self.local_AC.apply_grads], + feed_dict=feed_dict) + return v_l / len(rollout), p_l / len(rollout), e_l / len(rollout), g_n, v_n + except Exception as e: + common.echosentence_color('error in test_rl.py->train():{}'.format(str(e))) + self.env.__del__() + raise + except KeyboardInterrupt as k: + common.echosentence_color('error in test_rl.py->train():{}'.format(str(k))) + self.env.__del__() + raise + + + def getwincolor(self,dic_metadata): + '''打印态势信息''' + try: + list_values = wgsdata.getSdataValue(dic_metadata) + # cout_left = [0] * 2 + # for cur_bop in self.dic_metadata['l_rbops'] + self.dic_metadata['l_bbops'] + self.dic_metadata['l_pbops']: + # if cur_bop.ObjBlood > 0: + # cout_left[int(cur_bop.GameColor)] += 1 + # print '\t 红方剩余算子数量:%d. 剩余兵力分值:%d, 夺控得分:%d' % (cout_left[0], list_values[0], list_values[1]) + # print '\t 蓝方剩余算子数量:%d. 剩余兵力分值:%d, 夺控得分:%d' % (cout_left[1], list_values[2], list_values[3]) + return 0 if list_values[0] + list_values[1] - list_values[2] > \ + list_values[2] + list_values[3] - list_values[0] \ + else 1 + except Exception as e: + common.echosentence_color('wgsdata > showSDDat():{}'.format(str(e))) + raise + + def work(self, max_episode_length, gamma, sess, coord, saver): + try: + episode_count = sess.run(self.global_episodes) + total_steps = 0 + print ("Starting worker " + str(self.number)) + with sess.as_default(), sess.graph.as_default(): + t_start = time.time() + winnums = 0 + while True: #not coord.should_stop(): + # Download copy of parameters from global network + prob = self.prob_dec_fn(episode_count) #用规则ai的概率 + sess.run(self.update_local_ops) + episode_buffer = [] + episode_values = [] + # episode_frames = [] + episode_reward = 0 + episode_step_count = 0 + episode_end = False + + # 测试ai性能 + if self.flag_testai and episode_count % self.testai_freq == 0 and episode_count != 0: + winrate,winscore = self.test_ai(sess,self.testai_runnums) + self.episode_test_winrates.append(winrate) + self.episode_test_winscores.append(winscore) + common.echosentence_color('====================','blue') + common.echosentence_color('测试50场的胜率为:{}% ;净胜分为 {}'.format(winrate*100,winscore)) + common.echosentence_color('====================', 'yellow') + summary = tf.Summary() + summary.value.add(tag='test/WinRate', simple_value=float(winrate)) + summary.value.add(tag='test/WinScore', simple_value=float(winscore)) + self.summary_writer.add_summary(summary, episode_count) + self.summary_writer.flush() + flag_wincolor = 0 + # Start new episode + flag_goon = self.env.reset() + episode_end = not flag_goon + np_mapFeature,np_bopFeature = process_observation(self.env.obj_main) #resize np_mapFeature to [1,2,0] + s_np_mapFeature,s_np_bopFeature = np_mapFeature,np_bopFeature + for i in range(self.num_whats): + self.dict_episode_actnums[i].append(0) + + while not episode_end: + flag_baseai = False + if(random.random() < prob): + flag_goon,reward,list2_chooseArg,list_npMapFea,list_npBopFea = self.env.stepFollowBaseAI() # 依概率选择按照规则AI走,不参与训练 + flag_baseai = True + else: + policy_args, v = sess.run([self.local_AC.policy_arg, self.local_AC.value], + feed_dict={self.local_AC.inputs_spatial_screen: np_mapFeature, + self.local_AC.inputs_nonspatial: np_bopFeature}) + # nonspatial_dense,screen_conv1,screen_conv2,latent_vector= sess.run([self.local_AC.nonspatial_dense, self.local_AC.screen_conv1,self.local_AC.screen_conv2,self.local_AC.latent_vector], + # feed_dict={self.local_AC.inputs_spatial_screen: np_mapFeature, + # self.local_AC.inputs_nonspatial: np_bopFeature}) + # + # local_vars,global_vars = sess.run([self.local_AC.local_vars,self.local_AC.global_vars]) + + l_nppolicy = [] + for policy_key in self.l_action_keys: + l_nppolicy.append(policy_args[policy_key][0, :]) + + flag_goon, reward, l_chooseArg = self.env.step(l_nppolicy[0], l_nppolicy[1], l_nppolicy[2]) + + episode_end = not flag_goon + np_mapFeature, np_bopFeature = process_observation(self.env.obj_main) # resize np_mapFeature to [1,2,0] + + if episode_end: #游戏结束,根据游戏胜负修正最后的reward + flag_wincolor = self.getwincolor(self.env.obj_main.dic_metadata) + if flag_rlaicolor == flag_wincolor: + reward += 200 # [0,200] + + s1_np_mapFeature, s1_np_bopFeature = np_mapFeature, np_bopFeature + # if not episode_end: + # s1_np_mapFeature, s1_np_bopFeature = np_mapFeature, np_bopFeature + # else: + # s1_np_mapFeature, s1_np_bopFeature = s_np_mapFeature,s_np_bopFeature + + # Append latest state to buffer + if not flag_baseai: + self.dict_episode_actnums[l_chooseArg[1]][-1] += 1 + episode_buffer.append([s_np_mapFeature,s_np_bopFeature, l_chooseArg, reward, s1_np_mapFeature,s1_np_bopFeature, episode_end, v[0, 0]]) + episode_values.append(v[0, 0]) + else: + assert (len(list_npBopFea) == len(list2_chooseArg)) + list_npMapFea = [s_np_mapFeature] + list_npMapFea # 修复bug 动作执行之前的状态应该是s_np_mapFeature + list_npBopFea = [s_np_bopFeature] + list_npBopFea + for l_i in range(len(list2_chooseArg)): + l_chooseArg,s_np_mapFeature,s_np_bopFeature = list2_chooseArg[l_i],list_npMapFea[l_i],list_npBopFea[l_i] + s1_np_mapFeature,s1_np_bopFeature = list_npMapFea[l_i+1],list_npBopFea[l_i+1] + v = sess.run(self.local_AC.value, + feed_dict={self.local_AC.inputs_spatial_screen: s_np_mapFeature, + self.local_AC.inputs_nonspatial: s_np_bopFeature}) + self.dict_episode_actnums[l_chooseArg[1]][-1] += 1 + episode_buffer.append([s_np_mapFeature, s_np_bopFeature, l_chooseArg, reward, s1_np_mapFeature,s1_np_bopFeature, episode_end, v[0, 0]]) + episode_values.append(v[0, 0]) + + episode_reward = reward + s_np_mapFeature, s_np_bopFeature = s1_np_mapFeature, s1_np_bopFeature + total_steps += 1 + episode_step_count += 1 + + # If the episode hasn't ended, but the experience buffer is full, then we make an update step using that experience rollout + if len(episode_buffer) == 30 and not episode_end and episode_step_count != max_episode_length - 1: + # Since we don't know what the true final return is, we "bootstrap" from our current value estimation + v1 = sess.run(self.local_AC.value,feed_dict={self.local_AC.inputs_spatial_screen: np_mapFeature, + self.local_AC.inputs_nonspatial: np_bopFeature}) + + v_l, p_l, e_l, g_n, v_n = self.train(episode_buffer, sess, gamma, v1) + episode_buffer = [] + sess.run(self.update_local_ops) + if episode_end: + break + + if flag_wincolor == flag_rlaicolor: + winnums += 1 + self.episode_rewards.append(episode_reward) + self.episode_lengths.append(episode_step_count) + self.episode_mean_values.append(numpy.mean(episode_values)) + self.episode_winnums.append(winnums) + #计算分数 + l_scores = calScore(self.env.obj_main,flag_rlaicolor) + for i in range(len(self.l_actkeys)): + self.dict_episode_scores[self.l_actkeys[i]].append(l_scores[i]) + + episode_count += 1 + + global _max_score, _running_avg_score, _episodes, _steps + if _max_score < episode_reward: + _max_score = episode_reward + _running_avg_score = (2.0 / 101) * (episode_reward - _running_avg_score) + _running_avg_score + _episodes[self.number] = episode_count + _steps[self.number] = total_steps + + t_now = time.time() + print("{} Step #{} Episode #{} Reward: {}".format(self.name, total_steps, episode_count, + episode_reward)) + print("Total Steps: {}\tTotal Episodes: {}\tTotal time: {}\tMax Score: {}\tAvg Score: {}".format(numpy.sum(_steps), + numpy.sum(_episodes), + t_now-t_start, + _max_score, + _running_avg_score)) + print(self.l_actkeys[0] + ' : ' + str(l_scores[0]) + ' '+self.l_actkeys[1] + ' : ' + str(l_scores[1]) + ' ' + +self.l_actkeys[2] + ' : ' + str(l_scores[2]) + ' ') + common.echosentence_color('=='*10,'blue') + # Update the network using the episode buffer at the end of the episode + if len(episode_buffer) != 0: + # v1 = sess.run(self.local_AC.value,feed_dict={self.local_AC.inputs_spatial_screen: np_mapFeature, + # self.local_AC.inputs_nonspatial: np_bopFeature}) + v_l, p_l, e_l, g_n, v_n = self.train(episode_buffer, sess, gamma, 0) # 用v1替换0; 2018年09月11日重新替换为0 + + if episode_count % 5 == 0 and episode_count != 0: + if episode_count % 250 == 0 and self.name == 'worker_0': + saver.save(sess, self.model_path + '/model-' + str(0) + '.cptk') + print ("Saved Model") + + mean_reward = numpy.mean(self.episode_rewards[-5:]) + mean_length = numpy.mean(self.episode_lengths[-5:]) + mean_value = numpy.mean(self.episode_mean_values[-5:]) + mean_winnums = numpy.mean(self.episode_winnums[-5:]) + summary = tf.Summary() + summary.value.add(tag='Perf/Reward', simple_value=float(mean_reward)) + summary.value.add(tag='Perf/Length', simple_value=float(mean_length)) + summary.value.add(tag='Perf/Value', simple_value=float(mean_value)) + summary.value.add(tag='Perf/winums', simple_value=float(mean_winnums)) + summary.value.add(tag='Losses/Value Loss', simple_value=float(v_l)) + summary.value.add(tag='Losses/Policy Loss', simple_value=float(p_l)) + summary.value.add(tag='Losses/Entropy', simple_value=float(e_l)) + summary.value.add(tag='Losses/Grad Norm', simple_value=float(g_n)) + summary.value.add(tag='Losses/Var Norm', simple_value=float(v_n)) + for i in range(self.num_whats): + summary.value.add(tag='ActNums/'+str(i),simple_value=float(self.dict_episode_actnums[i][-1])) + for actkey in self.l_actkeys: + summary.value.add(tag='Scores/' + actkey, simple_value=float(self.dict_episode_scores[actkey][-1])) + self.summary_writer.add_summary(summary, episode_count) + + self.summary_writer.flush() + if self.name == 'worker_0': + sess.run(self.increment) + except Exception as e: + common.echosentence_color('error in test_rl.py->work():{}'.format(str(e))) + self.env.__del__() + raise + except KeyboardInterrupt as k: + common.echosentence_color('error in test_rl.py->work():{}'.format(str(k))) + self.env.__del__() + raise + + def test_ai(self,sess,test_nums): + try: + winrate = 0 + winscore = 0 + for gamenum in range(test_nums): + flag_goon = self.env.reset() + episode_end = not flag_goon + np_mapFeature, np_bopFeature = process_observation(self.env.obj_main) # resize np_mapFeature to [1,2,0] + while not episode_end: + policy_args, v = sess.run([self.local_AC.policy_arg, self.local_AC.value], + feed_dict={self.local_AC.inputs_spatial_screen: np_mapFeature, + self.local_AC.inputs_nonspatial: np_bopFeature}) + l_nppolicy = [] + for policy_key in self.l_action_keys: + l_nppolicy.append(policy_args[policy_key][0, :]) + + flag_goon, reward, l_chooseArg = self.env.step(l_nppolicy[0], l_nppolicy[1], l_nppolicy[2]) + + episode_end = not flag_goon + np_mapFeature, np_bopFeature = process_observation(self.env.obj_main) # resize np_mapFeature to [1,2,0] + + list_values = wgsdata.getSdataValue(self.env.obj_main.dic_metadata) + red_score = 2*list_values[0] + list_values[1] - 2* list_values[2] - list_values[3] + myscore = red_score if self.flag_rlaicolor == 0 else -red_score + winrate = winrate + 1 if myscore > 0 else winrate + winscore += myscore + winrate /= test_nums + winscore /= test_nums + return winrate,winscore + except Exception as e: + common.echosentence_color('error in test_rl.py->Worker->test_ai():{}'.format(str(e))) + self.env.__del__() + raise + except KeyboardInterrupt as k: + common.echosentence_color('error in test_rl.py->Worker->test_ai():{}'.format(str(k))) + self.env.__del__() + raise + +def defmainparas(): + try: + num_xd, strategy_id, num_plays, num_objcutility = 0, 1, 1, 1 + import AI_QD, wgdensestranet + dic2_rolloutaiparas = { + 'red': {'type_ai': AI_QD.AI_QD_BASE, + 'type_stra': 'rule-base', + 'type_stranet': wgdensestranet.StraDenseNet, + }, + 'blue': {'type_ai': AI_QD.AI_QD_STRA, + 'type_stra': 'random', + 'type_stranet': wgdensestranet.StraDenseNet, + }, + } + dic_mainparas = {'str_wgrootdir': '../../', + 'str_global_flag': 'QD', + 'flag_show': True, + 'num_plays': num_plays, + 'num_objcutility': num_objcutility, + 'num_xd': num_xd, + 'strategy_id': strategy_id, + 'flag_action_cache': False, + 'flag_qd_rm': True, + 'flag_cache': True, + 'flag_gpu': False, + 'flag_dllnum': 0, + 'cuda_id': 0, + 'flag_savestate': False, + 'dic2_aiparas': { + 'flag_color4acai': 0, + 'red': {'type_ai': AI_QD.AI_QD_BASE, + 'type_stra': 'rule-base', + # type of stratree of nodes, how to select next path, [rule-base, random, net] + 'type_stranet': wgdensestranet.StraDenseNet, + 'dic2_rolloutaiparas': dic2_rolloutaiparas, + 'flag_candidateactions': 'rule-base' + # [rule-base, stra] how to get candidate actions + }, + 'blue': {'type_ai': AI_QD.AI_QD_HA, + 'type_stra': 'net', + 'type_stranet': wgdensestranet.StraDenseNet, + 'dic2_rolloutaiparas': dic2_rolloutaiparas, + 'flag_candidateactions': 'stra' + }, + }, + 'rewrad_type': 'nowscore-base', # ['nowsocoe-base','action-base'] + } + return dic_mainparas + except Exception as e: + print('error in defmainparas() : '+str(e)) + raise + +global BattleMode +BattleMode = '1v1' +global flag_ignoreEnemyReward +flag_ignoreEnemyReward = True +if __name__ == '__main__': + try: + '''注: 需要修改参数说明 + 修改rl颜色: flag_rlaicolor + defmainparas()中的dic_mainparas中dic2_paras的'red'和'blue'互换 + 修改算子数: BattleMode (1v0,1v1,6v6) + 是否加载已训练模型: load_model + 注意:每次更换实验条件之后,记得修改exp_version,免得覆盖之前的游戏版本 + ''' + load_model = False + flag_rlaicolor = 1 + exp_version = 'v0' + + flag_testai = True + max_episode_length = 300 + gamma = .99 # Discount rate for advantage estimation and reward discounting + + str_ai = 'red' if flag_rlaicolor == 0 else 'blue' + save_path = '../../../a3c-explog/'+ BattleMode+'_'+str_ai+'_'+exp_version+'/' + model_path = save_path + 'model/' + log_path = save_path + 'train_0/' + dic_mainparas = defmainparas() + + tf.reset_default_graph() + if not os.path.exists(model_path): + os.makedirs(model_path) + + common.echosentence_color('BattleMode = ' + BattleMode ,'yellow') + print('Initializing temporary environment to retrive action_spec...') + env = wgenv.ENV(dic_mainparas = dic_mainparas,flag_rlaicolor=flag_rlaicolor) + wgfeature.cfunRegister(env.obj_main) + + wgfeature.calOneTimeFeature(env.obj_main) + wgfeature.calUpdateFeature(env.obj_main) + + nonspatial_size = env.obj_main.dic_metadata['np_bopFeature'].shape[0] + tmp_map_size = env.obj_main.dic_metadata['np_mapFeature'].shape + map_size = (tmp_map_size[1], tmp_map_size[2], tmp_map_size[0]) + l_action_keys = ['who', 'what', 'how'] + dict_actionsepc = {l_action_keys[0]: env.getWhoNums(), l_action_keys[1]: env.getWhatNums(),l_action_keys[2]: env.getHowNums()} + print('Initializing temporary environment to retrive action_spec done...') + + with tf.device("/cpu:0"): + global_episodes = tf.Variable(0, dtype=tf.int32, name='global_episodes', trainable=False) + trainer = tf.train.AdamOptimizer(learning_rate=1e-4) + master_network = AC_Network('global', None, nonspatial_size,map_size,dict_actionsepc) # Generate global network + # num_workers = multiprocessing.cpu_count() # Set workers to number of available CPU threads + num_workers = 1 # psutil.cpu_count() # Set workers to number of available CPU threads + global _max_score, _running_avg_score, _steps, _episodes + _max_score = -200 + _running_avg_score = 0 + _steps = numpy.zeros(num_workers) + _episodes = numpy.zeros(num_workers) + workers = [] + # Create worker classes + for i in range(num_workers): + workers.append(Worker(i, trainer, model_path, log_path, global_episodes, flag_rlaicolor,dic_mainparas,flag_testai=flag_testai)) + saver = tf.train.Saver(max_to_keep=5) + + config = tf.ConfigProto() + config.gpu_options.allow_growth = True + with tf.Session(config = config) as sess: + # coord = tf.train.Coordinator() + if load_model == True: + print ('Loading Model...') + ckpt = tf.train.get_checkpoint_state(model_path) + saver.restore(sess, ckpt.model_checkpoint_path) + else: + sess.run(tf.global_variables_initializer()) + + # This is where the asynchronous magic happens + # Start the "work" process for each worker in a separate thread + while(True): + for worker in workers: + worker.work(max_episode_length, gamma, sess, None, saver) + # worker_threads = [] + # for worker in workers: + # worker_work = lambda: worker.work(max_episode_length, gamma, sess, coord, saver) + # t = threading.Thread(target=(worker_work)) + # t.start() + # time.sleep(0.5) + # worker_threads.append(t) + # coord.join(worker_threads) + except Exception as e: + common.echosentence_color('error in test_rl.py-> main() : {}'.format(str(e))) + env.__del__() + raise + except KeyboardInterrupt as k: + common.echosentence_color('error in test_rl.py-> main() : {}'.format(str(k))) + env.__del__() + raise + +