From 6367d4a84c67fdec3f9c8822ca0c079fd7754e8e Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 15 Jan 2024 15:36:47 -0500 Subject: [PATCH 01/15] conspec updates --- .../a2c_ppo_acktr/algo/ppoConSpec.py | 20 +- Multikeytodoor/a2c_ppo_acktr/envs.py | 29 +- .../a2c_ppo_acktr/storageConSpec.py | 28 +- Multikeytodoor/main.py | 363 +++++++++++------- Multikeytodoor/moduleConSpec.py | 1 + Multikeytodoor/requirements.txt | 240 ++++++------ 6 files changed, 388 insertions(+), 293 deletions(-) diff --git a/Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py b/Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py index 9738581..0dfbf18 100644 --- a/Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py +++ b/Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py @@ -83,7 +83,10 @@ def fictitiousReward(self,rollouts,keysUsed,device,iteration): rollouts.contrastvalueReward(sendContrastvalue) - def update(self, rollouts, head, keysUsed,goodones,iterate): + def update(self, rollouts, head, keysUsed, goodones,iterate): + """ + Learning RL update and ConsPec + """ advantages = rollouts.returns[:-1] - rollouts.value_preds[:-1] advantages = (advantages - advantages.mean()) / ( advantages.std() + 1e-5) @@ -95,7 +98,7 @@ def update(self, rollouts, head, keysUsed,goodones,iterate): wwtotalneg = [] attentionCL = [] costCL = 0 - #################ConSpec module is learned + ################# ConSpec module is learned if rollouts.stepS > rollouts.success -1: ######################## @@ -121,7 +124,7 @@ def update(self, rollouts, head, keysUsed,goodones,iterate): actions_batch) hidden = hidden.view(*obs_batchorig.size()[:2], -1) costCL0, attentionCL0, ww = self.moduleCL(hidden, reward_batch, iii, obs_batchorig, iterate, self.args.seed,0) - cossimtotalmaxxx, _ = (torch.max(attentionCL0, dim=0)) + cossimtotalmaxxx, _ = (torch.max(attentionCL0, dim=0)) ## not necessary attentionCL.append(attentionCL0[:,:,iii].squeeze().transpose(1,0)) costCL += costCL0 wwtotalpos.append(ww[0][iii].detach().cpu()) @@ -130,13 +133,13 @@ def update(self, rollouts, head, keysUsed,goodones,iterate): for indall in range(head): if (wwtotalpos[indall] - wwtotalneg[indall] > 0.6) and wwtotalpos[indall] > 0.6: - goodones[indall] += 1 + goodones[indall] += 1 #indall (i) else: - goodones[indall] = 0 + goodones[indall] = 0 for iii in range(head): - if goodones[iii] > 25 and keysUsed[iii] < 0.1: - keysUsed[iii] = 1. - rollouts.storeheadsSF(iii) + if goodones[iii] > 25 and keysUsed[iii] < 0.1: ## goodones[prototype] > 25 if the the agent has satsified the criterion of 0.6 more than 25 consequitive times then promote it to be frozen in the success RB + keysUsed[iii] = 1. # specifies that which prototype has satisfied the criterion + rollouts.storeheadsSF(iii) # take a snapshot of trajectories that lead critical prototypes(iii) of sucesses and failures if self.args.factorR < 0.01: pass else: @@ -145,6 +148,7 @@ def update(self, rollouts, head, keysUsed,goodones,iterate): self.optimizerCL.step() print('trained!') + ## RL algorithm is learned (default ppo code) for e in range(self.ppo_epoch): if self.actor_critic.is_recurrent: data_generator = rollouts.recurrent_generator( diff --git a/Multikeytodoor/a2c_ppo_acktr/envs.py b/Multikeytodoor/a2c_ppo_acktr/envs.py index 2d9f316..32e6ce6 100644 --- a/Multikeytodoor/a2c_ppo_acktr/envs.py +++ b/Multikeytodoor/a2c_ppo_acktr/envs.py @@ -15,21 +15,20 @@ VecEnvWrapper) from stable_baselines3.common.vec_env.vec_normalize import \ VecNormalize as VecNormalize_ - -try: - import dmc2gym -except ImportError: - pass - -try: - import roboschool -except ImportError: - pass - -try: - import pybullet_envs -except ImportError: - pass +# try: +# import dmc2gym +# except ImportError: +# pass + +# try: +# import roboschool +# except ImportError: +# pass + +# try: +# import pybullet_envs +# except ImportError: +# pass def make_env(env_id, seed, rank, log_dir, allow_early_resets): diff --git a/Multikeytodoor/a2c_ppo_acktr/storageConSpec.py b/Multikeytodoor/a2c_ppo_acktr/storageConSpec.py index 4bd7e11..13ae426 100644 --- a/Multikeytodoor/a2c_ppo_acktr/storageConSpec.py +++ b/Multikeytodoor/a2c_ppo_acktr/storageConSpec.py @@ -1,6 +1,6 @@ import torch from torch.utils.data.sampler import BatchSampler, SubsetRandomSampler - +import numpy as np def _flatten_helper(T, N, _tensor): return _tensor.view(T * N, *_tensor.size()[2:]) @@ -8,7 +8,7 @@ def _flatten_helper(T, N, _tensor): class RolloutStorage(object): def __init__(self, num_steps, num_processes, obs_shape, action_space, - recurrent_hidden_state_size, head): + recurrent_hidden_state_size, num_prototype): self.obs = torch.zeros(num_steps + 1, num_processes, *obs_shape) self.num_processes = num_processes @@ -35,9 +35,9 @@ def __init__(self, num_steps, num_processes, obs_shape, action_space, self.step = 0 self.recurrent_hidden_state_size = recurrent_hidden_state_size - self.heads = head - self.success = 16 - self.successTake = 16 + self.heads = num_prototype + self.success = 16 # size of both success anf failure buffers + self.successTake = 16 # how many trajectories you take from the success and failure buffers self.hidden_state_size = 256 self.obs_batchheadsS = [None] * self.heads @@ -48,7 +48,6 @@ def __init__(self, num_steps, num_processes, obs_shape, action_space, self.stepheadsS = 0 self.obs_batchheadsF = [None] * self.heads - self.r_batchheadsF = [None] * self.heads self.recurrent_hidden_statesbatchheadsF = [None] * self.heads self.act_batchheadsF = [None] * self.heads @@ -129,14 +128,14 @@ def storeheadsSF(self, head): def addPosNeg(self, ForS, device, args): totalreward = self.rewards[-10:].sum(0) - if ForS == 1: + if ForS == 1: ## for success, record trajectories of successful trajectories rewardssortgood = torch.nonzero(totalreward > 0.5).reshape(-1, ) indicesrewardbatch = rewardssortgood[0::2] obsxx = self.obs[:, indicesrewardbatch].to(device) numberaddedxx = obsxx.shape[1] if numberaddedxx >1: indicesrewardbatch = rewardssortgood[0:4:2] - else: + else: rewardssortbad = torch.nonzero(totalreward < 0.5).reshape(-1, ) indicesrewardbatch = rewardssortbad[0::2] obs = self.obs[:, indicesrewardbatch].to(device) @@ -487,3 +486,16 @@ def recurrent_generator(self, advantages, num_mini_batch): yield obs_batch, recurrent_hidden_states_batch, actions_batch, \ value_preds_batch, return_batch, masks_batch, old_action_log_probs_batch, adv_targ + + def save(self, filename): + data={'success_traj_protos': self.obs_batchheadsS, + 'fail_traj_protos':self.obs_batchheadsF, + 'success_traj':self.obs_batchS, + 'replay':self.obs, + 'success_traj_rewards':self.r_batchS, + 'length':self.step, + 'success_proto_length':self.stepheadsF, + 'success_length': self.stepS, + 'fail_length': self.stepF, + } + np.savez_compressed(filename, **data) \ No newline at end of file diff --git a/Multikeytodoor/main.py b/Multikeytodoor/main.py index 290a075..0067ebc 100644 --- a/Multikeytodoor/main.py +++ b/Multikeytodoor/main.py @@ -1,48 +1,37 @@ -import copy -import glob import os import time -from collections import deque - import torch - import torch.nn as nn import torch.nn.functional as F import torch.optim as optim - +import time +import numpy as np +import tensorflow.compat.v1 as tf +from six.moves import range +from six.moves import zip +from collections import deque from a2c_ppo_acktr import algo, utils from a2c_ppo_acktr.algo import gail from a2c_ppo_acktr.argumentstvt import get_args from a2c_ppo_acktr.modelRL import Policy from a2c_ppo_acktr.modelConSpec import PolicyCL - from a2c_ppo_acktr.storageConSpec import RolloutStorage from evaluation import evaluate from moduleConSpec import moduleCL -import traceback - -from tensorflow.contrib import framework as contrib_framework - -from time import process_time - -import time - -import numpy as np -from six.moves import range -from six.moves import zip -import tensorflow.compat.v1 as tf - from tvt import batch_env -from tvt import nest_utils from tvt.pycolab import env as pycolab_env -import sys -import numpy +import wandb +from tqdm import trange +import pickle -def main(): - args = get_args() +def main(args): + print(args.wandb_group, args.wandb_project, args.exp_name) + wandb.init(project=args.wandb_project, name=args.exp_name, tags=['multikeydoor']) + wandb.config.update(args) + #wandb.run.summary.update(slurm_infos()) - keysUsed = np.zeros((args.head,)) - goodones = np.zeros((args.head,)) + prototypes = np.zeros((args.num_prototype,)) + protos_thresh = np.zeros((args.num_prototype,)) torch.manual_seed(args.seed) torch.cuda.manual_seed_all(args.seed) @@ -69,7 +58,6 @@ def main(): args.pycolab_game = 'key_to_doormany4' - env_builder = pycolab_env.PycolabEnvironment env_kwargs = { 'game': args.pycolab_game, @@ -78,8 +66,8 @@ def main(): args.pycolab_apple_reward_max], 'fix_apple_reward_in_episode': args.pycolab_fix_apple_reward_in_episode, 'final_reward': args.pycolab_final_reward, - 'crop': args.pycolab_crop - } + 'crop': args.pycolab_crop} + env = batch_env.BatchEnv(args.num_processes, env_builder, **env_kwargs) ep_length = env.episode_length args.num_steps = ep_length @@ -100,9 +88,11 @@ def main(): base_kwargs={'recurrent': args.recurrent_policy}) # envs.observation_space.shape, actor_criticCL.to(device) - moduleuse = moduleCL(input_size=512, hidden_size=1010, head=args.head, device=device, args=args) + moduleuse = moduleCL(input_size=512, hidden_size=1010, head=args.num_prototype, device=device, args=args) moduleuse.to(device) - keysUsedt = torch.FloatTensor(keysUsed).to(device=device) + + prototypes_gpu = torch.FloatTensor(prototypes).to(device=device) + if args.algo == 'a2c': agent = algo.A2C_ACKTR( actor_critic, @@ -113,7 +103,6 @@ def main(): alpha=args.alpha, max_grad_norm=args.max_grad_norm) - elif args.algo == 'ppoConSpec': agent = algo.PPOConSpec( actor_critic, actor_criticCL, @@ -132,126 +121,218 @@ def main(): rollouts = RolloutStorage(args.num_steps, args.num_processes, obsspace, env.num_actions, - actor_critic.recurrent_hidden_state_size, args.head) # envs.observation_space.shape + actor_critic.recurrent_hidden_state_size, args.num_prototype) # envs.observation_space.shape rollouts.to(device) - - obs, _ = envs.reset() obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) rollouts.obs[0].copy_(obs) rollouts.to(device) - - episode_rewards = deque(maxlen=10) start = time.time() num_updates = int( args.num_env_steps) // args.num_steps // args.num_processes - - for j in range(10000): - - obs, _ = envs.reset() - obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) - rollouts.obs[0].copy_(obs) - donetotal = np.zeros((args.num_processes,)) # .to(device) - if args.use_linear_lr_decay: - # decrease learning rate linearly - utils.update_linear_schedule( - agent.optimizer, j, num_updates, - agent.optimizer.lr if args.algo == "acktr" else args.lr) - - for step in range(args.num_steps): - # print(step) - # Sample actions - with torch.no_grad(): - value, action, action_log_prob, recurrent_hidden_states = actor_critic.act( - rollouts.obs[step], rollouts.recurrent_hidden_states[step], - rollouts.masks[step]) - - obs, reward = envs.step(action) - obs = torch.from_numpy(obs).permute((0, 3, 1, 2)).to(device) - reward = torch.from_numpy(reward).reshape(-1, 1) - done = donetotal - masks = torch.FloatTensor( - [[0.0] if done_ else [1.0] for done_ in done]) - bad_masks = masks #torch.FloatTensor([[1.0]]) - rollouts.insert(obs, recurrent_hidden_states, action, - action_log_prob, value, reward, masks, bad_masks) - try: - with torch.no_grad(): - next_value = actor_critic.get_value( - rollouts.obs[-1], rollouts.recurrent_hidden_states[-1], - rollouts.masks[-1]).detach() - - - ############################### - with torch.no_grad(): - # now compute new rewards - rewardstotal = rollouts.retrieveR() - episode_rewards.append(rewardstotal.sum(0).mean().cpu().detach().numpy()) - - rollouts.addPosNeg(1, device, args) - rollouts.addPosNeg(0, device, args) - - agent.fictitiousReward(rollouts, keysUsedt, device, j) - - ############################### - - rollouts.compute_returns(next_value, args.use_gae, args.gamma, - args.gae_lambda, args.use_proper_time_limits) - - value_loss, action_loss, dist_entropy, keysUsed, goodones = agent.update(rollouts, args.head, keysUsed, - goodones, j) - keysUsedt = torch.FloatTensor(keysUsed).to(device=device) #for the next fictitius reward - - rollouts.after_update() - - if (j % args.save_interval == 0 - or j == num_updates - 1) and args.save_dir != "": - save_path = os.path.join(args.save_dir, args.algo) - try: - os.makedirs(save_path) - except OSError: - pass - - torch.save([ - actor_critic, - getattr(utils.get_vec_normalize(envs), 'obs_rms', None) - ], os.path.join(save_path, args.env_name + ".pt")) - if j % args.log_interval == 0 and len(episode_rewards) > 1: - total_num_steps = (j + 1) * args.num_processes * args.num_steps - end = time.time() - print( - "Updates {}, num timesteps {}, FPS {} \n Last {} training episodes: mean/median reward {:.1f}/{:.1f}, min/max reward {:.1f}/{:.1f}\n" - .format(j, total_num_steps, - int(total_num_steps / (end - start)), - len(episode_rewards), rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy() , - np.median(episode_rewards), np.min(episode_rewards), - np.max(episode_rewards), dist_entropy, value_loss, - action_loss)) - LOGFILE = './Results' + str(args.algo) + 'lr' + str(args.lr) + 'lrCL' + str(args.lrCL) + 'exp'+ str(args.expansion) + 'factor' + str(args.factorR)+ 'factorC' + str(args.factorC)+ 'finalR' + str(args.pycolab_final_reward) + 'entropy' + str(args.entropy_coef) + 'seed' + str(args.seed)+ '.txt' - print(LOGFILE) - try: - printlog1 = f' final costs {total_num_steps} {rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy()} {episode_rewards[-1]} {episode_rewards[-1]} {np.mean(episode_rewards)} {np.median(episode_rewards)} {dist_entropy} {value_loss} {action_loss} \n' - with open(LOGFILE, 'a') as f: - f.write(printlog1) - - except: - pass - - if (args.eval_interval is not None and len(episode_rewards) > 1 - and j % args.eval_interval == 0): # a - obs_rms = utils.get_vec_normalize(envs).obs_rms - evaluate(actor_critic, obs_rms, args.env_name, args.seed, - args.num_processes, eval_log_dir, device) - - - except: - - pass + # training RL + # for j in range(args.num_iterations) as pbar: + with trange(args.num_iterations) as pbar: + for iteration in pbar: + obs, _ = envs.reset() + obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) + rollouts.obs[0].copy_(obs) + donetotal = np.zeros((args.num_processes,)) # .to(device) + if args.use_linear_lr_decay: + # decrease learning rate linearly + utils.update_linear_schedule( + agent.optimizer, iteration, num_updates, + agent.optimizer.lr if args.algo == "acktr" else args.lr) + + for step in range(args.num_steps): + # print(step) + # Sample actions + with torch.no_grad(): + value, action, action_log_prob, recurrent_hidden_states = actor_critic.act( + rollouts.obs[step], rollouts.recurrent_hidden_states[step], + rollouts.masks[step]) + + obs, reward = envs.step(action) + obs = torch.from_numpy(obs).permute((0, 3, 1, 2)).to(device) + reward = torch.from_numpy(reward).reshape(-1, 1) + done = donetotal + masks = torch.FloatTensor( + [[0.0] if done_ else [1.0] for done_ in done]) + bad_masks = masks #torch.FloatTensor([[1.0]]) + rollouts.insert(obs, recurrent_hidden_states, action, + action_log_prob, value, reward, masks, bad_masks) + try: + with torch.no_grad(): + next_value = actor_critic.get_value( + rollouts.obs[-1], rollouts.recurrent_hidden_states[-1], + rollouts.masks[-1]).detach() + + ############################### CONSPEC + with torch.no_grad(): + # now compute new rewards + rewardstotal = rollouts.retrieveR() + episode_rewards.append(rewardstotal.sum(0).mean().cpu().detach().numpy()) + + rollouts.addPosNeg(1, device, args) # add a new traj to positive memory buffer ## dongyan: change these for procgen + rollouts.addPosNeg(0, device, args) # add a new traj to negatove memory buffer ## dongyan: change these for procgen + + agent.fictitiousReward(rollouts, prototypes_gpu, device, iteration) # calculate the intrinsic reward + + ############################### + # part of ppo, after you add the fictitious reward (reward for acieving a prototype) + rollouts.compute_returns(next_value, args.use_gae, args.gamma, args.gae_lambda, args.use_proper_time_limits) + # compute the return based on those real and intrinsic rewards + # usual ppo update + value_loss, action_loss, dist_entropy, prototypes, protos_thresh = agent.update(rollouts, args.num_prototype, prototypes, protos_thresh, iteration) + + #keys used to be the prorotypes + prototypes_gpu = torch.FloatTensor(prototypes).to(device=device) #list of prototypes that have satisfied the prototype (being frozen) + + rollouts.after_update() + + # logging information + if (iteration % args.save_interval == 0 or iteration == num_updates - 1) and args.save_dir != "": + save_path = os.path.join(args.save_dir, args.algo) + + pbar.set_postfix(value_loss=f"{value_loss:.2f}", action_loss=f"{action_loss:.2f}", dist_entropy=f"{dist_entropy:.2f}", prototypes=f"{prototypes:.2f}", protos_thresh=f"{protos_thresh:.2f}") + + try: + os.makedirs(save_path) + except OSError: + pass + torch.save([actor_critic, getattr(utils.get_vec_normalize(envs), 'obs_rms', None)], os.path.join(save_path, args.env_name + ".pt")) + + if iteration % args.log_interval == 0 and len(episode_rewards) > 1: + total_num_steps = (iteration + 1) * args.num_processes * args.num_steps + end = time.time() + print( + "Updates {}, num timesteps {}, FPS {} \n Last {} training episodes: mean/median reward {:.1f}/{:.1f}, min/max reward {:.1f}/{:.1f}\n" + .format(iteration, total_num_steps, + int(total_num_steps / (end - start)), + len(episode_rewards), rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy(), + np.median(episode_rewards), np.min(episode_rewards), + np.max(episode_rewards), dist_entropy, value_loss, + action_loss)) + wandb.log({"number_episodes": iteration, + "total_num_steps": total_num_steps, + "FPS": int(total_num_steps / (end - start)), + "mean_reward": rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy(), + "median_reward": np.median(episode_rewards), + "min_reward": np.min(episode_rewards), + "max_reward": np.max(episode_rewards), + "dist_entropy": dist_entropy, + "value_loss": value_loss, + "action_loss": action_loss, + "prototypes": prototypes, + "protos_thresh": protos_thresh}, step=iteration) + + LOGFILE = './Results' + str(args.algo) + 'lr' + str(args.lr) + 'lrCL' + str(args.lrCL) + 'exp'+ str(args.expansion) + 'factor' + str(args.factorR)+ 'factorC' + str(args.factorC)+ 'finalR' + str(args.pycolab_final_reward) + 'entropy' + str(args.entropy_coef) + 'seed' + str(args.seed)+ '.txt' + print(LOGFILE) + try: + printlog1 = f'final costs {total_num_steps} {rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy()} {episode_rewards[-1]} {episode_rewards[-1]} {np.mean(episode_rewards)} {np.median(episode_rewards)} {dist_entropy} {value_loss} {action_loss} \n' + with open(LOGFILE, 'a') as f: + f.write(printlog1) + except: + pass + if (args.eval_interval is not None and len(episode_rewards) > 1 and iteration % args.eval_interval == 0): # a + obs_rms = utils.get_vec_normalize(envs).obs_rms + evaluate(actor_critic, obs_rms, args.env_name, args.seed, + args.num_processes, eval_log_dir, device) + except: + pass + + # with open(os.path.join(wandb.run.dir, 'agent.pkl'), 'wb') as f: + # pickle.dump(agent, f) + wandb.save('agent.pkl', policy='now') + + # with open(os.path.join(wandb.run.dir, 'actor_critic.pkl'), params=actor_critic.params) as f: + # pickle.dump(agent, f) + wandb.save('actor_critic.pth', policy='now') + + # with open(os.path.join(wandb.run.dir, 'actor_criticCL.pkl'), params=params) as f: + # pickle.dump(agent, f) + wandb.save('actor_criticCL.pth', policy='now') + # with open(os.path.join(wandb.run.dir, 'moduleuse.pkl'), params=params) as f: + # pickle.dump(agent, f) + wandb.save('moduleuse.pth', policy='now') + rollouts.save(args.output_folder / 'rollouts.npz') + + wandb.log() + wandb.finish() + + + #wandb.save(agent) if __name__ == "__main__": - main() + import argparse + from pathlib import Path + parser = argparse.ArgumentParser(description='multi-key-door-conspec') + parser.add_argument('--num_prototype', type=int, default=8, help='number of prototypes(default: 8)') + parser.add_argument('--choiceCLparams', type=int, default=0, help='CL params (default: 0)') + parser.add_argument('--expansion', type=int, default=24, help='gail batch size (default: 24)') + + parser.add_argument('--pycolab_game', default='key_to_doormany4', help='name of the environment (default: key_to_doormany4)') + parser.add_argument('--pycolab_apple_reward_min', type=float, default=1., help='pycolab apple reward min (default: 1.)') + parser.add_argument('--pycolab_apple_reward_max', type=float, default=2., help='pycolab apple reward max (default: 2.)') + parser.add_argument('--pycolab_final_reward', type=float, default=50., help='RMSprop optimizer epsilon (default: 1e-5)') + parser.add_argument('--pycolab_num_apples', type=int, default=10, help='gail batch size (default: 128)') + parser.add_argument('--pycolab_fix_apple_reward_in_episode', action='store_false', default=True, help='use generalized advantage estimation') + parser.add_argument('--pycolab_crop', action='store_true', default=False, help='use generalized advantage estimation') + + parser.add_argument('--skip', type=int, default=4, help='gail batch size (default: 128)') + parser.add_argument('--lrCL', type=float, default=7e-4, help='Conspec learning rate (default: 7e-4)') + parser.add_argument('--algo', default='ppoCL', help='algorithm to use: a2c | ppo | acktr') + parser.add_argument('--gail', action='store_true', default=False, help='do imitation learning with gail') + parser.add_argument('--gail-experts-dir', default='./gail_experts', help='directory that contains expert demonstrations for gail') + parser.add_argument('--gail-batch-size', type=int, default=128, help='gail batch size (default: 128)') + parser.add_argument('--gail-epoch', type=int, default=5, help='gail epochs (default: 5)') + parser.add_argument('--lr', type=float, default=7e-4, help='learning rate (default: 7e-4)') + parser.add_argument('--eps', type=float, default=1e-5, help='RMSprop optimizer epsilon (default: 1e-5)') + parser.add_argument('--alpha', type=float, default=0.99, help='RMSprop optimizer apha (default: 0.99)') + parser.add_argument('--factorR', type=float, default=0.2, help='discount factor for rewards (default: 0.99)') + parser.add_argument('--factorC', type=float, default=5000., help='discount factor for rewards (default: 0.99)') + parser.add_argument('--gamma', type=float, default=0.99, help='discount factor for rewards (default: 0.99)') + parser.add_argument('--use-gae', action='store_true', default=False, help='use generalized advantage estimation') + parser.add_argument('--gae-lambda', type=float, default=0.95, help='gae lambda parameter (default: 0.95)') + parser.add_argument('--entropy-coef', type=float, default=0.01, help='entropy term coefficient (default: 0.01)') + parser.add_argument('--value-loss-coef', type=float, default=0.5, help='value loss coefficient (default: 0.5)') + parser.add_argument('--max-grad-norm', type=float, default=0.5, help='max norm of gradients (default: 0.5)') + + parser.add_argument('--seed', type=int, default=1, help='random seed (default: 1)') + parser.add_argument('--cuda-deterministic', action='store_true', default=False, help="sets flags for determinism when using CUDA (potentially slow!)") + parser.add_argument('--num_iterations', type=int, default=10000, help='Number of iterations (default: %(default)s)') + parser.add_argument('--num-processes', type=int, default=16, help='how many training CPU processes to use (default: 16)') + parser.add_argument('--num-steps', type=int, default=5, help='number of forward steps in A2C (default: 5)') + parser.add_argument('--ppo-epoch', type=int, default=4, help='number of ppo epochs (default: 4)') + parser.add_argument('--num-mini-batch', type=int, default=32, help='number of batches for ppo (default: 32)') + parser.add_argument('--clip-param', type=float, default=0.2, help='ppo clip parameter (default: 0.2)') + parser.add_argument('--log-interval', type=int, default=10, help='log interval, one log per n updates (default: 10)') + parser.add_argument('--save-interval', type=int, default=100, help='save interval, one save per n updates (default: 100)') + parser.add_argument('--eval-interval', type=int, default=None, help='eval interval, one eval per n updates (default: None)') + parser.add_argument('--num-env-steps', type=int, default=10e8, help='number of environment steps to train (default: 10e6)') + parser.add_argument('--env_name', default='PongNoFrameskip-v4', help='environment to train on (default: PongNoFrameskip-v4)') + parser.add_argument('--log-dir', default='/tmp/gym/', help='directory to save agent logs (default: /tmp/gym)') + parser.add_argument('--save-dir', default='trained_models', help='directory to save agent logs (default: ./trained_models/)') + parser.add_argument('--no-cuda',action='store_true', default=False, help='disables CUDA training') + parser.add_argument('--use-proper-time-limits', action='store_true', default=False, help='compute returns taking into account time limits') + parser.add_argument('--recurrent-policy', action='store_false', default=True, help='use a recurrent policy') + parser.add_argument('--use-linear-lr-decay', action='store_true', default=False, help='use a linear schedule on the learning rate') + parser.add_argument('--output_folder', type=Path, default='output', help='Output folder (default: %(default)s)') + parser.add_argument("--wandb_project",type=str,default='gfn-conspec',help="Wandb project name") + parser.add_argument("--wandb_group",type=str,default='blake-richards',help="Wandb group name") + parser.add_argument("--wandb_dir",type=str,default=f'{os.environ["SCRATCH"]}/exploringConsPec',help="Wandb logdir") + parser.add_argument("--exp_name",type=str,default='exp-conspec',help="experiment name") + parser.add_argument("--exp_group",type=str,default='exp-conspec',help="conspec") + parser.add_argument("--exp_job_type",type=str,default='exp-conspec',help='conspec training') + + + args = parser.parse_args() + args.cuda = not args.no_cuda and torch.cuda.is_available() + + main(args) + diff --git a/Multikeytodoor/moduleConSpec.py b/Multikeytodoor/moduleConSpec.py index 0d33198..0a7fcaa 100644 --- a/Multikeytodoor/moduleConSpec.py +++ b/Multikeytodoor/moduleConSpec.py @@ -45,6 +45,7 @@ def forward(self, hidden, reward, keyused, obs, time, seed, doimage): # obs = miniSuccesssize = int(hidden.shape[1] / 2) for iii in range(self.head): + out1[iii] = self.layers[iii](self.main[iii](hidden)) # hidden = length, minibatch, latent #keyhead s1, s2, s3 = out1[iii].shape currentweights = self.layers2[iii].reshape(1, 1, -1).repeat(s1, 1, 1) diff --git a/Multikeytodoor/requirements.txt b/Multikeytodoor/requirements.txt index 3fd7b3f..9dfe590 100644 --- a/Multikeytodoor/requirements.txt +++ b/Multikeytodoor/requirements.txt @@ -1,121 +1,119 @@ -Package Version ----------------------- ----------- -absl-py 1.0.0 -argon2-cffi 21.3.0 -argon2-cffi-bindings 21.2.0 -astor 0.8.1 -attrs 21.4.0 -backcall 0.2.0 -beautifulsoup4 4.11.1 -bleach 5.0.0 -cached-property 1.5.2 -certifi 2021.10.8 -cffi 1.15.0 -charset-normalizer 2.0.12 -cloudpickle 2.0.0 -contextlib2 21.6.0 -cycler 0.11.0 -debugpy 1.6.0 -decorator 4.4.2 -defusedxml 0.7.1 -dm-sonnet 1.34 -dm-tree 0.1.7 -entrypoints 0.4 -fastjsonschema 2.15.3 -fonttools 4.33.3 -future 0.18.2 -gast 0.5.3 -google-pasta 0.2.0 -grpcio 1.46.0 -gym 0.16.0 -gym-notices 0.0.6 -h5py 3.6.0 -idna 3.3 -imageio 2.19.0 -imageio-ffmpeg 0.4.7 -importlib-metadata 4.11.3 -importlib-resources 5.7.1 -ipykernel 6.13.0 -ipython 7.33.0 -ipython-genutils 0.2.0 -ipywidgets 7.7.0 -jedi 0.18.1 -Jinja2 3.1.2 -jsonschema 4.5.1 -jupyter 1.0.0 -jupyter-client 7.3.0 -jupyter-console 6.4.3 -jupyter-core 4.10.0 -jupyterlab-pygments 0.2.2 -jupyterlab-widgets 1.1.0 -Keras-Applications 1.0.8 -Keras-Preprocessing 1.1.2 -kiwisolver 1.4.2 -Markdown 3.3.7 -MarkupSafe 2.1.1 -matplotlib 3.5.2 -matplotlib-inline 0.1.3 -mistune 0.8.4 -moviepy 1.0.3 -nbclient 0.6.2 -nbconvert 6.5.0 -nbformat 5.4.0 -nest-asyncio 1.5.5 -notebook 6.4.11 -numpy 1.21.5 -opt-einsum 3.3.0 -packaging 21.3 -pandas 1.1.5 -pandocfilters 1.5.0 -parso 0.8.3 -pexpect 4.8.0 -pickleshare 0.7.5 -Pillow 9.1.0 -pip 21.2.2 -proglog 0.1.10 -prometheus-client 0.14.1 -prompt-toolkit 3.0.29 -protobuf 3.20.1 -psutil 5.9.0 -ptyprocess 0.7.0 -pybullet 3.2.2 -pycolab 1.2 -pycparser 2.21 -pyglet 1.5.0 -Pygments 2.12.0 -pyparsing 3.0.8 -pyrsistent 0.18.1 -python-dateutil 2.8.2 -pytz 2022.1 -pyzmq 22.3.0 -qtconsole 5.3.0 -QtPy 2.1.0 -requests 2.27.1 -scipy 1.7.3 -semantic-version 2.9.0 -Send2Trash 1.8.0 -setuptools 61.2.0 -six 1.16.0 -soupsieve 2.3.2.post1 -stable-baselines3 0.9.0 -tensorboard 1.15.0 -tensorflow 1.15.0 -tensorflow-estimator 1.15.1 -tensorflow-probability 0.7.0 -termcolor 1.1.0 -terminado 0.13.3 -tinycss2 1.1.1 -torch 1.11.0 -tornado 6.1 -tqdm 4.64.0 -traitlets 5.1.1 -trfl 1.2.0 -typing_extensions 4.2.0 -urllib3 1.26.9 -wcwidth 0.2.5 -webencodings 0.5.1 -Werkzeug 2.1.2 -wheel 0.37.1 -widgetsnbextension 3.6.0 -wrapt 1.14.1 -zipp 3.8.0 +absl-py==1.0.0 +argon2-cffi==21.3.0 +argon2-cffi-bindings==21.2.0 +astor==0.8.1 +attrs==21.4.0 +backcall==0.2.0 +beautifulsoup4==4.11.1 +bleach==5.0.0 +cached-property==1.5.2 +certifi==2021.10.8 +cffi==1.15.0 +charset-normalizer==2.0.12 +cloudpickle<=2.0.0 +contextlib2==21.6.0 +cycler==0.11.0 +debugpy==1.6.0 +decorator==4.4.2 +defusedxml==0.7.1 +dm-sonnet==1.34 +dm-tree==0.1.7 +entrypoints==0.4 +fastjsonschema==2.15.3 +fonttools==4.33.3 +future==0.18.2 +gast==0.2.2 +google-pasta==0.2.0 +grpcio==1.46.0 +gym>=0.16.0 +gym-notices==0.0.6 +h5py==3.6.0 +idna==3.3 +imageio==2.19.0 +imageio-ffmpeg==0.4.7 +importlib-metadata==4.11.3 +importlib-resources==5.7.1 +ipykernel==6.13.0 +ipython==7.33.0 +ipython-genutils==0.2.0 +ipywidgets==7.7.0 +jedi==0.18.1 +Jinja2==3.1.2 +jsonschema==4.5.1 +jupyter==1.0.0 +jupyter-client==7.3.0 +jupyter-console==6.4.3 +jupyter-core==4.10.0 +jupyterlab-pygments==0.2.2 +jupyterlab-widgets==1.1.0 +Keras-Applications==1.0.8 +Keras-Preprocessing==1.1.2 +kiwisolver==1.4.2 +Markdown==3.3.7 +MarkupSafe==2.1.1 +matplotlib==3.5.2 +matplotlib-inline==0.1.3 +mistune==0.8.4 +moviepy==1.0.3 +nbclient==0.6.2 +nbconvert==6.5.0 +nbformat==5.4.0 +nest-asyncio==1.5.5 +notebook==6.4.11 +numpy==1.21.5 +opt-einsum==3.3.0 +packaging==21.3 +pandas==1.1.5 +pandocfilters==1.5.0 +parso==0.8.3 +pexpect==4.8.0 +pickleshare==0.7.5 +Pillow==9.1.0 +pip==21.2.2 +proglog==0.1.10 +prometheus-client==0.14.1 +prompt-toolkit==3.0.29 +protobuf==3.20.1 +psutil==5.9.0 +ptyprocess==0.7.0 +pybullet==3.2.2 +pycolab==1.2 +pycparser==2.21 +pyglet==1.5.0 +Pygments==2.12.0 +pyparsing==3.0.8 +pyrsistent==0.18.1 +python-dateutil==2.8.2 +pytz==2022.1 +pyzmq==22.3.0 +qtconsole==5.3.0 +QtPy==2.1.0 +requests==2.27.1 +scipy==1.7.3 +semantic-version==2.9.0 +Send2Trash==1.8.0 +setuptools==61.2.0 +six==1.16.0 +soupsieve==2.3.2.post1 +stable-baselines3==0.9.0 +tensorboard==1.15.0 +tensorflow==1.15.0 +tensorflow-estimator==1.15.1 +tensorflow-probability==0.7.0 +termcolor==1.1.0 +terminado==0.13.3 +tinycss2==1.1.1 +torch==1.11.0 +tornado==6.1 +tqdm==4.64.0 +traitlets==5.1.1 +trfl==1.2.0 +typing_extensions==4.2.0 +urllib3==1.26.9 +wcwidth==0.2.5 +webencodings==0.5.1 +Werkzeug==2.1.2 +wheel==0.37.1 +widgetsnbextension==3.6.0 +wrapt==1.14 +zipp==3.8.0 From 52caebbcb15795c2ca1d208a1e0c9ae0183b329f Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 15 Jan 2024 16:17:24 -0500 Subject: [PATCH 02/15] adds .gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e2638f6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.pyc +__pycache__/ +wandb/ + From 43014fbcc1cee0e92de8fe31ead16173ca37c36d Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 15 Jan 2024 16:56:15 -0500 Subject: [PATCH 03/15] Deleting pycache files --- .../tvt/__pycache__/__init__.cpython-37.pyc | Bin 157 -> 0 bytes .../tvt/__pycache__/batch_env.cpython-37.pyc | Bin 3990 -> 0 bytes .../tvt/__pycache__/losses.cpython-37.pyc | Bin 3155 -> 0 bytes .../tvt/__pycache__/memory.cpython-37.pyc | Bin 8302 -> 0 bytes .../tvt/__pycache__/nest_utils.cpython-37.pyc | Bin 3296 -> 0 bytes .../__pycache__/rma_memobsendend.cpython-37.pyc | Bin 15945 -> 0 bytes .../tvt/__pycache__/tvt_rewards.cpython-37.pyc | Bin 6005 -> 0 bytes .../pycolab/__pycache__/common.cpython-37.pyc | Bin 11443 -> 0 bytes .../tvt/pycolab/__pycache__/env.cpython-37.pyc | Bin 3181 -> 0 bytes .../tvt/pycolab/__pycache__/game.cpython-37.pyc | Bin 1307 -> 0 bytes .../__pycache__/key_to_door2.cpython-37.pyc | Bin 7436 -> 0 bytes .../__pycache__/key_to_door3.cpython-37.pyc | Bin 9665 -> 0 bytes .../__pycache__/key_to_door4.cpython-37.pyc | Bin 10705 -> 0 bytes .../key_to_door5_2keyseasy.cpython-37.pyc | Bin 7447 -> 0 bytes .../key_to_door5_3keyseasy.cpython-37.pyc | Bin 9676 -> 0 bytes .../key_to_door5_4keyseasy.cpython-37.pyc | Bin 10715 -> 0 bytes .../__pycache__/key_to_doormany4.cpython-37.pyc | Bin 6082 -> 0 bytes .../pycolab/__pycache__/objects.cpython-37.pyc | Bin 3740 -> 0 bytes 18 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 conspecfunction/tvt/__pycache__/__init__.cpython-37.pyc delete mode 100644 conspecfunction/tvt/__pycache__/batch_env.cpython-37.pyc delete mode 100644 conspecfunction/tvt/__pycache__/losses.cpython-37.pyc delete mode 100644 conspecfunction/tvt/__pycache__/memory.cpython-37.pyc delete mode 100644 conspecfunction/tvt/__pycache__/nest_utils.cpython-37.pyc delete mode 100644 conspecfunction/tvt/__pycache__/rma_memobsendend.cpython-37.pyc delete mode 100644 conspecfunction/tvt/__pycache__/tvt_rewards.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/common.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/env.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/game.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/key_to_door2.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/key_to_door3.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/key_to_door4.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/key_to_door5_2keyseasy.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/key_to_door5_3keyseasy.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/key_to_door5_4keyseasy.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/key_to_doormany4.cpython-37.pyc delete mode 100644 conspecfunction/tvt/pycolab/__pycache__/objects.cpython-37.pyc diff --git a/conspecfunction/tvt/__pycache__/__init__.cpython-37.pyc b/conspecfunction/tvt/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index f8354a449c563384089b4d37934673288d16b441..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmZ?b<>g`kf(1z>sfkPs439w^7y$Aa9Dul(2S}taq%h_%gfOHq1v6+ezhndoX)@ko z)baz83@aImSbzdx;+Ls@Mt*Lper{$?qJFY|az<*NUU6xjesX?ZaY1TwT4`Q#NoIbY leo0x0etdjpUS>&ryk0@&Ee@O9{FKt1R69PPNuPn30RUEICD{M~ diff --git a/conspecfunction/tvt/__pycache__/batch_env.cpython-37.pyc b/conspecfunction/tvt/__pycache__/batch_env.cpython-37.pyc deleted file mode 100644 index c0b5a496b98d094504c8a5bf89ec18b7ab748c94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3990 zcmbVPTaO#J73N$djV`P|-@wVK`0 zj7)O&B53KM3;F?{K79?QWa|9f8y#hdewy{LXhcAFi#n z7@m`Xk@a=P{zHxB<3qTIq7zht^_g&ln>Z7Z!VkiEWVWgoKN_pMw@YLj}uZsmH? zm<0X6$_>cPe$&c9(wemUZHN7aiKb}1V4@{E&%OSdXg^}z&g|XCV@MiH8f2~w%6XqsP^pMmq9}mJk6#W>LWPJzzaD~(Nge$xktnUk7 z)bL*ubVtHD_U|X< z7P%QmhHE3Inosh?#M4BsxCv{w)HS(NDiWhKtpmH zMgJMq+?lhGea=32MsS#LUj)XPJI|eu;TpVg=WG`)e2wjTX!%vEhE~05HP8x7bGL;a zCj2jHW?L}0t@d!}U=?~?lp4wpQ1mraJ8aILt{*#Juo3&h`G@mQ_nH5Q{fjBWeAg}9 z-Uo#fLTCeC;UJF_Ayv_$#@<1scC;P%^)I)_*+gzn;w0K0ZV$&Y?dd$-9%iYY%Ha}M z+h*TvTd;;u(3>88-MW*++6=SF^zJP(iR`Ph+55|5?uB8T#wHAVcW@?AqVGaj&QP=~ z0J1%a4#R^??MbD(ouXB)pyQcTb&M!#w3;s3X+8-f3vgX@!qwJBHqcV-M+E**kE5w9 zHp9z(>v9_FOvo^i>5dr}SHklhid?!4}-)6bo4T=G+O(zNpc( z!y5#XkJ;1f$KKpM0a$k36AwW2PTf<-Vb88TVZsys3pRHNhR5y`mcHjRWSI{>J{uQui}v>L-mkbo|LZ_K$0Ge_k880AXWx^HZs%v2g*4iV-gMpm;Vq z7q7i)3v|2$h)1*q+RL1suv0>`^U(4V=_6jk@md&`m37<(f>ath_$4R)oV1WS=FGa4 z-|Vn6a9x^J8ACHEaIG<~K(LY1IYyw8QDxkeQR5VK=m8gXT}3fohD(;4X>KmqsjlMv zuTYlAzwt85&S3u-TlNp4*mMI$aa`1i>r zI5#3YNEJDA!QI#D2d1yW#pf^T)l;%+bEV- zm=}1i<2xPay0dBF8o2AuZ2kQ9hW0!#hYYIF`gb%IXmyW%4YYcPJws?CQUn^GzO}%X zcS6+Yo%nN?aCYih%a=qR9CFC|v0^pyJTR(2h>+?p5+~_MH z@ewl2Ilz`lg!B6#!P}sBdP;V&p1aNObMhd;dqFx|He(&m1t2tdfTOn+^2p<)laDUDOKd|6{guj^FB(+G*?TexrVg3!Zd5=%&%NV zIfcqcG@WuJ2*hTT*}dPN-2o7FxC8JDp}NK6p6r#_O0xwSROs$?9rY>{;?HvF1)J%z z^%s=#u)W#qm3=GWRo*?m+gPMO^~0C1Md?XaYq_&msPGY*IvHLb-apKR(Z8r z<@~Ma+(HyZ*7ub7N|L7&AfiSbdFOAc-#6d(HC$i@ zeY-OJk{W#$g=e^j^9kzTe9*<_WhIm4Vz_#|@hyuz#O)O~zBHQ1Ff3YOILSnwklYDF zqRhpcMi`207>4RcP;B$AqL3&8e4PNZ=139R6v05zDX9;rI`e{+=$fROsK`Z{d=k`r zH)sZ%!P}i$$M5*|?ZfW6`UPH+IpsGY)}>Qa9#wQiMGN=*VXhReb>$VfspG>QeF$lL t1Gn^0c)0zSH;;NY*p)+L^?#FDMR2Fw`P~hux3>9i2X~2%iyzhA{{YIC*#iIo diff --git a/conspecfunction/tvt/__pycache__/losses.cpython-37.pyc b/conspecfunction/tvt/__pycache__/losses.cpython-37.pyc deleted file mode 100644 index 6ece58a60f75adceb7fa7339d70247d4a0a59c6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3155 zcmaJ@-Hzk76(%KFmSxMcJDL3{ngYtUN!LK&>81&ii$%NGP0)+o?nM(cfZ9~hm>gR( zw&W%0`Eg~S=;U^QUi1NGde_(JBlJ>N1$wowP@vs@hw^x5incaLk%v6zkca2{$fr>h zGW>R)o4rr&F!p!qT>V@$o}lOnD!~#axNxR?<|GcMwu`o#xVG(~?IoUVx2CP6h4I$Z zpS2yv*(^vp80iaNw7=y^C<4*>mL**giY~rA(GwBAk!XF%23yOm7p2zm{-PL}ye#za zHQciSueY*2T}~H9rul4MDg#j<@}pd17TW!}$_tZT>Af5|q=z4UTPV*^^g~n?yI_~> zf(w4hIWx|Ii{e#GIKn-5gi~?hox4~|Yx($DIh(_!j?F~IGno}}c_dZ*G|seM%<^I! z8(HX5#kr2l{a8=3xr~4H)raxZZ-%eQv*M_*JTE)R^}ta+y0uqiGdXD0ov}2j)xqwx zmdd1)Os6U<4r|Bk*IgyWVkA>?T!-rp{0^MjZ~Uq@?ERUkK0g2WV0S#<*SnK)CU=id zKl%96-4Oyfm!n;CWOke715PymIfd zGyZ#Cc@^4^*{gTIX0Li*vx+0m&hi=Jyq6a;o|faW6!B3uT_ETp9~nK2znZA>SjYK3 zor02aMx{87m7L4WVEUmv)x+ic&*f?S;C=mo4r4Qx7ch#1BFi|h;lQgsvRk`4KdC#p zkqTv|>+qN4^b4g*HE1R8G%HD)m85nhNi=GfDQv%vZp^9qVa<>1Ni@|K;#A*RtE4yP zzDIGSGh>d=L%zcU-s88px(~^S0!_aNh0?_)E^x#uNAN>WJu&QnA0SN++=?Bz!Z~+V zEyFInswG_EiPqS?bXI=lRQ?WIwN0yPpYc_@2rQ=pd2Z<6a@BTtkP8+qb>|l=;Nj;`` z(T|WZ&GzI}<6Dk%qhJ5?&6_u`|3wwboAu1U{dC|Zw-gz}$!HBu0S=Pe*Cd(sa6_cz zai&D_9aEZYn%cRWrC2kAz9K@coua7U)A@K-<{}*_av%$%%K2$}oSO+H1C~~|tXI{8 zip5(U*v(~ysk_rmo3vR&-7<^$RMrpmJX2bxy4*Lj?BxF#ZnT@_)@}W2A>~rmJ{rJ| zx=n$KYQNb)-8Pv55di^qIq9g>@ZY#zcN$B!liVxhI5YVX@i1`*_L9z3xtH{c=`@{7 zWvL}u8>8TEj8SJ3P}<)*px`+QtPNouHqoWI3U^Y&ZPyX?U*azHhnT59M#b6zFxBVV zz*Ojj&W;lRSxw6a%0i4$uje?t`3H{Lh2Ds;MnA$WVbJ1kO1Q&Samdv}oAvl2qwVDZ zjQIvA15!BUrvV;?d*&$6;(-U0v4a+H)5F)dz4j`on8k~ueq%bqBTBqxjr@4(FOY;l zZ<{a#q_z$n^+(}D3S>11D&B>>4f&s{4sg_mtpF%9cJ=c4&$B}r>jiEY>+z;eOwiEw{#i;@ z#>W#`#6@Z1a$)dHF!Uav)lU}Xd?&g{taY>6(%^LYTSA^9>!3qbrELADGiYz14 zZM;1)W0ZOXQQfgV=w?kiS6+1OkwAT)barS~8$6WH7Blrj>iPR{nHfuHc;ujCX>G8z zwnky8qbq9-w`^~^rkvt6QjBDMdm}@fQVLETZFXeoX?xRss}*gcV!4BMp@@S^wvCZKqbo_hA_VR_Ixy7r8rXNt0Kncy*wVlkCJ Xp$kNl2hZtY**#F~wj26EHyHjKx$%df diff --git a/conspecfunction/tvt/__pycache__/memory.cpython-37.pyc b/conspecfunction/tvt/__pycache__/memory.cpython-37.pyc deleted file mode 100644 index ef8845ab5d79a80cb25e9da0d6937bbf8908f031..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8302 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 diff --git a/conspecfunction/tvt/__pycache__/nest_utils.cpython-37.pyc b/conspecfunction/tvt/__pycache__/nest_utils.cpython-37.pyc deleted file mode 100644 index 1b3e3ff0b7302b384646c47ed6420663c7447b70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3296 zcmeHJPjB2r6d!xN$!3$?CMm5b6d0jiR%$mDAdo^7(W*t_5()t!S*n~_dv@22J$7bh zlWep(r4r@P1K*%M@|Aq$#F<-9y!X8JHflMc-f-gC@ywg|=l9;c_wIK(Z3fSaftB~y z82b}Hs;2>yZ{Rf+hKTtraw0czQrCAKoHtM*(bWX)fTTG7f==69lYvI1e9C6*0lRR{-4Q!)oPKMWb!KkVxB+Vy&I9)Nv)|aSZ0JND z(6(kS(RxvnPI~3ntntE~IWzCVdFeRp=+-aHHlBDhhFoTiXz95N7A}h)K#_+>llWL9 zQdw>@K2*2)U}8C{X?Ui15*vFb8{R=IOuyac{3kHT3^Sb?E-r5)1Hq9JPvA*&o7=He zT;zEYOT!O_>Ht^(ofP4iXG7fPu~JeKt5U*umdC){m`N%lpb(aeBq7FzkHxX1QwGrF z#_CCECtCLT!$hWF1!!GzCGVwT3i1Y$?`2Bf21)#69E0Rg7~(SJLW2S$m1!BlejgZt zN>d(XTxFJ{oje!X&bb0JV?}t_=Rb`>NBEx@Ih-WG7R;orSdF+CA)fGQ!D!e58OWs8 zjdsW&U`Q4XB%B|{i3Qq-aK5KUW*fFSAroZ7fPApc@9{@dJD&Rn^_u$zNr!5iz^Ni| zj(mi!M5xgzcqEYkV~O^U67W-VQTJ;139ZEx{8ws^XUi1=3}FG+45s8!vY1%+LEq4U zK*k5793y-mUUMCW5k&Um?zv;x3ugwA`MZ1M?Xy2v&n-N(p;#U!!dj_d!R_BI9Hp1x z7!9w!+8Sr6+)Cp_Y=v7Pz}+_!wH0Q{nJZ`hb!8f&2j8Gd&F)o zv2acoTIgED7Yh+R*I%jckKZ8$jXau270O;yqw9(WB!*%MK$0rbEm-l_a|r*Sq6>uS zHH!{nRYz#y4wb)IE!B1#|7tx)TDmO8Zz*{~(3i?Px(iZB-{RU^UGy^h!v z-Pv@y@Oq9$Z`8T9iayG%xPwtgc@uMNYsOw;4s7hzK%>}`P-4%gdGd_a)HbR z;UY!=;N{w&@;>?O-ByT7%Kvo&Qtmse6BxhS{QDe}kVvRX^8;Kwfc!p!x(nqCk~}}C z-9a_!Kh}zx*}qf_yn=OZ#XPXMg4D6N&`{}Xunrdl3rf+XfW*s}%y$+SPk#UukKolG z!fl5_)JzX;(7_=T3Mb;X8V;C=IUF>!6{ShMzI_OQ5FV4(GH-W#uhIKG#afDTa95- zG!?>ChQf-8Px~npa#L2WP3R*`riV#((uXF&>Uf}+@X*HmE2#T%O14xz2qy9mqmn&u89kzBS@$Tk&7oM5OK_ya;gidVoqk^o5{1ym{pDFc@xBm`WZp*J_H4;J$UB}R`P?AqT=JHrtcd)ww<7t{V0C!HTQiMdt-tQA2f2gC{IXy1 ztA1_UKD4}(QnJ8zzwR$?J19FPWetDHU*5Lx{Zc=*d%Ee}9I~YY94|rxRGg;_d566SuC}{VFJ7X20$n|@-dSP!o zLcX@6dZVblwL9uYDA`0&PIX4x0W$Waw}VH1Fb=~YWNsJ?$7&C`;+E_%ad-;viO-;n_m_j)G`2E9>`l&(g>j&7C|RnYOO^SO9jl-nO1`|Kf?Mr$pz;r14+C|p!(}G9-VobN%7acAWewy-1-CoOPpWTiZpwh0 z<14{1X>`YDyxyUd4+^nyh@9`>OmmZsOXJb4Kt*9Q>J5YDu+tx_W)zIVu|m;UN<%=lIp~E^xS_bF zBMZx;Uo9czBj_L zwsGXu(eAL#C2+D(J&D1-_rY`9J6qwo8{=Vc?)KjA`@WB!14P4}pnER56`fPV4k0(j zxs81MZ|v-SuXKUS?2d;!FTTPx5psEB@?kX^0Ud}z?Px5=-|Mz#g&P+J<8EgVzKG1U z|7OcgO2A{Tchn7%T(rA0z$3iT*$I+DCv3B6;xJVNf@(5(3JEr+Hx?#!teD^ph>o0J zcGfc088&_zN%G`u9gkex_oGoLMAI&r4g6IswSlti6o?wcDn7$Mgam}lx`&fUkKed! z>|1v}5}A<|gNUvJ5$>9=8lOM?Wg`aSM9x7@kj6nTH%84}^ALZg@y;`!0mAfwFzgju ze(t^nq{&Y{o+3?iOO1!kK``2mZZxk6iZsVt%@Gb!kcSx-O!4V<5AC*k3Z;H;*u1up z?STiC!}lupu!=-5sW!!=LsR3ChMtu;962d$4LT9VZdvLyx+LaE>UBccs%Mb=0KQX1 z_y}))di3c`;!JvZm%gD%DEBk`+>&Dzl)8*>b6}j3r7Y=kcd&gFJ zWwuJ7PZ2n^+l_WrkW{5x7`(F^01aEN`T$xg!YZ)=c~HWg9bms;AFz{`OPynFeFxe0 zv}3yyw(O*kZqlm~ZQJ9mHb)PW@+i1HrCfT^rus1F5ez;3dqa&>Nh7IMGxO%EdD>JL zP}U`&_#uMwmR!O&{2&t0FbmYliOjy$w__uAVl%dV^S<*rYd^Q2kDNG%`a)cY^IJqa zYjWnzKy8iHu-R$q6*YH9q`HD)H-aXQaie9cvlu?9_C~#^*BPY5KIcb!J3%WaS4RWO z8jX_DY-_S!TzZGYDBe05NWF-hw>WE;UgV^f7NsCfToNPI3qaE6@kyUE>6r#*Ua$F+ zCS(g>l&lH5=$50X&o(a*&@=ee7%W`jR-?>-xoFLcF`#C>< z5BJwA$Xmg8<<0erehK11@r#CIcqIU{k}SPJ9{1X)JN5(hY9Nov<5Jj6OV6dn&EeSJ z9RwT6itxoY5RskQzV6i};o*nRV)_g}jZ6eC6&rW0z6Ii8-UmtXt=MSev=5v^!|hFiW`vWMbv4s< zolDoXfqUkRAV_SstOo@3gC-K>xlZ*7ohLt2mzhW7s~4}l)^d^seWdN~jm~Hk3_`DZ zGf>F1h4zO@0k^Z~zI+o4z9>WzSFgU(){T4mhB-JL)w9$4bGfibUgece)V=Yslr`AOW6cU{ zYEu|#@IQ1jHU5NX8j@5QcFC^WlgA#lYuz;4GxwYAnG?oFA8h!hs~QpZd)NFCFke!+ zzF+>HYe}9vJ0jQ8E4RZTd)1?=Jf!?G-$r9uglvT-ipo%x{`8IuI?xZD}po? z0d!LObZ4*|yr$Gx3B1*3vE8IX@hunxL(CZpc~vj5+)=?`H_=D(Rv`CBJ%EN5kUj@0k`RH@i z9gm15#Ov2NQUytbQ{`#;kW^aM=49hjA=EXYhbh@<4uj~%*bkeO93kP8IpMMa^6fS$ z($eNQdSeJtlAsEF0VD(%B2D6S)V7uoXSXuRx3BN^2L2!866B7($I^8(oE8@g8U(sS z;s?4@YPU57N50Z-zq8vJq&0G+$68n#L4$vY-$ZLVOcBwws+MRj=pABNV^7 zd1*s7!Oh`w=H+fd=L|kc%=i`FJIBuQnw>#p0Xu`Jf-4@ITjmLpwH)4YReej|@^KDj z1&B9bY`%@vIvp41cnPYE2zgk}|NW9nr6xWXfi5pduG!=T)Vgf=LUVI>cs)==J--)r zRS*Tuw2nGm_r@4kP6)-uTyMRK_Kltobqa%Aqr%gKI(Qkf;@KwIN5~=5)n2*$W>dEX ztpVE$=f|3=<-hl6)0WNm98Y#SY6iodXs;<+*f~nCIK*&w07auW0thv&(kq$2dYusm zo-U0*&^rDL%}cnFWVdIV!N&GRGuql1jW(d`-Iz8`;n5xRcG@s=;7Wk-z0lkmj5`3w zn_`G)ZmW*p6GDq-O=&Xi&pY-)^CDzb7(uqr3c1$z@cm(vl>+-Ic{NkcR#X%X)rbji zC2s88(W+-zR0GSWRYc1h&@$UoC{9aOr!9`IJ}C>1Xb`jtn(CD2#!ni2Nk>mHAz5Zw zHp8^EGy`U`@<>>v!iJ^`nFK7m`Y~)n2&&O&Sb30RY7LVG4b+EaiZYs$R9s@WZzGA# z&)NIdz774s=z~+ncI<3Jd+@FM&>qNZ`?zp@Tsyf<}ik3p->qP)O2dq63LCi@r8Q%cLgwA!yqk_C`nFJ9oTFcI=$cnoaTG zf8hgNizlPV8C4ZYYe9H_k_WZzb|NhxP!mXO+(Na(c9gG@@(@?IHyRHiXTaPxiavZE zVl{N!05YmV3$H3Gn_jP^8b;%t_ViV~!;xqdX_d8rM?ur8Lcma&sl{6k?m$|YVzait zeCUy-=e=SI*WPHhC9jv_BdVz_c@(iEJIsP)fAvHzAESbx>JVXqK!iEiV4TKK| z>RsL}S!+ns8nXuBdRng4Ki8V1=FW|jnU~ZJ45@ld`b=&zX)@8`73q~`-du$mGRc;A zge8-pd=1~Qh6F6x;ha=F>&rrHx+u;*lx6t|X*@Z?mTRf0h>X}t8F3DpS`iF69~6M; zWvy}|5Bs>}XKLpHq!JjBFG22{RB26yS+vQwjcbWZgB~^K?o=qC(4Og&cc7`wFqGo!T-Y``~fZ z)uA~w;wAsYH>gXTJb2>J_zCMPT)|1Kc{zHL?Y60Jm|1Q)Ui8;wMNN@(*I~IA%JSe> za3;wAC>{^sK`|asB<+3M2HsJlesCVi$Gqw!GZK()IBJ4oAs${WWg9_TRAw3Vh`i0y zU&8kxGa$^#N6mm*V0A8Ey>=xt0n(PdL|G4pp;Y+Litp^cK7+vvSh_X}nv?UZS z_&cOc%k;!2AQ}>{GCpTshPi4N85J?P#Y9N_9ptd#brw9vgnI)mc9}oLKYqS(N?7E>POhT z);@CHVx9B~uLi*m?l)wP8Q{E7{L=#OJ^6r1!`LR8SN*@ zYPH`)C|FWRNqthDV~g6vms&sQqriG-xl2nTYQSP! zE1KEJdHhM~IR_^}0IvpwpA)h?VZ>S)552XFp|BOvB9*4(oV}?ZNourEt$qyCWH>cN zq|mFRuoG1Biu56nc0xc%D_~&vrWYagOKEIenVrTQAiSC&D1Bxr(qbI#qDs5*T|;}m zTYi$_uSj{I4CFCd2_$0u2EHNrIn7C~4hcP8J`!*O{e~SBJMn^897xM)>8v@l9>zZB&T zO1>F8TeR(zkGxed3Q8bj+E8yHv%>yK$(8bBC9aZhz#eLgMHGAmeXIELxe(WU_Yfn- z;J)-4?=Sep{W{kPUcgn<<04kE$XT(DMb;fOWMwEr&62FI0Up7f6ywEAj$Ix(adCec zZI|PPEqi|jJ(uGZtbR3G*)mXG_eTCc??;x)15SEo{~+QTV`M5<`uNGacUUs6AWw^lwWKqRD1-E(_z^4)3CWcrg=($Oq}(KbqfO6s;%)^Ux`<$(zD|=T74#bcd>3Cu53e$TuPI8M z72eYP8|g8nb3y_Vf5z2F>SQBc6%JN(1;jy8G5+k8aJMECF9*-tZP>l#fi+-mVJ#X$ zvMuh&Yov0u7R5yd_o|t!O^>KoOJ6n74%MsdhfR*yClh8hO(B9@An)b@8>A9qqOO1f zl$?fB!*eZ9Dqtb^L<#f()TIU*QL&aS2lQnsb5}qsNJS_C!z5@;7G~5!>}{ECml7z= z!9pu2gagk(FX*?Te?qLCkQ5koI zIv-3!xGTAXN_w+$F=H;A$pso1Q&*OFyW}D&J<`^yzb-Ra#V9-tCpl%6s zqj<08Wrc?ky_%HRMH6+=E$CQyK1bK<0g0iimwkebZ zBZW1nzrxC&VWKaIaNlFX%JFmNba#2qoWro{az;}FZr-ZsbF(Vd$!d0PDU|d^GLaI4 zP)^my$8+TI0kkGX+CPJLJUl#(ui#Ik?9Xup6mSh|vXsp;lOF!hCOJg^_n71xsQUAB zlPqVG%tzev9$0$Ei8x;AC_dQ~u-9y2gMgv|13$Zyl$2I>||N&*bY@_TWA9o3jul znn>SH1+TZ8B#f{aZoy7T6DVx1pq#M(`ml{ESUzA->~*yzpC)3MImNFiF&k%_s>3UW z0VB8so1eb;+Vg|n%^>x$hy_yH5aEiv^4eRM-`GsUq|oEqgWtgczbkMv-gtTQ-9Nni zGq3;F}twed0{nV=NIPdkdb zq}KfKnQ6s;5ifIE@xr`WTC`n949_`G80x=}XQ2Oth^ZHC?p!Fl8QhxtSQB5`U|%$=6>a#D0MZB@S;{6q93s5fBUD zy~T$hBqxz9&N*9C|8!*@OkU#=P|69ASalpm-if1SGZ1|os{|H&jw==>|1@(v^1n`k zcorF>PTTN%{@E3)WJ7DPDDzKhLI*MxK4ae`-@GouzF$N}V$&cl`|#ErnqNHwB%Wj5 zFxckl$-%QAg1OC@r!@G0e8btC)Xp7YHDIqTj5}qu4d!XUK&(y^kEA5dHgW2!f6U57 zCjX3yaMi!S94RUW5>6yXc}(zO%ikhkTx1MHfnnq3WJz!O$a1<<;~kkDjVZG8H<5vo z19H%Z5nDY0S2IKun4uA>>YFDG)L6a&hxIG5*@ro8-4HW6yjOq)TH!)N)QRZFf+_^} zH9c9mP4XSX_|5Ul+Nzw&8@Bk{)hepg2_%37A=RC6b;+QL?hT)G(Gwr!74I= zQ?qMM-L65%o>WtC>NeRuJc5lB@c|r(5(U5z_#nX%FzWKoNnnJ{G6qUyB@AN)h@mpm zaiay~{HC{*u3c!|(U=8+qPLXp=SYJTMFmcT2oO%->vO-KV)9ug0?|2y6rIT{YvL&b zdX@S4y~_M#NnR7+hXJVL3=o8#27%cXd)aP)n(>c*fE0*nJi_!!)0USJvk6{wJOW4< zvCja&;B*F2J8u#{aitkk*Uuf=sa?Z3pgYpm8rd}Vym+{zw-APH}xwUrjRdy8IC8~J~)Fp*orfLpH z_sU#$YTv^Zpp=zXA0@tsr9#7}cv#fU4IEIzTrR*+RjUgTp)pIFu-w8#hnsJ(OGZ72 z{Mosk$ICG$gkKimylkEpB7xG=nw^U1f`~TB0Nun8$KaPzOnuP>mK5v77VyYRT+{b+ zYD3uM?zl|ymQ&_rStH=lMww^kF|;EHg|++|$bjre{I87d5*i2=OI(9>Nur%V1#Ms? ze6sX305kJ!Uh$wd9vD^Fp+YAnH0sg4gD*akB_p+ba5>Uz1y(uZ;EdSkR^pX-0pTW#Ck)u+mZf~P|MVdP@z2Do{b#b=`wva}t@hWVg@b3~ zwYVNPz`xdEnOpZ4FBp8v?QTpKFCmN`zw8i2h(FTU&_=r{r>EuahyrY*;3~et5)d&>3F$J1_Q#hG=C>PH6;`iRZ%eb+iAcdDXwexW`Db z`c0Hk#g|F7G-G`CC72QaB`T6agorFgV3ua$@*J}aBd?q>%P>m2qn~y8L%5G5g78Vt z>kM8ad(A{)1{bGlg$lMAsueKebgw-^tTTufW@%)vS+9Ai(_6Tj#)n@#f9W!gs#VI2 zY*0RW*uX;OdC+PIe!-yKRtapAq@fHgpee97+C{{`!u9bu!m>I$T5U-R`heQ%S7lS# zXk4E5eA!-MXB)as7$&es>R;vP*Gz$s%97T1m~XXIlVBDD6n{{GINKjafp+YbUZGX< z;?B-sPYH(*<{%>T&$H2MOwO@?b%=Fh9Xe!Q{e4#aD<(VSS?Ku45?A!Ono zu)#k;lDMKmb{KOj-XGy$&$8>9s4zI1-2ozWC-M^^>92m7z5fvt5nM%%{Ur`ogjlBc z17ok+8hB@Barpi%Oaf*@C(&57yKrdX7YPK1jyw=o-9O}@zsRA0VE%45fH$l&@|IIm z=`;>PcYBwOzm3F$Z)bQNQJW~AQ#o6YX<@oDFB7Z(z+S)2UJXVu^M_ARLsMi(*8Sb# zaIa0vARK|hD5nThW-Md+qRw&@VYED$q%`|6i`a2B|KVNos#^ZaZj^rIzA2#r`bQVd z_RuDIBc#ph-0R%l)PLmIMTWVJcM*H)xt;SGn(#EIxwaUe)dRL%%?giz2#tmPb1JUm z7@5G&d{A+fbV6Yi17RHvaQqq!k#5elYA_}@>^hXyMxhQ_fI=MQ0fuKCoSv4ky?%pAYgHgq&`>=cDNlhgl`6Q5OsXIU&fzOu_=k`IwTA>jAv)#4jE)kK zIpe~)V_Y~VT$GaFJQtqlx^7&61gN>Li#P~!?GpT1Gp<_#H!a0w5c)S_mSr?X{b#(Qw1 zw9>C+2JU~0im6#)3;APfkdWSg&dE6ntlSknRT_R&xpqzcP4@a*NH#asH<|z2O#Tj& zzsuzBG5I+pw5Tt>w}o2h_OG+CXjcQ~1mZ%dxlZ*PO#TOx|H*{x^mj8||19eN5>?O* zWZayShn@csf3+uF*IleF*OuJp(aNm6U3)^YZ)-!ssTdx;wM$1D!kGyMWixS*B;_uD z)R{8M987dOd+JwMQ4D)`HiqL{U?IGL@&iCGA2J$5N4+J>2*1aVDB(%Dy}=(OcA|}2 zA7Wq}vx#-=JnjYUqI!{wkWexQ1e3lv7e9Jp4z?H&H(izo5hWp|7oXla a=J~YDRiua>D7(d4wQ;`jiN+r_-umB^wgR63 diff --git a/conspecfunction/tvt/__pycache__/tvt_rewards.cpython-37.pyc b/conspecfunction/tvt/__pycache__/tvt_rewards.cpython-37.pyc deleted file mode 100644 index cd40f361ad028a9bee2d859c50d1d18c55d3babb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6005 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 diff --git a/conspecfunction/tvt/pycolab/__pycache__/game.cpython-37.pyc b/conspecfunction/tvt/pycolab/__pycache__/game.cpython-37.pyc deleted file mode 100644 index 8a9527e31d97e905c6545660104c2a05e192cc40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1307 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 P7E6nBiwleMi;MpT!H18> diff --git a/conspecfunction/tvt/pycolab/__pycache__/key_to_door3.cpython-37.pyc b/conspecfunction/tvt/pycolab/__pycache__/key_to_door3.cpython-37.pyc deleted file mode 100644 index f3f651ac10f43b59430e2fd70958f3527b4b865d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9665 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 diff --git a/conspecfunction/tvt/pycolab/__pycache__/key_to_door4.cpython-37.pyc b/conspecfunction/tvt/pycolab/__pycache__/key_to_door4.cpython-37.pyc deleted file mode 100644 index f31430b7cda993bb96c41085ba0a06d0904facbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10705 zcmd^FOKcoxa_-m6^gQ{}`(d|4N%mM;(k8WD$8k2ICCaO;L@6Yll{=5daQ^0ShV$CL zo3c2dafoK!QC<8z4Y(4v<5x0rs%h00BD3T_7=#bAaqA-}iTOUM8irCGBNr z(DheW|Ie!Gs`~5ikBh~ehTqRNLjUhR(6nFjX8)H0at&ATK-V;(xth?0(bQXpYv{yH z;HGOT+yZX7mcmobR4eVK6`ls3aWe|f0Jq(&!tG|Rm3Q+B&jK&F1%>B;7u_Q8yeQOl zw#Fqv8$mrf^id znNKuvPMm+NiSvH8apVirJqpUKxB$w9gmMg&i{cU}mlDcxP~H-6gYtGlIRQ#pyaUQR z3FRaxm&FxOt|XLGpnOZrfijm+PJ=Qp-Ua2|gmMOy_rwAy3x2+F7V|j^%A&Xm%2mJ6 zcmtF-#kbeA^81w(nE!o$*9kk0=yaqLR)X!hTyA~KcWRZE@6-b)=r-%2v(t6zZPW_4 zr0+Z3txDhrALibhbKdqJcAFhp3G1D9OfNg#W@XoxPPNi@s-0%juZB*=+4gs@vgZ9sulvQYB%(oO{@S9)8Q77fLOKDYN-Ym84F6Lv(W%& zf=I8I&H8_vnl=Ev)GU7}oNY%HPJDNncg^@&Q#hB^okOBCn-r=Y);a5dh~gnTyDU_p z?(l@qF2{u<-r?OWnzO;|We(&BH6CluR>_(Dp8@0=uHXcKuemzjTtn!tDGXsg)?7IF$b6m!)Kn)8>%g_Ud9aRmzid#O-s=qI&?@hGzgxR=>B z9@)T5Ik#uaIic^Rh4GOl%stJsgoe?qmGvkCh4j$#&2mcG=q5_vyS?<;@@iyvJ3*bI ziZT@9M$?aMFTu*$$O`=CW|V<8qDl~@HagI=D6RB2i0q9@bz8_zS8~3Qjp=((_Ar`= zHQXC?-mO=+y`AnqYVs7S{(5PCtJCu5TlHpTzB*ss^4oL4PJ6zJLAri*Uw!7o2jP5o z7fN5*n8)nBu;cMHygJw2jnX?^QGqIiV!SjB&Q)wnoG9LP`dY(LkUe!#8z-iJ70Cf&&0ob}_D9Sg|fn0x<3tvMC zKE${OE5W|#l`^~!Wq2P-kQNq{LGLR=YUQRZqKoy&PE=wcQ3+WBSxyj45=;SU1=P|PA1cX0*enx^Dq#}b+vtbHINc^0+g8w76>I0T1E z;vAknz%`HrDK9CB#ow+Z&SS;{Ni4ozN&FR=^&Ckoep5-zqT?U2^Zq+Q%1cV(>Tg#P z7ck?2B(A<*N&GFD^&ClD{ic$*h>m~4&ij%eWkeDt2>baGg z?zrb$_)GFtruF2y8GKce?$25Xz!ANybz{1Mt6Y<*#GKiEq@ zHHH36R~Q!9NIlaLOdGJmI;=3AvAH5Ip^uy8wDQ9PqZ^rs%-mc>h-9(y9n^aT2Kb-2 z)PaL6=>@YlHMHQ^LzXiKT3_-?nc%3Hu(FEaZJ(XwX<3(ZtfW{=@%=rnAPqq8Sg@2x zUx@}52a`sO*?aX$DEUgr_XyOwl>lOulb1IA_c5d}R*)^pAsvH2r-BVUxS|}{Rdf@p6%F7HYy7IJ zWl)`Ct5rP)!rTS37TalgY~P;+_lKylmouK}Bh-&oU2}}Osi+phtxfc4Jyn?z23%n} zL~aD}rXBMRv1V#7{fs$L@+-BXcEFO>Pg0TPB>;FzPE~$~;M)ZBpKhLcu7t5sTKcWd z1AmCU+?|5oih(n1bcEo5P4ZXy$)^8-B8-QUo=YD{D0b%)8Bej_pX_0xXyJ|DeeWANH@SMmiJPW)aiVDvGNA6hR zd1R2Mu%9R}e~hxo95TuhGsq|>m_6C`eW%o#ZA9fwZD zA!Y7MDpuL}5=mO^ONO}XH30lBT&q%;{O#-Cb>P7Uz+dux(mZXC88Th%Lk#E#b|ZUf zKx+@WGV3`V<-PV!%Zu~3h^rNn)Qiq|oArkyBH7MuyDMu*fT_vE z2|l-Y^Va?48{YN1x9@(sx)xd04l-@FhYVb2M+WguAhZAUq~||GrrPUl1ipNrGTfM- z-xNXFjyGziY}caP&}s`Ki#`3kwH8K}YN?gx1`8d8lJVAq5&Qp9#>_@(wgK}r_)qFK zvQGuQS5$h_-{Vnn_+!aSDGA>Oh?b^8?_FZ5UoFaEjxcaKn~qwwGqmbp4zKqgp&1Hg z3Y69Co6hLOVSFlK(7-@L&Fr03Q#-6?^~FC5P4UX%XN~(EzTxXZn?&{ z29vyb_+0Zt>M%1jy-78_p@%P?5&V)|K76E7qSc9Rp6Cx|^k!mS#9E&`fAM&|i)*{B zjZTxNHL=Dztx8uV*0%>|I9&ht4xd#f(e*R^>6pEOnojbdKM%@{J3^&2e+?wmp6a0i zZ^k5m`AFye9$>>t?o*BQ9&#+Cgc;TgZNO}pYUILvqd*Gn?GqDNF-$$pp`?|W5UG>e zGox&v=_e_uZe~UPKIZgm-6v3c`4VQ*dC0UKP0^vr zxwe&E_-(%uZbg|u9bUk~#4gGUki%z6J<9aF zjugHuPby;*o!s{QuGjYZS(< zIM*5!SNScKZkO+~M&=$SSFbcBEq`?MR$J7o6`U{KRp&-=ycMO^Z{0!AlV7i+gP0~i zR*X<@s#{3bs%A81Q=%Cd)@>hFjwg6v5Kr~aQ7;_ypcxh{N_-i*VbI#}p0Hp}>%9|7 zYYyn5uR#b0-$boB$>b6I5U#W^pD+_=t+=_t387>{s+@L<$$?8O z7I_;~`NsgR9keRV=0?3H?~t~_>Y3OLOb)tZlHVoxL$)~BtR0KjHr~w# zY_J;aakHX|%yK0~qOFMz}>5xNS1Qw)AV$%H)e$_nF&0SaG}49Yxc z1!00|2w9$(byKxr3)HEN-3?xoKfx$iAyYbx@OYBCj)?k*dOxVQLw+0?$j?wux&(hp z@Mi>n4p1&iDz2;mMETX_A1tljP?{abmFjebkyjjHZV-Em;2MD-@ClT19?b9QnBVaf zW05V9*F27ic}*?MDPL#nwo%f1$A@@6+^)}W15KxJDSrPH$XARQ0>8v)A*=?c?a+ep zK`_+FLnW2D3u(HFie73=09QeyGGmj9sx_uie_Es=8-$LK4TE(`k_Ip~cUohzb_i8u zl}XFRCQS|rY}B^NA7BCUJ^;ef_@!NdC}ka#=SglR77^7gDh){vX-3zASy~uKHnvb> za%8S5mg6~Mv`)$>$ttli*&1?N?s&*mA1P^AzmbS#e!da^lAjZI3jq4O3Ku8 z2LO|dv;I(jYCO{(>21Uth*^kObQR@CIu86_7CYdKKbOF5Xi7guG<}Mx(Cr2r%l^n#B$o?q)*5|v-3j{6zP9+(l4@1lD^C~^SQv2K+ Uq79y&m@ZCFsQ=XTr20?)KUw9&ga7~l diff --git a/conspecfunction/tvt/pycolab/__pycache__/key_to_door5_2keyseasy.cpython-37.pyc b/conspecfunction/tvt/pycolab/__pycache__/key_to_door5_2keyseasy.cpython-37.pyc deleted file mode 100644 index f170b7c4ba094ee8fd5135a3b2ac32867ae74506..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7447 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 diff --git a/conspecfunction/tvt/pycolab/__pycache__/key_to_door5_3keyseasy.cpython-37.pyc b/conspecfunction/tvt/pycolab/__pycache__/key_to_door5_3keyseasy.cpython-37.pyc deleted file mode 100644 index 63d5fbb9bb051748ff74ee9629a14b413ca676fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9676 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 diff --git a/conspecfunction/tvt/pycolab/__pycache__/key_to_door5_4keyseasy.cpython-37.pyc b/conspecfunction/tvt/pycolab/__pycache__/key_to_door5_4keyseasy.cpython-37.pyc deleted file mode 100644 index 1454261563f4d7bed628c39d1b31b78c2882ca35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10715 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 ZZM+tc8=0hWjeinmjH?DSm4 zJE=Er^nAs;X|vbFJTGmH*LrKZ_P)j%%zvRVpZlZsbF;S&Nt3l8X>oV70m&vLYpe}P zyOwM*_fYGs&o&;N$9Wp{133{%!DaU|XsLDday{zHJe?LiOvaO36cBkVIZb4eXW-iy zo)zI>n#DyWaf)G*9ZP(3>$Ud5J8?c9=UGgvE-tfXQiP$PBb3g)gU9#x9+&NKoS)*n;Y3-a+zQ9h(@++C zB17mDMsZR4VKyCCGT6?NJROiXM8-wwO>&u#-^xZjj0A>r(cAp5HF|3++rXWTFjNN) z!@p|(zPmHb$9!j;q|r{i6AyXTmD6koCzBH%FG6FdI4yQ2Rg~@I{Sl7~*`1t=77i5P zmc(e5ueWs1aCAqX-Ms4O?!p2wS%5Bjl2hNsE&mSkJ8O;*I%$YobG^_;`iUcN6~^!N zxpQGM{Q|BW*>nBUxYXfZ=fYtXhrk-y%>037ki%)Fdt!)RVT5<7VWc){h)ao3+BPD$}#ZAIIX%qqhRT5tElL?yYC)7JlH=h+q+V7L4Ms6A{V8Z=EtQo z$i+A+#0F-Re#BTP_!&a7Y*y34Uw-iLsN6&ZjFSxE9r8&cbH+uRCM*U$**iQc?eL7t zVkz6(RWcqy)~XlVKX`ofpmf3vkTG0J4-Y<2QkhSSp;#x~T>+rfN*A#QePwB@Bq$vf z(6aRUQGCKgJ`pwz^N`pG_Ph|U;I$%Oq7Tk=!l3jw!OPb`G~F;fy=~mkeNbP86gYaT z@0QWhXWJ_wR;|%-Dc!PY%)=1bgA`-al=xN{el(5J`imQeERT_q6t{vlF4yX;hcY%F7SVPIu(Wo2^8&u}X%YX}3vldC3qi6;hz(M3=NNLLCDGC}q zaT=vlF2TzrlSP!pTsgbrD_e=zX$lp3(IN6C5eg*n4UlrZDq!KV9=VewJ_)CjQa}Bi zbycbzVv?j7(NHdYF^jUifI%M_-guB5Q5QrKjcN@1HhEB%dE-mE)}TwFcL z>|a-MnEIQf>O+vxxk~k}?+3xrH6MaR21xE|RMn!$NpzM$S_DzRxJ-@-@ma7ie}GPn zV>Q~Q@=QSfkim3vWhKT{=MwbK)xZy_g`hU3KqGPTVGxPq>6luuFHlSAfsF~5MpH@Z zAbgHf9t;Ekn5OQpbZ|@T`5~-&E%w-|1^AjmA5$Tb#VC;>SG^piGljWZ0n$CJQvp)r zW%RYfm9q%i4Cqcam`*~aTF0s4`g1_FwlcBY%ul%x2}9AUJFV-XYK#r41_)5)0jyL5 zbo<&sc!^vtX3^Eay+p3J@v?#!Xk Date: Wed, 20 Mar 2024 02:41:51 -0400 Subject: [PATCH 04/15] adds main_eval, run_eval, collect data for gfns --- conspecfunction/collect_data.py | 154 ++++++++++ ...19-212006_key_to_door3_1_2500-epoch-70.png | Bin 0 -> 341677 bytes conspecfunction/main.py | 136 ++++++--- conspecfunction/main_eval.py | 266 ++++++++++++++++++ conspecfunction/run.sh | 17 ++ conspecfunction/run_eval.sh | 17 ++ 6 files changed, 558 insertions(+), 32 deletions(-) create mode 100644 conspecfunction/collect_data.py create mode 100644 conspecfunction/data/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png create mode 100644 conspecfunction/main_eval.py create mode 100755 conspecfunction/run.sh create mode 100644 conspecfunction/run_eval.sh diff --git a/conspecfunction/collect_data.py b/conspecfunction/collect_data.py new file mode 100644 index 0000000..be13027 --- /dev/null +++ b/conspecfunction/collect_data.py @@ -0,0 +1,154 @@ +import numpy as np +import os +import torch +import csv +import pandas as pd +import glob + +def collect_gfn_data_max_states(exp_name, epoch): + base_directory = "data" + full_path = os.path.join(base_directory, exp_name) + + # buffer_path = os.path.join(full_path, 'buffer_epoch_{}.pth'.format(epoch)) + sf_buffer = os.path.join(full_path, 'conspec_rollouts_epoch_{}.pth'.format(epoch)) + observations = torch.load(sf_buffer)['obs'] + # observations = torch.load(buffer_path)['obs'] + cos_path = os.path.join(full_path, 'cos_sim_epoch_{}.pth'.format(epoch)) + cos_sim_info = torch.load(cos_path) + cos_scores_max = cos_sim_info['cos_max_scores'].detach().cpu().numpy() + max_indices = cos_sim_info['max_indices'].detach().cpu().numpy() + print(observations.shape, cos_scores_max.shape) + # Number of batches + num_batches = cos_scores_max.shape[0] + num_similar = cos_scores_max.shape[1] + cos_sim_threshold = 0.6 + num_prototypes = cos_scores_max.shape[1] + data = [] + cos_data = [] + default = (np.zeros((3,5,5)), -1) + state_prototypes = {0:default, 1:default, 2: default, 3: default, 4: default, 5:default, 6: default, 7:default} # prototype, states, cosine similarity + + for group_idx in range(num_batches): + traj_proto = [] + cos_proto = [] + proto_active = False + for i in range(num_similar): + # Calculate the index in the flattened axes array + # ax_idx = group_idx * num_similar + i + + idx = max_indices[group_idx, i] + cos_sim = cos_scores_max[group_idx, i] + if cos_sim > cos_sim_threshold: + proto_active = True + else: + proto_active = False + traj_proto.append(proto_active) + cos_proto.append(cos_sim) + data.append(traj_proto) + cos_data.append(cos_proto) + + gfn_path = 'data/gfn/max_gfn_data_{}_{}.csv'.format(exp_name,epoch) + cos_path = 'data/gfn/max_cos_data_{}_{}.csv'.format(exp_name, epoch) + # Write the data to a CSV file + with open(gfn_path, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(['Prototype_' + str(i) for i in range(num_prototypes)]) + writer.writerows(data) + with open(cos_path, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerows(cos_data) + # print(state_prototypes) + return state_prototypes + + +def collect_gfn_data(exp_name, epoch): + base_directory = "data" + full_path = os.path.join(base_directory, exp_name) + + buffer_path = os.path.join(full_path, 'buffer_epoch_{}.pth'.format(epoch)) + sf_buffer = os.path.join(full_path, 'conspec_rollouts_epoch_{}.pth'.format(epoch)) + observations = torch.load(sf_buffer)['obs'] + # observations = torch.load(buffer_path)['obs'] + cos_path = os.path.join(full_path, 'cos_sim_epoch_{}.pth'.format(epoch)) + cos_sim_info = torch.load(cos_path) + cos_scores_max = cos_sim_info['cos_max_scores'].detach().cpu().numpy() + max_indices = cos_sim_info['max_indices'].detach().cpu().numpy() + cos_scores = cos_sim_info['cos_scores'].detach().cpu().numpy() + print(observations.shape, cos_scores.shape) + # Number of batches + num_batches = cos_scores.shape[1] + cos_sim_threshold = 0.6 + num_prototypes = cos_scores_max.shape[1] + data = [] + cos_data = [] + default = (np.zeros((3,5,5)), -1) + state_prototypes = {0:default, 1:default, 2: default, 3: default, 4: default, 5:default, 6: default, 7:default} # prototype, states, cosine similarity + time_steps = int(observations.shape[0] / num_batches) + print(time_steps, num_batches) + for batch in range(num_batches): + for state in range(time_steps): + traj_proto = [] + cos_proto = [] + proto_active = False + for proto in range(num_prototypes): + cos_sim = cos_scores[state, batch, proto] + if cos_sim > cos_sim_threshold: + proto_active = True + else: + proto_active = False + traj_proto.append(proto_active) + cos_proto.append(cos_sim) + data.append(traj_proto) + cos_data.append(cos_proto) + + gfn_path = 'data/gfn/gfn_data_{}_{}.csv'.format(exp_name,epoch) + cos_path = 'data/gfn/cos_data_{}_{}.csv'.format(exp_name, epoch) + # Write the data to a CSV file + with open(gfn_path, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(['Prototype_' + str(i) for i in range(num_prototypes)]) + writer.writerows(data) + with open(cos_path, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerows(cos_data) + # print(state_prototypes) + return state_prototypes + +def merge_csv_files(exp_name, prefix, output_file): + # List all CSV files in the current directory + base_directory = "data/gfn/" + full_path = os.path.join(base_directory) + # Combine all CSV files into a single DataFrame + file_list = glob.glob(full_path + "/{}_*.csv".format(prefix)) + print(file_list) + files = [f for f in file_list] + + combined_csv = pd.concat([pd.read_csv(file) for file in files], ignore_index=True) + + # Write the combined DataFrame to a new CSV file + combined_csv.to_csv(output_file, index=False) + + + + +if __name__ == "__main__": + exp_name_ktd2 = '20240228-031400_key_to_door2_1_1000' + exp_name_ktd3 = '20240319-193056_key_to_door3_1_5000' + exp_name_ktd4 = '20240229-011752_key_to_door4_1_3000' + exp_kd3_eval = '20240319-212006_key_to_door3_1_2500' + + + for i in np.arange(1, 40, 1): + collect_gfn_data_max_states(exp_kd3_eval, i) + + + + # merge_csv_files(exp_name_ktd3, 'max_gfn_data_{}'.format(exp_name_ktd3), 'merged_rollouts_kd3_5k_odds.csv') + + # collect_gfn_data_max_states(exp_name_ktd3, 1499) + # collect_gfn_data_max_states(exp_name_ktd3, 1599) + # collect_gfn_data_max_states(exp_name_ktd3, 1699) + # collect_gfn_data_max_states(exp_name_ktd3, 1799) + # collect_gfn_data_max_states(exp_name_ktd3, 1899) + # collect_gfn_data_max_states(exp_name_ktd3, 1999) + diff --git a/conspecfunction/data/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png b/conspecfunction/data/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png new file mode 100644 index 0000000000000000000000000000000000000000..af785de699090a495836d31a2e0de89435f3a831 GIT binary patch literal 341677 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∾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

Q@VZ72W^~g4F5B4|%-5Kz4T+>lx2x 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ℜ8$B4K0&QB1_M5Jn8D(c->P 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 B+xP$g literal 0 HcmV?d00001 diff --git a/conspecfunction/main.py b/conspecfunction/main.py index b300124..92ee243 100644 --- a/conspecfunction/main.py +++ b/conspecfunction/main.py @@ -1,21 +1,14 @@ -import copy -import glob import os -import time from collections import deque import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim -import sys -import numpy -import wandb -from misc import Logger, makedir - +from misc import Logger, vis_prototypes +import matplotlib.pyplot as plt +import json ########packages to runthe pycolab game from tvt import batch_env from tvt import nest_utils from tvt.pycolab import env as pycolab_env +from Conspec.ConSpec import ConSpec ########packages to run the underlying RL algorithm, mostly identical to https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail from a2c_ppo_acktr import algo, utils @@ -29,8 +22,9 @@ from six.moves import range from six.moves import zip import tensorflow.compat.v1 as tf - - +# from data_collection import collect_gfn_data, read_data, get_cosine_similarity, visualize +import pickle +import datetime ''' The code below is nearly identical to https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail @@ -42,22 +36,31 @@ def main(): torch.manual_seed(args.seed) torch.cuda.manual_seed_all(args.seed) + # Create the folder for results + timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + subfolder_name = f"{timestamp}_{args.pycolab_game}_{args.seed}_{args.num_episodes}" + base_directory = "data" + full_path = os.path.join(base_directory, subfolder_name) + os.makedirs(full_path, exist_ok=True) + + if args.cuda and torch.cuda.is_available() and args.cuda_deterministic: torch.backends.cudnn.benchmark = False torch.backends.cudnn.deterministic = True + wandb_project_name = 'conspec' - wandb.init(name='sunchipsster', project=wandb_project_name) - proj_name = 'Results' + str(args.pycolab_game) + str(args.seed) + #wandb.init(project=wandb_project_name) + proj_name = str(args.pycolab_game) +' seed'+ str(args.seed)+ ' episodes'+ str(args.num_episodes) logger = Logger( exp_name=proj_name, - save_dir='/home/mila/c/chen.sun/scratch/conspec', + save_dir='/home/mila/s/samieima/scratch/conspec', print_every=1, - save_every=10000, - total_step=10000, + save_every=args.log_interval, + total_step=args.num_episodes, print_to_stdout=True, wandb_project_name=wandb_project_name, - wandb_tags=[], + wandb_tags=['multikeydoor'], wandb_config=args, ) @@ -71,18 +74,18 @@ def main(): env_builder = pycolab_env.PycolabEnvironment env_kwargs = { - 'game': args.pycolab_game, - 'num_apples': args.pycolab_num_apples, - 'apple_reward': [args.pycolab_apple_reward_min, - args.pycolab_apple_reward_max], + 'game': args.pycolab_game, # key to door 4 + 'num_apples': args.pycolab_num_apples, # 10 + 'apple_reward': [args.pycolab_apple_reward_min, #0 + args.pycolab_apple_reward_max], #0 'fix_apple_reward_in_episode': args.pycolab_fix_apple_reward_in_episode, 'final_reward': args.pycolab_final_reward, 'crop': args.pycolab_crop } env = batch_env.BatchEnv(args.num_processes, env_builder, **env_kwargs) + ep_length = env.episode_length args.num_steps = ep_length - envs = env obsspace = (3,5,5) #env.observation_shape actor_critic = Policy( @@ -119,25 +122,28 @@ def main(): ''' Here, the main ConSpec class is loaded. All the relevant ConSpec functions and objects are contained in this class. ''' - from Conspec.ConSpec import ConSpec conspecfunction = ConSpec(args, obsspace, env.num_actions, device) - ############################################################## + # file_path='datasets/frozen/trajectory_data_gfn_{}_seed_{}_{}_episodes_frozen.csv'.format(args.pycolab_game, args.seed, args.num_episodes) + # cos_file_path='datasets/frozen/cos_sim_{}_seed_{}_{}_episodes_frozen.csv'.format(args.pycolab_game, args.seed ,args.num_episodes) + ############################################################## + print('steps', args.num_steps) rollouts = RolloutStorage(args.num_steps, args.num_processes, obsspace, env.num_actions, actor_critic.recurrent_hidden_state_size, args.num_prototypes) # envs.observation_space.shape rollouts.to(device) - obs, _ = envs.reset() + obs, _ = envs.reset() obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) rollouts.obs[0].copy_(obs) rollouts.to(device) episode_rewards = deque(maxlen=10) num_updates = int(args.num_env_steps) // args.num_steps // args.num_processes - + ##retrieving memories from the success/failure buffers + all_memories = [] logger.start() - for j in range(10000): + for episode in range(args.num_episodes): logger.step() obs, _ = envs.reset() obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) @@ -146,7 +152,7 @@ def main(): if args.use_linear_lr_decay: # decrease learning rate linearly utils.update_linear_schedule( - agent.optimizer, j, num_updates, + agent.optimizer, episode, num_updates, agent.optimizer.lr if args.algo == "acktr" else args.lr) for step in range(args.num_steps): @@ -176,13 +182,15 @@ def main(): ###############CONSPEC FUNCTIONS############################## ''' - the purpose here is to: + The purpose here is to: 1. retrieve the current minibatch of trajectory (including its observations, rewards, hidden states, actions, masks) 2. "do everything" that ConSpec needs to do internally for training, and output the intrinsic + extrinsic reward for the current minibatch of trajectories 3. store this total reward in the memory buffer ''' + obstotal, rewardtotal, recurrent_hidden_statestotal, actiontotal, maskstotal = rollouts.release() reward_intrinsic_extrinsic = conspecfunction.do_everything(obstotal, recurrent_hidden_statestotal, actiontotal, rewardtotal, maskstotal) + rollouts.storereward(reward_intrinsic_extrinsic) ############################################################## @@ -192,11 +200,75 @@ def main(): value_loss, action_loss, dist_entropy= agent.update(rollouts) rollouts.after_update() - if j % args.log_interval == 0 and len(episode_rewards) > 1: + + if episode % args.log_interval == 0 and len(episode_rewards) > 1: logger.meter("results", "R", rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy()) logger.meter("results", "dist_entropy", dist_entropy) logger.meter("results", "value_loss", value_loss) logger.meter("results", "action_loss", action_loss) + + if episode > args.start_checkpoint and (episode+1) % args.checkpoint_interval == 0: + buffer = { + 'obs': rollouts.obs, + 'rewards': rollouts.rewards, + 'hidden_states': rollouts.recurrent_hidden_states, + 'actions': rollouts.actions, + 'masks': rollouts.masks, + 'bad_masks': rollouts.bad_masks, + 'value_preds': rollouts.value_preds, + } + sf_buffer = conspecfunction.rollouts.retrieve_SFbuffer() + conspec_rollouts = { + 'obs': sf_buffer[0], + 'rewards': sf_buffer[5], + 'hidden_states': sf_buffer[1], + 'actions': sf_buffer[3], + 'masks': sf_buffer[2], + 'bad_masks': sf_buffer[2], + 'value_preds': sf_buffer[4], + } + # print(type(conspecfunction.prototypes)) + tensor_proto_list = [p.data for p in conspecfunction.prototypes.prototypes] + checkpoint = { + 'epoch': episode, + 'encoder_state_dict': conspecfunction.encoder.state_dict(), + 'actor_critic_state_dict': actor_critic.state_dict(), + 'optimizer_conspec_state_dict': conspecfunction.optimizerConSpec.state_dict(), + 'optimizer_ppo_state_dict': agent.optimizer.state_dict(), + 'prototypes_state_dict': tensor_proto_list, + 'prototypes': conspecfunction.prototypes.prototypes.state_dict(), + } + cos_checkpoint = { + 'cos_max_scores' : conspecfunction.rollouts.cos_max_scores, + 'max_indices' : conspecfunction.rollouts.max_indx, + 'cos_scores' : conspecfunction.rollouts.cos_scores, + # 'cos_success' : conspecfunction.rollouts.cos_score_pos, + # 'cos_failure' : conspecfunction.rollouts.cos_score_neg, + } + + print('saving checkpoints....') + checkpoint_path = os.path.join(full_path, f'checkpoint_epoch_{episode}.pth') + buffer_path = os.path.join(full_path, f'buffer_epoch_{episode}.pth') + conspec_rollouts_path = os.path.join(full_path, f'conspec_rollouts_epoch_{episode}.pth') + cos_path = os.path.join(full_path, f'cos_sim_epoch_{episode}.pth') + + torch.save(checkpoint, checkpoint_path) + print('checkpoint saved') + + torch.save(buffer, buffer_path) + print('buffer saved') + + torch.save(conspec_rollouts, conspec_rollouts_path) + print('success/failure buffers saved') + + torch.save(cos_checkpoint, cos_path) + print('cosine similarity saved') + + + # pickle data files + + logger.finish() + if __name__ == "__main__": main() diff --git a/conspecfunction/main_eval.py b/conspecfunction/main_eval.py new file mode 100644 index 0000000..dbaf5f5 --- /dev/null +++ b/conspecfunction/main_eval.py @@ -0,0 +1,266 @@ +import os +from collections import deque +import torch +from misc import Logger, vis_prototypes +import matplotlib.pyplot as plt +import json +########packages to runthe pycolab game +from tvt import batch_env +from tvt import nest_utils +from tvt.pycolab import env as pycolab_env +from Conspec.ConSpec import ConSpec + +########packages to run the underlying RL algorithm, mostly identical to https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail +from a2c_ppo_acktr import algo, utils +from a2c_ppo_acktr.algo import gail +from a2c_ppo_acktr.arguments import get_args +from a2c_ppo_acktr.modelRL import Policy +from a2c_ppo_acktr.storage import RolloutStorage +from evaluation import evaluate +from tensorflow.contrib import framework as contrib_framework +import numpy as np +from six.moves import range +from six.moves import zip +import tensorflow.compat.v1 as tf +# from data_collection import collect_gfn_data, read_data, get_cosine_similarity, visualize +import pickle +import datetime + +''' +The code below is nearly identical to https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail +With only minor additions of ConSpec-specific operations that have been commented ######## +''' + +def main_eval(): + args = get_args() + torch.manual_seed(args.seed) + torch.cuda.manual_seed_all(args.seed) + + # Create the folder for results + timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + subfolder_name = f"{timestamp}_{args.pycolab_game}_{args.seed}_{args.num_episodes}" + base_directory = "data" + full_path = os.path.join(base_directory, subfolder_name) + os.makedirs(full_path, exist_ok=True) + + + if args.cuda and torch.cuda.is_available() and args.cuda_deterministic: + torch.backends.cudnn.benchmark = False + torch.backends.cudnn.deterministic = True + + + wandb_project_name = 'conspec-eval' + #wandb.init(project=wandb_project_name) + proj_name = str(args.pycolab_game) +' seed'+ str(args.seed)+ ' episodes'+ str(args.num_episodes) + logger = Logger( + exp_name=proj_name, + save_dir='/home/mila/s/samieima/scratch/conspec', + print_every=1, + save_every=args.log_interval, + total_step=args.num_episodes, + print_to_stdout=True, + wandb_project_name=wandb_project_name, + wandb_tags=['multikeydoor'], + wandb_config=args, + ) + + log_dir = os.path.expanduser(args.log_dir) + eval_log_dir = log_dir + "_eval" + utils.cleanup_log_dir(log_dir) + utils.cleanup_log_dir(eval_log_dir) + + torch.set_num_threads(1) + device = torch.device("cuda:0" if args.cuda else "cpu") + + env_builder = pycolab_env.PycolabEnvironment + env_kwargs = { + 'game': args.pycolab_game, # key to door 4 + 'num_apples': args.pycolab_num_apples, # 10 + 'apple_reward': [args.pycolab_apple_reward_min, #0 + args.pycolab_apple_reward_max], #0 + 'fix_apple_reward_in_episode': args.pycolab_fix_apple_reward_in_episode, + 'final_reward': args.pycolab_final_reward, + 'crop': args.pycolab_crop + } + env = batch_env.BatchEnv(args.num_processes, env_builder, **env_kwargs) + + ep_length = env.episode_length + args.num_steps = ep_length + envs = env + obsspace = (3,5,5) #env.observation_shape + actor_critic = Policy( + obsspace, + env.num_actions, + base_kwargs={'recurrent': args.recurrent_policy}) # envs.observation_space.shape, + actor_critic.to(device) + + ################################### + ##decide on which underlying RL agent to use - ppo or a2c. But any other RL agent of choice should also work + if args.algo == 'a2c': + agent = algo.A2C_ACKTR( + actor_critic, + args.value_loss_coef, + args.entropy_coef, + lr=args.lr, + eps=args.eps, + alpha=args.alpha, + max_grad_norm=args.max_grad_norm) + + elif args.algo == 'ppo': + agent = algo.PPO( + actor_critic, + args.clip_param, + args.ppo_epoch, + args.num_mini_batch, + args.value_loss_coef, + args.entropy_coef, + lr=args.lr, + eps=args.eps, + max_grad_norm=args.max_grad_norm) + + + ###############CONSPEC FUNCTIONS############################## + ''' + Here, the main ConSpec class is loaded. All the relevant ConSpec functions and objects are contained in this class. + ''' + conspecfunction = ConSpec(args, obsspace, env.num_actions, device) + + ############################################################## + print('steps', args.num_steps) + rollouts = RolloutStorage(args.num_steps, args.num_processes, + obsspace, env.num_actions, + actor_critic.recurrent_hidden_state_size, args.num_prototypes) # envs.observation_space.shape + rollouts.to(device) + + obs, _ = envs.reset() + obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) + rollouts.obs[0].copy_(obs) + rollouts.to(device) + + episode_rewards = deque(maxlen=10) + num_updates = int(args.num_env_steps) // args.num_steps // args.num_processes + logger.start() + + checkpoint = torch.load('data/kd3/checkpoint_epoch_1999.pth') + actor_critic.load_state_dict(checkpoint['actor_critic_state_dict']) + agent.optimizer.load_state_dict(checkpoint['optimizer_ppo_state_dict']) + conspecfunction.optimizerConSpec.load_state_dict(checkpoint['optimizer_conspec_state_dict']) + proto_list = checkpoint['prototypes_state_dict'] + for idx, proto in enumerate(conspecfunction.prototypes.prototypes): + proto.data = proto_list[idx] + + + for episode in range(args.num_episodes): + logger.step() + obs, _ = envs.reset() + obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) + rollouts.obs[0].copy_(obs) + donetotal = np.zeros((args.num_processes,)) # .to(device) + if args.use_linear_lr_decay: + # decrease learning rate linearly + utils.update_linear_schedule( + agent.optimizer, episode, num_updates, + agent.optimizer.lr if args.algo == "acktr" else args.lr) + + for step in range(args.num_steps): + # Sample actions + with torch.no_grad(): + value, action, action_log_prob, recurrent_hidden_states = actor_critic.act( + rollouts.obs[step], rollouts.recurrent_hidden_states[step], + rollouts.masks[step]) + + obs, reward = envs.step(action) + obs = torch.from_numpy(obs).permute((0, 3, 1, 2)).to(device) + reward = torch.from_numpy(reward).reshape(-1, 1) + done = donetotal + masks = torch.FloatTensor( + [[0.0] if done_ else [1.0] for done_ in done]) + bad_masks = masks + rollouts.insert(obs, recurrent_hidden_states, action, + action_log_prob, value, reward, masks, bad_masks) + + with torch.no_grad(): + next_value = actor_critic.get_value( + rollouts.obs[-1], rollouts.recurrent_hidden_states[-1], + rollouts.masks[-1]).detach() + # now compute new rewards + rewardstotal = rollouts.retrieveR() + episode_rewards.append(rewardstotal.sum(0).mean().cpu().detach().numpy()) + + ###############CONSPEC FUNCTIONS############################## + ''' + The purpose here is to: + 1. retrieve the current minibatch of trajectory (including its observations, rewards, hidden states, actions, masks) + 2. "do everything" that ConSpec needs to do internally for training, and output the intrinsic + extrinsic reward for the current minibatch of trajectories + 3. store this total reward in the memory buffer + ''' + + obstotal, rewardtotal, recurrent_hidden_statestotal, actiontotal, maskstotal = rollouts.release() + reward_intrinsic_extrinsic = conspecfunction.do_everything(obstotal, recurrent_hidden_statestotal, actiontotal, rewardtotal, maskstotal) + + rollouts.storereward(reward_intrinsic_extrinsic) + ############################################################## + + rollouts.compute_returns(next_value, args.use_gae, args.gamma, + args.gae_lambda, args.use_proper_time_limits) + + value_loss, action_loss, dist_entropy= agent.update(rollouts) + rollouts.after_update() + + + if episode % args.log_interval == 0 and len(episode_rewards) > 1: + logger.meter("results", "R", rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy()) + logger.meter("results", "dist_entropy", dist_entropy) + logger.meter("results", "value_loss", value_loss) + logger.meter("results", "action_loss", action_loss) + + if episode > args.start_checkpoint and (episode+1) % args.checkpoint_interval == 0: + buffer = { + 'obs': rollouts.obs, + 'rewards': rollouts.rewards, + 'hidden_states': rollouts.recurrent_hidden_states, + 'actions': rollouts.actions, + 'masks': rollouts.masks, + 'bad_masks': rollouts.bad_masks, + 'value_preds': rollouts.value_preds, + } + sf_buffer = conspecfunction.rollouts.retrieve_SFbuffer() + conspec_rollouts = { + 'obs': sf_buffer[0], + 'rewards': sf_buffer[5], + 'hidden_states': sf_buffer[1], + 'actions': sf_buffer[3], + 'masks': sf_buffer[2], + 'bad_masks': sf_buffer[2], + 'value_preds': sf_buffer[4], + } + cos_checkpoint = { + 'cos_max_scores' : conspecfunction.rollouts.cos_max_scores, + 'max_indices' : conspecfunction.rollouts.max_indx, + 'cos_scores' : conspecfunction.rollouts.cos_scores, + # 'cos_success' : conspecfunction.rollouts.cos_score_pos, + # 'cos_failure' : conspecfunction.rollouts.cos_score_neg, + } + + print('saving checkpoints....') + buffer_path = os.path.join(full_path, f'buffer_epoch_{episode}.pth') + conspec_rollouts_path = os.path.join(full_path, f'conspec_rollouts_epoch_{episode}.pth') + cos_path = os.path.join(full_path, f'cos_sim_epoch_{episode}.pth') + + torch.save(buffer, buffer_path) + print('buffer saved') + + torch.save(conspec_rollouts, conspec_rollouts_path) + print('success/failure buffers saved') + + torch.save(cos_checkpoint, cos_path) + print('cosine similarity saved') + + + # pickle data files + + + logger.finish() + +if __name__ == "__main__": + main_eval() diff --git a/conspecfunction/run.sh b/conspecfunction/run.sh new file mode 100755 index 0000000..a771e8f --- /dev/null +++ b/conspecfunction/run.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +#SBATCH --partition=long +#SBATCH --gres=gpu:rtx8000:1 +#SBATCH --mem=8GB +#SBATCH --time=14:00:00 +#SBATCH --cpus-per-task=4 +#SBATCH --output=sbatch_out/Conspec_k3_ppo.%A.%a.out +#SBATCH --error=sbatch_err/Conspec_k3_ppo.%A.%a.err +#SBATCH --job-name=Conspec_k3_ppo + +module load anaconda/3 +module load cuda/10.0/cudnn/7.6 +conda activate py37tf15 + +python -u main.py --pycolab_game key_to_door3 --num_episodes 5000 --seed 1 --num-processes 32 --checkpoint_interval 2 --start_checkpoint 1 + + diff --git a/conspecfunction/run_eval.sh b/conspecfunction/run_eval.sh new file mode 100644 index 0000000..ce88bc4 --- /dev/null +++ b/conspecfunction/run_eval.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +#SBATCH --partition=long +#SBATCH --gres=gpu:rtx8000:1 +#SBATCH --mem=8GB +#SBATCH --time=14:00:00 +#SBATCH --cpus-per-task=4 +#SBATCH --output=sbatch_out/Conspec_k3_eval.%A.%a.out +#SBATCH --error=sbatch_err/Conspec_k3_eval.%A.%a.err +#SBATCH --job-name=Conspec_k3_eval + +module load anaconda/3 +module load cuda/10.0/cudnn/7.6 +conda activate py37tf15 + +python -u main_eval.py --pycolab_game key_to_door3 --num_episodes 2500 --seed 1 --num-processes 32 --checkpoint_interval 1 --start_checkpoint 0 + + From b151a1be8601b2fde0625fac513962a07bccff72 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 25 Mar 2024 15:47:40 -0400 Subject: [PATCH 05/15] 'update bash scripts' --- conspecfunction/data_collection.py | 121 +++++++++++++++++++++++++++++ conspecfunction/run.sh | 19 +++-- conspecfunction/run_eval.sh | 19 +++-- 3 files changed, 145 insertions(+), 14 deletions(-) create mode 100644 conspecfunction/data_collection.py mode change 100644 => 100755 conspecfunction/run_eval.sh diff --git a/conspecfunction/data_collection.py b/conspecfunction/data_collection.py new file mode 100644 index 0000000..41ffccb --- /dev/null +++ b/conspecfunction/data_collection.py @@ -0,0 +1,121 @@ +import csv +import numpy as np +from Conspec.ConSpec import ConSpec +import torch +import matplotlib.pyplot as plt +import pdb + +def get_cosine_similarity(conspec, trajectories): + obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = trajectories + #obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch = trajectories + hidden = conspec.encoder.retrieve_hiddens(obs_batch, recurrent_hidden_states_batch,masks_batch, actions_batch) + #print('in cos scores in data', hidden.view(*obs_batchorig.size()[:2], -1).shape, obs_batchorig.shape) + default = (np.zeros((3,5,5)), -1) + state_prototypes = {0:default, 1:default, 2: default, 3: default, 4: default, 5:default, 6: default, 7:default} # prototype, states, cosine similarity + cos_max,_, cos_sim, _ = conspec.prototypes(hidden.view(*obs_batchorig.size()[:2], -1), -1) # [32,8] + + max_indices = torch.argmax(cos_max, axis=0) + + max_indices= max_indices.detach().cpu().numpy() # max_indices: torch.Size([8]): [26, 16, 1, 4, 5, 6, 7, 8] + pdb.set_trace() + + for proto, traj in enumerate(max_indices): + if cos_max[traj][proto] > state_prototypes[proto][1]: + print('replaced') + state_prototypes[proto] = (obs_batch[traj], cos_max[traj][proto]) + return cos_max, cos_sim, state_prototypes + +def read_data(file_path): + + # Read the data from a CSV file + with open(file_path, 'r') as file: + reader = csv.reader(file) + data = list(reader) + + # Convert the data to a numpy array + data = np.array(data) + return data + +def collect_gfn_data(conspec, buffer, gfnpath, cospath): + # collect success and failure trajectories from the environment + # store their cosine similarity (per prototype) scores in a csv file + # each prototype appear as a variable in the csv file + # each row is a trajectory + data = [] + cos_data = [] + default = (np.zeros((3,5,5)), -1) + state_prototypes = {0:default, 1:default, 2: default, 3: default, 4: default, 5:default, 6: default, 7:default} # prototype, states, cosine similarity + + # Collect trajectories and compute their cosine similarities + for epoch in buffer: #only for when we use memories over epochs + cos_max, cos_scores, _ = get_cosine_similarity(conspec, epoch) # torch.Size([125, 32, 8]) + # cos_max = np.max(cos_sim, axis=0) # cos_max: torch.Size([32, 8]) + # max_indices = np.argmax(cos_max, axis=0) # max_indices: torch.Size([8]) + # epoch = epoch[0].detach().cpu().numpy() # states + # buffer = buffer[0].detach().cpu().numpy() + cos_scores = cos_scores.detach().cpu().numpy() + + # store the cosine similarity data for each trajectory + for i, t in enumerate(cos_scores): + for j, p in enumerate(t): + cos_sim_p = [1 if element > 0.6 else 0 for element in p] + if 1 in cos_sim_p: + data.append(cos_sim_p) + cos_data.append(p) + num_prototypes = cos_scores.shape[2] + + # Write the data to a CSV file + with open(gfnpath, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerow(['Prototype_' + str(i) for i in range(num_prototypes)]) + writer.writerows(data) + with open(cospath, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerows(cos_data) + # print(state_prototypes) + return state_prototypes + +def frozen_examplars(conspec, num_prototypes): + + for prototype in range(num_prototypes): + examplars = conspec.rollouts.retrieve_SFbuffer_frozen(prototype) # tuple of 5 + cos_sim = get_cosine_similarity(conspec, examplars).detach().cpu().numpy() # torch.Size([125, 32, 1]) + cos_max = np.max(cos_sim, axis=0) # cos_max: torch.Size([32, 8]) + max_indices = np.argmax(cos_max, axis=0) # max_indices: torch.Size([8]) + print('examplars shape', cos_sim.shape, cos_max) + + return examplars + +def visualize_states_prototypes(conspec, trajectories, env_name, seed, num_episodes): + '''does compare the observations to prototypes before visualizing''' + cos_sim = get_cosine_similarity(conspec, trajectories).detach().cpu().numpy() # torch.Size([125, 32, 8]) + cos_max = np.max(cos_sim, axis=0) # cos_max: torch.Size([32, 8]) + max_indices = np.argmax(cos_max, axis=0) # max_indices: torch.Size([8]) + + for prototype, traj_id in enumerate(max_indices): + print('traj_id, cos_max traj: ', traj_id, cos_max[traj_id]) + obs = trajectories[0][traj_id].detach().cpu().numpy() + obs = np.transpose(obs, (1, 2, 0)) + plt.imshow(obs.astype(np.uint8)) + plt.axis('off') # Remove the axis + plt.title("state corresponding to prototype " + str(prototype)) + plt.savefig("figures/{}_{}_seed_{}_eps_{}.png".format(env_name, prototype, seed, num_episodes)) + +def visualize(obs, env_name, seed, num_episodes, tag): + + for prototype, (state, cos) in obs.items(): + state = np.transpose(state, (1, 2, 0)) + plt.imshow(state.astype(np.uint8)) + plt.axis('off') # Remove the axis + plt.title("frozen state corres. to proto {} with cos sim: {}".format(prototype, cos)) + plt.savefig("figures/frozen/{}_frozen_examplars_{}_{}_seed_{}_eps_{}.png".format(tag, env_name, prototype, seed, num_episodes)) + +def visualize_per_proto(obs, prototype, env_name, seed, num_episodes, tag): + state = np.transpose(obs, (1, 2, 0)) + plt.imshow(state.astype(np.uint8)) + plt.axis('off') # Remove the axis + plt.title("frozen state corres. to proto {} with cos sim: {}".format(prototype)) + plt.savefig("figures/frozen/{}_examplars_{}_{}_seed_{}_eps_{}.png".format(tag, env_name, prototype, seed, num_episodes)) + + + diff --git a/conspecfunction/run.sh b/conspecfunction/run.sh index a771e8f..651228a 100755 --- a/conspecfunction/run.sh +++ b/conspecfunction/run.sh @@ -1,17 +1,22 @@ #!/usr/bin/env bash #SBATCH --partition=long #SBATCH --gres=gpu:rtx8000:1 -#SBATCH --mem=8GB -#SBATCH --time=14:00:00 -#SBATCH --cpus-per-task=4 -#SBATCH --output=sbatch_out/Conspec_k3_ppo.%A.%a.out -#SBATCH --error=sbatch_err/Conspec_k3_ppo.%A.%a.err -#SBATCH --job-name=Conspec_k3_ppo +#SBATCH --mem=16GB +#SBATCH --time=24:00:00 +#SBATCH --cpus-per-task=8 +#SBATCH --output=sbatch_out/conspec_key_to_door4_train.%A.%a.out +#SBATCH --error=sbatch_err/conspec_key_to_door4_train.%A.%a.err +#SBATCH --job-name=conspec_key_to_door4_train + +echo "Date: $(date)" + module load anaconda/3 module load cuda/10.0/cudnn/7.6 conda activate py37tf15 -python -u main.py --pycolab_game key_to_door3 --num_episodes 5000 --seed 1 --num-processes 32 --checkpoint_interval 2 --start_checkpoint 1 +# Stage dataset into $SLURM_TMPDIR + +python -u main.py --pycolab_game key_to_door4 --num_episodes 10000 --seed 1 --num-processes 32 --checkpoint_interval 1 --start_checkpoint 0 diff --git a/conspecfunction/run_eval.sh b/conspecfunction/run_eval.sh old mode 100644 new mode 100755 index ce88bc4..f2ca359 --- a/conspecfunction/run_eval.sh +++ b/conspecfunction/run_eval.sh @@ -1,17 +1,22 @@ #!/usr/bin/env bash #SBATCH --partition=long #SBATCH --gres=gpu:rtx8000:1 -#SBATCH --mem=8GB -#SBATCH --time=14:00:00 -#SBATCH --cpus-per-task=4 -#SBATCH --output=sbatch_out/Conspec_k3_eval.%A.%a.out -#SBATCH --error=sbatch_err/Conspec_k3_eval.%A.%a.err -#SBATCH --job-name=Conspec_k3_eval +#SBATCH --mem=16GB +#SBATCH --time=48:00:00 +#SBATCH --cpus-per-task=8 +#SBATCH --output=sbatch_out/conspec_key_to_door2_eval.%A.%a.out +#SBATCH --error=sbatch_err/conspec_key_to_door2_eval.%A.%a.err +#SBATCH --job-name=conspec_key_to_door2_eval + +echo "Date: $(date)" + module load anaconda/3 module load cuda/10.0/cudnn/7.6 conda activate py37tf15 -python -u main_eval.py --pycolab_game key_to_door3 --num_episodes 2500 --seed 1 --num-processes 32 --checkpoint_interval 1 --start_checkpoint 0 +# Stage dataset into $SLURM_TMPDIR + +python -u main_eval.py --pycolab_game key_to_door2 --num_episodes 5000 --seed 1 --num-processes 32 --checkpoint_interval 1 --start_checkpoint 0 From 555da57fef61b0cbcf211c7ea9f5c90c3a6f6afd Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 25 Mar 2024 16:09:23 -0400 Subject: [PATCH 06/15] adds cos_score and max_indicies to conspec rollout --- conspecfunction/Conspec/prototype.py | 79 +++++++++++++++++++++++ conspecfunction/Conspec/storageConSpec.py | 72 ++++++++++++++++----- 2 files changed, 134 insertions(+), 17 deletions(-) create mode 100644 conspecfunction/Conspec/prototype.py diff --git a/conspecfunction/Conspec/prototype.py b/conspecfunction/Conspec/prototype.py new file mode 100644 index 0000000..ad30066 --- /dev/null +++ b/conspecfunction/Conspec/prototype.py @@ -0,0 +1,79 @@ +from misc_util import orthogonal_init, xavier_uniform_init +import torch.nn as nn +import torch +import torch.nn.functional as F +import math +import numpy as np +import matplotlib.pyplot as plt +from a2c_ppo_acktr.utils import init +import traceback + +np.set_printoptions(threshold=10_000) +torch.set_printoptions(threshold=10_000) + +class prototypes(nn.Module): + def __init__(self, + input_size, hidden_size, num_prototypes, device): + super(prototypes, self).__init__() + self.num_prototypes = num_prototypes + self.input_size = input_size + self.hidden_size = hidden_size + self.device = device + self.layers1 = nn.ModuleList([nn.Sequential( + (nn.Linear(in_features=input_size, out_features=hidden_size, bias=False)), nn.ReLU(), + ) for i in range(num_prototypes)]) + self.layers2 = nn.ModuleList([nn.Sequential( + (nn.Linear(in_features=hidden_size, out_features=hidden_size,bias=False)), nn.ReLU(), + ) for i in range(num_prototypes)]) + + self.prototypes = nn.ParameterList([nn.Parameter(torch.randn(1, self.hidden_size) * 1.) for i in range(num_prototypes)]) + self.cos = nn.CosineSimilarity(dim=2, eps=1e-6) + + def forward(self, hidden, prototype_train): # obs = [600, 16, 1, 54, 64] + #print('all prototypes: ', len(self.prototypes)) # 8 + # print('hidden shape in forward prototype = ', hidden.shape) # hidden.shape = torch.Size([125, 16, 512]) + out1 = [None] * self.num_prototypes + cos_scores = [None] * self.num_prototypes + ortho = [None] * self.num_prototypes + success_inds = int(hidden.shape[1] / 2) + for i in range(self.num_prototypes): + out1[i] = self.layers2[i](self.layers1[i](hidden)) # hidden = length, minibatch, latent + s1, s2, s3 = out1[i].shape + #print('prototype shape=', self.prototypes[i].shape) # self.prototypes[i].shape = torch.Size([1, 1010])) + prototypes = self.prototypes[i].reshape(1, 1, -1).repeat(s1, 1, 1) + #print('in forward fun of prototype class: ', out1[i].shape, prototypes.shape) # out1[i].shape = torch.Size([125, 16, 1010]), prototypes.shape = torch.Size([125, 1, 1010]) + cos_scores[i] = self.cos(out1[i], prototypes) + #print('cos scores in prototype forward class: ', cos_scores[i].shape) # cos scores[i]: torch.Size([125, 16]) + ortho[i] = F.softmax(cos_scores[i].squeeze() * 100., dim=0) # length,minibatch,1 --> length,minibatch + + cos_scores = torch.stack(cos_scores, dim=2) # stacked cos scores: torch.Size([125, 16, 8]) + #print('stacked cos scores:', cos_scores.shape) + ortho_scores = torch.stack(ortho, dim=2) # length,minibatch,keys + cos_max, indices = torch.max(cos_scores, dim=0) # cos_max: torch.Size([16, 8]) + # cos_max = cos_max.squeeze() # minibatch,keys + loss_cos = ((torch.abs(1 - cos_max[:success_inds]).mean(0) + torch.abs( cos_max[success_inds:]).mean(0)).squeeze()) + #print('prototype train: ', prototype_train) = -1 + if prototype_train > -0.5: + loss_cos = loss_cos[prototype_train] + else: + loss_cos = loss_cos.sum() + #print('loss_cos: ', loss_cos) + ortho_scores = F.normalize(ortho_scores.permute(1, 0, 2), dim=1, p=2) + ortho_scores = torch.abs(torch.matmul(ortho_scores.permute(0, 2, 1), ortho_scores)) + ortho_scores_diag = torch.diagonal(ortho_scores, dim1=1, dim2=2) + loss_ortho = (ortho_scores[:, :, :])[:success_inds] - torch.diag_embed(ortho_scores_diag[:, :], dim1=1, dim2=2)[:success_inds] + loss_ortho = loss_ortho.sum() + costfinal = loss_cos * 1. + (loss_ortho * .2) /self.num_prototypes + success_scores = torch.abs(cos_max[:success_inds]).mean(0) + fail_scores = torch.abs(cos_max[success_inds:]).mean(0) + + return cos_max, indices, costfinal, cos_scores, [success_scores, fail_scores] + + + def get_prototype_data(self): + prototypes = {} + for i, param in enumerate(self.prototypes): + # Convert parameter to numpy array and flatten it + param_data = param.detach().cpu().numpy().flatten() # each prototype shape is (1010,) + prototypes['proto '+str(i)] = param_data + return prototypes \ No newline at end of file diff --git a/conspecfunction/Conspec/storageConSpec.py b/conspecfunction/Conspec/storageConSpec.py index 775a7f3..a53dff0 100644 --- a/conspecfunction/Conspec/storageConSpec.py +++ b/conspecfunction/Conspec/storageConSpec.py @@ -33,8 +33,10 @@ def __init__(self, num_steps, num_processes, obs_shape, action_space, action_shape = 1 self.actions = torch.zeros(num_steps, num_processes, action_shape) self.actions = self.actions.long() - self.masks = torch.ones(num_steps + 1, num_processes, 1) + self.max_indx = torch.zeros(num_processes, num_prototypes) # torch.Size([32, 8]) + self.cos_scores = torch.zeros(num_steps, num_processes, num_prototypes) # torch.Size([125, 32, 8]) + self.cos_max_scores= torch.zeros(num_processes, num_prototypes) # torch.Size([32, 8]) # Masks that indicate whether it's a true terminal state # or time limit end state @@ -50,7 +52,6 @@ def __init__(self, num_steps, num_processes, obs_shape, action_space, self.success_sample = 16 self.hidden_state_size = 256 - self.obs_batchS = torch.zeros(self.num_steps + 1, self.success, *self.obs_shape) self.r_batchS = torch.zeros(self.num_steps, self.success, 1) self.recurrent_hidden_statesS = torch.zeros(self.num_steps + 1, self.success, self.recurrent_hidden_state_size) @@ -58,6 +59,7 @@ def __init__(self, num_steps, num_processes, obs_shape, action_space, self.act_batchS = self.act_batchS.long() self.masks_batchS = torch.zeros(self.num_steps + 1, self.success, 1) self.stepS = 0 + self.obs_batchF = torch.zeros(self.num_steps + 1, self.success, *self.obs_shape) self.r_batchF = torch.zeros(self.num_steps, self.success, 1) self.recurrent_hidden_statesF = torch.zeros(self.num_steps + 1, self.success, self.recurrent_hidden_state_size) @@ -67,7 +69,6 @@ def __init__(self, num_steps, num_processes, obs_shape, action_space, self.stepF = 0 - self.obs_batch_frozen_S = [None] * self.num_prototypes self.r_batch_frozen_S = [None] * self.num_prototypes self.recurrent_hidden_statesbatch_frozen_S = [None] * self.num_prototypes @@ -99,6 +100,7 @@ def __init__(self, num_steps, num_processes, obs_shape, action_space, self.prototypesUsed = torch.zeros(self.num_prototypes,) self.count_prototypes_timesteps_criterion = torch.zeros(self.num_prototypes,) + def calc_total_reward(self, contrastval): self.rewardsORIG = torch.clone(self.rewards) self.rewards = self.rewards + contrastval.unsqueeze(-1) @@ -128,6 +130,7 @@ def store_frozen_SF(self, i): self.act_batch_frozen_F[i] = self.act_batchF self.masks_batch_frozen_F[i] = self.masks_batchF + def addPosNeg(self, S_or_F, device): '''this is the function for adding the trajectories to success (pos) and failure (neg) memory buffers ''' totalreward = self.rewards[-10:].sum(0) @@ -135,20 +138,25 @@ def addPosNeg(self, S_or_F, device): if S_or_F == 'pos': rewardssortgood = torch.nonzero(totalreward > 0.5).reshape(-1, ) indicesrewardbatch = rewardssortgood[0::2] + # print('pos: indicesrewardbatch', indicesrewardbatch) obsxx = self.obs[:, indicesrewardbatch].to(device) numberaddedxx = obsxx.shape[1] if numberaddedxx >1: indicesrewardbatch = rewardssortgood[0:4:2] + # print('pos: indicesrewardbatch', indicesrewardbatch) else: rewardssortbad = torch.nonzero(totalreward < 0.5).reshape(-1, ) indicesrewardbatch = rewardssortbad[0::2] + # print('neg: indicesrewardbatch', indicesrewardbatch) + obs = self.obs[:, indicesrewardbatch].to(device) rec = self.recurrent_hidden_states[:, indicesrewardbatch].to(device) masks = self.masks[:, indicesrewardbatch].to(device) act = self.actions[:, indicesrewardbatch].to(device) rew = self.rewards[:, indicesrewardbatch].to(device) + # cos = self.cos_scores[:, indicesrewardbatch].to(device) numberadded = obs.shape[1] - + # print('numberadded', numberadded) # print(obs.shape, rec.shape, masks.shape, act.shape, rew.shape) # ''' @@ -158,24 +166,33 @@ def addPosNeg(self, S_or_F, device): elif S_or_F == 'neg': numcareabout = self.stepF if numberadded + numcareabout <= self.obs_batchS.shape[1]: + # print('numberadded + numcareabout <= self.obs_batchS.shape[1]', numberadded, numcareabout, self.obs_batchS.shape[1]) if S_or_F == 'pos': self.obs_batchS[:, self.stepS:self.stepS + numberadded] = obs self.r_batchS[:, self.stepS:self.stepS + numberadded] = rew self.recurrent_hidden_statesS[:, self.stepS:self.stepS + numberadded] = rec self.act_batchS[:, self.stepS:self.stepS + numberadded] = act self.masks_batchS[:, self.stepS:self.stepS + numberadded] = masks + # print('add pos, stepS, stepS+numberadded, numberadded:', self.stepS, self.stepS + numberadded, numberadded) + # print(self.cos_score_pos.shape, cos.shape) + # self.cos_score_pos[:, self.stepS:self.stepS + numberadded] = cos self.stepS = (self.stepS + numberadded) + elif S_or_F == 'neg': self.obs_batchF[:, self.stepF:self.stepF + numberadded] = obs self.r_batchF[:, self.stepF:self.stepF + numberadded] = rew self.recurrent_hidden_statesF[:, self.stepF:self.stepF + numberadded] = rec self.act_batchF[:, self.stepF:self.stepF + numberadded] = act self.masks_batchF[:, self.stepF:self.stepF + numberadded] = masks + # print('add pos, stepF, stepF+numbertoadd, numbertoadd:', self.stepF, self.stepF + numbertoadd, numbertoadd) + # print(self.cos_score_neg.shape, cos.shape) + # self.cos_score_neg[:, self.stepF:self.stepF + numberadded] = cos self.stepF = (self.stepF + numberadded) #''' elif (numberadded + numcareabout >= self.obs_batchS.shape[1]) and ( numcareabout < self.obs_batchS.shape[1]): - + # print('numberadded + numcareabout >= self.obs_batchS.shape[1]', numberadded, numcareabout, self.obs_batchS.shape[1]) + if S_or_F == 'pos': numbertoadd = self.obs_batchS.shape[1] - self.stepS self.obs_batchS[:, self.stepS:self.stepS + numbertoadd, :] = obs[:, :numbertoadd] @@ -183,6 +200,9 @@ def addPosNeg(self, S_or_F, device): self.recurrent_hidden_statesS[:, self.stepS:self.stepS + numbertoadd] = rec[:, :numbertoadd] self.act_batchS[:, self.stepS:self.stepS + numbertoadd] = act[:, :numbertoadd] self.masks_batchS[:, self.stepS:self.stepS + numbertoadd] = masks[:, :numbertoadd] + # print('add pos:', self.stepS, self.stepS + numbertoadd, numbertoadd) + # print(self.cos_score_pos.shape, cos.shape) + # self.cos_score_pos[:, self.stepS:self.stepS + numbertoadd] = cos[:, :numbertoadd] self.stepS = (self.stepS + numbertoadd) elif S_or_F == 'neg': @@ -192,38 +212,51 @@ def addPosNeg(self, S_or_F, device): self.recurrent_hidden_statesF[:, self.stepF:self.stepF + numbertoadd] = rec[:, :numbertoadd] self.act_batchF[:, self.stepF:self.stepF + numbertoadd] = act[:, :numbertoadd] self.masks_batchF[:, self.stepF:self.stepF + numbertoadd] = masks[:, :numbertoadd] + # print('add neg:', self.stepF, self.stepF + numbertoadd, numbertoadd) + # print(self.cos_score_pos.shape, cos.shape) + # self.cos_score_neg[:, self.stepF:self.stepF + numbertoadd] = cos[:, :numbertoadd] self.stepF = (self.stepF + numbertoadd) - elif numcareabout == self.obs_batchS.shape[ - 1]: + elif numcareabout == self.obs_batchS.shape[1]: + # print('numcareabout == self.obs_batchS.shape[1]', numcareabout, self.obs_batchS.shape[1]) hidden_state = rec masks = masks if S_or_F == 'pos': lenconsider = obs.shape[1] - self.obs_batchS = torch.cat((self.obs_batchS , obs),1) - self.r_batchS = torch.cat((self.r_batchS , rew),1) - self.recurrent_hidden_statesS = torch.cat((self.recurrent_hidden_statesS , rec),1) - self.act_batchS = torch.cat((self.act_batchS , act),1) - self.masks_batchS = torch.cat((self.masks_batchS , masks),1) + self.obs_batchS = torch.cat((self.obs_batchS , obs),dim=1) + self.r_batchS = torch.cat((self.r_batchS , rew),dim=1) + self.recurrent_hidden_statesS = torch.cat((self.recurrent_hidden_statesS , rec),dim=1) + self.act_batchS = torch.cat((self.act_batchS , act),dim=1) + self.masks_batchS = torch.cat((self.masks_batchS , masks),dim=1) + # print('add pos:', lenconsider) + # print(self.cos_score_pos.shape, cos.shape) + # self.cos_score_pos = torch.cat((self.cos_score_pos, cos), dim=1) + self.obs_batchS = self.obs_batchS[:,lenconsider:] self.r_batchS = self.r_batchS[:,lenconsider:] self.recurrent_hidden_statesS = self.recurrent_hidden_statesS[:,lenconsider:] self.act_batchS = self.act_batchS[:,lenconsider:] self.masks_batchS = self.masks_batchS[:,lenconsider:] + # self.cos_score_pos = self.cos_score_pos[:,lenconsider:] elif S_or_F == 'neg': lenconsider = obs.shape[1] - self.obs_batchF = torch.cat((self.obs_batchF, obs), 1) - self.r_batchF = torch.cat((self.r_batchF, rew), 1) - self.recurrent_hidden_statesF = torch.cat((self.recurrent_hidden_statesF, rec),1) - self.act_batchF = torch.cat((self.act_batchF, act),1) - self.masks_batchF = torch.cat((self.masks_batchF, masks), 1) + self.obs_batchF = torch.cat((self.obs_batchF, obs), dim=1) + self.r_batchF = torch.cat((self.r_batchF, rew), dim=1) + self.recurrent_hidden_statesF = torch.cat((self.recurrent_hidden_statesF, rec),dim=1) + self.act_batchF = torch.cat((self.act_batchF, act),dim=1) + self.masks_batchF = torch.cat((self.masks_batchF, masks), dim=1) + # print('add neg:', lenconsider) + # print(self.cos_score_neg.shape, cos.shape) + # self.cos_score_neg = torch.cat((self.cos_score_neg, cos), dim=1) + self.obs_batchF = self.obs_batchF[:, lenconsider:] self.r_batchF = self.r_batchF[:, lenconsider:] self.recurrent_hidden_statesF = self.recurrent_hidden_statesF[:, lenconsider:] self.act_batchF = self.act_batchF[:, lenconsider:] self.masks_batchF = self.masks_batchF[:, lenconsider:] + # self.cos_score_neg = self.cos_score_neg[:, lenconsider:] def to(self, device): '''just adding cuda to all the memory buffers''' @@ -236,6 +269,7 @@ def to(self, device): self.actions = self.actions.to(device) self.masks = self.masks.to(device) self.bad_masks = self.bad_masks.to(device) + # self.cos_score_pos = self.cos_score_pos.to(device) self.obs_batchS = self.obs_batchS.to(device) self.r_batchS = self.r_batchS.to(device) @@ -247,17 +281,21 @@ def to(self, device): self.recurrent_hidden_statesF = self.recurrent_hidden_statesF.to(device) self.act_batchF = self.act_batchF.to(device) self.masks_batchF = self.masks_batchF.to(device) + # self.cos_score_neg = self.cos_score_neg.to(device) + for i in range(self.num_prototypes): self.obs_batch_frozen_S[i] = self.obs_batch_frozen_S[i].to(device) self.r_batch_frozen_S[i] = self.r_batch_frozen_S[i].to(device) self.recurrent_hidden_statesbatch_frozen_S[i] = self.recurrent_hidden_statesbatch_frozen_S[i].to(device) self.act_batch_frozen_S[i] = self.act_batch_frozen_S[i].to(device) self.masks_batch_frozen_S[i] = self.masks_batch_frozen_S[i].to(device) + self.obs_batch_frozen_F[i] = self.obs_batch_frozen_F[i].to(device) self.r_batch_frozen_F[i] = self.r_batch_frozen_F[i].to(device) self.recurrent_hidden_statesbatch_frozen_F[i] = self.recurrent_hidden_statesbatch_frozen_F[i].to(device) self.act_batch_frozen_F[i] = self.act_batch_frozen_F[i].to(device) self.masks_batch_frozen_F[i] = self.masks_batch_frozen_F[i].to(device) + def insert(self, obs, recurrent_hidden_states, actions, rewards, masks, bad_masks): self.obs[self.step + 1].copy_(obs) From 733ec84bd9d00cda54190dd4bf1a6a2749325a42 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 25 Mar 2024 16:10:56 -0400 Subject: [PATCH 07/15] adds conspec analysis file --- conspecfunction/analysis.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 conspecfunction/analysis.py diff --git a/conspecfunction/analysis.py b/conspecfunction/analysis.py new file mode 100644 index 0000000..e7fcd26 --- /dev/null +++ b/conspecfunction/analysis.py @@ -0,0 +1,30 @@ +import torch +import os + +def vis_proto_states(data_path, cos_path ): + + sf_buffer_obs = torch.load(data_path)['obs'] + cos_max_scores = torch.load(cos_path)['cos_max_scores'] + cos_max_indices = torch.load(cos_path)['max_indices'] + cos_scores = torch.load(cos_path)['cos_scores'] + + sf_buffer_obs = sf_buffer_obs.detach().cpu().numpy() + cos_max_scores = cos_max_scores.detach().cpu().numpy() + cos_max_indices = cos_max_indices.detach().cpu().numpy() + cos_scores = cos_scores.detach().cpu().numpy() + + print(sf_buffer_obs.shape, cos_max_scores.shape, cos_max_indices.shape, cos_scores.shape) + + + + + +if __name__ == "__main__": + base_directory = "data/kd3/" + data_path = 'conspec_rollouts_epoch_650.pth' + cos_sim_path = 'cos_sim_epoch_650.pth' + + data_full_path = os.path.join(base_directory, data_path) + cos_full_path = os.path.join(base_directory, cos_sim_path) + + vis_proto_states(data_full_path, cos_full_path) From ccb4984be4121da93e5dd09d33b5825941c00893 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 25 Mar 2024 18:37:24 -0400 Subject: [PATCH 08/15] visualize stats that maximally match the prototype --- conspecfunction/analysis.py | 115 +++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/conspecfunction/analysis.py b/conspecfunction/analysis.py index e7fcd26..4f1f53b 100644 --- a/conspecfunction/analysis.py +++ b/conspecfunction/analysis.py @@ -1,5 +1,7 @@ import torch import os +import numpy as np +import matplotlib.pyplot as plt def vis_proto_states(data_path, cos_path ): @@ -7,17 +9,112 @@ def vis_proto_states(data_path, cos_path ): cos_max_scores = torch.load(cos_path)['cos_max_scores'] cos_max_indices = torch.load(cos_path)['max_indices'] cos_scores = torch.load(cos_path)['cos_scores'] - + cos_score_proto = {} sf_buffer_obs = sf_buffer_obs.detach().cpu().numpy() cos_max_scores = cos_max_scores.detach().cpu().numpy() cos_max_indices = cos_max_indices.detach().cpu().numpy() cos_scores = cos_scores.detach().cpu().numpy() + sf_obs_reshaped = np.reshape(sf_buffer_obs, (cos_scores.shape[0], cos_scores.shape[1], *sf_buffer_obs.shape[1:])) + num_processes = cos_max_scores.shape[0] + num_prototypes = cos_max_scores.shape[1] + # fig, axes = plt.subplots(num_processes, num_prototypes, figsize=(15, 10)) + # axes = axes.flatten() + + fig, axes = plt.subplots(1, 32, figsize=(32 * 2, 2)) + + # print(sf_buffer_obs.shape, cos_max_scores.shape, cos_max_indices.shape, cos_scores.shape) + # print(cos_max_indices, cos_max_scores) + # Iterate over time steps and processes to find observations with maximum cosine similarity + + for prototype in range(num_prototypes): + cos_score_proto[prototype] = cos_scores[:,:,prototype] + indx = np.argmax(cos_score_proto[prototype], axis=0) + scores = np.max(cos_score_proto[prototype], axis=0) + obs_over_time = [] + for i in range(indx.shape[0]): + obs = sf_obs_reshaped[indx[i], i] + obs = np.transpose(obs, (1, 2, 0)) + obs_over_time.append(obs) + + # Iterate over the list of images + for i, image in enumerate(obs_over_time): + # Plot the i-th image + axes[i].imshow(image) + axes[i].axis('off') + plt.tight_layout() + plt.savefig("states_prototypes{}.png".format(prototype)) + + + # idx = num_prototypes * i + prototype + + # axes[idx].imshow(obs) + # # axes[idx].set_title(f"Prototype: {prototype}, Score: {scores}") + # axes[idx].axis('off') + # plt.savefig(f"states_prototypes.png") + + # fig, axes = plt.subplots(1, len(max_cosine_observation), figsize=(10, 2)) + # fig.suptitle(f"Time Step {time_step}, Process {process}") + + # for i, observation in enumerate(max_cosine_observation): + # axes[i].imshow(observation, cmap='gray') + # axes[i].axis('off') + # axes[i].set_title(f"Prototype {i + 1}") + + # plt.savefig(f"time_step_{time_step}_process_{process}.png") + # plt.close() # Close the figure to avoid displaying it + +def extract_observations(cosine_sim_idx_matrix, observation_matrix): + + # Example matrices + # cosine_similarity_matrix -> (32, 8) + # observation_matrix => (185, 32, 3, 5, 5) + + # Extract observations + extracted_observations = np.zeros((cosine_sim_idx_matrix.shape[0], cosine_sim_idx_matrix.shape[1], *observation_matrix.shape[2:])) + + for i in range(cosine_sim_idx_matrix.shape[0]): + for j in range(cosine_sim_idx_matrix.shape[1]): + idx = cosine_sim_idx_matrix[i, j] + observation = observation_matrix[idx, i] # Extract the observation + extracted_observations[i, j] = observation # Assig + + return extracted_observations + + +def plot_observations(observations): + # Number of rows and columns in the cosine similarity matrix + rows, cols = observations.shape[:2] + + fig, axs = plt.subplots(rows, cols, figsize=(cols * 2, rows * 2)) - print(sf_buffer_obs.shape, cos_max_scores.shape, cos_max_indices.shape, cos_scores.shape) + for i in range(rows): + for j in range(cols): + ax = axs[i, j] + obs = observations[i, j].transpose(1, 2, 0) # Adjust for color channel position + + if obs.max() > 1.0: # assuming the data should be in [0, 1] range + obs = obs / 255.0 # Normalize + + ax.imshow(obs, vmin=0, vmax=1) + ax.axis('off') + + plt.tight_layout() + plt.show() + plt.savefig(f"max_states.png") + +def vis_proto_max_state(obs, cos_score, indices, num_processes, num_prototypes): + dim= int(obs.shape[0]/num_processes) + sf_obs_reshaped = np.reshape(obs, (dim, num_processes, *sf_buffer_obs.shape[1:])) + # print(sf_obs_reshaped.shape) + maxx_indx = np.argmax(cos_max_scores, axis=0) + maxx_scores = np.max(cos_max_scores, axis=0) + # print(maxx_indx, maxx_scores) + extracted_obs = extract_observations(cos_max_indices, sf_obs_reshaped) + plot_observations(extracted_obs) if __name__ == "__main__": base_directory = "data/kd3/" @@ -27,4 +124,16 @@ def vis_proto_states(data_path, cos_path ): data_full_path = os.path.join(base_directory, data_path) cos_full_path = os.path.join(base_directory, cos_sim_path) - vis_proto_states(data_full_path, cos_full_path) + sf_buffer_obs = torch.load(data_full_path)['obs'] + cos_max_scores = torch.load(cos_full_path)['cos_max_scores'] + cos_max_indices = torch.load(cos_full_path)['max_indices'] + cos_scores = torch.load(cos_full_path)['cos_scores'] + + sf_buffer_obs = sf_buffer_obs.detach().cpu().numpy() + cos_max_scores = cos_max_scores.detach().cpu().numpy() + cos_max_indices = cos_max_indices.detach().cpu().numpy() + cos_scores = cos_scores.detach().cpu().numpy() + num_processes = cos_max_scores.shape[0] + num_prototypes = cos_max_scores.shape[1] + + vis_proto_max_state(sf_buffer_obs, cos_max_scores, cos_max_indices, num_processes, num_prototypes) From dcebc0d2857fd9d8dc837017bb51acdd3346f2d3 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Mon, 25 Mar 2024 22:15:51 -0400 Subject: [PATCH 09/15] makes visualization of prototype states --- conspecfunction/analysis.py | 201 +++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 74 deletions(-) diff --git a/conspecfunction/analysis.py b/conspecfunction/analysis.py index 4f1f53b..ed256b9 100644 --- a/conspecfunction/analysis.py +++ b/conspecfunction/analysis.py @@ -3,29 +3,19 @@ import numpy as np import matplotlib.pyplot as plt -def vis_proto_states(data_path, cos_path ): - - sf_buffer_obs = torch.load(data_path)['obs'] - cos_max_scores = torch.load(cos_path)['cos_max_scores'] - cos_max_indices = torch.load(cos_path)['max_indices'] - cos_scores = torch.load(cos_path)['cos_scores'] +def vis_proto_states(sf_buffer_obs, cos_scores): + ''' + plot the states that are matched with each prototype using cos scores and not max score + num_prototype figures each has num_processes images + ''' cos_score_proto = {} - sf_buffer_obs = sf_buffer_obs.detach().cpu().numpy() - cos_max_scores = cos_max_scores.detach().cpu().numpy() - cos_max_indices = cos_max_indices.detach().cpu().numpy() - cos_scores = cos_scores.detach().cpu().numpy() sf_obs_reshaped = np.reshape(sf_buffer_obs, (cos_scores.shape[0], cos_scores.shape[1], *sf_buffer_obs.shape[1:])) - num_processes = cos_max_scores.shape[0] - num_prototypes = cos_max_scores.shape[1] - # fig, axes = plt.subplots(num_processes, num_prototypes, figsize=(15, 10)) - # axes = axes.flatten() + num_prototypes = cos_scores.shape[2] + # axes = axes.flatten() fig, axes = plt.subplots(1, 32, figsize=(32 * 2, 2)) - # print(sf_buffer_obs.shape, cos_max_scores.shape, cos_max_indices.shape, cos_scores.shape) - # print(cos_max_indices, cos_max_scores) # Iterate over time steps and processes to find observations with maximum cosine similarity - for prototype in range(num_prototypes): cos_score_proto[prototype] = cos_scores[:,:,prototype] indx = np.argmax(cos_score_proto[prototype], axis=0) @@ -39,91 +29,147 @@ def vis_proto_states(data_path, cos_path ): # Iterate over the list of images for i, image in enumerate(obs_over_time): # Plot the i-th image + if image.max() > 1.0: # assuming the data should be in [0, 1] range + image = image / 255.0 # Normalize + elif image.max() > 1.0: + image = image.astype(np.uint8) + axes[i].imshow(image) axes[i].axis('off') + # set the title of each obs with cosine similarity + title = '' + if scores is not None: + score = scores[i] + title += f"Score: {score:.2f}" + axes[i].set_title(title) plt.tight_layout() plt.savefig("states_prototypes{}.png".format(prototype)) - # idx = num_prototypes * i + prototype - - # axes[idx].imshow(obs) - # # axes[idx].set_title(f"Prototype: {prototype}, Score: {scores}") - # axes[idx].axis('off') - # plt.savefig(f"states_prototypes.png") - - # fig, axes = plt.subplots(1, len(max_cosine_observation), figsize=(10, 2)) - # fig.suptitle(f"Time Step {time_step}, Process {process}") - - # for i, observation in enumerate(max_cosine_observation): - # axes[i].imshow(observation, cmap='gray') - # axes[i].axis('off') - # axes[i].set_title(f"Prototype {i + 1}") - - # plt.savefig(f"time_step_{time_step}_process_{process}.png") - # plt.close() # Close the figure to avoid displaying it - def extract_observations(cosine_sim_idx_matrix, observation_matrix): - - # Example matrices - # cosine_similarity_matrix -> (32, 8) - # observation_matrix => (185, 32, 3, 5, 5) - - # Extract observations - extracted_observations = np.zeros((cosine_sim_idx_matrix.shape[0], cosine_sim_idx_matrix.shape[1], *observation_matrix.shape[2:])) - - for i in range(cosine_sim_idx_matrix.shape[0]): - for j in range(cosine_sim_idx_matrix.shape[1]): - idx = cosine_sim_idx_matrix[i, j] - observation = observation_matrix[idx, i] # Extract the observation - extracted_observations[i, j] = observation # Assig + """ + Given matrices: + cosine_similarity_matrix -> (32, 8) or (8, ) + observation_matrix => (185, 32, 3, 5, 5) or (32, 8, 3, 5, 5) + """ + if cosine_sim_idx_matrix.ndim == 2: # When cosine similarity index matrix is 2D + num_time_steps = cosine_sim_idx_matrix.shape[0] + num_prototypes = cosine_sim_idx_matrix.shape[1] + + extracted_observations = np.zeros((num_time_steps, num_prototypes, *observation_matrix.shape[2:])) + for i in range(cosine_sim_idx_matrix.shape[0]): + for j in range(cosine_sim_idx_matrix.shape[1]): + idx = cosine_sim_idx_matrix[i, j] + observation = observation_matrix[idx, i] # Extract the observation + extracted_observations[i, j] = observation # Assign to the result + + elif cosine_sim_idx_matrix.ndim == 1: # When cosine similarity index matrix is 1D + num_prototypes = cosine_sim_idx_matrix.shape[0] + extracted_observations = np.zeros((num_prototypes, *observation_matrix.shape[2:])) + for j in range(num_prototypes): + idx = cosine_sim_idx_matrix[j] + observation = observation_matrix[idx, j] # Extract the observation + extracted_observations[j] = observation # Assign to the result return extracted_observations -def plot_observations(observations): - # Number of rows and columns in the cosine similarity matrix - rows, cols = observations.shape[:2] +def plot_observations(observations, scores, path, filename): + """ + Given matrices: + scores -> (32, 8) or (8, ) + observations => (32, 8, 3, 5, 5) or (8, 3, 5, 5) + """ + if scores.ndim == 2: + # Number of rows and columns in the cosine similarity matrix + rows, cols = observations.shape[:2] + print(rows, cols) + fig, axs = plt.subplots(rows, cols, figsize=(cols * 2, rows * 2)) + for i in range(rows): + for j in range(cols): + ax = axs[i, j] + obs = observations[i, j].transpose(1, 2, 0) # Adjust for color channel position + + if obs.max() > 1.0: # assuming the data should be in [0, 1] range + obs = obs / 255.0 # Normalize + # Convert to uint8 if data is of integer type but not uint8 + elif obs.max() > 1.0: + obs = obs.astype(np.uint8) + + + ax.imshow(obs, vmin=0, vmax=1) + ax.axis('off') + # add title with cosine similarity score + title = '' + if scores is not None: + score = scores[i, j] + title += f"Score: {score:.2f}" + ax.set_title(title) + plt.tight_layout() - fig, axs = plt.subplots(rows, cols, figsize=(cols * 2, rows * 2)) - - for i in range(rows): - for j in range(cols): - ax = axs[i, j] - obs = observations[i, j].transpose(1, 2, 0) # Adjust for color channel position - + elif scores.ndim == 1: + rows = observations.shape[0] + print(rows) + fig, axs = plt.subplots(rows, figsize=(rows * 2, rows)) + + for i in range(rows): + ax = axs[i] + obs = observations[i].transpose(1, 2, 0) # Adjust for color channel position if obs.max() > 1.0: # assuming the data should be in [0, 1] range obs = obs / 255.0 # Normalize + # Convert to uint8 if data is of integer type but not uint8 + elif obs.max() > 1.0: + obs = obs.astype(np.uint8) + ax.imshow(obs, vmin=0, vmax=1) ax.axis('off') + # add title with cosine similarity score + title = '' + if scores is not None: + score = scores[i] + title += f"Score: {score:.2f}, Prototype: {i}" + ax.set_title(title) + plt.tight_layout() + + # Create folder if it doesn't exist + if not os.path.exists(path): + os.makedirs(path) - plt.tight_layout() - plt.show() - plt.savefig(f"max_states.png") - - + # Save the figure + save_path = os.path.join(path, filename) + fig.savefig(save_path) + plt.close(fig) # Close the plot to free up memory + return save_path -def vis_proto_max_state(obs, cos_score, indices, num_processes, num_prototypes): +def vis_proto_max_state_processes(obs, max_cos_score, indices, num_processes, path, filename): + ''' + num_processes rows of num of prototype images, a figure of 32 x 8 + ''' + dim= int(obs.shape[0]/num_processes) + sf_obs_reshaped = np.reshape(obs, (dim, num_processes, *sf_buffer_obs.shape[1:])) + extracted_obs = extract_observations(indices, sf_obs_reshaped) + saved_file_path = plot_observations(extracted_obs, max_cos_score, path, filename) +def vis_proto_max_state(obs, max_cos_score, indices, num_processes, path, filename): dim= int(obs.shape[0]/num_processes) sf_obs_reshaped = np.reshape(obs, (dim, num_processes, *sf_buffer_obs.shape[1:])) - # print(sf_obs_reshaped.shape) - maxx_indx = np.argmax(cos_max_scores, axis=0) - maxx_scores = np.max(cos_max_scores, axis=0) - # print(maxx_indx, maxx_scores) - extracted_obs = extract_observations(cos_max_indices, sf_obs_reshaped) - plot_observations(extracted_obs) + extracted_obs = extract_observations(indices, sf_obs_reshaped) # (32, 8, 3, 5, 5) + maxx_score = np.max(max_cos_score, axis=0) # max over processes + maxx_index = np.argmax(max_cos_score, axis=0) + max_extracted_obs = extract_observations(maxx_index, extracted_obs) + saved_file_path = plot_observations(max_extracted_obs, maxx_score, path, filename) if __name__ == "__main__": + + ### Data loaded from key to door 3 envs base_directory = "data/kd3/" data_path = 'conspec_rollouts_epoch_650.pth' cos_sim_path = 'cos_sim_epoch_650.pth' - data_full_path = os.path.join(base_directory, data_path) cos_full_path = os.path.join(base_directory, cos_sim_path) - + ## Load the data sf_buffer_obs = torch.load(data_full_path)['obs'] cos_max_scores = torch.load(cos_full_path)['cos_max_scores'] cos_max_indices = torch.load(cos_full_path)['max_indices'] @@ -135,5 +181,12 @@ def vis_proto_max_state(obs, cos_score, indices, num_processes, num_prototypes): cos_scores = cos_scores.detach().cpu().numpy() num_processes = cos_max_scores.shape[0] num_prototypes = cos_max_scores.shape[1] - - vis_proto_max_state(sf_buffer_obs, cos_max_scores, cos_max_indices, num_processes, num_prototypes) + + figure_path = "data/kd3/figures/" + # filename = "max_states_kd3.png" + # vis_proto_max_state_processes(sf_buffer_obs, cos_max_scores, cos_max_indices, num_processes, figure_path, filename) + + # vis_proto_states(sf_buffer_obs, cos_scores) + + filename = "max_proto_1state_kd3.png" + vis_proto_max_state(sf_buffer_obs, cos_max_scores, cos_max_indices, num_processes, figure_path, filename) From 1b84c5e79c2fa99253e28a11757a4db52b4cd5f4 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Tue, 26 Mar 2024 17:19:45 -0400 Subject: [PATCH 10/15] collects data for gflownet --- conspecfunction/analysis.py | 32 ++++---- conspecfunction/collect_data.py | 126 +++++++++++++++++--------------- 2 files changed, 84 insertions(+), 74 deletions(-) diff --git a/conspecfunction/analysis.py b/conspecfunction/analysis.py index ed256b9..b08ca86 100644 --- a/conspecfunction/analysis.py +++ b/conspecfunction/analysis.py @@ -6,7 +6,9 @@ def vis_proto_states(sf_buffer_obs, cos_scores): ''' plot the states that are matched with each prototype using cos scores and not max score - num_prototype figures each has num_processes images + num_prototype figures each has num_processes images + sf_buffer_obs -> (185, 32, 3, 5, 5) : time steps, processes, channels, height, width + cos_scores -> (185, 32, 8) ''' cos_score_proto = {} sf_obs_reshaped = np.reshape(sf_buffer_obs, (cos_scores.shape[0], cos_scores.shape[1], *sf_buffer_obs.shape[1:])) @@ -121,7 +123,6 @@ def plot_observations(observations, scores, path, filename): elif obs.max() > 1.0: obs = obs.astype(np.uint8) - ax.imshow(obs, vmin=0, vmax=1) ax.axis('off') # add title with cosine similarity score @@ -138,7 +139,7 @@ def plot_observations(observations, scores, path, filename): # Save the figure save_path = os.path.join(path, filename) - fig.savefig(save_path) + plt.savefig(save_path) plt.close(fig) # Close the plot to free up memory return save_path @@ -164,16 +165,19 @@ def vis_proto_max_state(obs, max_cos_score, indices, num_processes, path, filena if __name__ == "__main__": ### Data loaded from key to door 3 envs - base_directory = "data/kd3/" - data_path = 'conspec_rollouts_epoch_650.pth' - cos_sim_path = 'cos_sim_epoch_650.pth' + base_directory = '/network/scratch/s/samieima/conspec_train/20240325-152802_key_to_door3_1_10000/' + + data_path = 'conspec_rollouts_epoch_9999.pth' + cos_sim_path = 'cos_sim_epoch_9999.pth' + data_full_path = os.path.join(base_directory, data_path) cos_full_path = os.path.join(base_directory, cos_sim_path) + ## Load the data - sf_buffer_obs = torch.load(data_full_path)['obs'] - cos_max_scores = torch.load(cos_full_path)['cos_max_scores'] - cos_max_indices = torch.load(cos_full_path)['max_indices'] - cos_scores = torch.load(cos_full_path)['cos_scores'] + sf_buffer_obs = torch.load(data_full_path)['obs'] # (185, 32, 3, 5, 5) + cos_max_scores = torch.load(cos_full_path)['cos_max_scores'] # (32, 8) + cos_max_indices = torch.load(cos_full_path)['max_indices'] # (32, 8) + cos_scores = torch.load(cos_full_path)['cos_scores'] # (185, 32, 8) sf_buffer_obs = sf_buffer_obs.detach().cpu().numpy() cos_max_scores = cos_max_scores.detach().cpu().numpy() @@ -182,11 +186,11 @@ def vis_proto_max_state(obs, max_cos_score, indices, num_processes, path, filena num_processes = cos_max_scores.shape[0] num_prototypes = cos_max_scores.shape[1] - figure_path = "data/kd3/figures/" - # filename = "max_states_kd3.png" - # vis_proto_max_state_processes(sf_buffer_obs, cos_max_scores, cos_max_indices, num_processes, figure_path, filename) + figure_path = "data/key_to_door3_10000/figures/" + filename = "max_states_key_to_door3_10000.png" + vis_proto_max_state_processes(sf_buffer_obs, cos_max_scores, cos_max_indices, num_processes, figure_path, filename) # vis_proto_states(sf_buffer_obs, cos_scores) - filename = "max_proto_1state_kd3.png" + filename = "max_proto_1state_key_to_door3_10000.png" vis_proto_max_state(sf_buffer_obs, cos_max_scores, cos_max_indices, num_processes, figure_path, filename) diff --git a/conspecfunction/collect_data.py b/conspecfunction/collect_data.py index be13027..f6444f8 100644 --- a/conspecfunction/collect_data.py +++ b/conspecfunction/collect_data.py @@ -4,40 +4,28 @@ import csv import pandas as pd import glob - -def collect_gfn_data_max_states(exp_name, epoch): - base_directory = "data" - full_path = os.path.join(base_directory, exp_name) - - # buffer_path = os.path.join(full_path, 'buffer_epoch_{}.pth'.format(epoch)) - sf_buffer = os.path.join(full_path, 'conspec_rollouts_epoch_{}.pth'.format(epoch)) - observations = torch.load(sf_buffer)['obs'] - # observations = torch.load(buffer_path)['obs'] - cos_path = os.path.join(full_path, 'cos_sim_epoch_{}.pth'.format(epoch)) - cos_sim_info = torch.load(cos_path) - cos_scores_max = cos_sim_info['cos_max_scores'].detach().cpu().numpy() - max_indices = cos_sim_info['max_indices'].detach().cpu().numpy() - print(observations.shape, cos_scores_max.shape) - # Number of batches - num_batches = cos_scores_max.shape[0] - num_similar = cos_scores_max.shape[1] +import argparse + + +def collect_gfn_data_max_states(sf_buffer_obs, cos_max_scores, max_indices, num_processes, num_prototypes, path, filename): + ''' + sf_buffer_obs: (185, 32, 3, 5, 5) + cos_max_scores: (32, 8) + max_indices: (32, 8) + num_processes: 8 + path: path to save the data + filename: name of the data + ''' cos_sim_threshold = 0.6 - num_prototypes = cos_scores_max.shape[1] data = [] cos_data = [] - default = (np.zeros((3,5,5)), -1) - state_prototypes = {0:default, 1:default, 2: default, 3: default, 4: default, 5:default, 6: default, 7:default} # prototype, states, cosine similarity - for group_idx in range(num_batches): - traj_proto = [] - cos_proto = [] + for process_idx in range(num_processes): + traj_proto, cos_proto = [], [] proto_active = False - for i in range(num_similar): - # Calculate the index in the flattened axes array - # ax_idx = group_idx * num_similar + i - - idx = max_indices[group_idx, i] - cos_sim = cos_scores_max[group_idx, i] + for i in range(num_prototypes): + idx = max_indices[process_idx, i] + cos_sim = cos_scores_max[process_idx, i] if cos_sim > cos_sim_threshold: proto_active = True else: @@ -47,18 +35,19 @@ def collect_gfn_data_max_states(exp_name, epoch): data.append(traj_proto) cos_data.append(cos_proto) - gfn_path = 'data/gfn/max_gfn_data_{}_{}.csv'.format(exp_name,epoch) - cos_path = 'data/gfn/max_cos_data_{}_{}.csv'.format(exp_name, epoch) + if not os.path.exists(path): + os.makedirs(path) + + # Save the figure + save_path = os.path.join(path, filename) # Write the data to a CSV file - with open(gfn_path, 'w', newline='') as file: + with open(f'{save_path}_binary_th_{cos_sim_threshold}.csv', 'w', newline='') as file: writer = csv.writer(file) - writer.writerow(['Prototype_' + str(i) for i in range(num_prototypes)]) + writer.writerow(['P_' + str(i) for i in range(num_prototypes)]) writer.writerows(data) - with open(cos_path, 'w', newline='') as file: + with open(f'{save_path}_cos.csv', 'w', newline='') as file: writer = csv.writer(file) writer.writerows(cos_data) - # print(state_prototypes) - return state_prototypes def collect_gfn_data(exp_name, epoch): @@ -114,13 +103,13 @@ def collect_gfn_data(exp_name, epoch): # print(state_prototypes) return state_prototypes -def merge_csv_files(exp_name, prefix, output_file): - # List all CSV files in the current directory - base_directory = "data/gfn/" - full_path = os.path.join(base_directory) +def merge_csv_files(base_path, prefix, postfix, output_file): + + full_path = os.path.join(base_path) # Combine all CSV files into a single DataFrame - file_list = glob.glob(full_path + "/{}_*.csv".format(prefix)) - print(file_list) + file_list = glob.glob(full_path + "{}_*_{}*.csv".format(prefix, postfix)) + num_files = len(file_list) + print(num_files) files = [f for f in file_list] combined_csv = pd.concat([pd.read_csv(file) for file in files], ignore_index=True) @@ -129,26 +118,43 @@ def merge_csv_files(exp_name, prefix, output_file): combined_csv.to_csv(output_file, index=False) - - if __name__ == "__main__": - exp_name_ktd2 = '20240228-031400_key_to_door2_1_1000' - exp_name_ktd3 = '20240319-193056_key_to_door3_1_5000' - exp_name_ktd4 = '20240229-011752_key_to_door4_1_3000' - exp_kd3_eval = '20240319-212006_key_to_door3_1_2500' - - for i in np.arange(1, 40, 1): - collect_gfn_data_max_states(exp_kd3_eval, i) + parser = argparse.ArgumentParser(description='Collect data for GFN') + parser.add_argument('--exp_name', type=str, default='20240325-152802_key_to_door3_1_10000', help='Experiment name') + parser.add_argument('--num_episodes', type=int, default=10000, help='Epoch number') + parser.add_argument('--cos_sim_threshold', type=float, default=0.6, help='Cosine similarity threshold') + parser.add_argument('--merge_data', action='store_true', default=False, help='if you are merging the csv files') + parser.add_argument('--output_file', type=str, default='merged_binary_kd3_10k_0.6.csv', help='Output file name') + parser.add_argument('--output_csv_files_prefix', type=str, default='gfn_kd3_10k_', help='Output cosine csv file name') + args = parser.parse_args() + base_directory = '/network/scratch/s/samieima/conspec_train/20240325-152802_key_to_door3_1_10000/' + + if args.merge_data == False: + for i in range(args.num_episodes): + if i == 0: + continue + data_path = f'conspec_rollouts_epoch_{i}.pth' + cos_sim_path = f'cos_sim_epoch_{i}.pth' + data_full_path = os.path.join(base_directory, data_path) + cos_full_path = os.path.join(base_directory, cos_sim_path) + + sf_buffer = torch.load(data_full_path)['obs'] + cos_sim_info = torch.load(cos_full_path) + cos_scores_max = cos_sim_info['cos_max_scores'].detach().cpu().numpy() + max_index = cos_sim_info['max_indices'].detach().cpu().numpy() + num_processes = cos_scores_max.shape[0] + num_prototypes = cos_scores_max.shape[1] + + + csv_path = '/network/scratch/s/samieima/conspec_train/20240325-152802_key_to_door3_1_10000/csv_files/' + filename = f'gfn_kd3_10k_{i}' + collect_gfn_data_max_states(sf_buffer, cos_scores_max, max_index, num_processes, num_prototypes, csv_path, filename) + + elif args.merge_data == True: + csv_path = 'csv_files/' + merge_csv_files(f'{base_directory}{csv_path}', 'gfn_kd3_10k_', 'binary', 'merged_binary_kd3_10k_0.6.csv') + # merge_csv_files(f'{base_directory}{csv_path}', 'gfn_kd3_10k_', 'cos', 'merged_cosine_kd3_10k_0.6.csv') - # merge_csv_files(exp_name_ktd3, 'max_gfn_data_{}'.format(exp_name_ktd3), 'merged_rollouts_kd3_5k_odds.csv') - - # collect_gfn_data_max_states(exp_name_ktd3, 1499) - # collect_gfn_data_max_states(exp_name_ktd3, 1599) - # collect_gfn_data_max_states(exp_name_ktd3, 1699) - # collect_gfn_data_max_states(exp_name_ktd3, 1799) - # collect_gfn_data_max_states(exp_name_ktd3, 1899) - # collect_gfn_data_max_states(exp_name_ktd3, 1999) - From c028cceeb1be27a27ace8e8a02446df5064aa005 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Tue, 26 Mar 2024 17:21:14 -0400 Subject: [PATCH 11/15] updates main to collect checkpoints and adds evaluation --- conspecfunction/main.py | 43 +++++++++++++++++++++--------------- conspecfunction/main_eval.py | 16 ++++++-------- conspecfunction/misc_util.py | 2 ++ conspecfunction/run.sh | 8 +++---- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/conspecfunction/main.py b/conspecfunction/main.py index 92ee243..832770c 100644 --- a/conspecfunction/main.py +++ b/conspecfunction/main.py @@ -22,9 +22,10 @@ from six.moves import range from six.moves import zip import tensorflow.compat.v1 as tf -# from data_collection import collect_gfn_data, read_data, get_cosine_similarity, visualize -import pickle import datetime +import pdb +# from moviepy.editor import ImageSequenceClip + ''' The code below is nearly identical to https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail @@ -38,8 +39,8 @@ def main(): # Create the folder for results timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") - subfolder_name = f"{timestamp}_{args.pycolab_game}_{args.seed}_{args.num_episodes}" - base_directory = "data" + subfolder_name = f"{timestamp}_{args.pycolab_game}_{args.seed}_{args.num_episodes}_{args.num_prototypes}_{args.num_processes}" + base_directory = '/network/scratch/s/samieima/conspec_train' full_path = os.path.join(base_directory, subfolder_name) os.makedirs(full_path, exist_ok=True) @@ -51,10 +52,10 @@ def main(): wandb_project_name = 'conspec' #wandb.init(project=wandb_project_name) - proj_name = str(args.pycolab_game) +' seed'+ str(args.seed)+ ' episodes'+ str(args.num_episodes) + proj_name = str(args.pycolab_game) +' seed'+ str(args.seed)+ ' episodes'+ str(args.num_episodes)+ ' prototype' + str(args.num_prototypes)+ ' num_processes' + str(args.num_processes) logger = Logger( exp_name=proj_name, - save_dir='/home/mila/s/samieima/scratch/conspec', + save_dir='/network/scratch/s/samieima/conspec_train', print_every=1, save_every=args.log_interval, total_step=args.num_episodes, @@ -140,13 +141,13 @@ def main(): episode_rewards = deque(maxlen=10) num_updates = int(args.num_env_steps) // args.num_steps // args.num_processes - ##retrieving memories from the success/failure buffers - all_memories = [] logger.start() + env_frames = {i: [] for i in range(args.num_processes)} # to make a video of training + for episode in range(args.num_episodes): logger.step() obs, _ = envs.reset() - obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) + obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) #torch.Size([num_processes, 3, 5, 5]) rollouts.obs[0].copy_(obs) donetotal = np.zeros((args.num_processes,)) # .to(device) if args.use_linear_lr_decay: @@ -171,6 +172,12 @@ def main(): bad_masks = masks rollouts.insert(obs, recurrent_hidden_states, action, action_log_prob, value, reward, masks, bad_masks) + + for i in range(args.num_processes): + vobs = obs[i].cpu().detach().numpy() + vobs = vobs.transpose(1, 2, 0) + env_frames[i].append(vobs) + with torch.no_grad(): next_value = actor_critic.get_value( @@ -197,6 +204,7 @@ def main(): rollouts.compute_returns(next_value, args.use_gae, args.gamma, args.gae_lambda, args.use_proper_time_limits) + print('epoch', episode) value_loss, action_loss, dist_entropy= agent.update(rollouts) rollouts.after_update() @@ -207,7 +215,7 @@ def main(): logger.meter("results", "value_loss", value_loss) logger.meter("results", "action_loss", action_loss) - if episode > args.start_checkpoint and (episode+1) % args.checkpoint_interval == 0: + if episode > args.start_checkpoint and (episode) % args.checkpoint_interval == 0: buffer = { 'obs': rollouts.obs, 'rewards': rollouts.rewards, @@ -227,9 +235,8 @@ def main(): 'bad_masks': sf_buffer[2], 'value_preds': sf_buffer[4], } - # print(type(conspecfunction.prototypes)) tensor_proto_list = [p.data for p in conspecfunction.prototypes.prototypes] - checkpoint = { + model_checkpoint = { 'epoch': episode, 'encoder_state_dict': conspecfunction.encoder.state_dict(), 'actor_critic_state_dict': actor_critic.state_dict(), @@ -247,13 +254,14 @@ def main(): } print('saving checkpoints....') - checkpoint_path = os.path.join(full_path, f'checkpoint_epoch_{episode}.pth') + checkpoint_path = os.path.join(full_path, f'model_checkpoint_epoch_{episode}.pth') buffer_path = os.path.join(full_path, f'buffer_epoch_{episode}.pth') conspec_rollouts_path = os.path.join(full_path, f'conspec_rollouts_epoch_{episode}.pth') cos_path = os.path.join(full_path, f'cos_sim_epoch_{episode}.pth') + - torch.save(checkpoint, checkpoint_path) - print('checkpoint saved') + torch.save(model_checkpoint, checkpoint_path) + print('model checkpoint saved') torch.save(buffer, buffer_path) print('buffer saved') @@ -264,9 +272,8 @@ def main(): torch.save(cos_checkpoint, cos_path) print('cosine similarity saved') - - # pickle data files - + frams_dict_path = os.path.join(full_path, f'env_frames.npz') + np.savez(frams_dict_path, **env_frames) logger.finish() diff --git a/conspecfunction/main_eval.py b/conspecfunction/main_eval.py index dbaf5f5..7baf984 100644 --- a/conspecfunction/main_eval.py +++ b/conspecfunction/main_eval.py @@ -25,11 +25,9 @@ # from data_collection import collect_gfn_data, read_data, get_cosine_similarity, visualize import pickle import datetime +from pathlib import Path + -''' -The code below is nearly identical to https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail -With only minor additions of ConSpec-specific operations that have been commented ######## -''' def main_eval(): args = get_args() @@ -37,9 +35,9 @@ def main_eval(): torch.cuda.manual_seed_all(args.seed) # Create the folder for results - timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + timestamp = datetime.datetime.now().strftime("%Y%m%d") subfolder_name = f"{timestamp}_{args.pycolab_game}_{args.seed}_{args.num_episodes}" - base_directory = "data" + base_directory = '/network/scratch/s/samieima/conspec_eval' full_path = os.path.join(base_directory, subfolder_name) os.makedirs(full_path, exist_ok=True) @@ -54,7 +52,7 @@ def main_eval(): proj_name = str(args.pycolab_game) +' seed'+ str(args.seed)+ ' episodes'+ str(args.num_episodes) logger = Logger( exp_name=proj_name, - save_dir='/home/mila/s/samieima/scratch/conspec', + save_dir='/network/scratch/s/samieima/conspec_eval', print_every=1, save_every=args.log_interval, total_step=args.num_episodes, @@ -208,13 +206,13 @@ def main_eval(): rollouts.after_update() - if episode % args.log_interval == 0 and len(episode_rewards) > 1: + if episode % args.log_interval == 0 and len(episode_rewards) > 0: logger.meter("results", "R", rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy()) logger.meter("results", "dist_entropy", dist_entropy) logger.meter("results", "value_loss", value_loss) logger.meter("results", "action_loss", action_loss) - if episode > args.start_checkpoint and (episode+1) % args.checkpoint_interval == 0: + if episode > args.start_checkpoint and (episode) % args.checkpoint_interval == 0: buffer = { 'obs': rollouts.obs, 'rewards': rollouts.rewards, diff --git a/conspecfunction/misc_util.py b/conspecfunction/misc_util.py index c0a4238..ab3c7d6 100644 --- a/conspecfunction/misc_util.py +++ b/conspecfunction/misc_util.py @@ -4,6 +4,8 @@ import torch import torch.nn as nn +def serialize_object(obj): + return {attr: getattr(obj, attr) for attr in dir(obj) if not attr.startswith('__') and not callable(getattr(obj, attr))} def set_global_seeds(seed): torch.manual_seed(seed) diff --git a/conspecfunction/run.sh b/conspecfunction/run.sh index 651228a..28458cd 100755 --- a/conspecfunction/run.sh +++ b/conspecfunction/run.sh @@ -4,9 +4,9 @@ #SBATCH --mem=16GB #SBATCH --time=24:00:00 #SBATCH --cpus-per-task=8 -#SBATCH --output=sbatch_out/conspec_key_to_door4_train.%A.%a.out -#SBATCH --error=sbatch_err/conspec_key_to_door4_train.%A.%a.err -#SBATCH --job-name=conspec_key_to_door4_train +#SBATCH --output=sbatch_out/conspec_key_to_door3_train.%A.%a.out +#SBATCH --error=sbatch_err/conspec_key_to_door3_train.%A.%a.err +#SBATCH --job-name=conspec_key_to_door3_train echo "Date: $(date)" @@ -17,6 +17,6 @@ conda activate py37tf15 # Stage dataset into $SLURM_TMPDIR -python -u main.py --pycolab_game key_to_door4 --num_episodes 10000 --seed 1 --num-processes 32 --checkpoint_interval 1 --start_checkpoint 0 +python -u main.py --pycolab_game key_to_door4 --num_episodes 10000 --seed 1 --num-processes 32 --num_prototypes 6 --checkpoint_interval 1 --start_checkpoint 0 From f2e11621ca61e7de6b69b09166b8eee7434c8d6e Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Tue, 26 Mar 2024 17:22:17 -0400 Subject: [PATCH 12/15] updates conspec --- conspecfunction/Conspec/ConSpec.py | 70 ++++++++++++++++------ conspecfunction/Conspec/loss.py | 66 -------------------- conspecfunction/a2c_ppo_acktr/arguments.py | 30 ++++++++-- conspecfunction/a2c_ppo_acktr/storage.py | 4 +- conspecfunction/misc.py | 65 +++++++++++++++++++- 5 files changed, 142 insertions(+), 93 deletions(-) delete mode 100644 conspecfunction/Conspec/loss.py diff --git a/conspecfunction/Conspec/ConSpec.py b/conspecfunction/Conspec/ConSpec.py index 226083b..a9951b4 100644 --- a/conspecfunction/Conspec/ConSpec.py +++ b/conspecfunction/Conspec/ConSpec.py @@ -1,12 +1,13 @@ -import numpy +import numpy as np import torch import torch.nn.functional as F import torch.nn as nn from torch.utils.data.sampler import BatchSampler, SubsetRandomSampler import torch.optim as optim from .storageConSpec import RolloutStorage -from .loss import prototypes +from .prototype import prototypes from .modelConSpec import EncoderConSpec +import matplotlib.pyplot as plt @@ -60,28 +61,39 @@ def store_memories(self,image_to_store, memory_to_store, action_to_store, reward self.rollouts.insert_trajectory_batch(image_to_store, memory_to_store, action_to_store, reward_to_store, masks_to_store) # self.rollouts.to(self.device) self.rollouts.addPosNeg('pos', self.device) ###add to the positive memory buffer - self.rollouts.addPosNeg('neg', self.device)###add to the negative memory buffer + self.rollouts.addPosNeg('neg', self.device) ###add to the negative memory buffer def calc_cos_scores(self,obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, prototype_number): '''computes the cosine similarity scores''' - hidden = self.encoder.retrieve_hiddens(obs_batch, recurrent_hidden_states_batch,masks_batch, actions_batch) + #print(obs_batch.shape) -> torch.Size([2000, 3, 5, 5]) + hidden = self.encoder.retrieve_hiddens(obs_batch, recurrent_hidden_states_batch, masks_batch) + #print('in cos scores in Conspec', hidden.shape) # hidden.shape after encoder is torch.Size([2000, 512]) + #print('in cose scores in Conspec', hidden.view(*obs_batchorig.size()[:2], -1).shape, obs_batchorig.shape) + # hidden.view(*obs_batchorig.size()[:2], -1).shape = torch.Size([125, 16, 512]) + # obs_batchorig.shape = torch.Size([125, 16, 3, 5, 5]) + #print('prototype number in cos scores in Conspec', prototype_number) => -1 return self.prototypes(hidden.view(*obs_batchorig.size()[:2], -1), prototype_number) def calc_intrinsic_reward(self): '''computes the intrinsic reward for the current minibatch of trajectories''' prototypes_used, count_prototypes_timesteps_criterion = self.rollouts.retrieve_prototypes_used() prototypes_used = prototypes_used.to(device=self.device) + #print('calc intrisic reward proto used',prototypes_used ) with torch.no_grad(): obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = self.rollouts.retrieve_batch() - _, cos_scores, _ = self.calc_cos_scores(obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, -1) + _, _, _, cos_scores, _ = self.calc_cos_scores(obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, -1) + #print('in calc intrisic cos scores shape before reshape', cos_scores.shape) # torch.Size([125, 16, 8]) 10 is the number of prototypes cos_scores = cos_scores.view(*obs_batchorig.size()[:2], -1) # length, minibatch, keyhead + #print('cos score after reshape:', cos_scores.shape) # torch.Size([125, 32, 8]) cos_scores = ((cos_scores > 0.6)) * cos_scores - prototypes_used = torch.tile(torch.reshape(prototypes_used, (1, 1, -1)), (*cos_scores.shape[:2], 1)) + prototypes_used = torch.tile(torch.reshape(prototypes_used, (1, 1, -1)), (*cos_scores.shape[:2], 1)) # + prototypes_used = prototypes_used * self.intrinsicR_scale + intrinsic_reward = (cos_scores * prototypes_used) roundhalf = 3 - '''find the max rewrads in each rollng average (equation 2 of the manuscript)''' + '''find the max rewrads in each rolling average (equation 2 of the manuscript)''' rolling_max = [] for i in range(roundhalf * 2 + 1): temp = torch.roll(intrinsic_reward, i - roundhalf, dims=0) @@ -107,29 +119,49 @@ def calc_intrinsic_reward(self): def update_conspec(self): '''trains the ConSpec module''' prototypes_used, count_prototypes_timesteps_criterion = self.rollouts.retrieve_prototypes_used() - wwtotalpos = [] - wwtotalneg = [] - attentionCL = [] + # wwtotalpos = [] + # wwtotalneg = [] + # attentionCL = [] + cos_scores_pos = [] + cos_scores_neg = [] costCL = 0 if self.rollouts.stepS > self.rollouts.success - 1: ######################## for j in range(self.num_prototypes): if prototypes_used[j] > 0.5: + print('prototypes used', j, prototypes_used[j]) obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = self.rollouts.retrieve_SFbuffer_frozen( j) else: + print('still using SF buffer not the frozen one') obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = self.rollouts.retrieve_SFbuffer() - costCL0, attentionCL0, ww = self.calc_cos_scores(obs_batch, recurrent_hidden_states_batch, masks_batch, - actions_batch, obs_batchorig, j) - cossimtotalmaxxx, _ = (torch.max(attentionCL0, dim=0)) - attentionCL.append(attentionCL0[:, :, j].squeeze().transpose(1, 0)) - costCL += costCL0 - wwtotalpos.append(ww[0][j].detach().cpu()) - wwtotalneg.append(ww[1][j].detach().cpu()) + cos_max_score, max_inds, cost_prototype, cos_scores, cos_score_sf = self.calc_cos_scores(obs_batch, recurrent_hidden_states_batch, masks_batch, + actions_batch, obs_batchorig, j) + # self.rollouts.cos_scores = cos_scores # torch.Size([125, 16, 8]) + # _, costCL0, attentionCL0, ww = self.calc_cos_scores(obs_batch, recurrent_hidden_states_batch, masks_batch, + # actions_batch, obs_batchorig, j) + + # cossimtotalmaxxx, _ = (torch.max(attentionCL0, dim=0)) + # attentionCL.append(attentionCL0[:, :, j].squeeze().transpose(1, 0)) + # costCL += costCL0 + # wwtotalpos.append(ww[0][j].detach().cpu()) + # wwtotalneg.append(ww[1][j].detach().cpu()) + + costCL += cost_prototype + cos_scores_pos.append(cos_score_sf[0][j].detach().cpu()) # torch.Size([16, 8]) + cos_scores_neg.append(cos_score_sf[1][j].detach().cpu()) # torch.Size([16, 8]) + self.rollouts.cos_max_scores = cos_max_score + self.rollouts.max_indx = max_inds + self.rollouts.cos_scores = cos_scores + # self.rollouts.cos_score_pos = cos_score_sf[0] + # self.rollouts.cos_score_neg = cos_score_sf[1] for i in range(self.num_prototypes): - if (wwtotalpos[i] - wwtotalneg[i] > 0.6) and wwtotalpos[i] > 0.6: + # if (wwtotalpos[i] - wwtotalneg[i] > 0.6) and wwtotalpos[i] > 0.6: + #print('hereeee', cos_scores_pos[i], cos_scores_neg[i], cos_scores_pos[i] - cos_scores_neg[i]) + + if (cos_scores_pos[i] - cos_scores_neg[i] > 0.6) and cos_scores_pos[i] > 0.6: count_prototypes_timesteps_criterion[i] += 1 else: count_prototypes_timesteps_criterion[i] = 0 @@ -148,3 +180,5 @@ def do_everything(self, obstotal, recurrent_hidden_statestotal, actiontotal,rew rewardtotal_intrisic_extrinsic = self.calc_intrinsic_reward() self.update_conspec() return rewardtotal_intrisic_extrinsic + + diff --git a/conspecfunction/Conspec/loss.py b/conspecfunction/Conspec/loss.py deleted file mode 100644 index 56f4ae8..0000000 --- a/conspecfunction/Conspec/loss.py +++ /dev/null @@ -1,66 +0,0 @@ -from misc_util import orthogonal_init, xavier_uniform_init -import torch.nn as nn -import torch -import torch.nn.functional as F -import math -import numpy as np -import matplotlib.pyplot as plt -from a2c_ppo_acktr.utils import init -import traceback - -np.set_printoptions(threshold=10_000) -torch.set_printoptions(threshold=10_000) - -class prototypes(nn.Module): - def __init__(self, - input_size, hidden_size, num_prototypes, device): - super(prototypes, self).__init__() - self.num_prototypes = num_prototypes - self.input_size = input_size - self.hidden_size = hidden_size - self.device = device - self.layers1 = nn.ModuleList([nn.Sequential( - (nn.Linear(in_features=input_size, out_features=hidden_size, bias=False)), nn.ReLU(), - ) for i in range(num_prototypes)]) - self.layers2 = nn.ModuleList([nn.Sequential( - (nn.Linear(in_features=hidden_size, out_features=hidden_size,bias=False)), nn.ReLU(), - ) for i in range(num_prototypes)]) - - self.prototypes = nn.ParameterList([nn.Parameter( - torch.randn(1, self.hidden_size) * 1.) for i - in range(num_prototypes)]) - self.cos = nn.CosineSimilarity(dim=2, eps=1e-6) - - def forward(self, hidden, prototype_train): # obs = [600, 16, 1, 54, 64 - out1 = [None] * self.num_prototypes - cos_scores = [None] * self.num_prototypes - ortho = [None] * self.num_prototypes - success_inds = int(hidden.shape[1] / 2) - for i in range(self.num_prototypes): - out1[i] = self.layers2[i](self.layers1[i](hidden)) # hidden = length, minibatch, latent - s1, s2, s3 = out1[i].shape - prototypes = self.prototypes[i].reshape(1, 1, -1).repeat(s1, 1, 1) - cos_scores[i] = self.cos(out1[i], prototypes) - ortho[i] = F.softmax(cos_scores[i].squeeze() * 100., dim=0) # length,minibatch,1 --> length,minibatch - - cos_scores = torch.stack(cos_scores, dim=2) - ortho_scores = torch.stack(ortho, dim=2) # length,minibatch,keys - cos_max, _ = (torch.max(cos_scores, dim=0)) - cos_max = cos_max.squeeze() # minibatch,keys - loss_cos = ((torch.abs(1 - cos_max[:success_inds]).mean(0) + torch.abs( cos_max[success_inds:]).mean(0)).squeeze()) - if prototype_train > -0.5: - loss_cos = loss_cos[prototype_train] - else: - loss_cos = loss_cos.sum() - ortho_scores = F.normalize(ortho_scores.permute(1, 0, 2), dim=1, p=2) - ortho_scores = torch.abs(torch.matmul(ortho_scores.permute(0, 2, 1), ortho_scores)) - ortho_scores_diag = torch.diagonal(ortho_scores, dim1=1, dim2=2) - loss_ortho = (ortho_scores[:, :, :])[:success_inds] - torch.diag_embed(ortho_scores_diag[:, :], dim1=1, dim2=2)[:success_inds] - loss_ortho = loss_ortho.sum() - costfinal = loss_cos * 1. + (loss_ortho * .2) /self.num_prototypes - success_scores = torch.abs(cos_max[:success_inds]).mean(0) - fail_scores = torch.abs(cos_max[success_inds:]).mean(0) - - return costfinal, cos_scores, [success_scores, fail_scores] - - diff --git a/conspecfunction/a2c_ppo_acktr/arguments.py b/conspecfunction/a2c_ppo_acktr/arguments.py index 4107004..a7663e8 100644 --- a/conspecfunction/a2c_ppo_acktr/arguments.py +++ b/conspecfunction/a2c_ppo_acktr/arguments.py @@ -16,7 +16,7 @@ def get_args(): default=8, help='') parser.add_argument( - '--lrConSpec', type=float, default=20e-4, help='learning rate (default: 7e-4)') + '--lrConSpec', type=float, default=2e-3, help='learning rate (default: 7e-4)') parser.add_argument( '--intrinsicR_scale', type=float, @@ -28,8 +28,15 @@ def get_args(): parser.add_argument( '--pycolab_game', - default='key_to_door4', - help='key_to_door4, key_to_door2, key_to_door3, ') + default='key_to_door3', + help='key_to_door4, key_to_door2, key_to_door3') + + parser.add_argument( + '--num_episodes', + type=int, + default=1000, + help='500 for 2 key, 1000 for 3 keys, 2000 for 4 keys') + parser.add_argument( '--pycolab_apple_reward_min', type=float, @@ -143,7 +150,7 @@ def get_args(): parser.add_argument( '--num-processes', type=int, - default=16, + default=8, help='how many training CPU processes to use (default: 16)') parser.add_argument( '--num-steps', @@ -180,11 +187,22 @@ def get_args(): type=int, default=None, help='eval interval, one eval per n updates (default: None)') + + parser.add_argument( + '--start_checkpoint', + type=int, + default=500, + help='checkpoint interval, one eval per n updates (default: None)') + parser.add_argument( + '--checkpoint_interval', + type=int, + default=100, + help='checkpoint interval, one eval per n updates (default: None)') parser.add_argument( '--num-env-steps', type=int, - default=10e8, - help='number of environment steps to train (default: 10e6)') + default=10e6, + help='number of environment steps to train (default: 10e6-8)') parser.add_argument( '--env-name', default='PongNoFrameskip-v4', diff --git a/conspecfunction/a2c_ppo_acktr/storage.py b/conspecfunction/a2c_ppo_acktr/storage.py index 2a85cf1..84e258a 100644 --- a/conspecfunction/a2c_ppo_acktr/storage.py +++ b/conspecfunction/a2c_ppo_acktr/storage.py @@ -54,12 +54,12 @@ def retrieveR(self): def retrieveobs(self): return self.obs - def retrieveeverything(self): + def retrieveeverything(self): ### !!! This function doesn't work return torch.cat((self.obs_batchS, self.obs_batchF), dim=1), torch.cat((self.r_batchS, self.r_batchF), dim=1), torch.cat( (self.masks_batchS, self.masks_batchF), dim=1), torch.cat((self.act_batchS, self.act_batchF), dim=1) - def retrieveRS(self): + def retrieveRS(self):## this too! return self.r_batchS, self.r_batchF diff --git a/conspecfunction/misc.py b/conspecfunction/misc.py index 20a73b4..fcc20c8 100644 --- a/conspecfunction/misc.py +++ b/conspecfunction/misc.py @@ -5,6 +5,8 @@ from datetime import datetime import torch.nn as nn import numpy as np +import matplotlib.pyplot as plt +from moviepy.editor import ImageSequenceClip def makedir(path): if not os.path.exists(path): @@ -13,6 +15,67 @@ def makedir(path): else: print(path, "already exist!") +def serialize_object(obj): + return {attr: getattr(obj, attr) for attr in dir(obj) if not attr.startswith('__') and not callable(getattr(obj, attr))} + +def visuali_obs(batch_env): + # Assuming batch_env is your BatchEnv instance + # and it has a method get_observations() that returns a list of observations + observations = batch_env.reset() + + # Number of environments + num_envs = len(observations) + + # Create subplots + fig, axes = plt.subplots(1, num_envs, figsize=(num_envs * 5, 5)) + + for i, obs in enumerate(observations): + ax = axes[i] + ax.imshow(obs) # Replace this with appropriate plotting code for your observations + ax.set_title(f"Environment {i+1}") + plt.savefig('observation.png') + wandb.log({"observation Plot": wandb.Image('observation.png')}) + +def vis_prototypes(conspec, args): + import time + current_time = time.strftime("%H:%M:%S") + prototypes_used, frequencies = conspec.rollouts.retrieve_prototypes_used() + print('prototypes_used', prototypes_used) + print('frequencies', frequencies) + + # obs = obs_batch[:, :, :3, :, :] + # o1, o2, o3, o4, o5 = obs.shape + + num_success_samples = conspec.rollouts.success_sample + ##obs = [600, 16, 1, 54, 64] + + for i in range(conspec.num_prototypes): # indtop5.size()[0]): # top5 + obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = conspec.rollouts.retrieve_SFbuffer_frozen(i) + cos_sim_total_max, cost_prototype, cos_scores, Ù€ = conspec.calc_cos_scores(obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, i) + cos_max, indmaxes0 = torch.max(cos_scores, dim=0) # cos_max: torch.Size([16, 8]) + # num_traj = obs_batch.shape[0] + # success_traj = int(num_traj/2) + + obs = obs_batch.view(args.num_steps, args.num_processes, *obs_batch.shape[1:]) + # print('cos_max', cos_max.shape) # torch.Size([32, 8]) + # print('indmaxes0', indmaxes0.shape) # torch.Size([32, 8]) + # indmaxes0 = torch.argmax(cos_sim_total_max, dim=0) + if prototypes_used[i] == 0: + indmaxestop5 = indmaxes0 # indtop5[jjjj, :, :].squeeze() + o1, o2, o3, o4, o5 = obs.shape + # for iii in range(self.head): + obsgathered0 = torch.gather(obs, 0, indmaxestop5[:, i].reshape(1, -1, 1, 1, 1).repeat(o1, 1, o3, o4, o5))[0] + print('obsgather', obsgathered0.shape) + imgs = (np.asarray(obsgathered0.cpu().detach().numpy()))[:, :, :, :].transpose((0, 2, 3, 1)) # .repeat(3,axis=-1) # .repeat(3,axis=-1) + fig = plt.figure(figsize=(20, 20)) # first coor = LENGTH + for j in range(num_success_samples*2): # 16 [64,16] + fig.add_subplot(4, 8, j + 1) + plt.imshow(imgs[j, :, :, :].squeeze() / 255., interpolation='nearest') # , cmap='gray') # (81, 48, 5, 5, 3) + plt.xlabel('R_' + str(reward_batch.sum(0)[j].cpu().detach().numpy()) + ' c_' + str( + cos_sim_total_max[j, i].cpu().detach().numpy()) + 'p_' + str(indmaxes0[j, i].cpu().detach().numpy())) + plt.savefig('moviemaxfirst_visualizeTVTX' + "S" + str(current_time) + str(args.pycolab_game) + 'CLparam' + str(args.intrinsicR_scale) + 'lrConSpec' + str(args.lrConSpec) + 'seed' + str(args.seed) + 'topk' + str(j) + 'prototype' + str(i) + 'top5costX.pdf') + plt.close() + class Logger: def __init__( self, @@ -46,7 +109,7 @@ def __init__( self.objects_to_save = dict() if "/" in exp_suffix: exp_suffix = "_".join(exp_suffix.split("/")[:-1]) - wandb.init(entity="sunchipsster", project=wandb_project_name, name=exp_name + "_" + exp_suffix, tags=wandb_tags, reinit=True) + wandb.init(entity="mandanasmi", project=wandb_project_name, name=exp_name + "_" + exp_suffix, tags=wandb_tags, reinit=True) wandb.config.update(wandb_config) def register_model_to_save(self, model, name): From b323be6761fcec35a5844d09c8bdf174e435a520 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Tue, 26 Mar 2024 17:24:43 -0400 Subject: [PATCH 13/15] updates model Conspec --- conspecfunction/Conspec/modelConSpec.py | 3 +-- conspecfunction/a2c_ppo_acktr/envs.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/conspecfunction/Conspec/modelConSpec.py b/conspecfunction/Conspec/modelConSpec.py index 9836705..310635e 100644 --- a/conspecfunction/Conspec/modelConSpec.py +++ b/conspecfunction/Conspec/modelConSpec.py @@ -72,7 +72,7 @@ def evaluate_actions(self, inputs, rnn_hxs, masks, action): return value, action_log_probs, dist_entropy, rnn_hxs - def retrieve_hiddens(self, inputs, rnn_hxs, masks, action): + def retrieve_hiddens(self, inputs, rnn_hxs, masks): value, actor_features, rnn_hxs = self.base(inputs, rnn_hxs, masks) return actor_features @@ -178,7 +178,6 @@ def __init__(self, num_inputs, recurrent=False, hidden_size=512): constant_(x, 0)) self.critic_linear = init_(nn.Linear(hidden_size, 1)) - self.train() def forward(self, inputs, rnn_hxs, masks): diff --git a/conspecfunction/a2c_ppo_acktr/envs.py b/conspecfunction/a2c_ppo_acktr/envs.py index 2d9f316..540fa46 100644 --- a/conspecfunction/a2c_ppo_acktr/envs.py +++ b/conspecfunction/a2c_ppo_acktr/envs.py @@ -21,15 +21,15 @@ except ImportError: pass -try: - import roboschool -except ImportError: - pass - -try: - import pybullet_envs -except ImportError: - pass +# try: +# import roboschool +# except ImportError: +# pass + +# try: +# import pybullet_envs +# except ImportError: +# pass def make_env(env_id, seed, rank, log_dir, allow_early_resets): From 281fa26af4854fe6f12713f7515041883c6d5ed6 Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Tue, 26 Mar 2024 18:29:07 -0400 Subject: [PATCH 14/15] updates the data collection --- conspecfunction/collect_data.py | 34 +++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/conspecfunction/collect_data.py b/conspecfunction/collect_data.py index f6444f8..9fcd3b8 100644 --- a/conspecfunction/collect_data.py +++ b/conspecfunction/collect_data.py @@ -5,9 +5,9 @@ import pandas as pd import glob import argparse +import pdb - -def collect_gfn_data_max_states(sf_buffer_obs, cos_max_scores, max_indices, num_processes, num_prototypes, path, filename): +def collect_gfn_data_max_states(cos_max_scores, max_indices, num_processes, num_prototypes, path, filename): ''' sf_buffer_obs: (185, 32, 3, 5, 5) cos_max_scores: (32, 8) @@ -25,7 +25,7 @@ def collect_gfn_data_max_states(sf_buffer_obs, cos_max_scores, max_indices, num_ proto_active = False for i in range(num_prototypes): idx = max_indices[process_idx, i] - cos_sim = cos_scores_max[process_idx, i] + cos_sim = cos_max_scores[process_idx, i] if cos_sim > cos_sim_threshold: proto_active = True else: @@ -105,15 +105,17 @@ def collect_gfn_data(exp_name, epoch): def merge_csv_files(base_path, prefix, postfix, output_file): - full_path = os.path.join(base_path) # Combine all CSV files into a single DataFrame - file_list = glob.glob(full_path + "{}_*_{}*.csv".format(prefix, postfix)) + if postfix == 'binary': + file_list = glob.glob(base_path + "{}*{}*".format(prefix, postfix)) + elif postfix == 'cos': + file_list = glob.glob(base_path + "{}*{}.csv".format(prefix, postfix)) num_files = len(file_list) - print(num_files) + files = [f for f in file_list] - combined_csv = pd.concat([pd.read_csv(file) for file in files], ignore_index=True) - + combined_csv = pd.concat([pd.read_csv(file) for file in files], ignore_index=True, sort=False) + print(combined_csv.shape) # Write the combined DataFrame to a new CSV file combined_csv.to_csv(output_file, index=False) @@ -124,13 +126,14 @@ def merge_csv_files(base_path, prefix, postfix, output_file): parser.add_argument('--exp_name', type=str, default='20240325-152802_key_to_door3_1_10000', help='Experiment name') parser.add_argument('--num_episodes', type=int, default=10000, help='Epoch number') parser.add_argument('--cos_sim_threshold', type=float, default=0.6, help='Cosine similarity threshold') - parser.add_argument('--merge_data', action='store_true', default=False, help='if you are merging the csv files') + parser.add_argument('--merge_data', action='store_true', default=True, help='if you are merging the csv files') parser.add_argument('--output_file', type=str, default='merged_binary_kd3_10k_0.6.csv', help='Output file name') parser.add_argument('--output_csv_files_prefix', type=str, default='gfn_kd3_10k_', help='Output cosine csv file name') args = parser.parse_args() base_directory = '/network/scratch/s/samieima/conspec_train/20240325-152802_key_to_door3_1_10000/' - + csv_path = 'csv_files/' + if args.merge_data == False: for i in range(args.num_episodes): if i == 0: @@ -147,14 +150,13 @@ def merge_csv_files(base_path, prefix, postfix, output_file): num_processes = cos_scores_max.shape[0] num_prototypes = cos_scores_max.shape[1] - - csv_path = '/network/scratch/s/samieima/conspec_train/20240325-152802_key_to_door3_1_10000/csv_files/' + path = f'{base_directory}{csv_path}' filename = f'gfn_kd3_10k_{i}' - collect_gfn_data_max_states(sf_buffer, cos_scores_max, max_index, num_processes, num_prototypes, csv_path, filename) + collect_gfn_data_max_states(cos_scores_max, max_index, num_processes, num_prototypes, path, filename) elif args.merge_data == True: - csv_path = 'csv_files/' - merge_csv_files(f'{base_directory}{csv_path}', 'gfn_kd3_10k_', 'binary', 'merged_binary_kd3_10k_0.6.csv') - # merge_csv_files(f'{base_directory}{csv_path}', 'gfn_kd3_10k_', 'cos', 'merged_cosine_kd3_10k_0.6.csv') + base_path = f'{base_directory}{csv_path}' + # merge_csv_files(base_path, 'gfn_kd3_10k_', 'binary', 'merged_binary_kd3_10k_0.6.csv') + merge_csv_files(base_path, 'gfn_kd3_10k_', 'cos', 'merged_cosine_kd3_10k_0.6.csv') From 75146810131008ac332c35b3b2e581cde69bd64d Mon Sep 17 00:00:00 2001 From: mandanasmi Date: Fri, 26 Sep 2025 12:07:36 -0400 Subject: [PATCH 15/15] Simplify codebase: remove redundant folders, consolidate to single implementation, update README and requirements --- 3DOrangeTree/README.md | 52 -- .../Utils/__pycache__/utils.cpython-36.pyc | Bin 570 -> 0 bytes .../Utils/__pycache__/utils.cpython-37.pyc | Bin 646 -> 0 bytes .../Utils/__pycache__/utils.cpython-38.pyc | Bin 610 -> 0 bytes 3DOrangeTree/Utils/utils.py | 10 - .../__pycache__/__init__.cpython-37.pyc | Bin 216 -> 0 bytes .../__pycache__/arguments.cpython-37.pyc | Bin 3740 -> 0 bytes .../__pycache__/argumentstvt.cpython-37.pyc | Bin 3724 -> 0 bytes .../__pycache__/distributions.cpython-37.pyc | Bin 5060 -> 0 bytes .../__pycache__/envs.cpython-37.pyc | Bin 8438 -> 0 bytes .../__pycache__/model.cpython-37.pyc | Bin 6990 -> 0 bytes .../__pycache__/model384.cpython-37.pyc | Bin 7320 -> 0 bytes .../__pycache__/modelCL.cpython-37.pyc | Bin 10369 -> 0 bytes .../__pycache__/modelCL64.cpython-37.pyc | Bin 10371 -> 0 bytes .../__pycache__/modelCLrnn.cpython-37.pyc | Bin 11278 -> 0 bytes .../__pycache__/modelCLrnn54.cpython-37.pyc | Bin 11280 -> 0 bytes .../__pycache__/modelConspec.cpython-37.pyc | Bin 6143 -> 0 bytes .../__pycache__/modelRL.cpython-37.pyc | Bin 5932 -> 0 bytes ...delsepmini384dkdecodeImpala.cpython-37.pyc | Bin 11816 -> 0 bytes ...lsepmini384dkdecodeImpala64.cpython-37.pyc | Bin 11818 -> 0 bytes ...sepmini384dkdecodeImpalarnn.cpython-37.pyc | Bin 12725 -> 0 bytes ...pmini384dkdecodeImpalarnn54.cpython-37.pyc | Bin 12727 -> 0 bytes .../__pycache__/storage.cpython-37.pyc | Bin 14322 -> 0 bytes .../storageCL84UNITY.cpython-37.pyc | Bin 13772 -> 0 bytes .../storageCL84UNITY2.cpython-37.pyc | Bin 14012 -> 0 bytes .../storageCL84UNITY2x.cpython-37.pyc | Bin 14680 -> 0 bytes .../storageCL84UNITY2x22.cpython-37.pyc | Bin 14032 -> 0 bytes .../storageCL84UNITY2xx.cpython-37.pyc | Bin 14000 -> 0 bytes .../storageCLminiTVTnobetter.cpython-37.pyc | Bin 13990 -> 0 bytes .../__pycache__/utils.cpython-37.pyc | Bin 2138 -> 0 bytes 3DOrangeTree/a2c_ppo_acktr/algo/__init__.py | 6 - .../algo/__pycache__/__init__.cpython-37.pyc | Bin 319 -> 0 bytes .../algo/__pycache__/gail.cpython-37.pyc | Bin 4558 -> 0 bytes .../__pycache__/ppoConspec.cpython-37.pyc | Bin 4981 -> 0 bytes .../__pycache__/ppoConspectest.cpython-37.pyc | Bin 3877 -> 0 bytes 3DOrangeTree/a2c_ppo_acktr/algo/ppoConspec.py | 196 ------ .../a2c_ppo_acktr/algo/ppoConspectest.py | 147 ----- 3DOrangeTree/a2c_ppo_acktr/arguments.py | 190 ------ 3DOrangeTree/a2c_ppo_acktr/envs.py | 259 -------- 3DOrangeTree/a2c_ppo_acktr/modelConspec.py | 164 ----- 3DOrangeTree/a2c_ppo_acktr/modelRL.py | 157 ----- 3DOrangeTree/a2c_ppo_acktr/storage.py | 482 -------------- 3DOrangeTree/evaluation.py | 48 -- 3DOrangeTree/generate_tmux_yaml.py | 37 -- 3DOrangeTree/gym_unity/__init__.py | 5 - .../__pycache__/__init__.cpython-36.pyc | Bin 200 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 262 -> 0 bytes 3DOrangeTree/gym_unity/envs/__init__.py | 361 ---------- .../envs/__pycache__/__init__.cpython-36.pyc | Bin 12269 -> 0 bytes .../envs/__pycache__/__init__.cpython-37.pyc | Bin 12327 -> 0 bytes 3DOrangeTree/gym_unity/tests/test_gym.py | 277 -------- 3DOrangeTree/main.py | 236 ------- 3DOrangeTree/maintestBlackobj.py | 232 ------- 3DOrangeTree/maintestNewContext.py | 232 ------- 3DOrangeTree/misc_util.py | 41 -- 3DOrangeTree/mlagents_envs/__init__.py | 5 - .../__pycache__/__init__.cpython-36.pyc | Bin 204 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 266 -> 0 bytes .../__pycache__/base_env.cpython-36.pyc | Bin 22756 -> 0 bytes .../__pycache__/base_env.cpython-37.pyc | Bin 22954 -> 0 bytes .../__pycache__/communicator.cpython-36.pyc | Bin 2309 -> 0 bytes .../__pycache__/communicator.cpython-37.pyc | Bin 2379 -> 0 bytes .../__pycache__/env_utils.cpython-36.pyc | Bin 3165 -> 0 bytes .../__pycache__/env_utils.cpython-37.pyc | Bin 3227 -> 0 bytes .../__pycache__/environment.cpython-36.pyc | Bin 15805 -> 0 bytes .../__pycache__/environment.cpython-37.pyc | Bin 15865 -> 0 bytes .../__pycache__/exception.cpython-36.pyc | Bin 2792 -> 0 bytes .../__pycache__/exception.cpython-37.pyc | Bin 2854 -> 0 bytes .../__pycache__/logging_util.cpython-36.pyc | Bin 1741 -> 0 bytes .../__pycache__/logging_util.cpython-37.pyc | Bin 1803 -> 0 bytes .../rpc_communicator.cpython-36.pyc | Bin 6055 -> 0 bytes .../rpc_communicator.cpython-37.pyc | Bin 6107 -> 0 bytes .../__pycache__/rpc_utils.cpython-36.pyc | Bin 12930 -> 0 bytes .../__pycache__/rpc_utils.cpython-37.pyc | Bin 12992 -> 0 bytes .../__pycache__/timers.cpython-36.pyc | Bin 10717 -> 0 bytes .../__pycache__/timers.cpython-37.pyc | Bin 10800 -> 0 bytes 3DOrangeTree/mlagents_envs/base_env.py | 616 ------------------ 3DOrangeTree/mlagents_envs/communicator.py | 43 -- .../communicator_objects/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 175 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 237 -> 0 bytes .../agent_action_pb2.cpython-36.pyc | Bin 2622 -> 0 bytes .../agent_action_pb2.cpython-37.pyc | Bin 2684 -> 0 bytes .../__pycache__/agent_info_pb2.cpython-36.pyc | Bin 3407 -> 0 bytes .../__pycache__/agent_info_pb2.cpython-37.pyc | Bin 3469 -> 0 bytes .../brain_parameters_pb2.cpython-36.pyc | Bin 4404 -> 0 bytes .../brain_parameters_pb2.cpython-37.pyc | Bin 4466 -> 0 bytes .../capabilities_pb2.cpython-36.pyc | Bin 3232 -> 0 bytes .../capabilities_pb2.cpython-37.pyc | Bin 3294 -> 0 bytes .../__pycache__/command_pb2.cpython-36.pyc | Bin 1808 -> 0 bytes .../__pycache__/command_pb2.cpython-37.pyc | Bin 1870 -> 0 bytes .../__pycache__/header_pb2.cpython-36.pyc | Bin 2185 -> 0 bytes .../__pycache__/header_pb2.cpython-37.pyc | Bin 2247 -> 0 bytes .../observation_pb2.cpython-36.pyc | Bin 5026 -> 0 bytes .../observation_pb2.cpython-37.pyc | Bin 5088 -> 0 bytes .../__pycache__/space_type_pb2.cpython-36.pyc | Bin 1785 -> 0 bytes .../__pycache__/space_type_pb2.cpython-37.pyc | Bin 1847 -> 0 bytes .../training_analytics_pb2.cpython-36.pyc | Bin 6392 -> 0 bytes .../training_analytics_pb2.cpython-37.pyc | Bin 6454 -> 0 bytes .../unity_input_pb2.cpython-36.pyc | Bin 2905 -> 0 bytes .../unity_input_pb2.cpython-37.pyc | Bin 2967 -> 0 bytes .../unity_message_pb2.cpython-36.pyc | Bin 3138 -> 0 bytes .../unity_message_pb2.cpython-37.pyc | Bin 3200 -> 0 bytes .../unity_output_pb2.cpython-36.pyc | Bin 2931 -> 0 bytes .../unity_output_pb2.cpython-37.pyc | Bin 2993 -> 0 bytes ...rl_initialization_input_pb2.cpython-36.pyc | Bin 3263 -> 0 bytes ...rl_initialization_input_pb2.cpython-37.pyc | Bin 3325 -> 0 bytes ...l_initialization_output_pb2.cpython-36.pyc | Bin 3736 -> 0 bytes ...l_initialization_output_pb2.cpython-37.pyc | Bin 3798 -> 0 bytes .../unity_rl_input_pb2.cpython-36.pyc | Bin 4229 -> 0 bytes .../unity_rl_input_pb2.cpython-37.pyc | Bin 4291 -> 0 bytes .../unity_rl_output_pb2.cpython-36.pyc | Bin 3830 -> 0 bytes .../unity_rl_output_pb2.cpython-37.pyc | Bin 3892 -> 0 bytes .../unity_to_external_pb2_grpc.cpython-36.pyc | Bin 1863 -> 0 bytes .../unity_to_external_pb2_grpc.cpython-37.pyc | Bin 1925 -> 0 bytes .../communicator_objects/agent_action_pb2.py | 92 --- .../communicator_objects/agent_action_pb2.pyi | 52 -- .../agent_info_action_pair_pb2.py | 83 --- .../agent_info_action_pair_pb2.pyi | 57 -- .../communicator_objects/agent_info_pb2.py | 123 ---- .../communicator_objects/agent_info_pb2.pyi | 67 -- .../brain_parameters_pb2.py | 170 ----- .../brain_parameters_pb2.pyi | 88 --- .../communicator_objects/capabilities_pb2.py | 113 ---- .../communicator_objects/capabilities_pb2.pyi | 53 -- .../communicator_objects/command_pb2.py | 64 -- .../communicator_objects/command_pb2.pyi | 39 -- .../custom_reset_parameters_pb2.py | 64 -- .../custom_reset_parameters_pb2.pyi | 23 - .../demonstration_meta_pb2.py | 99 --- .../demonstration_meta_pb2.pyi | 50 -- .../engine_configuration_pb2.py | 106 --- .../engine_configuration_pb2.pyi | 51 -- .../communicator_objects/header_pb2.py | 78 --- .../communicator_objects/header_pb2.pyi | 44 -- .../communicator_objects/observation_pb2.py | 224 ------- .../communicator_objects/observation_pb2.pyi | 122 ---- .../communicator_objects/space_type_pb2.py | 59 -- .../communicator_objects/space_type_pb2.pyi | 37 -- .../training_analytics_pb2.py | 257 -------- .../training_analytics_pb2.pyi | 101 --- .../communicator_objects/unity_input_pb2.py | 83 --- .../communicator_objects/unity_input_pb2.pyi | 57 -- .../communicator_objects/unity_message_pb2.py | 92 --- .../unity_message_pb2.pyi | 65 -- .../communicator_objects/unity_output_pb2.py | 83 --- .../communicator_objects/unity_output_pb2.pyi | 57 -- .../unity_rl_initialization_input_pb2.py | 102 --- .../unity_rl_initialization_input_pb2.pyi | 58 -- .../unity_rl_initialization_output_pb2.py | 111 ---- .../unity_rl_initialization_output_pb2.pyi | 71 -- .../unity_rl_input_pb2.py | 179 ----- .../unity_rl_input_pb2.pyi | 105 --- .../unity_rl_output_pb2.py | 170 ----- .../unity_rl_output_pb2.pyi | 99 --- .../unity_to_external_pb2.py | 58 -- .../unity_to_external_pb2.pyi | 6 - .../unity_to_external_pb2_grpc.py | 46 -- 3DOrangeTree/mlagents_envs/env_utils.py | 130 ---- 3DOrangeTree/mlagents_envs/environment.py | 518 --------------- 3DOrangeTree/mlagents_envs/exception.py | 86 --- 3DOrangeTree/mlagents_envs/logging_util.py | 63 -- .../mlagents_envs/mock_communicator.py | 111 ---- .../mlagents_envs/registry/__init__.py | 4 - .../__pycache__/__init__.cpython-37.pyc | Bin 276 -> 0 bytes .../base_registry_entry.cpython-37.pyc | Bin 2395 -> 0 bytes .../__pycache__/binary_utils.cpython-37.pyc | Bin 7224 -> 0 bytes .../remote_registry_entry.cpython-37.pyc | Bin 3193 -> 0 bytes .../unity_env_registry.cpython-37.pyc | Bin 5397 -> 0 bytes .../registry/base_registry_entry.py | 56 -- .../mlagents_envs/registry/binary_utils.py | 235 ------- .../registry/remote_registry_entry.py | 71 -- .../registry/unity_env_registry.py | 125 ---- .../mlagents_envs/rpc_communicator.py | 158 ----- 3DOrangeTree/mlagents_envs/rpc_utils.py | 431 ------------ .../mlagents_envs/side_channel/__init__.py | 7 - .../__pycache__/__init__.cpython-36.pyc | Bin 534 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 596 -> 0 bytes ...ning_analytics_side_channel.cpython-36.pyc | Bin 2214 -> 0 bytes ...ning_analytics_side_channel.cpython-37.pyc | Bin 2169 -> 0 bytes .../incoming_message.cpython-36.pyc | Bin 3823 -> 0 bytes .../incoming_message.cpython-37.pyc | Bin 3885 -> 0 bytes .../outgoing_message.cpython-36.pyc | Bin 2791 -> 0 bytes .../outgoing_message.cpython-37.pyc | Bin 2853 -> 0 bytes .../__pycache__/side_channel.cpython-36.pyc | Bin 2108 -> 0 bytes .../__pycache__/side_channel.cpython-37.pyc | Bin 2170 -> 0 bytes .../side_channel_manager.cpython-36.pyc | Bin 3226 -> 0 bytes .../side_channel_manager.cpython-37.pyc | Bin 3288 -> 0 bytes ...default_training_analytics_side_channel.py | 49 -- .../engine_configuration_channel.py | 127 ---- .../environment_parameters_channel.py | 100 --- .../side_channel/float_properties_channel.py | 62 -- .../side_channel/incoming_message.py | 93 --- .../side_channel/outgoing_message.py | 66 -- .../side_channel/raw_bytes_channel.py | 39 -- .../side_channel/side_channel.py | 46 -- .../side_channel/side_channel_manager.py | 81 --- .../side_channel/stats_side_channel.py | 62 -- 3DOrangeTree/mlagents_envs/tests/__init__.py | 0 .../mlagents_envs/tests/test_env_utils.py | 64 -- 3DOrangeTree/mlagents_envs/tests/test_envs.py | 170 ----- .../mlagents_envs/tests/test_registry.py | 44 -- .../tests/test_rpc_communicator.py | 82 --- .../mlagents_envs/tests/test_rpc_utils.py | 503 -------------- .../mlagents_envs/tests/test_set_action.py | 55 -- .../mlagents_envs/tests/test_side_channel.py | 258 -------- .../mlagents_envs/tests/test_steps.py | 136 ---- .../mlagents_envs/tests/test_timers.py | 92 --- 3DOrangeTree/mlagents_envs/timers.py | 362 ---------- 3DOrangeTree/moduleConspec.py | 81 --- 3DOrangeTree/requirements.txt | 75 --- .../Conspec => Conspec}/ConSpec.py | 0 .../Conspec => Conspec}/modelConSpec.py | 0 .../Conspec => Conspec}/ppoConSpec.py | 0 .../Conspec => Conspec}/prototype.py | 0 .../Conspec => Conspec}/storageConSpec.py | 0 3DOrangeTree/LICENSE => LICENSE | 0 .../a2c_ppo_acktr/algo/ppoConSpec.py | 208 ------ Multikeytodoor/a2c_ppo_acktr/envs.py | 258 -------- .../a2c_ppo_acktr/storageConSpec.py | 501 -------------- Multikeytodoor/main.py | 338 ---------- Multikeytodoor/moduleConSpec.py | 84 --- Multikeytodoor/requirements.txt | 119 ---- README.md | 49 +- .../__init__.py | 0 .../algo/__init__.py | 0 .../algo/a2c_acktr.py | 0 .../algo/gail.py | 0 .../algo/ppo.py | 0 .../algo/ppoConSpec.py | 0 .../arguments.py | 0 .../distributions.py | 0 .../a2c_ppo_acktr => a2c_ppo_acktr}/envs.py | 0 .../modelRL.py | 0 .../storage.py | 0 .../a2c_ppo_acktr => a2c_ppo_acktr}/utils.py | 0 conspecfunction/analysis.py => analysis.py | 0 .../collect_data.py => collect_data.py | 0 conspecfunction/LICENSE | 21 - conspecfunction/README.md | 47 -- conspecfunction/a2c_ppo_acktr/__init__.py | 0 conspecfunction/a2c_ppo_acktr/algo/gail.py | 166 ----- .../a2c_ppo_acktr/distributions.py | 109 ---- conspecfunction/a2c_ppo_acktr/utils.py | 65 -- conspecfunction/requirements.txt | 121 ---- ...19-212006_key_to_door3_1_2500-epoch-70.png | Bin .../data_collection.py => data_collection.py | 0 .../evaluation.py => evaluation.py | 0 ...rate_tmux_yaml.py => generate_tmux_yaml.py | 0 conspecfunction/main.py => main.py | 0 conspecfunction/main_eval.py => main_eval.py | 0 conspecfunction/misc.py => misc.py | 0 conspecfunction/misc_util.py => misc_util.py | 0 requirements.txt | 31 + conspecfunction/run.sh => run.sh | 0 conspecfunction/run_eval.sh => run_eval.sh | 0 {conspecfunction/tvt => tvt}/__init__.py | 0 {conspecfunction/tvt => tvt}/batch_env.py | 0 {conspecfunction/tvt => tvt}/dmlab/README.md | 0 .../tvt => tvt}/dmlab/active_visual_match.lua | 0 .../tvt => tvt}/dmlab/image_utils.lua | 0 .../tvt => tvt}/dmlab/key_to_door.lua | 0 .../tvt => tvt}/dmlab/key_to_door_bluekey.lua | 0 .../tvt => tvt}/dmlab/key_to_door_factory.lua | 0 .../dmlab/key_to_door_to_match.lua | 0 .../dmlab/latent_information_acquisition.lua | 0 ...latent_information_acquisition_factory.lua | 0 .../dmlab/passive_visual_match.lua | 0 .../dmlab/two_keys_to_choose_factory.lua | 0 .../tvt => tvt}/dmlab/two_negative_keys.lua | 0 .../dmlab/visual_match_factory.lua | 0 .../tvt => tvt}/images/avm_notvt.png | Bin .../tvt => tvt}/images/avm_notvt_gamma1.png | Bin .../tvt => tvt}/images/avm_tvt.png | Bin .../tvt => tvt}/images/ktd_notvt.png | Bin .../tvt => tvt}/images/ktd_notvt_gamma1.png | Bin .../tvt => tvt}/images/ktd_tvt.png | Bin {conspecfunction/tvt => tvt}/nest_utils.py | 0 .../tvt => tvt}/pycolab/common.py | 0 {conspecfunction/tvt => tvt}/pycolab/env.py | 0 {conspecfunction/tvt => tvt}/pycolab/game.py | 0 .../tvt => tvt}/pycolab/human_player.py | 0 .../tvt => tvt}/pycolab/key_to_door2.py | 0 .../tvt => tvt}/pycolab/key_to_door3.py | 0 .../tvt => tvt}/pycolab/key_to_door4.py | 0 .../tvt => tvt}/pycolab/objects.py | 0 286 files changed, 75 insertions(+), 14238 deletions(-) delete mode 100644 3DOrangeTree/README.md delete mode 100644 3DOrangeTree/Utils/__pycache__/utils.cpython-36.pyc delete mode 100644 3DOrangeTree/Utils/__pycache__/utils.cpython-37.pyc delete mode 100644 3DOrangeTree/Utils/__pycache__/utils.cpython-38.pyc delete mode 100644 3DOrangeTree/Utils/utils.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/arguments.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/argumentstvt.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/distributions.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/envs.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/model.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/model384.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelCL.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelCL64.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelCLrnn.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelCLrnn54.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelConspec.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelRL.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpala.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpala64.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpalarnn.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpalarnn54.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/storage.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY2.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY2x.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY2x22.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY2xx.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCLminiTVTnobetter.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/__pycache__/utils.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/algo/__init__.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/gail.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/ppoConspec.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/ppoConspectest.cpython-37.pyc delete mode 100644 3DOrangeTree/a2c_ppo_acktr/algo/ppoConspec.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/algo/ppoConspectest.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/arguments.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/envs.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/modelConspec.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/modelRL.py delete mode 100644 3DOrangeTree/a2c_ppo_acktr/storage.py delete mode 100644 3DOrangeTree/evaluation.py delete mode 100644 3DOrangeTree/generate_tmux_yaml.py delete mode 100644 3DOrangeTree/gym_unity/__init__.py delete mode 100644 3DOrangeTree/gym_unity/__pycache__/__init__.cpython-36.pyc delete mode 100644 3DOrangeTree/gym_unity/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/gym_unity/envs/__init__.py delete mode 100644 3DOrangeTree/gym_unity/envs/__pycache__/__init__.cpython-36.pyc delete mode 100644 3DOrangeTree/gym_unity/envs/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/gym_unity/tests/test_gym.py delete mode 100644 3DOrangeTree/main.py delete mode 100644 3DOrangeTree/maintestBlackobj.py delete mode 100644 3DOrangeTree/maintestNewContext.py delete mode 100644 3DOrangeTree/misc_util.py delete mode 100644 3DOrangeTree/mlagents_envs/__init__.py delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/__init__.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/base_env.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/base_env.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/communicator.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/communicator.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/env_utils.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/env_utils.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/environment.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/environment.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/exception.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/exception.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/logging_util.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/logging_util.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/rpc_communicator.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/rpc_communicator.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/rpc_utils.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/rpc_utils.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/timers.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/__pycache__/timers.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/base_env.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__init__.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/__init__.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/agent_action_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/agent_action_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/agent_info_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/agent_info_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/brain_parameters_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/brain_parameters_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/capabilities_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/capabilities_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/command_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/command_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/header_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/header_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/observation_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/observation_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/space_type_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/space_type_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/training_analytics_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/training_analytics_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_input_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_input_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_message_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_message_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_output_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_output_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_input_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_input_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_output_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_output_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_input_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_input_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_output_pb2.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_output_pb2.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_to_external_pb2_grpc.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_to_external_pb2_grpc.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/agent_action_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/agent_action_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.py delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.pyi delete mode 100644 3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2_grpc.py delete mode 100644 3DOrangeTree/mlagents_envs/env_utils.py delete mode 100644 3DOrangeTree/mlagents_envs/environment.py delete mode 100644 3DOrangeTree/mlagents_envs/exception.py delete mode 100644 3DOrangeTree/mlagents_envs/logging_util.py delete mode 100644 3DOrangeTree/mlagents_envs/mock_communicator.py delete mode 100644 3DOrangeTree/mlagents_envs/registry/__init__.py delete mode 100644 3DOrangeTree/mlagents_envs/registry/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/registry/__pycache__/base_registry_entry.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/registry/__pycache__/binary_utils.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/registry/__pycache__/remote_registry_entry.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/registry/__pycache__/unity_env_registry.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/registry/base_registry_entry.py delete mode 100644 3DOrangeTree/mlagents_envs/registry/binary_utils.py delete mode 100644 3DOrangeTree/mlagents_envs/registry/remote_registry_entry.py delete mode 100644 3DOrangeTree/mlagents_envs/registry/unity_env_registry.py delete mode 100644 3DOrangeTree/mlagents_envs/rpc_communicator.py delete mode 100644 3DOrangeTree/mlagents_envs/rpc_utils.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__init__.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/__init__.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/__init__.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/default_training_analytics_side_channel.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/default_training_analytics_side_channel.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/incoming_message.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/incoming_message.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/outgoing_message.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/outgoing_message.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel_manager.cpython-36.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel_manager.cpython-37.pyc delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/default_training_analytics_side_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/engine_configuration_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/environment_parameters_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/float_properties_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/incoming_message.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/outgoing_message.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/raw_bytes_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/side_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/side_channel_manager.py delete mode 100644 3DOrangeTree/mlagents_envs/side_channel/stats_side_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/__init__.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_env_utils.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_envs.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_registry.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_rpc_communicator.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_rpc_utils.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_set_action.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_side_channel.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_steps.py delete mode 100644 3DOrangeTree/mlagents_envs/tests/test_timers.py delete mode 100644 3DOrangeTree/mlagents_envs/timers.py delete mode 100644 3DOrangeTree/moduleConspec.py delete mode 100644 3DOrangeTree/requirements.txt rename {conspecfunction/Conspec => Conspec}/ConSpec.py (100%) rename {conspecfunction/Conspec => Conspec}/modelConSpec.py (100%) rename {conspecfunction/Conspec => Conspec}/ppoConSpec.py (100%) rename {conspecfunction/Conspec => Conspec}/prototype.py (100%) rename {conspecfunction/Conspec => Conspec}/storageConSpec.py (100%) rename 3DOrangeTree/LICENSE => LICENSE (100%) delete mode 100644 Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py delete mode 100644 Multikeytodoor/a2c_ppo_acktr/envs.py delete mode 100644 Multikeytodoor/a2c_ppo_acktr/storageConSpec.py delete mode 100644 Multikeytodoor/main.py delete mode 100644 Multikeytodoor/moduleConSpec.py delete mode 100644 Multikeytodoor/requirements.txt rename {3DOrangeTree/a2c_ppo_acktr => a2c_ppo_acktr}/__init__.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/algo/__init__.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/algo/a2c_acktr.py (100%) rename {3DOrangeTree/a2c_ppo_acktr => a2c_ppo_acktr}/algo/gail.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/algo/ppo.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/algo/ppoConSpec.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/arguments.py (100%) rename {3DOrangeTree/a2c_ppo_acktr => a2c_ppo_acktr}/distributions.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/envs.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/modelRL.py (100%) rename {conspecfunction/a2c_ppo_acktr => a2c_ppo_acktr}/storage.py (100%) rename {3DOrangeTree/a2c_ppo_acktr => a2c_ppo_acktr}/utils.py (100%) rename conspecfunction/analysis.py => analysis.py (100%) rename conspecfunction/collect_data.py => collect_data.py (100%) delete mode 100644 conspecfunction/LICENSE delete mode 100644 conspecfunction/README.md delete mode 100644 conspecfunction/a2c_ppo_acktr/__init__.py delete mode 100644 conspecfunction/a2c_ppo_acktr/algo/gail.py delete mode 100644 conspecfunction/a2c_ppo_acktr/distributions.py delete mode 100644 conspecfunction/a2c_ppo_acktr/utils.py delete mode 100644 conspecfunction/requirements.txt rename {conspecfunction/data => data}/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png (100%) rename conspecfunction/data_collection.py => data_collection.py (100%) rename conspecfunction/evaluation.py => evaluation.py (100%) rename conspecfunction/generate_tmux_yaml.py => generate_tmux_yaml.py (100%) rename conspecfunction/main.py => main.py (100%) rename conspecfunction/main_eval.py => main_eval.py (100%) rename conspecfunction/misc.py => misc.py (100%) rename conspecfunction/misc_util.py => misc_util.py (100%) create mode 100644 requirements.txt rename conspecfunction/run.sh => run.sh (100%) rename conspecfunction/run_eval.sh => run_eval.sh (100%) rename {conspecfunction/tvt => tvt}/__init__.py (100%) rename {conspecfunction/tvt => tvt}/batch_env.py (100%) rename {conspecfunction/tvt => tvt}/dmlab/README.md (100%) rename {conspecfunction/tvt => tvt}/dmlab/active_visual_match.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/image_utils.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/key_to_door.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/key_to_door_bluekey.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/key_to_door_factory.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/key_to_door_to_match.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/latent_information_acquisition.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/latent_information_acquisition_factory.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/passive_visual_match.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/two_keys_to_choose_factory.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/two_negative_keys.lua (100%) rename {conspecfunction/tvt => tvt}/dmlab/visual_match_factory.lua (100%) rename {conspecfunction/tvt => tvt}/images/avm_notvt.png (100%) rename {conspecfunction/tvt => tvt}/images/avm_notvt_gamma1.png (100%) rename {conspecfunction/tvt => tvt}/images/avm_tvt.png (100%) rename {conspecfunction/tvt => tvt}/images/ktd_notvt.png (100%) rename {conspecfunction/tvt => tvt}/images/ktd_notvt_gamma1.png (100%) rename {conspecfunction/tvt => tvt}/images/ktd_tvt.png (100%) rename {conspecfunction/tvt => tvt}/nest_utils.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/common.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/env.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/game.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/human_player.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/key_to_door2.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/key_to_door3.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/key_to_door4.py (100%) rename {conspecfunction/tvt => tvt}/pycolab/objects.py (100%) diff --git a/3DOrangeTree/README.md b/3DOrangeTree/README.md deleted file mode 100644 index da39147..0000000 --- a/3DOrangeTree/README.md +++ /dev/null @@ -1,52 +0,0 @@ - - - -# ConSpec on the OrangeTree task - -## Information -The 3D environments were designed and built in SilicoLabs Experimenter software (https://www.silicolabs.ca/), which is built on top of Unity. - -The ConSpec code is built on top of the basic PPO code taken from the repository: https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail - -The interface between the environment and Pytorch was built on top of ML-agents: https://github.com/Unity-Technologies/ml-agents - - -## Installation -There are 3 environment binary files that need to be -1) downloaded from the Google Drive https://drive.google.com/drive/folders/1azC6fJoQjth_rcDm499HfetS7AU9vUtB?usp=sharing -2) unzipped. - -To create this environment, install the packages in the requirements.txt file -In main.py --> modify the directory line 52. The directory line should where you placed the environment files. - - -### Launching - -#### To run ConSpec on the OrangeTree task: -In the command line, first access the environment by running: -``` -chmod -R 755 /home/chen/PycharmProjects/ProjTreeSimplePink2extrahardLinux4590_338084842miss/GridWorld.x86_64 -``` -Then run: -``` -python main.py --algo Conspec --use-gae --lr 2e-4 --clip-param 0.08 --value-loss-coef 0.5 --num-processes 16 --num-steps 65 --num-mini-batch 4 --log-interval 1 --use-linear-lr-decay --entropy-coef 0.02 --lrCL 20e-4 --choiceCLparams 0 --seed 80000 --head 8 --factorR 0.5 -``` - -#### To test the runs from main.py on the modified OrangeTree task with novel black objects: -In the command line, first access the environment by running: -``` -chmod -R 755 /home/chen/PycharmProjects/ProjTreeSimplePink2extrahardLinux4590_33_84842onevarb/GridWorld.x86_64 -``` -Then run: -``` -python maintestBlackobj.py --algo Conspec --use-gae --lr 2e-4 --clip-param 0.08 --value-loss-coef 0.5 --num-processes 16 --num-steps 65 --num-mini-batch 4 --log-interval 1 --use-linear-lr-decay --entropy-coef 0.02 --lrCL 20e-4 --choiceCLparams 0 --seed 80000 --head 8 --factorR 0.5 -``` -#### To test the runs from main.py on the new green and pink environment: -In the command line, first access the environment by running: -``` -chmod -R 755 /home/chen/PycharmProjects/ProjTreeSimplePink2extrahardLinux4590_338084842TestmissRoommgp/GridWorld.x86_64 -``` -Then run: -``` -python maintestNewContext.py --algo Conspec --use-gae --lr 2e-4 --clip-param 0.08 --value-loss-coef 0.5 --num-processes 16 --num-steps 65 --num-mini-batch 4 --log-interval 1 --use-linear-lr-decay --entropy-coef 0.02 --lrCL 20e-4 --choiceCLparams 0 --seed 80000 --head 8 --factorR 0.5 -``` diff --git a/3DOrangeTree/Utils/__pycache__/utils.cpython-36.pyc b/3DOrangeTree/Utils/__pycache__/utils.cpython-36.pyc deleted file mode 100644 index 4a59eacb3c4a92b7408fd0addcf71483f7752d8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 570 zcmYjNO>Yx15S_7ildx%#+8zK2p}inA7gWThLKQ-45u7T-hmfL0(KhQWj=bK*_C`sy zJq3OYf5}%)J##^v7;i4MHE-V7GtV=AvA>`E8UM{C0{n(MixGcKW}grgP@sY-_MR>I zG%8rZf50>@@FPs3TgrjUIS-CjOg1DtC$oyc!4e(oa7+7!uTLGPh==F`z8>F1bRTu- zNUbB~hp=Vj`2+aL9>Eqn-bH8d{qYxYgXORTs$>}WsED@MvwIy2tN`jJzBDup+$I46 zyMFqi)mrK@%~!(YrAX^V+8D8tb!*e-C#jv+M%YQ>nQnZ1Elh1aS3>*Pu_b@?oMDb+cW8GHG#)KSyP~|SvD|tm){Ro4dH{q-LlD@G!a2N_lXH{La OO1ui6X@k}X6ZRh!2bNL* diff --git a/3DOrangeTree/Utils/__pycache__/utils.cpython-37.pyc b/3DOrangeTree/Utils/__pycache__/utils.cpython-37.pyc deleted file mode 100644 index d40d20fac8cba6023f327007e3059368875e3397..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 646 zcmY*W!EVz)5Z&3e(~zc!mIEMh@CB(k1g9V&4i!SA=c)oBP$U!7C6#rd&8-xZJ%g&VJR5`#7Ou0?n(X6~T8rr{$C7=$`~H+S znS=ZX(RXmHUrjt$g@}{6DC3J|GUvLu(CV{Dtck0oovZQ>{hz(}ROw_sP+2#wrzGmA*75qtUbYt<9y0YmbksrMv6LpGv{CKgu+zbt3{C$n+5i z+=e4KhCcK_A0Z!fTv*mcwbZ`G9TwdBewlwlt?eN?yQuxaw=LWC{((c^*gY*&T1)Z5 M{}SW1y3nV;0eh~myZ`_I diff --git a/3DOrangeTree/Utils/__pycache__/utils.cpython-38.pyc b/3DOrangeTree/Utils/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 7864af533499461e4c9b9d5163d2ba94003936a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 610 zcmYjN&2G~`5T4n!(~zd9g#$k)UqD1c815B9N_s#_BUF@&C1jj9 z_s9w!c?c;>`7K0#il3q9?WhYzQ|{ou`GjrqKDk~{FmQ*4HMqeo-f+W-^9^MK`10z; zqpH`SA-%>+*;CjsLjDAPuxGHvhBw|he1C3QcSj90e9I7sw^MJ6d-kAVj-^1;_#;It z!Om^CbL{%XRb7@@IS-PhP{~{bau!rdEHhc_;N9CmPo)yN*RiautbZ+()RyO>w7yEp zxv*X#lG5@bSy^7?Ci1FW8ta?PTNWwhmhMm`-XX;#o#5$LjEYoGj-S zv!9?&X{^7aa3Kp3CN$f(aG+#0k*jd{anuin$s`!aXnVEI? zX>FvMF2b?Navjz#zNyysu^TJSMWWoY@w8S;;n737O9Aj9p5jaFVh7bD%6l#AmvvFC vmFtPlip044c{U*}$D-B&mHWv3mHpWF!Wk88`@E28os0MGtF_Z=W0(B{)H0qr diff --git a/3DOrangeTree/Utils/utils.py b/3DOrangeTree/Utils/utils.py deleted file mode 100644 index 2f21b7e..0000000 --- a/3DOrangeTree/Utils/utils.py +++ /dev/null @@ -1,10 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt - -def plot_learning_curve(x, scores, figure_file): - running_avg = np.zeros(len(scores)) - for i in range(len(running_avg)): - running_avg[i] = np.mean(scores[max(0, i-10):(i+1)]) - plt.plot(x, running_avg) - plt.title('Running average of previous 10 scores') - plt.savefig(figure_file) \ No newline at end of file diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/__init__.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index b0a25ee40212c25f998bb789346bbb860527312c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216 zcmZ?b<>g`k0=63GWDxxrM8E(ekl_Ht#VkM~g&~+hlhJP_LlH&ryk0@&Ee@O9{FKt1 MR6CH92q9 zSC3vhabmiJtG3tj|N3O9^qE=gUlqLE!mXadgOyl0Ds2|O<;^myu!#>!n-x~RS87xT zpeU{T=4md&S;O7Jt^R>kR@yEz@H{NPU)n2egEyOCRW`|L53A(@nF3NDLyiHN9z%|2 zRW`#;I9#*rF?N!jdN?tZa+*EP&afxg*#o&xvUBVk4#hVi^;=_7p8|58U2vp6eMk=h za&b)aGl!68fy|B3JO|`?_JSk%5|9Ra(LpX->yWx zTw^ag$SW4P?jSed>9^Ud4)PtV>!zb?1vIzVszdXdjZe!#ZUdQS-*u2XKwf9xbCB;t z`w!R;9b^qOZ?JU-`4Nx}_NIf}1yW-79ONw^_u1PH@(z2K{n*LqCi@Bdsk8nW`#Ebn z>t9$OspI38MSKTgjI$049HeV$!hPh!$&X6!m-ouswVBdyD3>6ZrArr z4{Wb*R_?Af%K34|l`q3I3q_)9p4a7+4JObD`a(d%h-}f!?-CViPA)Otp}i=(K^B)@ zX*4GCYSvGAJ~f2%YL`c;KIwUWSA;%qt)*1bSjn=H2GQz4m=3DLMI>8m!C(ITr-!xA z@2u$a5vMW;=k*ExwLbf6uA+0`rYAD-= z+%q8`{K{BAv#&E1es^HJ(&ub$xB--tm#Yn3^}I;xW1iQ6?LyuSK#ptf)(C6q<48tE zx56mQ`a^=xSM;Rk@l*x>>3;T`KmPZhH+AFg8~0KvQX)_tG0c$!`(cD=Ii1@8pEJY(GaU`1aV!US9~^2|G(&<_EQiC9={nB4Brs0Ry#QiYTv zF@Iap&)FSfc8-(*D<1Q_n7-!)k}@w5GS+ig67xnxhZxvs9*-5+OyhCR2DS^&Nt!Sb z6N5N5!oV|V+a9AHGZBcxBt-0deN%Br>_jvu>U6Xllie;)(0rz8Tla6Tl1r(`U_eNt zs83WRb}w3+lV0qhihQmVSA&!AS}%9SE{SP^{*Y)4D`De4IiMPLwQJzDhACPjOJyiR zeHpJ?NEJLs|Ck~nc7ucoSzT&5tOx-(F&R+YXcv8P#A(LGp&r7x!3Z;&OcXrZj00lK zeqqFEQC`HvNEubkm8FI$Ha`ke&sJ3M``?-ClNEi@P@0V+N)4Q-v`7SAm>>zLih=pu z(TjlKR{_05M1qn9f&oO3fRtfkx>;XbuyI#(hmQm?8+U^}BFREWiz;Ms*m59CUp31| z#8~JkG3zk-pcZ(tQ{>PN9{%a4t9p49SnP&UB(dqCBB7Y@wo05BFD`J@!?fwj9WS9V z*QYl`60D0mIB&Q)X1twcnCZwmkTN#B4s$ikm^3LcgZ)@Di_>P%kDGeIndySqpkczm zNYJ{$-{-LA*%TN-r{)cJj7`&OoZ)LeHKHLZbityZNdF^(&vi# zXr?!p9;P4$k2&j!l(J z{r=|h;vDVJNb$GySu=qt1P-Z4L8YH4jEKSnhdWLs%od;a^@|000TbnSIqO9nWsTDk zTHOzU#&lk%GC&_Gp3knzpl1qW!z^V!Lm6vh*JAku9LOg-k)T;VZ5hm-+MG&6+YGjR z5~rcx&8v1X6RI}d!J%z}*Qn$*%OUfs;rT;Jn*SmG_v>a?#JmXuljcU>?@}3WNU@Eh zT{Y8w))mQcIlg+=ER8M?A0>A1*bfr>1=2*TX3Z5HHV^tL2LQs~_<;3;ZzEIJKd9^!{S0Uwzle|LR;{k7M7v zM}I5jePrydHnOZLe=SQEuyx=(&SN95zlt74#ojc@Q09BKUa3#~ EA2iD@ivR!s diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/argumentstvt.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/argumentstvt.cpython-37.pyc deleted file mode 100644 index e44f6fdc8fedacf8acb0336460b73c8f0cd44685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3724 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/envs.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/envs.cpython-37.pyc deleted file mode 100644 index c5d5bb4468a3c5f5bc26aa0a6ebf64307b7cc880..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8438 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 qi4Az99|hdnRuizh%Y4*bG`TqlTYlPPT diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/model.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/model.cpython-37.pyc deleted file mode 100644 index f4fc315dcb824cd3cf2e391d5f5289758ad42871..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6990 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/model384.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/model384.cpython-37.pyc deleted file mode 100644 index 3b0fbcac0aaca248725819a1b678c6d583313c40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7320 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelCLrnn.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelCLrnn.cpython-37.pyc deleted file mode 100644 index df547540b7911bca37552803e48958d6aa26b852..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11278 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelConspec.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelConspec.cpython-37.pyc deleted file mode 100644 index 3ea5480a794fa22a48d046226e11bca48d0e9962..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6143 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 KKVDf{>HHU{KsT!Z diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelRL.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelRL.cpython-37.pyc deleted file mode 100644 index 86737319df9f2379d1561526b0023df57c73ee7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5932 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 O+s&7oUt3;UZvGFjIBmxO diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpala64.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpala64.cpython-37.pyc deleted file mode 100644 index a3a2b6a5bfbfe3121aab218b0fefdbcea81498c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11818 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 PX1n=v^Bc=c%gz4*8ar)U diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpalarnn.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/modelsepmini384dkdecodeImpalarnn.cpython-37.pyc deleted file mode 100644 index d0b1cf4153b73df278d53e5829908d1890166b0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12725 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/storage.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/storage.cpython-37.pyc deleted file mode 100644 index 9f44fd79d99580702a5cd2ca20044d05c3118812..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14322 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY.cpython-37.pyc deleted file mode 100644 index 56676fe694a53954f956c12b38cd5ae0117a2aee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13772 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY2x.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCL84UNITY2x.cpython-37.pyc deleted file mode 100644 index 90ed8d602aa1347f3811aec2cf0c7cbea027ba5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14680 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 E0Fw80o&W#< diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCLminiTVTnobetter.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/storageCLminiTVTnobetter.cpython-37.pyc deleted file mode 100644 index a9906a7d6da4d88932843cbeff33f304c41431a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13990 zcmcIrO^hT*R?few%F6ob>YwR9&y0J<cO5EZ$|XP4ACZy~Ffio5J4On#%0% zs;RE(iOe3i+gbbLu?34TG=CBtSalyjAaPg;331#bC**Sq& zxAv(FA?#e}=bqM|<9_?yfhy zb?4pgZb$6h5u?7>4g6dC?*_Z0p~_}+Z&G$7y1O?!FLZD2?~iVFx(@!e_S(e7u1fH{+R?^WG}BCD#VN=$2gv?~+?_t9aXP&8_2Ic4yoM z-i|x#&f#5g=iLRotL_DN5$~G2~2YRdFUUr`ZX4YMEui!oB zUUi?sd)~d~K8^Q+d)<8o?+fm_+jMWB#iIM1`#dm9?z3Ret*Cx?G#HEyf-N~Q-4Z^B z{>pfYc$n2c#n%Q}Uk`OxUjoy&jnE_phg#bRw37rM7EVpzOoAXw$1y|cai~j5ajdCHATg>E^GP&hUZiPo$ÐM(`hI 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 EKSwEZ&Hw-a diff --git a/3DOrangeTree/a2c_ppo_acktr/__pycache__/utils.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/__pycache__/utils.cpython-37.pyc deleted file mode 100644 index faa1ed0686d23ab9b7c8e1d0f6e482ca65d782dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2138 zcmZuyQEwYX5Z>Lpv(Jw0q*X{kAQYg0Tok)dfe=(xX^MElR4St7By_soZsK#!ch2rP zX(ET0MCud&A%5g9?JH0D3%tNLYbPxcYwhmL?0R?hn{VbGwcAaG7S6WQPiu_*MapIK zAv{Dk6AY3`p0j8%^N2fLM8eJ9*pGZpYa$QEwWtQ!ll~ct>N1cu%;67A)@69cWT^a6 zBIKG*#fdjhC73S^;L0TG#zgJ z1IX6H(5>0}FfmD0X-#+9npTBW+OF=ZDqhI(&a_B1VWtBNUGC&RnQlP)`}h8^9IJjh zR7L;EQ94ZY_=zq@Dy>X^a#Rh=VyXUDdroSp)8SU~MY=Valv_!m%yqB z*3JwNRbmP9hp*vu(20S2Z#S^b%w&bBk|I@F-~bI?F?)lMI#6j`Tt;%Se*u#NX)zEV zbqm7=x^e7;qdqw+oIQp8s!=qkncEl?BVI=072Dww3^)rTZ^=Xd74umXP>gN;J1HM! ziAl*jYBW>K=rDIsg%{7*sW=yN@T~IA{TV+GB%k9qV{vWy;tQflw{8P7ohYr_&}z7Y(-Jn#*;)RV^x7FjcH-_r%D|w8^kYgeOFlDsC>uzPUE%_$7!Az6UT2Lv4%rG zAis!NjCc6)+S2{rCMH7C|shvw!tpu z{)w3JnYcyi;14cb0Esgf|Dbh!>&a}a*I}@{LWX4OuZ%$gYLb)^|#Mm}vPi z)(p{*fqUy>LmaPOK4iHASqAh9;05%WaXc>NG$*+g$NSSHU#w_CM8A*0wwHjVD$g%L zqijR&-J(s7N)(k%bO&I_TfU1^>fnT#@S@l|%w6a)qDH1h^_fFKG;hO6Y@aeT* zVqxJfUn6(>(64Hh2ZiG8JpCEMQKw?(@OBQ*p0VPgk9xJ&)B}zzc6sbo_yn8>RKwMohlI0BC>!2i1oHt^KSQM;fw3sr6K Ax&QzG diff --git a/3DOrangeTree/a2c_ppo_acktr/algo/__init__.py b/3DOrangeTree/a2c_ppo_acktr/algo/__init__.py deleted file mode 100644 index 05df2e4..0000000 --- a/3DOrangeTree/a2c_ppo_acktr/algo/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ - - -from .ppoConspec import PPOConspec -from .ppoConspectest import PPOConspectest - - diff --git a/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/__init__.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index ce26f7823c16fa41e2f1dc225f832a5d2334e5a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 319 zcmY+8K~BRk5CH8Y2Nco1fDhyl+=9djRTb?SBDkPjEX%R#P&;ecMkpWP1$=^!@Q7YH z@dZw-tD>qad3R?u^6uSaQWA`>kF|Wn`kmlEGHjOk!Ud*|bkq<_TS`-(nat*Gj(z?_ zs^W*DQqf)6G!H8nf>RP{dZegAyswJ3bPf)JPye^m;~+Uc$KfaO1(tpKePSJ0_9@Y^t-&2AWa i96i4Gm@pe)ocBW?Ilpw{?(Eh=_iEH4T^Q2s=kyQqu3J$6 diff --git a/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/gail.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/gail.cpython-37.pyc deleted file mode 100644 index 84f72ecc81cbf0b4d1db772ea8f8f9e4dc8541c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4558 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 diff --git a/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/ppoConspec.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/ppoConspec.cpython-37.pyc deleted file mode 100644 index 727cae0d40f844dda52c4bf3a033fa0525f2a7be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4981 zcmcgw%WoUU8J~TSTrMA?B$|55cKoDcNq!Vb+PZZb8A%R?>c(juEF3I0oE1fi+@)rh zmh8^<5(fy1rqH36<`9s_0!42P(BAqF^w`6kS|k_U+FKD6Xn!+HQmm6x4_#uu`R4V_ z>znWUeSD)-vI)LF|LR`jPZtRJLKeoK0p@k2=pG0qRO=8Y&9$!X=vvAfU0o*{>6%Vv zRFm!IoSa79B2=fwb3%;|b;qLGLsBC=*usAB;D_5`5cT}V&by5YhRRRoQrNQv!EHC1I_X>XpYZ-THFH7a~sr-3tS%*hvY*I9BJoMeu1E^6qnmGT$44t$V*iF zM9xrAwWM9*g-P8kCD^^bQ`d#wVZ!ixQGHGny+#}|x4~L*t0BtMrS1E|Zgg5bx92gh zEAqWw==!~|u_wwwzw35eLCgKXi&36=;&uAI+XzU6)VZv_TuUCW_`JG)R?}KF}$w^{Kl9xm(9xH%|Y&yFrH}=9-1FJ~qVKcJP z?6B?oOzI*tB`Hc$0{IPL%gDa^cxx~0`df`XKiGQkw6W*0?gJLK{YD&Z^`6FiVK6HG zcj-M@3|V7u!@JekzyWV~js2KyG`&`5EB2#!>-N3vkot!q+mCMExbeys`nmEVRKG2+ z(+syz9BJWZ@2Rj{7Z($|uH0m_3PLJbEvqA?H04lQ)oR+a`BNR<9FJ_sX~N%~?dRGkl((L0+TzWPvXv zi%pU&9sMLO@kOdt3AGmR@a~cK-$<4*cbV7tGGACESb_bCk*thM`{uF6ZqWi?p(L&Q zNWVk)(qM+K3^k1$lY@UfB9KtwOX=#9CAF7P342+^UTS=GktA!7Q{$lf_AMJTPFuTgoy(2Qr3!1(#S=i}_tOt`6 zU|TW(W?!fXdQPSphV&WsiDSE&X15$wx-D`|=3_|=m(c1U-wqjb z3a9){XEwqi!Qz}Ai<4(zKcIVFXBQ_bStsvxI_k(GCl@jpz*dY)@Vh;yIBCJfIP;Sd zZSC&*IGTpSSHS{Q>y#hL?TWBewz6`5a1U1pGsM*@Hl_~r9;%p7+QRKIUBt40;lL8)s zYwd}}0}nVsHEI3u+On{d*?~R;kKBM|)ECGK>Zy_BkSwG;Y?Il}P;;NK2giEwN65$` zT7_fn{l6q-K#el&Eo>p|62)tV)f{TD-7~43 zOy*$)N!x~XoROB1&neq|CP{y=2<;-DAC#2s&Q00w8f>?;f>pqkc?n{$))|^nwj0(n zS>nY(1-26>@R6QUUfwm9$Y6Fz26F&Yu)xx;@Dg8uMJjO{{g)_u$Q2Lf(W^Qnsz*V! zWWL^V@H6b_jPgbQ`+ic7^3D4(PWKbn+6&*bAHYLP`JiR^kpIh`ACaR6<6D0J9(<3@ zS8z7)Ia0T19(S#?&(hjS$>b{;0!_%gN(^|D02&4Wx^jmc>jxAPU!O?)7PJPQ6MbzZ z>GP2e!3#m|=kP1gDfl#Puqbs2K21OP9KM9Kmj=s20B~L!tf*YptV#}g`6=X+_S#4@ zf1a$OwB9}oEq)D>&Pf2=J`bO~7L-wb>9mZo@9{OI&pYr|>yIs^yK~9eegmf6e4VaxuA-oQZ3Li~J%#zX&}_F7wO$CHTWDsJ+B5V;`h_8Rw<)1u`^L>s7Q~ z;aB+8p)TKNfh2YGyLxQ0ReqLV;Aa;JMq^|_?)dT$?>4!H`g5qS17B##%lz6@={n6q z;sSq}Ur!}s1sg$)X8AdOVLV38BBO} zV<=Z~bBGWK`L*=4fxtEfw}u3-3RsNSN4&-J{L+Ze9~%cdj|k|Zy16xsK93b_V(jKx zI!@+tjLh>A)q#i3>}C)^%?w$N_~xGP(I|}oE~1fLl0*i3DQdVPIcdcq
R&)~q} z-VoY_kuQBZ0KuLx8oj<#oEFQj%7Jwdrx*cl_-dYqZ?ZE|Rvw@vRDqAMJ^-SS*a27t zYfU2%3A3GID{?2Oz?q-0ZqpAWf`I##5ZtM$d3Qr5rJOc8l^3BABDxmR{u zvX;aXVcP#=;b9!c zUI(|}jQPNCI)y1n<769Q6mQ>mj8?0~UXcraRg%{v`L-nAk>tCQ+>zvaAWkkFbOUJQ z6fWHm`r)BdK~vP~s)>P6j*gscE1-ZWLi3$6^oIV~2TY-9@_W+YO)9jWgOa?`fGk3b6 zajfkWPwxS@Qk^c1`w08ARup8I-|u0|e)J;r%BJ-{!eK_g1t9=VwpP|ta0Mu(&y9eV zslZol3XWX`xLVd$^{NU*Q;2p^OKaElvUU-GtgN7zrBw_Yy=|ik>84hMd|NLYRYQWi zvYADjg`O1!;dE^gD=5nvy{6j$a1z{Ex@|~sx2P8Z^YGK3%}#;3bRYH14!(EmSs6bE zUe|YBVY_bnp8)ux>mKyIPTIm`RLvyVV^k9P55N?W(3HtoDTfrvsKhG36RMwGwXUeP zdS2NMVW}WxGYHtb=qTpL#m(J*ptQy72z!dx-V}wjkNTg3&0&-hIJE$^9tDuCJLwL- RFN3m3{v#k^?VMIL{sWsPR-6C; diff --git a/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/ppoConspectest.cpython-37.pyc b/3DOrangeTree/a2c_ppo_acktr/algo/__pycache__/ppoConspectest.cpython-37.pyc deleted file mode 100644 index dd785bebf0ae9f3e4f6ce52f384d05b44ee2c4c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3877 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 diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/header_pb2.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/header_pb2.cpython-37.pyc deleted file mode 100644 index 1c2bb04facca85ce50e82692a355ea9e0a23ab04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2247 zcmb6a%Wm67kV{FFL_O`;j-7|&=F!9lOL+io4?)nxPMQFXZ8$Da2n7g|JCbNqB(Y05 zmXKR|HG1t)Iu-3_^fUI_lh3{N)EQE;<-$NxE_Qcjc4l^7JA6^8m>PcOhfVhvg#IFA z`mG@FEl&9p(=@Je=4&ktv;)Sq6^-kMnpou-p8Z*i?(!V%EgiWGKhw*$a*QPM2pg?@ z0v8Z2w2BE_MA&SV64*qz+$u8-N~6kHYgHk4P~#80_Suo#rM^ znZ@OUhOBJ+cU%-Z7Q~z^|NPqQhCOJyT?m@H1Gj67-mVA_z>Q@y8pPc&n4lN29|;YG z+ug7qyBkpyZrJW&EH*l}=Qm@Jar4R6X2{`vC=TVLhY!DM_I$eoK`bo@j%3pfd%b?( zxi%`XLMOei3pNK~Mb6_!G*E@7zTI=U{Va#Z{*6-;1}+zTBtH@#sS-bEBMkkRf}(FL z!?$BEc!d5M5V&Z{IujI$bKeCiPIM+f9x>!LIY?J{5gLYAz6VmG;dCIN?PFZLFhHy( z2R$eBEpErQV@qPFo=cJs!_RlQ5s5Gk)xu>_QATq3r2iY*XZ~NE^Ox$p-7rh9lVD?V z<8Z!e8Zx%yzFcN&>_Kk6W={QH){#(raqrJR^xHoKUOZ^L{r-89$HwMN3U|^BIul#h zvnm_dJy7`w%L2ov3^@p5`&d;Z2+#JtA#jY5nzdrMcA5K)89Px+V&(Aur#Kra<0-v? zQ_AkE^}3kDT@~AX-?tLua$dmUSQ$aT=YUYzco2aqxKU&!P|mj<@YP(`mKKM$-S=bb z$oBi7Di_i6q()M)BA~t$thpgN?FC-YNeN{S%l|lrKw=T8+8Jm`H^jU1VMNs>RkrQ< zAWCTO@WCfto!ow^ldnbcQ5)v^aeL#N(>FwVkITe+L2X$TNIOM9+(%U0A)3+lz~@q# zXEsSy4)7ggo+ui0GWAP}FG-{_b%xsxT6=|P^)qox*g*%yj4*((EmeIc@t7PDtLh8| z0zTZh&>6W8voiOb9kiJZ(-xkziR0%6#+8vVosDd?#zbK~+=UqZnl8{*c=@g<$aO?W}XvN?G@!{hG1}@#-_^F>zB{BUheJg?d|vEipFd`4|ra$E{*m6fL>Q^;kRo{X|Fg%H=X%wPpZ fYj(01ST(^+9Y5qqrBbMnF`21XQIDB1GY0z?C$P4d diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/observation_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/observation_pb2.cpython-36.pyc deleted file mode 100644 index aaeb9ea40bf1fa669d74f04252675f2bb0e7a844..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5026 zcmbVPPj?f^5uX{2q|xZFg>5Xu0yefmW|52yED%C4*aou3a%}D9WiFGEx+RZxG}7xC z5v<3}x%%ajFOl5x752Cvp$~a^FDHG4oKn@Je>MWlYMxrvHPyeaKV4O=jbu`<8M(^e zmnG@H(%9!Z(9hxPt*MekBqBSKAyKIz6DcPV zS45p~Gh##qtpTkWF+s2 z%&BT*fqRKekt~rZ($nM;>;?M4GkqEsoEb6;PoGm)1a+Crk=$v_n4y`*ES))#VIQ?| z87X5FmnPkH^co-r+j>|^o-B!5Gm zlHUrN~fWdkg)-4@6!#jR#1%xNRxe< zH6MaUzN4weqZ0|v#UD=O69u@BiF_#K4|-Ti_Ie>0t1{B?!C(Bogs%rxMfxCtsJ!w6}3-+9GqtJws}s^zzs*{U>X)%S|6ibvTy%ePyu*{-Y?+Q(db>R8PRv7UudANWcv z0>c?~6<`Q;bs#=S4T${-+NbRChy!TuJy1PD-D-=_yv)$3kr@nu1?F%Eke;G$r)m1f zZEF67S?xAuz|;x#s?2VK$}o#Ispo-7_=3@z0~UbZFiU&K%}UELiRD`r%R_B8$u~l` z!`Ur816s8i_yVJb9-C8c$hTALtA$DG7G92|%OD(p=JfOcg%aVoxe$OPUQ5{>U9UMU z%MZ9JaO3N1lcCS+TG+vbTM!1oS=8spwx}Liu1g)W39+@^`dnBTb5)-vc9Xio6mTnq z-M6VX7a5p3en5q((a)JWrq9UKgs!?)lg??dGB%&nV?!mg@Cwh2@T~G8t7pcy!#AsW zeR`t*G+o^*?QLhIY*Y{J@4d>%tIzf6iTlU(=+^em<`27NkWTCISEbEe^YG29z0KW> zyr^nQMu9Pu3B6eU`Jc+-517q`x4WAncQJayv@Hc$Tj?Lbyvl`TJleLZKS5&fhZW*#)4}#+o6I|k>ZhemeZjgheHVl*e;w9ak5zs zcg&2LwTIj)V60_b~9$q3ISU`fUtVWY{PbxHx0o z`(L@Nfak9VdrLj6zdQMi@FM#LChRf}b2!Yyz_n_-E&Rp9j#Z%!pE|NUlhB&gaePzw zmM70n6a8WuEQ<}RFIzysgbiKey&ohdPY+4ct748~R2W``?SEmAe}UnQde;W;1GGrZ zrVjDAKE&~O!i5$E#}f|?z8O@1F9>;Zpa8Kd4rP~6smyS>$t<@H%OWk8wrU<*#Qkmx zne%bzE?>y+JgBkVI~S5Jh=Sb1{>4A4#@&Y(!vLu>RlJu1xSocXkOslKer@hP_&Uh` zvR(oaV~8m6v7+8xyBOT44fL>u_u@EU%jch|?A_-V10OT-TyNkLdqVfg#c(I}6Mm+! z=y3v7Kc3;%AFM$ zFV?d1Pk6{XhOB=_ndtSlTWfK}tnj&dt5tVsaN(+SY6aW%DRV7{iF2Di_nL|07l+z5 zxEL}#m0UCX^^D<}=W%m%L1anfWXyAyM26`Gbw4PQJc{p4QsJo`Xh>Tlc(j+NwxK?a znEVpXf5e_OVj45%%hKEZgYCn^H>JJupZ2%+4@%_{pFN;;8)_XphmpoPUQ_-U+;`aw z>;xdC7l+#iKW>)CLD&+!W3xD1!C@H(bU#FEs47qIV4WQ?j4R_{LK|~ux3pQ_+AMGK z2%&gC=jjp_(a|bC_0g)JjHiM!ZdQ&(6K89vL=lxp1$B7%2G1dn;4L0{GZe^SPZx50 zX1w=!gH=3BhfQF}8#?c7RQT0b)TPXV4kEg3wdK4G{v4n~d9*)))@xUN_5{^Q55mxY zCr&euW1}40V3Ov(#XMT-UufdE=U}1@q{jZph<|3H320A)GCPiucibNnxZQ@@PgTwq*Rbp)uFT;$ZG;qm30L^!0TfPN*if# zPC8gMSUZ?$Lc_rfbyelBpQXe))CY7O=mWGWCt#+9A|r3fSwUxIJ$RIqk^*mNsv_$l JT~2`P{{ij#(YpWu diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/observation_pb2.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/observation_pb2.cpython-37.pyc deleted file mode 100644 index 04121308f2a4d2f71b5552eb37ffbe3ce3897ae5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5088 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 CJnduv diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/space_type_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/space_type_pb2.cpython-36.pyc deleted file mode 100644 index e0da9bcd92dbcfba18fed9722c0a1a7d621acc3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1785 zcmbVM%WmT~6eVR@mgQ%h#FI?Y^j*MR*l4pI3_49xpukLGB%T)4My1SaM;<*4QcB}= zcJ4MG(stV~=x1=-ReqtXUdl=A39@J_f>(!^m*lw*a=%t{ess6}KT3rBMOMBV;;*pF zT}lWioQA|DKqi!vZNiN=MC|bbH-911Pk2%PT?4JGun?K9N%e|SSd1*Ulw%vQ?Ur*~ zM(nti96N}sZY{?Z#C5k$3DhQyIdPj%nym3Eukktto^n`Em?d!6;3C&3xHs=)2F(*$na<@2fw|U!r3Y*ZH?C`Z` z1g&Zwe@f7_9u$f87tTOB2Og zf~NHNR}_j~3T>Q=zy02M5Wfu3cI7nx`ftaNiX|F#^&y#onGVMhn z8$+B*58?~i8zxbNmP3{%!b|)K3{%;YQ#J%IolU`;`d@aZGi5&uS>$u}yr}75C&EJU z4qF2iIa>$8TQb3r&b52Sv9dyz2Jsij+=6(RaOhB>eOh`U^v3y~_a~tB8pK(&Ao7!7 z(U2|dnI<};}c>dTedv8(<66pQXu zBx#~H9t)YW^2z<|cXY$~Kl`>G-S_jZQ$N$$7+^B``utYav3Y<2fE1dfRd<|W5@T?) zB$G}0^{0RSW_Mg-Gh}JpDa@B-}3F4%8XeAs)UEU!7wUI&f=6^s+t55 zurRm+j+LX!q}e*ZEKtpS1qg}!y&xVX%J6)(HBORo2#ZSbvr#vQQxGu=MOm|GJeU^x zrl^XyEK5<*8r!=qYEfMnEDKxcXH_-52gNPwT3tGX5zE3T*qY!2`5i*gQ+ z&JIq$?GH{)Rs9Ilurjx<$KUBFt|%McS^ves(cp*vQUCO0aH86$Fb*Vo^-N3%HT6swF zhfzNw_-I85&q8>vpBniRg-!Qpb=eAb(WFM+s)ajb7$&t)XVJyqHWn7P;TR6;%z{Im Hf<^xUd^;I5 diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/space_type_pb2.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/space_type_pb2.cpython-37.pyc deleted file mode 100644 index 9b2d0335b35f82dcacd8dbcb5e2fab45d833a4d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1847 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 diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/training_analytics_pb2.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/training_analytics_pb2.cpython-37.pyc deleted file mode 100644 index c867d2af2d43a9b3149e35c060b236aa57b11cb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6454 zcmb_gOLyDG6$bbO!KbN5Xv>yuHA$nkqAa_yliG2jmmM}XrOJw$PTPY6VuloC5a1br zipb-gyY+vN&grIIbk%J)>A%1>E3UKas&@t;M2fIz(jgAOd3)oWWTV!MWEW&cBJF z0*qe41$+gIqyTsPsECVr2KJc6b8yY#c|d>gT0EV>r85zG*F5_N{M9#XeGy;73xK>n z!HOGr5%7@-R@}t50DpUe6-)RRfd6oU6(8Y`0sl+5XBp>AH~hND?R_^ozQaBSK7Nt&0xImIeSL-6VMrQG!FnSX?i=qXr9)R5s&1@0#CBHiZEaeZd~ea0_S&60_g9;S+90N5 zE5tmuS2e5IY@52K0ujZkdHXq3)lJ=OD5|L%9Y@z}rB%CIZgpJgk)bwgSbYq6MED7A zfhOQF#4qEC^ULzlE8!Hv%NY|;r0OON)zQs0;5|W14UV-eQYMviIZ#HJ)8vgL^Z+em zVrx`y!6BiSY!cfBCfEcebpvFiTPF1KcBfgh3T2pNX$epibJaivU#eTU(Eyr?a z!=!~0eDYrVJ}@r75B*{&{iXl@OOzM)eU)sR$2zslCTOr?>W;1&dY9m0NiGD89TRGU zJWAp%@sm{XhCCO{FpVqy=?I^mmvf$V1>;dZJ|}0nSp~x}K73Wa;tgYRtZPJZIxSL) z^QnR?ne8UGs!{?*;>9KTnm^J%veHti+9VE~u$1JO897bcred|23hk1_NG<*FpQyah z=Xir0s>ixT2ib+w)%;<_1cE-VvvP);E}`DRJQi=sC350W-L!R0q2zm&VmPH*GYBp* zW~JhSJj49u;v{2PD#CKDO?AuGoz6uB<6J6UlZ({E7w4D^BqoFYNmWD942%0!e|sha zsR%-)1oohy)Zk=H5>gS=bFABKSnBx;Eu~;Q#kORkHHpIw2SW)#4`X#tpSb4EM^RYAcx3)wba%$EwjL zZg!}PGJa6x%TS6i6JWI5JZQ%8<2fJ5=n(r)90LAenJ6DL6 zrlHF8&cxeec^O?2fV9<4FmW`^kp~8#I(2yI)L9 zEyx-yNWC?yjtLGSe3n7tp$Qs=CFU{lIgEZtdPi?f>rz?)HmotT{9+DgwY%>j8I5HG=-!GD<`k2>ao`t^wyGU z3S$}EW3W2wrFrxToXjuH#w4yV(Oe|a%P`8LrQH;o94QZbSw=ggHk?BGqXlL!2h?4^ zy6irf*s#5_w3i1e`cududJNvux}OKd8cUVsP^w&pBQL?r5m(;YezCb%+1=mSb7e(o zTDWZxMcHq&udMG@_%1KGQM+Ti8NXIkbhB=`5v7Lm4a;g6#Czeawd<5yUm9w^{tGZ= zR^m#EU++<_+BCd<^k0N2S4cs*@G?x9BvEq9D~V$YApM0LnjM zS@nFtO<=;_-O){De{a1~tyG_GR}U(CJJsjg)qUviSJt0Z(DoL(9soABzg|D6?CcHB z&J9+qwo>bOIck27G;~PWbogB8`cq;OszNS@42ly(YtIk%}Qy%#zk3WSEV-D@m@bsn(gU#K*T<3;OhkYw!uG9z?TqD@sC+eX#X2b zOA;5wO#g~X@t7FlS0>SKK|c}`6QU&M;2DGe_v^9M=TwG!-VSmEez2=|60ar2COgkC d-Jhp7%>U0xGnC_~EW#DZfj;DD@E=Wx{|Ae()vy2n diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_input_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_input_pb2.cpython-36.pyc deleted file mode 100644 index 018e23bc9c16cdff4177254fd23709a12eb41f74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2905 zcmbVOOK;mo5av=(Q%}p5BiV`LICc^pDxpb>pg@o|kGc?$*oLDNC@%!bUCCtl5OyiU zGICR|2Kpn~L;ExG3wqvbPyP!%b#^IQa^f^jNN_njJ2N{o`^}IKN+r$Go7VRgMfpdW zyP81%01x{ODGF9F@)TVmii@z)RIvI+q3bw>)4wXiEu0Z=T?MJEm-5qk1__NE&{;hv z={(SReL>O-Kx=wI(i+f3y@(W2a7zo zWYMjYCAU6M@#1MlufzHZuHhw&NFAPxdkrt+I#^r5*Kh;ICPvd+QXsW@T9tBZ_&TiL z_&>RUI#9$77Mi#ssdao4Z=6>326)mW4R;kUHx*+Ie7Y`YYjV~gb@v9YJyJ;7T_^Pk zf=CwJo47`D?nWPxTcm++;muQZlF~Op<~G?BGWa&B8(ZMrHYvJyCJMy7H9->J2EfO&Y#c=9F)uMfC0+;ygz+LKLlR(sw?i0zKNBZg9}j!x96!(2 z$yZmAZzst;6RqN`AO=x|f9$kR9$h^X^G6;R@R?{zXMe-sM3AFtUg(-gPG0OQazk4% zrQ3p+?K{N7jBDrKGF}XzZ^9vqJc*SgVn*)?l~NKWHZ70PCBdtns~gk|2B4M=0}}Qb zug;-{MJA1Sd5!}BI=O$LATI}b+_apeL$_3}J^%65vxDw_Z|{I>hT(^JLsGa*R^L8q3IngD&-%r7lsF>WTdrl;>@ crm1j&M64H6`BWK|k%lz24A!)imdc|40QDNLx&QzG diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_input_pb2.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_input_pb2.cpython-37.pyc deleted file mode 100644 index 6efdf60d5659c2b650337f6dd42cbe3b24cd36f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2967 zcmbVOOK;mo5av=(Q%@^aEIW?lIL<=_EG15#K#(@E>q0A zMGEMoo|1GL=(Ij1=_#N!JtJui=&YVa3dtPjP82;4b{VJ8E9%p7J_~e7zXbD%?hMZ1 zJT4Fw7hfSV-7S+#-Ev38(?djNJPg|!k7%kW!d5O1p*5P4s7+xx%injiMfujQ|l;!a6ul0Se zN9xu-aqBw+Yu}{39qM(76|lNL2=+a9$WC%U2-c(4{;IiVt@^&VYFf_&y4o>qrydX% z)bDSsdzk#>(dX>m-MgRHdyd&5ZomxUzF>9B>-GAsZJFT2@LJ(|AP5GA?fU(|@LOv& zf56iZ9JANL=EDR;{0}?|O~Npds7OX8Dj@t)IflJC5tUK5c+xQg+r0-#Cy8r8JXJ(R zIYtGb!m;!zi4<_4tzp6}YWol!aH$?)45Akkl(Zcvj_tX?71*HH@*D%3f!Q*dP{@xg zMGhb-g=tY|lo?2`k4f#oHXZvALiOB{(&48cR#H? z>v;Z)3kMk$AdGW<^TQ0^u2JY``Sou|E9?p6Gz4$}t$|niN=rw}RnQW;lUci6JFhM^ zX}J4j%=CM0R+_%OU`3UlK6{U+al?_{$2VX9sV>XqYEPd$lC4l%AM1kcunAhjovJ2y z+%{vj*CLe1gMm+Y+VXuvQVGXw5r&!7q7(lmWK^|s*0NY1%n+xjfQoh3!*q_v972M{RCKgOUROK zn>d(p?JQcxvo4&Yu*srMVkXL%(W)@XMQLKQ-#EZ=bF2Hg=lZyIeDjo`?GmF^pzkq;)aKSMTr` z8$iA<2o+lf6>NK4HCnvT@w|>h!cK4X+f;yzX8@tLChpc&W;j0wO*Uo|-s*3E#n8J_Rr+dzxL z(eB4Pnt5A~XG*WCd8;_ne^heFc_STqLdAxO5WX&({l8y}sr<2k0h3|+iBPs8tTQyd+sA;aU?wgNgULMTL@qPdJXPNF`~89OFrWP8~58L?c%q$91dKLYu4 zB>o2A?<2(XL-EhRTo}@55oM!0mW}}(iz8LuNwt`WXppFJltgJH#`y3ZaheJjXoPkl Um5$|69%)EZ^WaU3X|W{w4*^5SQ~&?~ diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_message_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_message_pb2.cpython-36.pyc deleted file mode 100644 index 5973ec65cf3020cfa717b630a341b891c04ea95d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3138 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 B4Ilsj diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_output_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_output_pb2.cpython-36.pyc deleted file mode 100644 index 454819a4d6e063cd31aff29d1638d8df8d547b15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2931 zcmbVOOK;mo5av>E>gk6Z$xfU^iBsz$p$Yl`8U#(9CJ>NVhNA#2FAI{plBrOnu%ryj z$W6T(=-)_z{)zmB-uBv)|3XilU5XN&Drpi?T+YtU%+7o}GvtF}QKNd@#AQYKTZ#SZ zK>rB0|2t9?q7dXLxT8AVk_1Wqri|~Blz8eYNTr>`D53KJYusTr5+C@sQ!ul3jCmRIOD%`2zHL^*nU~P+BBQ+T71kEo=fz#%;~ zV{!v^poj}B)Ja)VyW}Rhby3l4;7OgAIZl$XSh6hd0RjLxq-xyR6diqlMwUnF2B2ouQcu+^-0F zsWkU4#ZetzCSbJSfaFg+#eD#`pM>F!0;1^fEesr;F(E96e@Oep8`1X2c8s>wwoa(q z@+WS4;@ZKq-DA_>G-w}9gA>o~Q9o#p9AiM;z{k`*_1l&=8iAx`1RlelIiyzLhpO0{ z1mj77$L9Ukc*?U69b;q?<55aD1h>M{FkJCh1%~uj1LBP`1c+xMK=qKP9V4*aufg{; zbuEw3CSoG0WgJWxmNpkVfV4)aZ!voe?!hcGqP`FAiv>pe4tQ&OF3igQbYyxCCPrYG zhA#w4OHC02a5f|)m^rb~fZbTIZGg-+9Qz!6_1u`$`8S`5T5HU_z~h^%;MLP|@xkOz zIA86{EU&M$y#4(rySV@%^mO~#=V-3PDKyl0_ZDfDS0eYiGJlQ)5bHl^xy6n(bPMh0 z@9(!(fzy(z$Is)+zi2g3Ub$&amA1b9sIAVGV~ttV8HAa+Y#)kD8@{p(fsT&w)yy#OVGlvpLHeMifOkDz*Zd0HC2afZ-4~HIe zk1sJhUs5Hmso_j0FJ7G%=0zE*G5=sITs zb$uu=US5#cw>;Q8myn#c*x;H0%mJ?CtAz7l1%|z<)ES@I_ z6X^&7%g)UTf>Xiob#GP_?97ue>v%@2V`A!!|3`t9Kvh3j2+Fq{CSHKA`c8zaEg8K0RAk(ep|9arhn?Q9-B-OM z_#bzBUA_^rpjF10r7%^oIh8fe?uZy}N0J?|(Ruv5qd)F-x`%PSYP^R1NS$vT(}4|n z&aOJluRo(MWd;<0Z10xmya->+J<&rl^9fH9+X~p0h^`!2iq`U?uS5l3#7746X?I@# zd9htI$wpGKPX+n$BR&)0vm{LFN8)3`cVWn)T~vs!L^c6*B8gOarPWF*qJg6(Q5t2D h7?bm7G}Bc0fkdbmQrScam5_!swFK6*gqBF7e*tvdyiEWA diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_output_pb2.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_output_pb2.cpython-37.pyc deleted file mode 100644 index 325fb79410ebd89a2b0c04f89f0be538331644de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2993 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 diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_output_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_initialization_output_pb2.cpython-36.pyc deleted file mode 100644 index 961f7fe0a75c103c456bb713c9a61b57600b981b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3736 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 GFa8Z}3(M>P diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_input_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_input_pb2.cpython-36.pyc deleted file mode 100644 index edad3d6f5779ed01ae0ecb59537067727f630bd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4229 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 diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_output_pb2.cpython-36.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_output_pb2.cpython-36.pyc deleted file mode 100644 index bd5c1da7af491e1e959335174337a5f00c86086f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3830 zcmbVOOLH4V5Z+xqy?R+#-zbip=$@6F)WuXS!#%ayheQtu*gl(X`*S zna>LFpTi^mFf@&7RChH?V_H|I+KNVv7aG4tV>JG~)?cRy{I?9yO1iOL+)C(Zkpezx zr4*kAK5Z>1egSyX$|&9hK5J!ljb*yIv1aALF5?z@MQagciEfEzX^!TZK?`G@Eq2Qt zofeN1RvG3l(M4LKIxEAI=w7B}dI_vA(ehF_2@)4bv; zbd_E?E?P^<<5hZX#^c-cy7G8~-T=SLfMRW|ci*Bn$DwER68WBBSO?8p3IkZE^-*_5 zuVaK5K!2HKyDMW2{N5hxW57JYbcb#zOcjNxO5d5mbeFyhn8FqQB}#?lJz4`K2CdIx zpWr!%hApuQqEa}+th`S@PzY8b=U3QL_bM%~Xyh7OWlQ93)Sr=5KvH3=Ah|oyDR-~a z>Sr3ucWc=No0(&Phpe-GF z_~1W258)AUAm3@As_*>>MCz|NDl77Lr+(!3SiR@CcD+?^9Wk#a23~#OIl-{r;KSf$ zP(K(3N50o!BB=LVyTiOd5azuU^_Ji3fo97Nd`|pkm$d>BniB33e-QKs0qHk4YyF{2 zf9Be~Cbb_V5EDEaPXaju8R|BKYy$J0)`k5YV~ob0OuBa9cpm`#B=cH6WmTPHV5gyQ zbgXMeX$w@ypITxJC{eK! z$7}m28EyanY}ESP4}5uPUgoT%n%o-v1zTsnvGdYg=asDsfIW>b#JTp{&xTogj%VR; zcVBJi0pc(1nx@j-fmDcP<9ci(v$)IE1gp}!HFW|${B{M4=%1GnTeOSJ7CMYT6BH>qGydNo>_<_B3v_L#$K=?c+oc&N?%W% z8ZgXkemdXjoJd{=_=&Nte;rTjMdQm`zx`yaDWlrcUA4ZbJ)EhS{jgw~lWngiWZbiR zOs4vF>xJE6GAV{$V84<%!MJ0)&WKSscQQ*^pLrC@z+pnpNz&+(i|)kh_+^;h(dTdO zqNX$#kpVCyGnBc9Xes z@yHg0vbH^N1EO5Z+}UAvQq`f^0t0^`TWI-^K*w{uPAJGa(79d(%o9-dvJkOEw0u}Q z<@d242pMlXE^`bB!TAQr1Us)_0BM{<{Coq3d>v)Uw!>U1q#1b>GV4LZgdM|JaAt~1 z@H=Rdn?j*>(`CGbvSMUTxb1boEa`j9ZwpzRIRYZEc_8yM5;zU={0Sd@e9;{|R~ixv zWAy18TGzn%WC4TGMu|btes6np|4m(m=Lj!_5mc4)6u09SAaYJi8r`|zDsrZCjW#c6 zRD*Jyv@Ch1SB>sn)Wd9tJIO*!CqDpjeua2OAD!vV^SjRgyYSg-wQ5N7(c@EIB852V|#V;AhVo|rAG)PkxI=I@*Ij&kHT7)DV!&?X|4Tt zdUzg8t^1LpdOso556GGQnZBf`8MUV*yw34Hm-#19*^f@cz{Ej@BY`YD!7@J;ShvaZ zy`9Fla5+A29Ki2zzp+ntcb+xA`0DXqV`uNlz7okKW%$k_bL7D0g6&V*O#W&3Ix-ns zH|M#FTs;Gqhu>P|IZCoXBDHYEeAtmlbEtYPUxQe}UUhl4TZ*ZITsmYOxNaFgn*@2~ zE9Nn7Lnl)gaLacmpc~k&QPX1ZOm9<>S;1}dK6^_d-=4(}(`^czdZvaz^ssBhB9CZ;?{jJTfE(>l_)ZW{0bS*RIu z>B#a_JFm1utMj&{$vWs|o^80&)HWThn|y6uTqUa>6OiSNJa|qg6pb6Y88b1ySW;gC Goqqr^7?7R- diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_output_pb2.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_rl_output_pb2.cpython-37.pyc deleted file mode 100644 index 09d96138971473796d4c9a082a85985b3a06d5ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3892 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 diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_to_external_pb2_grpc.cpython-37.pyc b/3DOrangeTree/mlagents_envs/communicator_objects/__pycache__/unity_to_external_pb2_grpc.cpython-37.pyc deleted file mode 100644 index ab01acf8b83b5964bf87453244c7e76e495ca289..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1925 zcmb7FO>Y}F5G8k4tF`bWrg9=zm6QBpTD4Z&45ug?f$N>sni1m`uM|PJA zNu`#cT$)__ADmnJmw4@|e<7#Na3xtv4Fe^>S+fnVYw_@VPdUgps|(k*k^A+?Qv zAPQ;MsNEaq12bWn&^qo3HoAC};HSm#U~vLd-vc8^mvYkeIOQIM^0^P80(Bw zE-_Y5)I57viC1Hx4bwsm;&d<-%6_7R9ziOCadG{+T?_5zIFHqYIcra{6wu3!W=!O- zHRIB-wHy{nxGx3dOUw~;yXUeyEy~~!w0oUJ9_Ik38st4&`ANxazK&K>541>M*zz2f zzlhoakU#v{=*vtrlD^0rXA}6SGKlQJXpAPNFY~#(?){3cR7w9Rev}-IM)D|5UK(}O ziw9}L06>k$Pn(j9-=un}zj^rZ+s5+tc=;Q_ZxnYnl8HG>@Yc)~Z#1zHV*?-&W1Gm3 z2n-1W>d}x+4{s_Pva7z>(*_PgfIQ9wW46LrCiytU^%i5V#&KGFQM(Y;0kdN6;5#2o z8Ky>_MuGGHcNg5hF;Agh4-%mgJOT$kaW-MbD^m2qdrHv@IK`DIar&124xI)) z=1&hhBImkl`l1>qF&EjSI*JwC7+OvjtpDs(KuLKum!>+%Mybevkb)l~StBiwkX+aR zA-9!|iOpDJ747!(_OsKoUs|WF_Ic~6-Nc`AVW8OB?zg3Rb{(swlvFieZ9(F;JZ~4E zorHrf&Bw4}E$`z!LCfIQJG4TlU)_dMeZgp`sM>=)>MojnG#G5<0OYrF#Y15_fVn6h z`b*(K)x^^s+{ds0(IG=RBSX*l!(do)Hbn6m&^MkTS7q+cy!YN4e@3sOng7BSgA)|G zwo3wp;@(0iRyD!yFQwvID5kYF6}U}_Y8&cPNYFl5(G>=@0-30cTMGlMZ7i+>&zX?l)J*yB88y4`o_Eks& c7i%TOC24H*eW4LQ;BKckk+ None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> AgentActionProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"continuous_actions",u"discrete_actions",u"value",u"vector_actions_deprecated"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"continuous_actions",b"continuous_actions",u"discrete_actions",b"discrete_actions",u"value",b"value",u"vector_actions_deprecated",b"vector_actions_deprecated"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.py deleted file mode 100644 index 667b91a..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.py +++ /dev/null @@ -1,83 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/agent_info_action_pair.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import agent_info_pb2 as mlagents__envs_dot_communicator__objects_dot_agent__info__pb2 -from mlagents_envs.communicator_objects import agent_action_pb2 as mlagents__envs_dot_communicator__objects_dot_agent__action__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/agent_info_action_pair.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n?mlagents_envs/communicator_objects/agent_info_action_pair.proto\x12\x14\x63ommunicator_objects\x1a\x33mlagents_envs/communicator_objects/agent_info.proto\x1a\x35mlagents_envs/communicator_objects/agent_action.proto\"\x91\x01\n\x18\x41gentInfoActionPairProto\x12\x38\n\nagent_info\x18\x01 \x01(\x0b\x32$.communicator_objects.AgentInfoProto\x12;\n\x0b\x61\x63tion_info\x18\x02 \x01(\x0b\x32&.communicator_objects.AgentActionProtoB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_agent__info__pb2.DESCRIPTOR,mlagents__envs_dot_communicator__objects_dot_agent__action__pb2.DESCRIPTOR,]) - - - - -_AGENTINFOACTIONPAIRPROTO = _descriptor.Descriptor( - name='AgentInfoActionPairProto', - full_name='communicator_objects.AgentInfoActionPairProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='agent_info', full_name='communicator_objects.AgentInfoActionPairProto.agent_info', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='action_info', full_name='communicator_objects.AgentInfoActionPairProto.action_info', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=198, - serialized_end=343, -) - -_AGENTINFOACTIONPAIRPROTO.fields_by_name['agent_info'].message_type = mlagents__envs_dot_communicator__objects_dot_agent__info__pb2._AGENTINFOPROTO -_AGENTINFOACTIONPAIRPROTO.fields_by_name['action_info'].message_type = mlagents__envs_dot_communicator__objects_dot_agent__action__pb2._AGENTACTIONPROTO -DESCRIPTOR.message_types_by_name['AgentInfoActionPairProto'] = _AGENTINFOACTIONPAIRPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -AgentInfoActionPairProto = _reflection.GeneratedProtocolMessageType('AgentInfoActionPairProto', (_message.Message,), dict( - DESCRIPTOR = _AGENTINFOACTIONPAIRPROTO, - __module__ = 'mlagents_envs.communicator_objects.agent_info_action_pair_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.AgentInfoActionPairProto) - )) -_sym_db.RegisterMessage(AgentInfoActionPairProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.pyi deleted file mode 100644 index e3711aa..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_action_pair_pb2.pyi +++ /dev/null @@ -1,57 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.agent_action_pb2 import ( - AgentActionProto as mlagents_envs___communicator_objects___agent_action_pb2___AgentActionProto, -) - -from mlagents_envs.communicator_objects.agent_info_pb2 import ( - AgentInfoProto as mlagents_envs___communicator_objects___agent_info_pb2___AgentInfoProto, -) - -from typing import ( - Optional as typing___Optional, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class AgentInfoActionPairProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - - @property - def agent_info(self) -> mlagents_envs___communicator_objects___agent_info_pb2___AgentInfoProto: ... - - @property - def action_info(self) -> mlagents_envs___communicator_objects___agent_action_pb2___AgentActionProto: ... - - def __init__(self, - *, - agent_info : typing___Optional[mlagents_envs___communicator_objects___agent_info_pb2___AgentInfoProto] = None, - action_info : typing___Optional[mlagents_envs___communicator_objects___agent_action_pb2___AgentActionProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> AgentInfoActionPairProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"action_info",u"agent_info"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"action_info",u"agent_info"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"action_info",b"action_info",u"agent_info",b"agent_info"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"action_info",b"action_info",u"agent_info",b"agent_info"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.py deleted file mode 100644 index 57bb77a..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.py +++ /dev/null @@ -1,123 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/agent_info.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import observation_pb2 as mlagents__envs_dot_communicator__objects_dot_observation__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/agent_info.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n3mlagents_envs/communicator_objects/agent_info.proto\x12\x14\x63ommunicator_objects\x1a\x34mlagents_envs/communicator_objects/observation.proto\"\xf9\x01\n\x0e\x41gentInfoProto\x12\x0e\n\x06reward\x18\x07 \x01(\x02\x12\x0c\n\x04\x64one\x18\x08 \x01(\x08\x12\x18\n\x10max_step_reached\x18\t \x01(\x08\x12\n\n\x02id\x18\n \x01(\x05\x12\x13\n\x0b\x61\x63tion_mask\x18\x0b \x03(\x08\x12<\n\x0cobservations\x18\r \x03(\x0b\x32&.communicator_objects.ObservationProto\x12\x10\n\x08group_id\x18\x0e \x01(\x05\x12\x14\n\x0cgroup_reward\x18\x0f \x01(\x02J\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x0c\x10\rB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_observation__pb2.DESCRIPTOR,]) - - - - -_AGENTINFOPROTO = _descriptor.Descriptor( - name='AgentInfoProto', - full_name='communicator_objects.AgentInfoProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='reward', full_name='communicator_objects.AgentInfoProto.reward', index=0, - number=7, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='done', full_name='communicator_objects.AgentInfoProto.done', index=1, - number=8, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='max_step_reached', full_name='communicator_objects.AgentInfoProto.max_step_reached', index=2, - number=9, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='id', full_name='communicator_objects.AgentInfoProto.id', index=3, - number=10, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='action_mask', full_name='communicator_objects.AgentInfoProto.action_mask', index=4, - number=11, type=8, cpp_type=7, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='observations', full_name='communicator_objects.AgentInfoProto.observations', index=5, - number=13, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='group_id', full_name='communicator_objects.AgentInfoProto.group_id', index=6, - number=14, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='group_reward', full_name='communicator_objects.AgentInfoProto.group_reward', index=7, - number=15, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=132, - serialized_end=381, -) - -_AGENTINFOPROTO.fields_by_name['observations'].message_type = mlagents__envs_dot_communicator__objects_dot_observation__pb2._OBSERVATIONPROTO -DESCRIPTOR.message_types_by_name['AgentInfoProto'] = _AGENTINFOPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -AgentInfoProto = _reflection.GeneratedProtocolMessageType('AgentInfoProto', (_message.Message,), dict( - DESCRIPTOR = _AGENTINFOPROTO, - __module__ = 'mlagents_envs.communicator_objects.agent_info_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.AgentInfoProto) - )) -_sym_db.RegisterMessage(AgentInfoProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.pyi deleted file mode 100644 index 821d242..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/agent_info_pb2.pyi +++ /dev/null @@ -1,67 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.internal.containers import ( - RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, - RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.observation_pb2 import ( - ObservationProto as mlagents_envs___communicator_objects___observation_pb2___ObservationProto, -) - -from typing import ( - Iterable as typing___Iterable, - Optional as typing___Optional, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class AgentInfoProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - reward = ... # type: builtin___float - done = ... # type: builtin___bool - max_step_reached = ... # type: builtin___bool - id = ... # type: builtin___int - action_mask = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___bool] - group_id = ... # type: builtin___int - group_reward = ... # type: builtin___float - - @property - def observations(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[mlagents_envs___communicator_objects___observation_pb2___ObservationProto]: ... - - def __init__(self, - *, - reward : typing___Optional[builtin___float] = None, - done : typing___Optional[builtin___bool] = None, - max_step_reached : typing___Optional[builtin___bool] = None, - id : typing___Optional[builtin___int] = None, - action_mask : typing___Optional[typing___Iterable[builtin___bool]] = None, - observations : typing___Optional[typing___Iterable[mlagents_envs___communicator_objects___observation_pb2___ObservationProto]] = None, - group_id : typing___Optional[builtin___int] = None, - group_reward : typing___Optional[builtin___float] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> AgentInfoProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"action_mask",u"done",u"group_id",u"group_reward",u"id",u"max_step_reached",u"observations",u"reward"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"action_mask",b"action_mask",u"done",b"done",u"group_id",b"group_id",u"group_reward",b"group_reward",u"id",b"id",u"max_step_reached",b"max_step_reached",u"observations",b"observations",u"reward",b"reward"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.py deleted file mode 100644 index ccd9140..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.py +++ /dev/null @@ -1,170 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/brain_parameters.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import space_type_pb2 as mlagents__envs_dot_communicator__objects_dot_space__type__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/brain_parameters.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n9mlagents_envs/communicator_objects/brain_parameters.proto\x12\x14\x63ommunicator_objects\x1a\x33mlagents_envs/communicator_objects/space_type.proto\"\x8b\x01\n\x0f\x41\x63tionSpecProto\x12\x1e\n\x16num_continuous_actions\x18\x01 \x01(\x05\x12\x1c\n\x14num_discrete_actions\x18\x02 \x01(\x05\x12\x1d\n\x15\x64iscrete_branch_sizes\x18\x03 \x03(\x05\x12\x1b\n\x13\x61\x63tion_descriptions\x18\x04 \x03(\t\"\xb6\x02\n\x14\x42rainParametersProto\x12%\n\x1dvector_action_size_deprecated\x18\x03 \x03(\x05\x12-\n%vector_action_descriptions_deprecated\x18\x05 \x03(\t\x12Q\n#vector_action_space_type_deprecated\x18\x06 \x01(\x0e\x32$.communicator_objects.SpaceTypeProto\x12\x12\n\nbrain_name\x18\x07 \x01(\t\x12\x13\n\x0bis_training\x18\x08 \x01(\x08\x12:\n\x0b\x61\x63tion_spec\x18\t \x01(\x0b\x32%.communicator_objects.ActionSpecProtoJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x04\x10\x05\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_space__type__pb2.DESCRIPTOR,]) - - - - -_ACTIONSPECPROTO = _descriptor.Descriptor( - name='ActionSpecProto', - full_name='communicator_objects.ActionSpecProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='num_continuous_actions', full_name='communicator_objects.ActionSpecProto.num_continuous_actions', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_discrete_actions', full_name='communicator_objects.ActionSpecProto.num_discrete_actions', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='discrete_branch_sizes', full_name='communicator_objects.ActionSpecProto.discrete_branch_sizes', index=2, - number=3, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='action_descriptions', full_name='communicator_objects.ActionSpecProto.action_descriptions', index=3, - number=4, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=137, - serialized_end=276, -) - - -_BRAINPARAMETERSPROTO = _descriptor.Descriptor( - name='BrainParametersProto', - full_name='communicator_objects.BrainParametersProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='vector_action_size_deprecated', full_name='communicator_objects.BrainParametersProto.vector_action_size_deprecated', index=0, - number=3, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='vector_action_descriptions_deprecated', full_name='communicator_objects.BrainParametersProto.vector_action_descriptions_deprecated', index=1, - number=5, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='vector_action_space_type_deprecated', full_name='communicator_objects.BrainParametersProto.vector_action_space_type_deprecated', index=2, - number=6, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='brain_name', full_name='communicator_objects.BrainParametersProto.brain_name', index=3, - number=7, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='is_training', full_name='communicator_objects.BrainParametersProto.is_training', index=4, - number=8, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='action_spec', full_name='communicator_objects.BrainParametersProto.action_spec', index=5, - number=9, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=279, - serialized_end=589, -) - -_BRAINPARAMETERSPROTO.fields_by_name['vector_action_space_type_deprecated'].enum_type = mlagents__envs_dot_communicator__objects_dot_space__type__pb2._SPACETYPEPROTO -_BRAINPARAMETERSPROTO.fields_by_name['action_spec'].message_type = _ACTIONSPECPROTO -DESCRIPTOR.message_types_by_name['ActionSpecProto'] = _ACTIONSPECPROTO -DESCRIPTOR.message_types_by_name['BrainParametersProto'] = _BRAINPARAMETERSPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ActionSpecProto = _reflection.GeneratedProtocolMessageType('ActionSpecProto', (_message.Message,), dict( - DESCRIPTOR = _ACTIONSPECPROTO, - __module__ = 'mlagents_envs.communicator_objects.brain_parameters_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.ActionSpecProto) - )) -_sym_db.RegisterMessage(ActionSpecProto) - -BrainParametersProto = _reflection.GeneratedProtocolMessageType('BrainParametersProto', (_message.Message,), dict( - DESCRIPTOR = _BRAINPARAMETERSPROTO, - __module__ = 'mlagents_envs.communicator_objects.brain_parameters_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.BrainParametersProto) - )) -_sym_db.RegisterMessage(BrainParametersProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.pyi deleted file mode 100644 index 19611e1..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/brain_parameters_pb2.pyi +++ /dev/null @@ -1,88 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.internal.containers import ( - RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.space_type_pb2 import ( - SpaceTypeProto as mlagents_envs___communicator_objects___space_type_pb2___SpaceTypeProto, -) - -from typing import ( - Iterable as typing___Iterable, - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class ActionSpecProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - num_continuous_actions = ... # type: builtin___int - num_discrete_actions = ... # type: builtin___int - discrete_branch_sizes = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___int] - action_descriptions = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] - - def __init__(self, - *, - num_continuous_actions : typing___Optional[builtin___int] = None, - num_discrete_actions : typing___Optional[builtin___int] = None, - discrete_branch_sizes : typing___Optional[typing___Iterable[builtin___int]] = None, - action_descriptions : typing___Optional[typing___Iterable[typing___Text]] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> ActionSpecProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"action_descriptions",u"discrete_branch_sizes",u"num_continuous_actions",u"num_discrete_actions"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"action_descriptions",b"action_descriptions",u"discrete_branch_sizes",b"discrete_branch_sizes",u"num_continuous_actions",b"num_continuous_actions",u"num_discrete_actions",b"num_discrete_actions"]) -> None: ... - -class BrainParametersProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - vector_action_size_deprecated = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___int] - vector_action_descriptions_deprecated = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] - vector_action_space_type_deprecated = ... # type: mlagents_envs___communicator_objects___space_type_pb2___SpaceTypeProto - brain_name = ... # type: typing___Text - is_training = ... # type: builtin___bool - - @property - def action_spec(self) -> ActionSpecProto: ... - - def __init__(self, - *, - vector_action_size_deprecated : typing___Optional[typing___Iterable[builtin___int]] = None, - vector_action_descriptions_deprecated : typing___Optional[typing___Iterable[typing___Text]] = None, - vector_action_space_type_deprecated : typing___Optional[mlagents_envs___communicator_objects___space_type_pb2___SpaceTypeProto] = None, - brain_name : typing___Optional[typing___Text] = None, - is_training : typing___Optional[builtin___bool] = None, - action_spec : typing___Optional[ActionSpecProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> BrainParametersProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"action_spec"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"action_spec",u"brain_name",u"is_training",u"vector_action_descriptions_deprecated",u"vector_action_size_deprecated",u"vector_action_space_type_deprecated"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"action_spec",b"action_spec"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"action_spec",b"action_spec",u"brain_name",b"brain_name",u"is_training",b"is_training",u"vector_action_descriptions_deprecated",b"vector_action_descriptions_deprecated",u"vector_action_size_deprecated",b"vector_action_size_deprecated",u"vector_action_space_type_deprecated",b"vector_action_space_type_deprecated"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.py deleted file mode 100644 index 35b8fbd..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.py +++ /dev/null @@ -1,113 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/capabilities.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/capabilities.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n5mlagents_envs/communicator_objects/capabilities.proto\x12\x14\x63ommunicator_objects\"\xec\x01\n\x18UnityRLCapabilitiesProto\x12\x1a\n\x12\x62\x61seRLCapabilities\x18\x01 \x01(\x08\x12#\n\x1b\x63oncatenatedPngObservations\x18\x02 \x01(\x08\x12 \n\x18\x63ompressedChannelMapping\x18\x03 \x01(\x08\x12\x15\n\rhybridActions\x18\x04 \x01(\x08\x12\x19\n\x11trainingAnalytics\x18\x05 \x01(\x08\x12!\n\x19variableLengthObservation\x18\x06 \x01(\x08\x12\x18\n\x10multiAgentGroups\x18\x07 \x01(\x08\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - - - - -_UNITYRLCAPABILITIESPROTO = _descriptor.Descriptor( - name='UnityRLCapabilitiesProto', - full_name='communicator_objects.UnityRLCapabilitiesProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='baseRLCapabilities', full_name='communicator_objects.UnityRLCapabilitiesProto.baseRLCapabilities', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='concatenatedPngObservations', full_name='communicator_objects.UnityRLCapabilitiesProto.concatenatedPngObservations', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='compressedChannelMapping', full_name='communicator_objects.UnityRLCapabilitiesProto.compressedChannelMapping', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='hybridActions', full_name='communicator_objects.UnityRLCapabilitiesProto.hybridActions', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='trainingAnalytics', full_name='communicator_objects.UnityRLCapabilitiesProto.trainingAnalytics', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='variableLengthObservation', full_name='communicator_objects.UnityRLCapabilitiesProto.variableLengthObservation', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='multiAgentGroups', full_name='communicator_objects.UnityRLCapabilitiesProto.multiAgentGroups', index=6, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=80, - serialized_end=316, -) - -DESCRIPTOR.message_types_by_name['UnityRLCapabilitiesProto'] = _UNITYRLCAPABILITIESPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityRLCapabilitiesProto = _reflection.GeneratedProtocolMessageType('UnityRLCapabilitiesProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYRLCAPABILITIESPROTO, - __module__ = 'mlagents_envs.communicator_objects.capabilities_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLCapabilitiesProto) - )) -_sym_db.RegisterMessage(UnityRLCapabilitiesProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.pyi deleted file mode 100644 index 1c6a1f7..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/capabilities_pb2.pyi +++ /dev/null @@ -1,53 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - Optional as typing___Optional, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityRLCapabilitiesProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - baseRLCapabilities = ... # type: builtin___bool - concatenatedPngObservations = ... # type: builtin___bool - compressedChannelMapping = ... # type: builtin___bool - hybridActions = ... # type: builtin___bool - trainingAnalytics = ... # type: builtin___bool - variableLengthObservation = ... # type: builtin___bool - multiAgentGroups = ... # type: builtin___bool - - def __init__(self, - *, - baseRLCapabilities : typing___Optional[builtin___bool] = None, - concatenatedPngObservations : typing___Optional[builtin___bool] = None, - compressedChannelMapping : typing___Optional[builtin___bool] = None, - hybridActions : typing___Optional[builtin___bool] = None, - trainingAnalytics : typing___Optional[builtin___bool] = None, - variableLengthObservation : typing___Optional[builtin___bool] = None, - multiAgentGroups : typing___Optional[builtin___bool] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLCapabilitiesProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"baseRLCapabilities",u"compressedChannelMapping",u"concatenatedPngObservations",u"hybridActions",u"multiAgentGroups",u"trainingAnalytics",u"variableLengthObservation"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"baseRLCapabilities",b"baseRLCapabilities",u"compressedChannelMapping",b"compressedChannelMapping",u"concatenatedPngObservations",b"concatenatedPngObservations",u"hybridActions",b"hybridActions",u"multiAgentGroups",b"multiAgentGroups",u"trainingAnalytics",b"trainingAnalytics",u"variableLengthObservation",b"variableLengthObservation"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.py deleted file mode 100644 index 397f310..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.py +++ /dev/null @@ -1,64 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/command.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/command.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n0mlagents_envs/communicator_objects/command.proto\x12\x14\x63ommunicator_objects*-\n\x0c\x43ommandProto\x12\x08\n\x04STEP\x10\x00\x12\t\n\x05RESET\x10\x01\x12\x08\n\x04QUIT\x10\x02\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - -_COMMANDPROTO = _descriptor.EnumDescriptor( - name='CommandProto', - full_name='communicator_objects.CommandProto', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='STEP', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='RESET', index=1, number=1, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='QUIT', index=2, number=2, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=74, - serialized_end=119, -) -_sym_db.RegisterEnumDescriptor(_COMMANDPROTO) - -CommandProto = enum_type_wrapper.EnumTypeWrapper(_COMMANDPROTO) -STEP = 0 -RESET = 1 -QUIT = 2 - - -DESCRIPTOR.enum_types_by_name['CommandProto'] = _COMMANDPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.pyi deleted file mode 100644 index 4378a8a..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/command_pb2.pyi +++ /dev/null @@ -1,39 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - EnumDescriptor as google___protobuf___descriptor___EnumDescriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - List as typing___List, - Tuple as typing___Tuple, - cast as typing___cast, -) - - -builtin___int = int -builtin___str = str - - -class CommandProto(builtin___int): - DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... - @classmethod - def Name(cls, number: builtin___int) -> builtin___str: ... - @classmethod - def Value(cls, name: builtin___str) -> 'CommandProto': ... - @classmethod - def keys(cls) -> typing___List[builtin___str]: ... - @classmethod - def values(cls) -> typing___List['CommandProto']: ... - @classmethod - def items(cls) -> typing___List[typing___Tuple[builtin___str, 'CommandProto']]: ... - STEP = typing___cast('CommandProto', 0) - RESET = typing___cast('CommandProto', 1) - QUIT = typing___cast('CommandProto', 2) -STEP = typing___cast('CommandProto', 0) -RESET = typing___cast('CommandProto', 1) -QUIT = typing___cast('CommandProto', 2) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.py deleted file mode 100644 index f4300d1..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.py +++ /dev/null @@ -1,64 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/custom_reset_parameters.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/custom_reset_parameters.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n@mlagents_envs/communicator_objects/custom_reset_parameters.proto\x12\x14\x63ommunicator_objects\"\x1c\n\x1a\x43ustomResetParametersProtoB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - - - - -_CUSTOMRESETPARAMETERSPROTO = _descriptor.Descriptor( - name='CustomResetParametersProto', - full_name='communicator_objects.CustomResetParametersProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=90, - serialized_end=118, -) - -DESCRIPTOR.message_types_by_name['CustomResetParametersProto'] = _CUSTOMRESETPARAMETERSPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -CustomResetParametersProto = _reflection.GeneratedProtocolMessageType('CustomResetParametersProto', (_message.Message,), dict( - DESCRIPTOR = _CUSTOMRESETPARAMETERSPROTO, - __module__ = 'mlagents_envs.communicator_objects.custom_reset_parameters_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.CustomResetParametersProto) - )) -_sym_db.RegisterMessage(CustomResetParametersProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.pyi deleted file mode 100644 index 8127e97..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/custom_reset_parameters_pb2.pyi +++ /dev/null @@ -1,23 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - - -builtin___bytes = bytes - - -class CustomResetParametersProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - - def __init__(self, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> CustomResetParametersProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.py deleted file mode 100644 index 3b86fee..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.py +++ /dev/null @@ -1,99 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/demonstration_meta.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/demonstration_meta.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n;mlagents_envs/communicator_objects/demonstration_meta.proto\x12\x14\x63ommunicator_objects\"\x8d\x01\n\x16\x44\x65monstrationMetaProto\x12\x13\n\x0b\x61pi_version\x18\x01 \x01(\x05\x12\x1a\n\x12\x64\x65monstration_name\x18\x02 \x01(\t\x12\x14\n\x0cnumber_steps\x18\x03 \x01(\x05\x12\x17\n\x0fnumber_episodes\x18\x04 \x01(\x05\x12\x13\n\x0bmean_reward\x18\x05 \x01(\x02\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - - - - -_DEMONSTRATIONMETAPROTO = _descriptor.Descriptor( - name='DemonstrationMetaProto', - full_name='communicator_objects.DemonstrationMetaProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='api_version', full_name='communicator_objects.DemonstrationMetaProto.api_version', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='demonstration_name', full_name='communicator_objects.DemonstrationMetaProto.demonstration_name', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='number_steps', full_name='communicator_objects.DemonstrationMetaProto.number_steps', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='number_episodes', full_name='communicator_objects.DemonstrationMetaProto.number_episodes', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='mean_reward', full_name='communicator_objects.DemonstrationMetaProto.mean_reward', index=4, - number=5, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=86, - serialized_end=227, -) - -DESCRIPTOR.message_types_by_name['DemonstrationMetaProto'] = _DEMONSTRATIONMETAPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -DemonstrationMetaProto = _reflection.GeneratedProtocolMessageType('DemonstrationMetaProto', (_message.Message,), dict( - DESCRIPTOR = _DEMONSTRATIONMETAPROTO, - __module__ = 'mlagents_envs.communicator_objects.demonstration_meta_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.DemonstrationMetaProto) - )) -_sym_db.RegisterMessage(DemonstrationMetaProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.pyi deleted file mode 100644 index ba3c306..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/demonstration_meta_pb2.pyi +++ /dev/null @@ -1,50 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class DemonstrationMetaProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - api_version = ... # type: builtin___int - demonstration_name = ... # type: typing___Text - number_steps = ... # type: builtin___int - number_episodes = ... # type: builtin___int - mean_reward = ... # type: builtin___float - - def __init__(self, - *, - api_version : typing___Optional[builtin___int] = None, - demonstration_name : typing___Optional[typing___Text] = None, - number_steps : typing___Optional[builtin___int] = None, - number_episodes : typing___Optional[builtin___int] = None, - mean_reward : typing___Optional[builtin___float] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> DemonstrationMetaProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"api_version",u"demonstration_name",u"mean_reward",u"number_episodes",u"number_steps"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"api_version",b"api_version",u"demonstration_name",b"demonstration_name",u"mean_reward",b"mean_reward",u"number_episodes",b"number_episodes",u"number_steps",b"number_steps"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.py deleted file mode 100644 index 9f4656c..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.py +++ /dev/null @@ -1,106 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/engine_configuration.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/engine_configuration.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n=mlagents_envs/communicator_objects/engine_configuration.proto\x12\x14\x63ommunicator_objects\"\x95\x01\n\x18\x45ngineConfigurationProto\x12\r\n\x05width\x18\x01 \x01(\x05\x12\x0e\n\x06height\x18\x02 \x01(\x05\x12\x15\n\rquality_level\x18\x03 \x01(\x05\x12\x12\n\ntime_scale\x18\x04 \x01(\x02\x12\x19\n\x11target_frame_rate\x18\x05 \x01(\x05\x12\x14\n\x0cshow_monitor\x18\x06 \x01(\x08\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - - - - -_ENGINECONFIGURATIONPROTO = _descriptor.Descriptor( - name='EngineConfigurationProto', - full_name='communicator_objects.EngineConfigurationProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='width', full_name='communicator_objects.EngineConfigurationProto.width', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='height', full_name='communicator_objects.EngineConfigurationProto.height', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='quality_level', full_name='communicator_objects.EngineConfigurationProto.quality_level', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='time_scale', full_name='communicator_objects.EngineConfigurationProto.time_scale', index=3, - number=4, type=2, cpp_type=6, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='target_frame_rate', full_name='communicator_objects.EngineConfigurationProto.target_frame_rate', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='show_monitor', full_name='communicator_objects.EngineConfigurationProto.show_monitor', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=88, - serialized_end=237, -) - -DESCRIPTOR.message_types_by_name['EngineConfigurationProto'] = _ENGINECONFIGURATIONPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -EngineConfigurationProto = _reflection.GeneratedProtocolMessageType('EngineConfigurationProto', (_message.Message,), dict( - DESCRIPTOR = _ENGINECONFIGURATIONPROTO, - __module__ = 'mlagents_envs.communicator_objects.engine_configuration_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.EngineConfigurationProto) - )) -_sym_db.RegisterMessage(EngineConfigurationProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.pyi deleted file mode 100644 index d4eef07..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/engine_configuration_pb2.pyi +++ /dev/null @@ -1,51 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - Optional as typing___Optional, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class EngineConfigurationProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - width = ... # type: builtin___int - height = ... # type: builtin___int - quality_level = ... # type: builtin___int - time_scale = ... # type: builtin___float - target_frame_rate = ... # type: builtin___int - show_monitor = ... # type: builtin___bool - - def __init__(self, - *, - width : typing___Optional[builtin___int] = None, - height : typing___Optional[builtin___int] = None, - quality_level : typing___Optional[builtin___int] = None, - time_scale : typing___Optional[builtin___float] = None, - target_frame_rate : typing___Optional[builtin___int] = None, - show_monitor : typing___Optional[builtin___bool] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> EngineConfigurationProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"height",u"quality_level",u"show_monitor",u"target_frame_rate",u"time_scale",u"width"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"height",b"height",u"quality_level",b"quality_level",u"show_monitor",b"show_monitor",u"target_frame_rate",b"target_frame_rate",u"time_scale",b"time_scale",u"width",b"width"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.py deleted file mode 100644 index 5aa8eb8..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.py +++ /dev/null @@ -1,78 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/header.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/header.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n/mlagents_envs/communicator_objects/header.proto\x12\x14\x63ommunicator_objects\".\n\x0bHeaderProto\x12\x0e\n\x06status\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\tB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - - - - -_HEADERPROTO = _descriptor.Descriptor( - name='HeaderProto', - full_name='communicator_objects.HeaderProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='status', full_name='communicator_objects.HeaderProto.status', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='message', full_name='communicator_objects.HeaderProto.message', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=73, - serialized_end=119, -) - -DESCRIPTOR.message_types_by_name['HeaderProto'] = _HEADERPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -HeaderProto = _reflection.GeneratedProtocolMessageType('HeaderProto', (_message.Message,), dict( - DESCRIPTOR = _HEADERPROTO, - __module__ = 'mlagents_envs.communicator_objects.header_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.HeaderProto) - )) -_sym_db.RegisterMessage(HeaderProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.pyi deleted file mode 100644 index ab7fdd6..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/header_pb2.pyi +++ /dev/null @@ -1,44 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class HeaderProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - status = ... # type: builtin___int - message = ... # type: typing___Text - - def __init__(self, - *, - status : typing___Optional[builtin___int] = None, - message : typing___Optional[typing___Text] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> HeaderProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"message",u"status"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"message",b"message",u"status",b"status"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.py deleted file mode 100644 index 838ca1d..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.py +++ /dev/null @@ -1,224 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/observation.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/observation.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n4mlagents_envs/communicator_objects/observation.proto\x12\x14\x63ommunicator_objects\"\x8f\x03\n\x10ObservationProto\x12\r\n\x05shape\x18\x01 \x03(\x05\x12\x44\n\x10\x63ompression_type\x18\x02 \x01(\x0e\x32*.communicator_objects.CompressionTypeProto\x12\x19\n\x0f\x63ompressed_data\x18\x03 \x01(\x0cH\x00\x12\x46\n\nfloat_data\x18\x04 \x01(\x0b\x32\x30.communicator_objects.ObservationProto.FloatDataH\x00\x12\"\n\x1a\x63ompressed_channel_mapping\x18\x05 \x03(\x05\x12\x1c\n\x14\x64imension_properties\x18\x06 \x03(\x05\x12\x44\n\x10observation_type\x18\x07 \x01(\x0e\x32*.communicator_objects.ObservationTypeProto\x12\x0c\n\x04name\x18\x08 \x01(\t\x1a\x19\n\tFloatData\x12\x0c\n\x04\x64\x61ta\x18\x01 \x03(\x02\x42\x12\n\x10observation_data*)\n\x14\x43ompressionTypeProto\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03PNG\x10\x01*@\n\x14ObservationTypeProto\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0f\n\x0bGOAL_SIGNAL\x10\x01\"\x04\x08\x02\x10\x02\"\x04\x08\x03\x10\x03\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - -_COMPRESSIONTYPEPROTO = _descriptor.EnumDescriptor( - name='CompressionTypeProto', - full_name='communicator_objects.CompressionTypeProto', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='NONE', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='PNG', index=1, number=1, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=480, - serialized_end=521, -) -_sym_db.RegisterEnumDescriptor(_COMPRESSIONTYPEPROTO) - -CompressionTypeProto = enum_type_wrapper.EnumTypeWrapper(_COMPRESSIONTYPEPROTO) -_OBSERVATIONTYPEPROTO = _descriptor.EnumDescriptor( - name='ObservationTypeProto', - full_name='communicator_objects.ObservationTypeProto', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='DEFAULT', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='GOAL_SIGNAL', index=1, number=1, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=523, - serialized_end=587, -) -_sym_db.RegisterEnumDescriptor(_OBSERVATIONTYPEPROTO) - -ObservationTypeProto = enum_type_wrapper.EnumTypeWrapper(_OBSERVATIONTYPEPROTO) -NONE = 0 -PNG = 1 -DEFAULT = 0 -GOAL_SIGNAL = 1 - - - -_OBSERVATIONPROTO_FLOATDATA = _descriptor.Descriptor( - name='FloatData', - full_name='communicator_objects.ObservationProto.FloatData', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='data', full_name='communicator_objects.ObservationProto.FloatData.data', index=0, - number=1, type=2, cpp_type=6, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=433, - serialized_end=458, -) - -_OBSERVATIONPROTO = _descriptor.Descriptor( - name='ObservationProto', - full_name='communicator_objects.ObservationProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='shape', full_name='communicator_objects.ObservationProto.shape', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='compression_type', full_name='communicator_objects.ObservationProto.compression_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='compressed_data', full_name='communicator_objects.ObservationProto.compressed_data', index=2, - number=3, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='float_data', full_name='communicator_objects.ObservationProto.float_data', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='compressed_channel_mapping', full_name='communicator_objects.ObservationProto.compressed_channel_mapping', index=4, - number=5, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='dimension_properties', full_name='communicator_objects.ObservationProto.dimension_properties', index=5, - number=6, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='observation_type', full_name='communicator_objects.ObservationProto.observation_type', index=6, - number=7, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='name', full_name='communicator_objects.ObservationProto.name', index=7, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[_OBSERVATIONPROTO_FLOATDATA, ], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - _descriptor.OneofDescriptor( - name='observation_data', full_name='communicator_objects.ObservationProto.observation_data', - index=0, containing_type=None, fields=[]), - ], - serialized_start=79, - serialized_end=478, -) - -_OBSERVATIONPROTO_FLOATDATA.containing_type = _OBSERVATIONPROTO -_OBSERVATIONPROTO.fields_by_name['compression_type'].enum_type = _COMPRESSIONTYPEPROTO -_OBSERVATIONPROTO.fields_by_name['float_data'].message_type = _OBSERVATIONPROTO_FLOATDATA -_OBSERVATIONPROTO.fields_by_name['observation_type'].enum_type = _OBSERVATIONTYPEPROTO -_OBSERVATIONPROTO.oneofs_by_name['observation_data'].fields.append( - _OBSERVATIONPROTO.fields_by_name['compressed_data']) -_OBSERVATIONPROTO.fields_by_name['compressed_data'].containing_oneof = _OBSERVATIONPROTO.oneofs_by_name['observation_data'] -_OBSERVATIONPROTO.oneofs_by_name['observation_data'].fields.append( - _OBSERVATIONPROTO.fields_by_name['float_data']) -_OBSERVATIONPROTO.fields_by_name['float_data'].containing_oneof = _OBSERVATIONPROTO.oneofs_by_name['observation_data'] -DESCRIPTOR.message_types_by_name['ObservationProto'] = _OBSERVATIONPROTO -DESCRIPTOR.enum_types_by_name['CompressionTypeProto'] = _COMPRESSIONTYPEPROTO -DESCRIPTOR.enum_types_by_name['ObservationTypeProto'] = _OBSERVATIONTYPEPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -ObservationProto = _reflection.GeneratedProtocolMessageType('ObservationProto', (_message.Message,), dict( - - FloatData = _reflection.GeneratedProtocolMessageType('FloatData', (_message.Message,), dict( - DESCRIPTOR = _OBSERVATIONPROTO_FLOATDATA, - __module__ = 'mlagents_envs.communicator_objects.observation_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.ObservationProto.FloatData) - )) - , - DESCRIPTOR = _OBSERVATIONPROTO, - __module__ = 'mlagents_envs.communicator_objects.observation_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.ObservationProto) - )) -_sym_db.RegisterMessage(ObservationProto) -_sym_db.RegisterMessage(ObservationProto.FloatData) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.pyi deleted file mode 100644 index 6427c50..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/observation_pb2.pyi +++ /dev/null @@ -1,122 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, - EnumDescriptor as google___protobuf___descriptor___EnumDescriptor, -) - -from google.protobuf.internal.containers import ( - RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - Iterable as typing___Iterable, - List as typing___List, - Optional as typing___Optional, - Text as typing___Text, - Tuple as typing___Tuple, - cast as typing___cast, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int -builtin___str = str - - -class CompressionTypeProto(builtin___int): - DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... - @classmethod - def Name(cls, number: builtin___int) -> builtin___str: ... - @classmethod - def Value(cls, name: builtin___str) -> 'CompressionTypeProto': ... - @classmethod - def keys(cls) -> typing___List[builtin___str]: ... - @classmethod - def values(cls) -> typing___List['CompressionTypeProto']: ... - @classmethod - def items(cls) -> typing___List[typing___Tuple[builtin___str, 'CompressionTypeProto']]: ... - NONE = typing___cast('CompressionTypeProto', 0) - PNG = typing___cast('CompressionTypeProto', 1) -NONE = typing___cast('CompressionTypeProto', 0) -PNG = typing___cast('CompressionTypeProto', 1) - -class ObservationTypeProto(builtin___int): - DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... - @classmethod - def Name(cls, number: builtin___int) -> builtin___str: ... - @classmethod - def Value(cls, name: builtin___str) -> 'ObservationTypeProto': ... - @classmethod - def keys(cls) -> typing___List[builtin___str]: ... - @classmethod - def values(cls) -> typing___List['ObservationTypeProto']: ... - @classmethod - def items(cls) -> typing___List[typing___Tuple[builtin___str, 'ObservationTypeProto']]: ... - DEFAULT = typing___cast('ObservationTypeProto', 0) - GOAL_SIGNAL = typing___cast('ObservationTypeProto', 1) -DEFAULT = typing___cast('ObservationTypeProto', 0) -GOAL_SIGNAL = typing___cast('ObservationTypeProto', 1) - -class ObservationProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - class FloatData(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - data = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___float] - - def __init__(self, - *, - data : typing___Optional[typing___Iterable[builtin___float]] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> ObservationProto.FloatData: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"data"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"data",b"data"]) -> None: ... - - shape = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___int] - compression_type = ... # type: CompressionTypeProto - compressed_data = ... # type: builtin___bytes - compressed_channel_mapping = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___int] - dimension_properties = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[builtin___int] - observation_type = ... # type: ObservationTypeProto - name = ... # type: typing___Text - - @property - def float_data(self) -> ObservationProto.FloatData: ... - - def __init__(self, - *, - shape : typing___Optional[typing___Iterable[builtin___int]] = None, - compression_type : typing___Optional[CompressionTypeProto] = None, - compressed_data : typing___Optional[builtin___bytes] = None, - float_data : typing___Optional[ObservationProto.FloatData] = None, - compressed_channel_mapping : typing___Optional[typing___Iterable[builtin___int]] = None, - dimension_properties : typing___Optional[typing___Iterable[builtin___int]] = None, - observation_type : typing___Optional[ObservationTypeProto] = None, - name : typing___Optional[typing___Text] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> ObservationProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"compressed_data",u"float_data",u"observation_data"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"compressed_channel_mapping",u"compressed_data",u"compression_type",u"dimension_properties",u"float_data",u"name",u"observation_data",u"observation_type",u"shape"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"compressed_data",b"compressed_data",u"float_data",b"float_data",u"observation_data",b"observation_data"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"compressed_channel_mapping",b"compressed_channel_mapping",u"compressed_data",b"compressed_data",u"compression_type",b"compression_type",u"dimension_properties",b"dimension_properties",u"float_data",b"float_data",u"name",b"name",u"observation_data",b"observation_data",u"observation_type",b"observation_type",u"shape",b"shape"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions___Literal[u"observation_data",b"observation_data"]) -> typing_extensions___Literal["compressed_data","float_data"]: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.py deleted file mode 100644 index df62c23..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.py +++ /dev/null @@ -1,59 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/space_type.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/space_type.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n3mlagents_envs/communicator_objects/space_type.proto\x12\x14\x63ommunicator_objects*.\n\x0eSpaceTypeProto\x12\x0c\n\x08\x64iscrete\x10\x00\x12\x0e\n\ncontinuous\x10\x01\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - -_SPACETYPEPROTO = _descriptor.EnumDescriptor( - name='SpaceTypeProto', - full_name='communicator_objects.SpaceTypeProto', - filename=None, - file=DESCRIPTOR, - values=[ - _descriptor.EnumValueDescriptor( - name='discrete', index=0, number=0, - options=None, - type=None), - _descriptor.EnumValueDescriptor( - name='continuous', index=1, number=1, - options=None, - type=None), - ], - containing_type=None, - options=None, - serialized_start=77, - serialized_end=123, -) -_sym_db.RegisterEnumDescriptor(_SPACETYPEPROTO) - -SpaceTypeProto = enum_type_wrapper.EnumTypeWrapper(_SPACETYPEPROTO) -discrete = 0 -continuous = 1 - - -DESCRIPTOR.enum_types_by_name['SpaceTypeProto'] = _SPACETYPEPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.pyi deleted file mode 100644 index 4527ffc..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/space_type_pb2.pyi +++ /dev/null @@ -1,37 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - EnumDescriptor as google___protobuf___descriptor___EnumDescriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - List as typing___List, - Tuple as typing___Tuple, - cast as typing___cast, -) - - -builtin___int = int -builtin___str = str - - -class SpaceTypeProto(builtin___int): - DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ... - @classmethod - def Name(cls, number: builtin___int) -> builtin___str: ... - @classmethod - def Value(cls, name: builtin___str) -> 'SpaceTypeProto': ... - @classmethod - def keys(cls) -> typing___List[builtin___str]: ... - @classmethod - def values(cls) -> typing___List['SpaceTypeProto']: ... - @classmethod - def items(cls) -> typing___List[typing___Tuple[builtin___str, 'SpaceTypeProto']]: ... - discrete = typing___cast('SpaceTypeProto', 0) - continuous = typing___cast('SpaceTypeProto', 1) -discrete = typing___cast('SpaceTypeProto', 0) -continuous = typing___cast('SpaceTypeProto', 1) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.py deleted file mode 100644 index 2701dac..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.py +++ /dev/null @@ -1,257 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/training_analytics.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/training_analytics.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n;mlagents_envs/communicator_objects/training_analytics.proto\x12\x14\x63ommunicator_objects\"\xee\x01\n\x1eTrainingEnvironmentInitialized\x12\x18\n\x10mlagents_version\x18\x01 \x01(\t\x12\x1d\n\x15mlagents_envs_version\x18\x02 \x01(\t\x12\x16\n\x0epython_version\x18\x03 \x01(\t\x12\x15\n\rtorch_version\x18\x04 \x01(\t\x12\x19\n\x11torch_device_type\x18\x05 \x01(\t\x12\x10\n\x08num_envs\x18\x06 \x01(\x05\x12\"\n\x1anum_environment_parameters\x18\x07 \x01(\x05\x12\x13\n\x0brun_options\x18\x08 \x01(\t\"\xbd\x03\n\x1bTrainingBehaviorInitialized\x12\x15\n\rbehavior_name\x18\x01 \x01(\t\x12\x14\n\x0ctrainer_type\x18\x02 \x01(\t\x12 \n\x18\x65xtrinsic_reward_enabled\x18\x03 \x01(\x08\x12\x1b\n\x13gail_reward_enabled\x18\x04 \x01(\x08\x12 \n\x18\x63uriosity_reward_enabled\x18\x05 \x01(\x08\x12\x1a\n\x12rnd_reward_enabled\x18\x06 \x01(\x08\x12\"\n\x1a\x62\x65havioral_cloning_enabled\x18\x07 \x01(\x08\x12\x19\n\x11recurrent_enabled\x18\x08 \x01(\x08\x12\x16\n\x0evisual_encoder\x18\t \x01(\t\x12\x1a\n\x12num_network_layers\x18\n \x01(\x05\x12 \n\x18num_network_hidden_units\x18\x0b \x01(\x05\x12\x18\n\x10trainer_threaded\x18\x0c \x01(\x08\x12\x19\n\x11self_play_enabled\x18\r \x01(\x08\x12\x1a\n\x12\x63urriculum_enabled\x18\x0e \x01(\x08\x12\x0e\n\x06\x63onfig\x18\x0f \x01(\tB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') -) - - - - -_TRAININGENVIRONMENTINITIALIZED = _descriptor.Descriptor( - name='TrainingEnvironmentInitialized', - full_name='communicator_objects.TrainingEnvironmentInitialized', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='mlagents_version', full_name='communicator_objects.TrainingEnvironmentInitialized.mlagents_version', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='mlagents_envs_version', full_name='communicator_objects.TrainingEnvironmentInitialized.mlagents_envs_version', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='python_version', full_name='communicator_objects.TrainingEnvironmentInitialized.python_version', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='torch_version', full_name='communicator_objects.TrainingEnvironmentInitialized.torch_version', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='torch_device_type', full_name='communicator_objects.TrainingEnvironmentInitialized.torch_device_type', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_envs', full_name='communicator_objects.TrainingEnvironmentInitialized.num_envs', index=5, - number=6, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_environment_parameters', full_name='communicator_objects.TrainingEnvironmentInitialized.num_environment_parameters', index=6, - number=7, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='run_options', full_name='communicator_objects.TrainingEnvironmentInitialized.run_options', index=7, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=86, - serialized_end=324, -) - - -_TRAININGBEHAVIORINITIALIZED = _descriptor.Descriptor( - name='TrainingBehaviorInitialized', - full_name='communicator_objects.TrainingBehaviorInitialized', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='behavior_name', full_name='communicator_objects.TrainingBehaviorInitialized.behavior_name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='trainer_type', full_name='communicator_objects.TrainingBehaviorInitialized.trainer_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='extrinsic_reward_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.extrinsic_reward_enabled', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='gail_reward_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.gail_reward_enabled', index=3, - number=4, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='curiosity_reward_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.curiosity_reward_enabled', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='rnd_reward_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.rnd_reward_enabled', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='behavioral_cloning_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.behavioral_cloning_enabled', index=6, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='recurrent_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.recurrent_enabled', index=7, - number=8, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='visual_encoder', full_name='communicator_objects.TrainingBehaviorInitialized.visual_encoder', index=8, - number=9, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_network_layers', full_name='communicator_objects.TrainingBehaviorInitialized.num_network_layers', index=9, - number=10, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_network_hidden_units', full_name='communicator_objects.TrainingBehaviorInitialized.num_network_hidden_units', index=10, - number=11, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='trainer_threaded', full_name='communicator_objects.TrainingBehaviorInitialized.trainer_threaded', index=11, - number=12, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='self_play_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.self_play_enabled', index=12, - number=13, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='curriculum_enabled', full_name='communicator_objects.TrainingBehaviorInitialized.curriculum_enabled', index=13, - number=14, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='config', full_name='communicator_objects.TrainingBehaviorInitialized.config', index=14, - number=15, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=327, - serialized_end=772, -) - -DESCRIPTOR.message_types_by_name['TrainingEnvironmentInitialized'] = _TRAININGENVIRONMENTINITIALIZED -DESCRIPTOR.message_types_by_name['TrainingBehaviorInitialized'] = _TRAININGBEHAVIORINITIALIZED -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -TrainingEnvironmentInitialized = _reflection.GeneratedProtocolMessageType('TrainingEnvironmentInitialized', (_message.Message,), dict( - DESCRIPTOR = _TRAININGENVIRONMENTINITIALIZED, - __module__ = 'mlagents_envs.communicator_objects.training_analytics_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.TrainingEnvironmentInitialized) - )) -_sym_db.RegisterMessage(TrainingEnvironmentInitialized) - -TrainingBehaviorInitialized = _reflection.GeneratedProtocolMessageType('TrainingBehaviorInitialized', (_message.Message,), dict( - DESCRIPTOR = _TRAININGBEHAVIORINITIALIZED, - __module__ = 'mlagents_envs.communicator_objects.training_analytics_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.TrainingBehaviorInitialized) - )) -_sym_db.RegisterMessage(TrainingBehaviorInitialized) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.pyi deleted file mode 100644 index 53709ca..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/training_analytics_pb2.pyi +++ /dev/null @@ -1,101 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from typing import ( - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class TrainingEnvironmentInitialized(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - mlagents_version = ... # type: typing___Text - mlagents_envs_version = ... # type: typing___Text - python_version = ... # type: typing___Text - torch_version = ... # type: typing___Text - torch_device_type = ... # type: typing___Text - num_envs = ... # type: builtin___int - num_environment_parameters = ... # type: builtin___int - run_options = ... # type: typing___Text - - def __init__(self, - *, - mlagents_version : typing___Optional[typing___Text] = None, - mlagents_envs_version : typing___Optional[typing___Text] = None, - python_version : typing___Optional[typing___Text] = None, - torch_version : typing___Optional[typing___Text] = None, - torch_device_type : typing___Optional[typing___Text] = None, - num_envs : typing___Optional[builtin___int] = None, - num_environment_parameters : typing___Optional[builtin___int] = None, - run_options : typing___Optional[typing___Text] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> TrainingEnvironmentInitialized: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"mlagents_envs_version",u"mlagents_version",u"num_environment_parameters",u"num_envs",u"python_version",u"run_options",u"torch_device_type",u"torch_version"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"mlagents_envs_version",b"mlagents_envs_version",u"mlagents_version",b"mlagents_version",u"num_environment_parameters",b"num_environment_parameters",u"num_envs",b"num_envs",u"python_version",b"python_version",u"run_options",b"run_options",u"torch_device_type",b"torch_device_type",u"torch_version",b"torch_version"]) -> None: ... - -class TrainingBehaviorInitialized(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - behavior_name = ... # type: typing___Text - trainer_type = ... # type: typing___Text - extrinsic_reward_enabled = ... # type: builtin___bool - gail_reward_enabled = ... # type: builtin___bool - curiosity_reward_enabled = ... # type: builtin___bool - rnd_reward_enabled = ... # type: builtin___bool - behavioral_cloning_enabled = ... # type: builtin___bool - recurrent_enabled = ... # type: builtin___bool - visual_encoder = ... # type: typing___Text - num_network_layers = ... # type: builtin___int - num_network_hidden_units = ... # type: builtin___int - trainer_threaded = ... # type: builtin___bool - self_play_enabled = ... # type: builtin___bool - curriculum_enabled = ... # type: builtin___bool - config = ... # type: typing___Text - - def __init__(self, - *, - behavior_name : typing___Optional[typing___Text] = None, - trainer_type : typing___Optional[typing___Text] = None, - extrinsic_reward_enabled : typing___Optional[builtin___bool] = None, - gail_reward_enabled : typing___Optional[builtin___bool] = None, - curiosity_reward_enabled : typing___Optional[builtin___bool] = None, - rnd_reward_enabled : typing___Optional[builtin___bool] = None, - behavioral_cloning_enabled : typing___Optional[builtin___bool] = None, - recurrent_enabled : typing___Optional[builtin___bool] = None, - visual_encoder : typing___Optional[typing___Text] = None, - num_network_layers : typing___Optional[builtin___int] = None, - num_network_hidden_units : typing___Optional[builtin___int] = None, - trainer_threaded : typing___Optional[builtin___bool] = None, - self_play_enabled : typing___Optional[builtin___bool] = None, - curriculum_enabled : typing___Optional[builtin___bool] = None, - config : typing___Optional[typing___Text] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> TrainingBehaviorInitialized: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"behavior_name",u"behavioral_cloning_enabled",u"config",u"curiosity_reward_enabled",u"curriculum_enabled",u"extrinsic_reward_enabled",u"gail_reward_enabled",u"num_network_hidden_units",u"num_network_layers",u"recurrent_enabled",u"rnd_reward_enabled",u"self_play_enabled",u"trainer_threaded",u"trainer_type",u"visual_encoder"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"behavior_name",b"behavior_name",u"behavioral_cloning_enabled",b"behavioral_cloning_enabled",u"config",b"config",u"curiosity_reward_enabled",b"curiosity_reward_enabled",u"curriculum_enabled",b"curriculum_enabled",u"extrinsic_reward_enabled",b"extrinsic_reward_enabled",u"gail_reward_enabled",b"gail_reward_enabled",u"num_network_hidden_units",b"num_network_hidden_units",u"num_network_layers",b"num_network_layers",u"recurrent_enabled",b"recurrent_enabled",u"rnd_reward_enabled",b"rnd_reward_enabled",u"self_play_enabled",b"self_play_enabled",u"trainer_threaded",b"trainer_threaded",u"trainer_type",b"trainer_type",u"visual_encoder",b"visual_encoder"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.py deleted file mode 100644 index 6c4a24f..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.py +++ /dev/null @@ -1,83 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_input.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import unity_rl_input_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__rl__input__pb2 -from mlagents_envs.communicator_objects import unity_rl_initialization_input_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__rl__initialization__input__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_input.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n4mlagents_envs/communicator_objects/unity_input.proto\x12\x14\x63ommunicator_objects\x1a\x37mlagents_envs/communicator_objects/unity_rl_input.proto\x1a\x46mlagents_envs/communicator_objects/unity_rl_initialization_input.proto\"\xa4\x01\n\x0fUnityInputProto\x12\x39\n\x08rl_input\x18\x01 \x01(\x0b\x32\'.communicator_objects.UnityRLInputProto\x12V\n\x17rl_initialization_input\x18\x02 \x01(\x0b\x32\x35.communicator_objects.UnityRLInitializationInputProtoB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_unity__rl__input__pb2.DESCRIPTOR,mlagents__envs_dot_communicator__objects_dot_unity__rl__initialization__input__pb2.DESCRIPTOR,]) - - - - -_UNITYINPUTPROTO = _descriptor.Descriptor( - name='UnityInputProto', - full_name='communicator_objects.UnityInputProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='rl_input', full_name='communicator_objects.UnityInputProto.rl_input', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='rl_initialization_input', full_name='communicator_objects.UnityInputProto.rl_initialization_input', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=208, - serialized_end=372, -) - -_UNITYINPUTPROTO.fields_by_name['rl_input'].message_type = mlagents__envs_dot_communicator__objects_dot_unity__rl__input__pb2._UNITYRLINPUTPROTO -_UNITYINPUTPROTO.fields_by_name['rl_initialization_input'].message_type = mlagents__envs_dot_communicator__objects_dot_unity__rl__initialization__input__pb2._UNITYRLINITIALIZATIONINPUTPROTO -DESCRIPTOR.message_types_by_name['UnityInputProto'] = _UNITYINPUTPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityInputProto = _reflection.GeneratedProtocolMessageType('UnityInputProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYINPUTPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_input_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityInputProto) - )) -_sym_db.RegisterMessage(UnityInputProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.pyi deleted file mode 100644 index 937acf1..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_input_pb2.pyi +++ /dev/null @@ -1,57 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.unity_rl_initialization_input_pb2 import ( - UnityRLInitializationInputProto as mlagents_envs___communicator_objects___unity_rl_initialization_input_pb2___UnityRLInitializationInputProto, -) - -from mlagents_envs.communicator_objects.unity_rl_input_pb2 import ( - UnityRLInputProto as mlagents_envs___communicator_objects___unity_rl_input_pb2___UnityRLInputProto, -) - -from typing import ( - Optional as typing___Optional, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityInputProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - - @property - def rl_input(self) -> mlagents_envs___communicator_objects___unity_rl_input_pb2___UnityRLInputProto: ... - - @property - def rl_initialization_input(self) -> mlagents_envs___communicator_objects___unity_rl_initialization_input_pb2___UnityRLInitializationInputProto: ... - - def __init__(self, - *, - rl_input : typing___Optional[mlagents_envs___communicator_objects___unity_rl_input_pb2___UnityRLInputProto] = None, - rl_initialization_input : typing___Optional[mlagents_envs___communicator_objects___unity_rl_initialization_input_pb2___UnityRLInitializationInputProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityInputProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"rl_initialization_input",u"rl_input"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"rl_initialization_input",u"rl_input"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"rl_initialization_input",b"rl_initialization_input",u"rl_input",b"rl_input"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"rl_initialization_input",b"rl_initialization_input",u"rl_input",b"rl_input"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.py deleted file mode 100644 index e01b522..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.py +++ /dev/null @@ -1,92 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_message.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import unity_output_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__output__pb2 -from mlagents_envs.communicator_objects import unity_input_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__input__pb2 -from mlagents_envs.communicator_objects import header_pb2 as mlagents__envs_dot_communicator__objects_dot_header__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_message.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n6mlagents_envs/communicator_objects/unity_message.proto\x12\x14\x63ommunicator_objects\x1a\x35mlagents_envs/communicator_objects/unity_output.proto\x1a\x34mlagents_envs/communicator_objects/unity_input.proto\x1a/mlagents_envs/communicator_objects/header.proto\"\xc0\x01\n\x11UnityMessageProto\x12\x31\n\x06header\x18\x01 \x01(\x0b\x32!.communicator_objects.HeaderProto\x12<\n\x0cunity_output\x18\x02 \x01(\x0b\x32&.communicator_objects.UnityOutputProto\x12:\n\x0bunity_input\x18\x03 \x01(\x0b\x32%.communicator_objects.UnityInputProtoB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_unity__output__pb2.DESCRIPTOR,mlagents__envs_dot_communicator__objects_dot_unity__input__pb2.DESCRIPTOR,mlagents__envs_dot_communicator__objects_dot_header__pb2.DESCRIPTOR,]) - - - - -_UNITYMESSAGEPROTO = _descriptor.Descriptor( - name='UnityMessageProto', - full_name='communicator_objects.UnityMessageProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='header', full_name='communicator_objects.UnityMessageProto.header', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='unity_output', full_name='communicator_objects.UnityMessageProto.unity_output', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='unity_input', full_name='communicator_objects.UnityMessageProto.unity_input', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=239, - serialized_end=431, -) - -_UNITYMESSAGEPROTO.fields_by_name['header'].message_type = mlagents__envs_dot_communicator__objects_dot_header__pb2._HEADERPROTO -_UNITYMESSAGEPROTO.fields_by_name['unity_output'].message_type = mlagents__envs_dot_communicator__objects_dot_unity__output__pb2._UNITYOUTPUTPROTO -_UNITYMESSAGEPROTO.fields_by_name['unity_input'].message_type = mlagents__envs_dot_communicator__objects_dot_unity__input__pb2._UNITYINPUTPROTO -DESCRIPTOR.message_types_by_name['UnityMessageProto'] = _UNITYMESSAGEPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityMessageProto = _reflection.GeneratedProtocolMessageType('UnityMessageProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYMESSAGEPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_message_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityMessageProto) - )) -_sym_db.RegisterMessage(UnityMessageProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.pyi deleted file mode 100644 index d8f85db..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_message_pb2.pyi +++ /dev/null @@ -1,65 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.header_pb2 import ( - HeaderProto as mlagents_envs___communicator_objects___header_pb2___HeaderProto, -) - -from mlagents_envs.communicator_objects.unity_input_pb2 import ( - UnityInputProto as mlagents_envs___communicator_objects___unity_input_pb2___UnityInputProto, -) - -from mlagents_envs.communicator_objects.unity_output_pb2 import ( - UnityOutputProto as mlagents_envs___communicator_objects___unity_output_pb2___UnityOutputProto, -) - -from typing import ( - Optional as typing___Optional, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityMessageProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - - @property - def header(self) -> mlagents_envs___communicator_objects___header_pb2___HeaderProto: ... - - @property - def unity_output(self) -> mlagents_envs___communicator_objects___unity_output_pb2___UnityOutputProto: ... - - @property - def unity_input(self) -> mlagents_envs___communicator_objects___unity_input_pb2___UnityInputProto: ... - - def __init__(self, - *, - header : typing___Optional[mlagents_envs___communicator_objects___header_pb2___HeaderProto] = None, - unity_output : typing___Optional[mlagents_envs___communicator_objects___unity_output_pb2___UnityOutputProto] = None, - unity_input : typing___Optional[mlagents_envs___communicator_objects___unity_input_pb2___UnityInputProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityMessageProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"header",u"unity_input",u"unity_output"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"header",u"unity_input",u"unity_output"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"header",b"header",u"unity_input",b"unity_input",u"unity_output",b"unity_output"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"header",b"header",u"unity_input",b"unity_input",u"unity_output",b"unity_output"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.py deleted file mode 100644 index 400fdb0..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.py +++ /dev/null @@ -1,83 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_output.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import unity_rl_output_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__rl__output__pb2 -from mlagents_envs.communicator_objects import unity_rl_initialization_output_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__rl__initialization__output__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_output.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n5mlagents_envs/communicator_objects/unity_output.proto\x12\x14\x63ommunicator_objects\x1a\x38mlagents_envs/communicator_objects/unity_rl_output.proto\x1aGmlagents_envs/communicator_objects/unity_rl_initialization_output.proto\"\xa9\x01\n\x10UnityOutputProto\x12;\n\trl_output\x18\x01 \x01(\x0b\x32(.communicator_objects.UnityRLOutputProto\x12X\n\x18rl_initialization_output\x18\x02 \x01(\x0b\x32\x36.communicator_objects.UnityRLInitializationOutputProtoB%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_unity__rl__output__pb2.DESCRIPTOR,mlagents__envs_dot_communicator__objects_dot_unity__rl__initialization__output__pb2.DESCRIPTOR,]) - - - - -_UNITYOUTPUTPROTO = _descriptor.Descriptor( - name='UnityOutputProto', - full_name='communicator_objects.UnityOutputProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='rl_output', full_name='communicator_objects.UnityOutputProto.rl_output', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='rl_initialization_output', full_name='communicator_objects.UnityOutputProto.rl_initialization_output', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=211, - serialized_end=380, -) - -_UNITYOUTPUTPROTO.fields_by_name['rl_output'].message_type = mlagents__envs_dot_communicator__objects_dot_unity__rl__output__pb2._UNITYRLOUTPUTPROTO -_UNITYOUTPUTPROTO.fields_by_name['rl_initialization_output'].message_type = mlagents__envs_dot_communicator__objects_dot_unity__rl__initialization__output__pb2._UNITYRLINITIALIZATIONOUTPUTPROTO -DESCRIPTOR.message_types_by_name['UnityOutputProto'] = _UNITYOUTPUTPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityOutputProto = _reflection.GeneratedProtocolMessageType('UnityOutputProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYOUTPUTPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_output_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityOutputProto) - )) -_sym_db.RegisterMessage(UnityOutputProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.pyi deleted file mode 100644 index 55950f7..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_output_pb2.pyi +++ /dev/null @@ -1,57 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.unity_rl_initialization_output_pb2 import ( - UnityRLInitializationOutputProto as mlagents_envs___communicator_objects___unity_rl_initialization_output_pb2___UnityRLInitializationOutputProto, -) - -from mlagents_envs.communicator_objects.unity_rl_output_pb2 import ( - UnityRLOutputProto as mlagents_envs___communicator_objects___unity_rl_output_pb2___UnityRLOutputProto, -) - -from typing import ( - Optional as typing___Optional, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityOutputProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - - @property - def rl_output(self) -> mlagents_envs___communicator_objects___unity_rl_output_pb2___UnityRLOutputProto: ... - - @property - def rl_initialization_output(self) -> mlagents_envs___communicator_objects___unity_rl_initialization_output_pb2___UnityRLInitializationOutputProto: ... - - def __init__(self, - *, - rl_output : typing___Optional[mlagents_envs___communicator_objects___unity_rl_output_pb2___UnityRLOutputProto] = None, - rl_initialization_output : typing___Optional[mlagents_envs___communicator_objects___unity_rl_initialization_output_pb2___UnityRLInitializationOutputProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityOutputProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"rl_initialization_output",u"rl_output"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"rl_initialization_output",u"rl_output"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"rl_initialization_output",b"rl_initialization_output",u"rl_output",b"rl_output"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"rl_initialization_output",b"rl_initialization_output",u"rl_output",b"rl_output"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.py deleted file mode 100644 index d111397..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.py +++ /dev/null @@ -1,102 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_rl_initialization_input.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import capabilities_pb2 as mlagents__envs_dot_communicator__objects_dot_capabilities__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_rl_initialization_input.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\nFmlagents_envs/communicator_objects/unity_rl_initialization_input.proto\x12\x14\x63ommunicator_objects\x1a\x35mlagents_envs/communicator_objects/capabilities.proto\"\xc0\x01\n\x1fUnityRLInitializationInputProto\x12\x0c\n\x04seed\x18\x01 \x01(\x05\x12\x1d\n\x15\x63ommunication_version\x18\x02 \x01(\t\x12\x17\n\x0fpackage_version\x18\x03 \x01(\t\x12\x44\n\x0c\x63\x61pabilities\x18\x04 \x01(\x0b\x32..communicator_objects.UnityRLCapabilitiesProto\x12\x11\n\tnum_areas\x18\x05 \x01(\x05\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_capabilities__pb2.DESCRIPTOR,]) - - - - -_UNITYRLINITIALIZATIONINPUTPROTO = _descriptor.Descriptor( - name='UnityRLInitializationInputProto', - full_name='communicator_objects.UnityRLInitializationInputProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='seed', full_name='communicator_objects.UnityRLInitializationInputProto.seed', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='communication_version', full_name='communicator_objects.UnityRLInitializationInputProto.communication_version', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='package_version', full_name='communicator_objects.UnityRLInitializationInputProto.package_version', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='capabilities', full_name='communicator_objects.UnityRLInitializationInputProto.capabilities', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='num_areas', full_name='communicator_objects.UnityRLInitializationInputProto.num_areas', index=4, - number=5, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=152, - serialized_end=344, -) - -_UNITYRLINITIALIZATIONINPUTPROTO.fields_by_name['capabilities'].message_type = mlagents__envs_dot_communicator__objects_dot_capabilities__pb2._UNITYRLCAPABILITIESPROTO -DESCRIPTOR.message_types_by_name['UnityRLInitializationInputProto'] = _UNITYRLINITIALIZATIONINPUTPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityRLInitializationInputProto = _reflection.GeneratedProtocolMessageType('UnityRLInitializationInputProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYRLINITIALIZATIONINPUTPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_initialization_input_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLInitializationInputProto) - )) -_sym_db.RegisterMessage(UnityRLInitializationInputProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.pyi deleted file mode 100644 index f502997..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_input_pb2.pyi +++ /dev/null @@ -1,58 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.capabilities_pb2 import ( - UnityRLCapabilitiesProto as mlagents_envs___communicator_objects___capabilities_pb2___UnityRLCapabilitiesProto, -) - -from typing import ( - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityRLInitializationInputProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - seed = ... # type: builtin___int - communication_version = ... # type: typing___Text - package_version = ... # type: typing___Text - num_areas = ... # type: builtin___int - - @property - def capabilities(self) -> mlagents_envs___communicator_objects___capabilities_pb2___UnityRLCapabilitiesProto: ... - - def __init__(self, - *, - seed : typing___Optional[builtin___int] = None, - communication_version : typing___Optional[typing___Text] = None, - package_version : typing___Optional[typing___Text] = None, - capabilities : typing___Optional[mlagents_envs___communicator_objects___capabilities_pb2___UnityRLCapabilitiesProto] = None, - num_areas : typing___Optional[builtin___int] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLInitializationInputProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"capabilities"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"capabilities",u"communication_version",u"num_areas",u"package_version",u"seed"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"capabilities",b"capabilities"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"capabilities",b"capabilities",u"communication_version",b"communication_version",u"num_areas",b"num_areas",u"package_version",b"package_version",u"seed",b"seed"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.py deleted file mode 100644 index 155af96..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.py +++ /dev/null @@ -1,111 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_rl_initialization_output.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import capabilities_pb2 as mlagents__envs_dot_communicator__objects_dot_capabilities__pb2 -from mlagents_envs.communicator_objects import brain_parameters_pb2 as mlagents__envs_dot_communicator__objects_dot_brain__parameters__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_rl_initialization_output.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\nGmlagents_envs/communicator_objects/unity_rl_initialization_output.proto\x12\x14\x63ommunicator_objects\x1a\x35mlagents_envs/communicator_objects/capabilities.proto\x1a\x39mlagents_envs/communicator_objects/brain_parameters.proto\"\x8c\x02\n UnityRLInitializationOutputProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1d\n\x15\x63ommunication_version\x18\x02 \x01(\t\x12\x10\n\x08log_path\x18\x03 \x01(\t\x12\x44\n\x10\x62rain_parameters\x18\x05 \x03(\x0b\x32*.communicator_objects.BrainParametersProto\x12\x17\n\x0fpackage_version\x18\x07 \x01(\t\x12\x44\n\x0c\x63\x61pabilities\x18\x08 \x01(\x0b\x32..communicator_objects.UnityRLCapabilitiesProtoJ\x04\x08\x06\x10\x07\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_capabilities__pb2.DESCRIPTOR,mlagents__envs_dot_communicator__objects_dot_brain__parameters__pb2.DESCRIPTOR,]) - - - - -_UNITYRLINITIALIZATIONOUTPUTPROTO = _descriptor.Descriptor( - name='UnityRLInitializationOutputProto', - full_name='communicator_objects.UnityRLInitializationOutputProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='communicator_objects.UnityRLInitializationOutputProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='communication_version', full_name='communicator_objects.UnityRLInitializationOutputProto.communication_version', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='log_path', full_name='communicator_objects.UnityRLInitializationOutputProto.log_path', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='brain_parameters', full_name='communicator_objects.UnityRLInitializationOutputProto.brain_parameters', index=3, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='package_version', full_name='communicator_objects.UnityRLInitializationOutputProto.package_version', index=4, - number=7, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='capabilities', full_name='communicator_objects.UnityRLInitializationOutputProto.capabilities', index=5, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=212, - serialized_end=480, -) - -_UNITYRLINITIALIZATIONOUTPUTPROTO.fields_by_name['brain_parameters'].message_type = mlagents__envs_dot_communicator__objects_dot_brain__parameters__pb2._BRAINPARAMETERSPROTO -_UNITYRLINITIALIZATIONOUTPUTPROTO.fields_by_name['capabilities'].message_type = mlagents__envs_dot_communicator__objects_dot_capabilities__pb2._UNITYRLCAPABILITIESPROTO -DESCRIPTOR.message_types_by_name['UnityRLInitializationOutputProto'] = _UNITYRLINITIALIZATIONOUTPUTPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityRLInitializationOutputProto = _reflection.GeneratedProtocolMessageType('UnityRLInitializationOutputProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYRLINITIALIZATIONOUTPUTPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_initialization_output_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLInitializationOutputProto) - )) -_sym_db.RegisterMessage(UnityRLInitializationOutputProto) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.pyi deleted file mode 100644 index cce72df..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_initialization_output_pb2.pyi +++ /dev/null @@ -1,71 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.internal.containers import ( - RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.brain_parameters_pb2 import ( - BrainParametersProto as mlagents_envs___communicator_objects___brain_parameters_pb2___BrainParametersProto, -) - -from mlagents_envs.communicator_objects.capabilities_pb2 import ( - UnityRLCapabilitiesProto as mlagents_envs___communicator_objects___capabilities_pb2___UnityRLCapabilitiesProto, -) - -from typing import ( - Iterable as typing___Iterable, - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityRLInitializationOutputProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - name = ... # type: typing___Text - communication_version = ... # type: typing___Text - log_path = ... # type: typing___Text - package_version = ... # type: typing___Text - - @property - def brain_parameters(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[mlagents_envs___communicator_objects___brain_parameters_pb2___BrainParametersProto]: ... - - @property - def capabilities(self) -> mlagents_envs___communicator_objects___capabilities_pb2___UnityRLCapabilitiesProto: ... - - def __init__(self, - *, - name : typing___Optional[typing___Text] = None, - communication_version : typing___Optional[typing___Text] = None, - log_path : typing___Optional[typing___Text] = None, - brain_parameters : typing___Optional[typing___Iterable[mlagents_envs___communicator_objects___brain_parameters_pb2___BrainParametersProto]] = None, - package_version : typing___Optional[typing___Text] = None, - capabilities : typing___Optional[mlagents_envs___communicator_objects___capabilities_pb2___UnityRLCapabilitiesProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLInitializationOutputProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"capabilities"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"brain_parameters",u"capabilities",u"communication_version",u"log_path",u"name",u"package_version"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"capabilities",b"capabilities"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"brain_parameters",b"brain_parameters",u"capabilities",b"capabilities",u"communication_version",b"communication_version",u"log_path",b"log_path",u"name",b"name",u"package_version",b"package_version"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.py deleted file mode 100644 index 69e14f3..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.py +++ /dev/null @@ -1,179 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_rl_input.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import agent_action_pb2 as mlagents__envs_dot_communicator__objects_dot_agent__action__pb2 -from mlagents_envs.communicator_objects import command_pb2 as mlagents__envs_dot_communicator__objects_dot_command__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_rl_input.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n7mlagents_envs/communicator_objects/unity_rl_input.proto\x12\x14\x63ommunicator_objects\x1a\x35mlagents_envs/communicator_objects/agent_action.proto\x1a\x30mlagents_envs/communicator_objects/command.proto\"\xfe\x02\n\x11UnityRLInputProto\x12P\n\ragent_actions\x18\x01 \x03(\x0b\x32\x39.communicator_objects.UnityRLInputProto.AgentActionsEntry\x12\x33\n\x07\x63ommand\x18\x04 \x01(\x0e\x32\".communicator_objects.CommandProto\x12\x14\n\x0cside_channel\x18\x05 \x01(\x0c\x1aM\n\x14ListAgentActionProto\x12\x35\n\x05value\x18\x01 \x03(\x0b\x32&.communicator_objects.AgentActionProto\x1aq\n\x11\x41gentActionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12K\n\x05value\x18\x02 \x01(\x0b\x32<.communicator_objects.UnityRLInputProto.ListAgentActionProto:\x02\x38\x01J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_agent__action__pb2.DESCRIPTOR,mlagents__envs_dot_communicator__objects_dot_command__pb2.DESCRIPTOR,]) - - - - -_UNITYRLINPUTPROTO_LISTAGENTACTIONPROTO = _descriptor.Descriptor( - name='ListAgentActionProto', - full_name='communicator_objects.UnityRLInputProto.ListAgentActionProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='value', full_name='communicator_objects.UnityRLInputProto.ListAgentActionProto.value', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=365, - serialized_end=442, -) - -_UNITYRLINPUTPROTO_AGENTACTIONSENTRY = _descriptor.Descriptor( - name='AgentActionsEntry', - full_name='communicator_objects.UnityRLInputProto.AgentActionsEntry', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='communicator_objects.UnityRLInputProto.AgentActionsEntry.key', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='value', full_name='communicator_objects.UnityRLInputProto.AgentActionsEntry.value', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')), - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=444, - serialized_end=557, -) - -_UNITYRLINPUTPROTO = _descriptor.Descriptor( - name='UnityRLInputProto', - full_name='communicator_objects.UnityRLInputProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='agent_actions', full_name='communicator_objects.UnityRLInputProto.agent_actions', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='command', full_name='communicator_objects.UnityRLInputProto.command', index=1, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='side_channel', full_name='communicator_objects.UnityRLInputProto.side_channel', index=2, - number=5, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[_UNITYRLINPUTPROTO_LISTAGENTACTIONPROTO, _UNITYRLINPUTPROTO_AGENTACTIONSENTRY, ], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=187, - serialized_end=569, -) - -_UNITYRLINPUTPROTO_LISTAGENTACTIONPROTO.fields_by_name['value'].message_type = mlagents__envs_dot_communicator__objects_dot_agent__action__pb2._AGENTACTIONPROTO -_UNITYRLINPUTPROTO_LISTAGENTACTIONPROTO.containing_type = _UNITYRLINPUTPROTO -_UNITYRLINPUTPROTO_AGENTACTIONSENTRY.fields_by_name['value'].message_type = _UNITYRLINPUTPROTO_LISTAGENTACTIONPROTO -_UNITYRLINPUTPROTO_AGENTACTIONSENTRY.containing_type = _UNITYRLINPUTPROTO -_UNITYRLINPUTPROTO.fields_by_name['agent_actions'].message_type = _UNITYRLINPUTPROTO_AGENTACTIONSENTRY -_UNITYRLINPUTPROTO.fields_by_name['command'].enum_type = mlagents__envs_dot_communicator__objects_dot_command__pb2._COMMANDPROTO -DESCRIPTOR.message_types_by_name['UnityRLInputProto'] = _UNITYRLINPUTPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityRLInputProto = _reflection.GeneratedProtocolMessageType('UnityRLInputProto', (_message.Message,), dict( - - ListAgentActionProto = _reflection.GeneratedProtocolMessageType('ListAgentActionProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYRLINPUTPROTO_LISTAGENTACTIONPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_input_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLInputProto.ListAgentActionProto) - )) - , - - AgentActionsEntry = _reflection.GeneratedProtocolMessageType('AgentActionsEntry', (_message.Message,), dict( - DESCRIPTOR = _UNITYRLINPUTPROTO_AGENTACTIONSENTRY, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_input_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLInputProto.AgentActionsEntry) - )) - , - DESCRIPTOR = _UNITYRLINPUTPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_input_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLInputProto) - )) -_sym_db.RegisterMessage(UnityRLInputProto) -_sym_db.RegisterMessage(UnityRLInputProto.ListAgentActionProto) -_sym_db.RegisterMessage(UnityRLInputProto.AgentActionsEntry) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -_UNITYRLINPUTPROTO_AGENTACTIONSENTRY.has_options = True -_UNITYRLINPUTPROTO_AGENTACTIONSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.pyi deleted file mode 100644 index 563f8fa..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_input_pb2.pyi +++ /dev/null @@ -1,105 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.internal.containers import ( - RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.agent_action_pb2 import ( - AgentActionProto as mlagents_envs___communicator_objects___agent_action_pb2___AgentActionProto, -) - -from mlagents_envs.communicator_objects.command_pb2 import ( - CommandProto as mlagents_envs___communicator_objects___command_pb2___CommandProto, -) - -from typing import ( - Iterable as typing___Iterable, - Mapping as typing___Mapping, - MutableMapping as typing___MutableMapping, - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityRLInputProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - class ListAgentActionProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - - @property - def value(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[mlagents_envs___communicator_objects___agent_action_pb2___AgentActionProto]: ... - - def __init__(self, - *, - value : typing___Optional[typing___Iterable[mlagents_envs___communicator_objects___agent_action_pb2___AgentActionProto]] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLInputProto.ListAgentActionProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"value"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> None: ... - - class AgentActionsEntry(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - key = ... # type: typing___Text - - @property - def value(self) -> UnityRLInputProto.ListAgentActionProto: ... - - def __init__(self, - *, - key : typing___Optional[typing___Text] = None, - value : typing___Optional[UnityRLInputProto.ListAgentActionProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLInputProto.AgentActionsEntry: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"value"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"key",u"value"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... - - command = ... # type: mlagents_envs___communicator_objects___command_pb2___CommandProto - side_channel = ... # type: builtin___bytes - - @property - def agent_actions(self) -> typing___MutableMapping[typing___Text, UnityRLInputProto.ListAgentActionProto]: ... - - def __init__(self, - *, - agent_actions : typing___Optional[typing___Mapping[typing___Text, UnityRLInputProto.ListAgentActionProto]] = None, - command : typing___Optional[mlagents_envs___communicator_objects___command_pb2___CommandProto] = None, - side_channel : typing___Optional[builtin___bytes] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLInputProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"agent_actions",u"command",u"side_channel"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"agent_actions",b"agent_actions",u"command",b"command",u"side_channel",b"side_channel"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.py deleted file mode 100644 index 099d0b0..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.py +++ /dev/null @@ -1,170 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_rl_output.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import agent_info_pb2 as mlagents__envs_dot_communicator__objects_dot_agent__info__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_rl_output.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n8mlagents_envs/communicator_objects/unity_rl_output.proto\x12\x14\x63ommunicator_objects\x1a\x33mlagents_envs/communicator_objects/agent_info.proto\"\xb9\x02\n\x12UnityRLOutputProto\x12L\n\nagentInfos\x18\x02 \x03(\x0b\x32\x38.communicator_objects.UnityRLOutputProto.AgentInfosEntry\x12\x14\n\x0cside_channel\x18\x03 \x01(\x0c\x1aI\n\x12ListAgentInfoProto\x12\x33\n\x05value\x18\x01 \x03(\x0b\x32$.communicator_objects.AgentInfoProto\x1an\n\x0f\x41gentInfosEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12J\n\x05value\x18\x02 \x01(\x0b\x32;.communicator_objects.UnityRLOutputProto.ListAgentInfoProto:\x02\x38\x01J\x04\x08\x01\x10\x02\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_agent__info__pb2.DESCRIPTOR,]) - - - - -_UNITYRLOUTPUTPROTO_LISTAGENTINFOPROTO = _descriptor.Descriptor( - name='ListAgentInfoProto', - full_name='communicator_objects.UnityRLOutputProto.ListAgentInfoProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='value', full_name='communicator_objects.UnityRLOutputProto.ListAgentInfoProto.value', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=258, - serialized_end=331, -) - -_UNITYRLOUTPUTPROTO_AGENTINFOSENTRY = _descriptor.Descriptor( - name='AgentInfosEntry', - full_name='communicator_objects.UnityRLOutputProto.AgentInfosEntry', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='communicator_objects.UnityRLOutputProto.AgentInfosEntry.key', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='value', full_name='communicator_objects.UnityRLOutputProto.AgentInfosEntry.value', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')), - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=333, - serialized_end=443, -) - -_UNITYRLOUTPUTPROTO = _descriptor.Descriptor( - name='UnityRLOutputProto', - full_name='communicator_objects.UnityRLOutputProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='agentInfos', full_name='communicator_objects.UnityRLOutputProto.agentInfos', index=0, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - _descriptor.FieldDescriptor( - name='side_channel', full_name='communicator_objects.UnityRLOutputProto.side_channel', index=1, - number=3, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None, file=DESCRIPTOR), - ], - extensions=[ - ], - nested_types=[_UNITYRLOUTPUTPROTO_LISTAGENTINFOPROTO, _UNITYRLOUTPUTPROTO_AGENTINFOSENTRY, ], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto3', - extension_ranges=[], - oneofs=[ - ], - serialized_start=136, - serialized_end=449, -) - -_UNITYRLOUTPUTPROTO_LISTAGENTINFOPROTO.fields_by_name['value'].message_type = mlagents__envs_dot_communicator__objects_dot_agent__info__pb2._AGENTINFOPROTO -_UNITYRLOUTPUTPROTO_LISTAGENTINFOPROTO.containing_type = _UNITYRLOUTPUTPROTO -_UNITYRLOUTPUTPROTO_AGENTINFOSENTRY.fields_by_name['value'].message_type = _UNITYRLOUTPUTPROTO_LISTAGENTINFOPROTO -_UNITYRLOUTPUTPROTO_AGENTINFOSENTRY.containing_type = _UNITYRLOUTPUTPROTO -_UNITYRLOUTPUTPROTO.fields_by_name['agentInfos'].message_type = _UNITYRLOUTPUTPROTO_AGENTINFOSENTRY -DESCRIPTOR.message_types_by_name['UnityRLOutputProto'] = _UNITYRLOUTPUTPROTO -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UnityRLOutputProto = _reflection.GeneratedProtocolMessageType('UnityRLOutputProto', (_message.Message,), dict( - - ListAgentInfoProto = _reflection.GeneratedProtocolMessageType('ListAgentInfoProto', (_message.Message,), dict( - DESCRIPTOR = _UNITYRLOUTPUTPROTO_LISTAGENTINFOPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_output_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLOutputProto.ListAgentInfoProto) - )) - , - - AgentInfosEntry = _reflection.GeneratedProtocolMessageType('AgentInfosEntry', (_message.Message,), dict( - DESCRIPTOR = _UNITYRLOUTPUTPROTO_AGENTINFOSENTRY, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_output_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLOutputProto.AgentInfosEntry) - )) - , - DESCRIPTOR = _UNITYRLOUTPUTPROTO, - __module__ = 'mlagents_envs.communicator_objects.unity_rl_output_pb2' - # @@protoc_insertion_point(class_scope:communicator_objects.UnityRLOutputProto) - )) -_sym_db.RegisterMessage(UnityRLOutputProto) -_sym_db.RegisterMessage(UnityRLOutputProto.ListAgentInfoProto) -_sym_db.RegisterMessage(UnityRLOutputProto.AgentInfosEntry) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) -_UNITYRLOUTPUTPROTO_AGENTINFOSENTRY.has_options = True -_UNITYRLOUTPUTPROTO_AGENTINFOSENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')) -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.pyi deleted file mode 100644 index 0ace7bd..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_rl_output_pb2.pyi +++ /dev/null @@ -1,99 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.descriptor import ( - Descriptor as google___protobuf___descriptor___Descriptor, -) - -from google.protobuf.internal.containers import ( - RepeatedCompositeFieldContainer as google___protobuf___internal___containers___RepeatedCompositeFieldContainer, -) - -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - -from mlagents_envs.communicator_objects.agent_info_pb2 import ( - AgentInfoProto as mlagents_envs___communicator_objects___agent_info_pb2___AgentInfoProto, -) - -from typing import ( - Iterable as typing___Iterable, - Mapping as typing___Mapping, - MutableMapping as typing___MutableMapping, - Optional as typing___Optional, - Text as typing___Text, -) - -from typing_extensions import ( - Literal as typing_extensions___Literal, -) - - -builtin___bool = bool -builtin___bytes = bytes -builtin___float = float -builtin___int = int - - -class UnityRLOutputProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - class ListAgentInfoProto(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - - @property - def value(self) -> google___protobuf___internal___containers___RepeatedCompositeFieldContainer[mlagents_envs___communicator_objects___agent_info_pb2___AgentInfoProto]: ... - - def __init__(self, - *, - value : typing___Optional[typing___Iterable[mlagents_envs___communicator_objects___agent_info_pb2___AgentInfoProto]] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLOutputProto.ListAgentInfoProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"value"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> None: ... - - class AgentInfosEntry(google___protobuf___message___Message): - DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... - key = ... # type: typing___Text - - @property - def value(self) -> UnityRLOutputProto.ListAgentInfoProto: ... - - def __init__(self, - *, - key : typing___Optional[typing___Text] = None, - value : typing___Optional[UnityRLOutputProto.ListAgentInfoProto] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLOutputProto.AgentInfosEntry: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def HasField(self, field_name: typing_extensions___Literal[u"value"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"key",u"value"]) -> None: ... - else: - def HasField(self, field_name: typing_extensions___Literal[u"value",b"value"]) -> builtin___bool: ... - def ClearField(self, field_name: typing_extensions___Literal[u"key",b"key",u"value",b"value"]) -> None: ... - - side_channel = ... # type: builtin___bytes - - @property - def agentInfos(self) -> typing___MutableMapping[typing___Text, UnityRLOutputProto.ListAgentInfoProto]: ... - - def __init__(self, - *, - agentInfos : typing___Optional[typing___Mapping[typing___Text, UnityRLOutputProto.ListAgentInfoProto]] = None, - side_channel : typing___Optional[builtin___bytes] = None, - ) -> None: ... - @classmethod - def FromString(cls, s: builtin___bytes) -> UnityRLOutputProto: ... - def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... - if sys.version_info >= (3,): - def ClearField(self, field_name: typing_extensions___Literal[u"agentInfos",u"side_channel"]) -> None: ... - else: - def ClearField(self, field_name: typing_extensions___Literal[u"agentInfos",b"agentInfos",u"side_channel",b"side_channel"]) -> None: ... diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.py deleted file mode 100644 index 6053ccc..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.py +++ /dev/null @@ -1,58 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: mlagents_envs/communicator_objects/unity_to_external.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from mlagents_envs.communicator_objects import unity_message_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__message__pb2 - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='mlagents_envs/communicator_objects/unity_to_external.proto', - package='communicator_objects', - syntax='proto3', - serialized_pb=_b('\n:mlagents_envs/communicator_objects/unity_to_external.proto\x12\x14\x63ommunicator_objects\x1a\x36mlagents_envs/communicator_objects/unity_message.proto2v\n\x14UnityToExternalProto\x12^\n\x08\x45xchange\x12\'.communicator_objects.UnityMessageProto\x1a\'.communicator_objects.UnityMessageProto\"\x00\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3') - , - dependencies=[mlagents__envs_dot_communicator__objects_dot_unity__message__pb2.DESCRIPTOR,]) - - - -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\252\002\"Unity.MLAgents.CommunicatorObjects')) - -_UNITYTOEXTERNALPROTO = _descriptor.ServiceDescriptor( - name='UnityToExternalProto', - full_name='communicator_objects.UnityToExternalProto', - file=DESCRIPTOR, - index=0, - options=None, - serialized_start=140, - serialized_end=258, - methods=[ - _descriptor.MethodDescriptor( - name='Exchange', - full_name='communicator_objects.UnityToExternalProto.Exchange', - index=0, - containing_service=None, - input_type=mlagents__envs_dot_communicator__objects_dot_unity__message__pb2._UNITYMESSAGEPROTO, - output_type=mlagents__envs_dot_communicator__objects_dot_unity__message__pb2._UNITYMESSAGEPROTO, - options=None, - ), -]) -_sym_db.RegisterServiceDescriptor(_UNITYTOEXTERNALPROTO) - -DESCRIPTOR.services_by_name['UnityToExternalProto'] = _UNITYTOEXTERNALPROTO - -# @@protoc_insertion_point(module_scope) diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.pyi b/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.pyi deleted file mode 100644 index 8bba4ff..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2.pyi +++ /dev/null @@ -1,6 +0,0 @@ -# @generated by generate_proto_mypy_stubs.py. Do not edit! -import sys -from google.protobuf.message import ( - Message as google___protobuf___message___Message, -) - diff --git a/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2_grpc.py b/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2_grpc.py deleted file mode 100644 index bedeb10..0000000 --- a/3DOrangeTree/mlagents_envs/communicator_objects/unity_to_external_pb2_grpc.py +++ /dev/null @@ -1,46 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -import grpc - -from mlagents_envs.communicator_objects import unity_message_pb2 as mlagents__envs_dot_communicator__objects_dot_unity__message__pb2 - - -class UnityToExternalProtoStub(object): - # missing associated documentation comment in .proto file - pass - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.Exchange = channel.unary_unary( - '/communicator_objects.UnityToExternalProto/Exchange', - request_serializer=mlagents__envs_dot_communicator__objects_dot_unity__message__pb2.UnityMessageProto.SerializeToString, - response_deserializer=mlagents__envs_dot_communicator__objects_dot_unity__message__pb2.UnityMessageProto.FromString, - ) - - -class UnityToExternalProtoServicer(object): - # missing associated documentation comment in .proto file - pass - - def Exchange(self, request, context): - """Sends the academy parameters - """ - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_UnityToExternalProtoServicer_to_server(servicer, server): - rpc_method_handlers = { - 'Exchange': grpc.unary_unary_rpc_method_handler( - servicer.Exchange, - request_deserializer=mlagents__envs_dot_communicator__objects_dot_unity__message__pb2.UnityMessageProto.FromString, - response_serializer=mlagents__envs_dot_communicator__objects_dot_unity__message__pb2.UnityMessageProto.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'communicator_objects.UnityToExternalProto', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) diff --git a/3DOrangeTree/mlagents_envs/env_utils.py b/3DOrangeTree/mlagents_envs/env_utils.py deleted file mode 100644 index 73393d9..0000000 --- a/3DOrangeTree/mlagents_envs/env_utils.py +++ /dev/null @@ -1,130 +0,0 @@ -import glob -import os -import subprocess -from sys import platform -from typing import Optional, List -from mlagents_envs.logging_util import get_logger, DEBUG -from mlagents_envs.exception import UnityEnvironmentException - - -logger = get_logger(__name__) - - -def get_platform(): - """ - returns the platform of the operating system : linux, darwin or win32 - """ - return platform - - -def validate_environment_path(env_path: str) -> Optional[str]: - """ - Strip out executable extensions of the env_path - :param env_path: The path to the executable - """ - env_path = ( - env_path.strip() - .replace(".app", "") - .replace(".exe", "") - .replace(".x86_64", "") - .replace(".x86", "") - ) - true_filename = os.path.basename(os.path.normpath(env_path)) - logger.debug(f"The true file name is {true_filename}") - - if not (glob.glob(env_path) or glob.glob(env_path + ".*")): - return None - - cwd = os.getcwd() - launch_string = None - true_filename = os.path.basename(os.path.normpath(env_path)) - if get_platform() == "linux" or get_platform() == "linux2": - candidates = glob.glob(os.path.join(cwd, env_path) + ".x86_64") - if len(candidates) == 0: - candidates = glob.glob(os.path.join(cwd, env_path) + ".x86") - if len(candidates) == 0: - candidates = glob.glob(env_path + ".x86_64") - if len(candidates) == 0: - candidates = glob.glob(env_path + ".x86") - if len(candidates) == 0: - if os.path.isfile(env_path): - candidates = [env_path] - if len(candidates) > 0: - launch_string = candidates[0] - - elif get_platform() == "darwin": - candidates = glob.glob( - os.path.join(cwd, env_path + ".app", "Contents", "MacOS", true_filename) - ) - if len(candidates) == 0: - candidates = glob.glob( - os.path.join(env_path + ".app", "Contents", "MacOS", true_filename) - ) - if len(candidates) == 0: - candidates = glob.glob( - os.path.join(cwd, env_path + ".app", "Contents", "MacOS", "*") - ) - if len(candidates) == 0: - candidates = glob.glob( - os.path.join(env_path + ".app", "Contents", "MacOS", "*") - ) - if len(candidates) > 0: - launch_string = candidates[0] - elif get_platform() == "win32": - candidates = glob.glob(os.path.join(cwd, env_path + ".exe")) - if len(candidates) == 0: - candidates = glob.glob(env_path + ".exe") - if len(candidates) == 0: - # Look for e.g. 3DBall\UnityEnvironment.exe - crash_handlers = set( - glob.glob(os.path.join(cwd, env_path, "UnityCrashHandler*.exe")) - ) - candidates = [ - c - for c in glob.glob(os.path.join(cwd, env_path, "*.exe")) - if c not in crash_handlers - ] - if len(candidates) > 0: - launch_string = candidates[0] - return launch_string - - -def launch_executable(file_name: str, args: List[str]) -> subprocess.Popen: - """ - Launches a Unity executable and returns the process handle for it. - :param file_name: the name of the executable - :param args: List of string that will be passed as command line arguments - when launching the executable. - """ - launch_string = validate_environment_path(file_name) - if launch_string is None: - raise UnityEnvironmentException( - f"Couldn't launch the {file_name} environment. Provided filename does not match any environments." - ) - else: - logger.debug(f"The launch string is {launch_string}") - logger.debug(f"Running with args {args}") - # Launch Unity environment - subprocess_args = [launch_string] + args - # std_out_option = DEVNULL means the outputs will not be displayed on terminal. - # std_out_option = None is default behavior: the outputs are displayed on terminal. - std_out_option = subprocess.DEVNULL if logger.level > DEBUG else None - try: - return subprocess.Popen( - subprocess_args, - # start_new_session=True means that signals to the parent python process - # (e.g. SIGINT from keyboard interrupt) will not be sent to the new process on POSIX platforms. - # This is generally good since we want the environment to have a chance to shutdown, - # but may be undesirable in come cases; if so, we'll add a command-line toggle. - # Note that on Windows, the CTRL_C signal will still be sent. - start_new_session=True, - stdout=std_out_option, - stderr=std_out_option, - ) - except PermissionError as perm: - # This is likely due to missing read or execute permissions on file. - raise UnityEnvironmentException( - f"Error when trying to launch environment - make sure " - f"permissions are set correctly. For example " - f'"chmod -R 755 {launch_string}"' - ) from perm diff --git a/3DOrangeTree/mlagents_envs/environment.py b/3DOrangeTree/mlagents_envs/environment.py deleted file mode 100644 index 18731a2..0000000 --- a/3DOrangeTree/mlagents_envs/environment.py +++ /dev/null @@ -1,518 +0,0 @@ -import atexit -from distutils.version import StrictVersion - -import numpy as np -import os -import subprocess -from typing import Dict, List, Optional, Tuple, Mapping as MappingType - -import mlagents_envs - -from mlagents_envs.logging_util import get_logger -from mlagents_envs.side_channel.side_channel import SideChannel -from mlagents_envs.side_channel import DefaultTrainingAnalyticsSideChannel -from mlagents_envs.side_channel.side_channel_manager import SideChannelManager -from mlagents_envs import env_utils - -from mlagents_envs.base_env import ( - BaseEnv, - DecisionSteps, - TerminalSteps, - BehaviorSpec, - ActionTuple, - BehaviorName, - AgentId, - BehaviorMapping, -) -from mlagents_envs.timers import timed, hierarchical_timer -from mlagents_envs.exception import ( - UnityEnvironmentException, - UnityActionException, - UnityTimeOutException, - UnityCommunicatorStoppedException, -) - -from mlagents_envs.communicator_objects.command_pb2 import STEP, RESET -from mlagents_envs.rpc_utils import behavior_spec_from_proto, steps_from_proto - -from mlagents_envs.communicator_objects.unity_rl_input_pb2 import UnityRLInputProto -from mlagents_envs.communicator_objects.unity_rl_output_pb2 import UnityRLOutputProto -from mlagents_envs.communicator_objects.agent_action_pb2 import AgentActionProto -from mlagents_envs.communicator_objects.unity_output_pb2 import UnityOutputProto -from mlagents_envs.communicator_objects.capabilities_pb2 import UnityRLCapabilitiesProto -from mlagents_envs.communicator_objects.unity_rl_initialization_input_pb2 import ( - UnityRLInitializationInputProto, -) - -from mlagents_envs.communicator_objects.unity_input_pb2 import UnityInputProto - -from .rpc_communicator import RpcCommunicator -import signal - -logger = get_logger(__name__) - - -class UnityEnvironment(BaseEnv): - # Communication protocol version. - # When connecting to C#, this must be compatible with Academy.k_ApiVersion. - # We follow semantic versioning on the communication version, so existing - # functionality will work as long the major versions match. - # This should be changed whenever a change is made to the communication protocol. - # Revision history: - # * 1.0.0 - initial version - # * 1.1.0 - support concatenated PNGs for compressed observations. - # * 1.2.0 - support compression mapping for stacked compressed observations. - # * 1.3.0 - support action spaces with both continuous and discrete actions. - # * 1.4.0 - support training analytics sent from python trainer to the editor. - # * 1.5.0 - support variable length observation training and multi-agent groups. - API_VERSION = "1.5.0" - - # Default port that the editor listens on. If an environment executable - # isn't specified, this port will be used. - DEFAULT_EDITOR_PORT = 5004 - - # Default base port for environments. Each environment will be offset from this - # by it's worker_id. - BASE_ENVIRONMENT_PORT = 5005 - - # Command line argument used to pass the port to the executable environment. - _PORT_COMMAND_LINE_ARG = "--mlagents-port" - - @staticmethod - def _raise_version_exception(unity_com_ver: str) -> None: - raise UnityEnvironmentException( - f"The communication API version is not compatible between Unity and python. " - f"Python API: {UnityEnvironment.API_VERSION}, Unity API: {unity_com_ver}.\n " - f"Please find the versions that work best together from our release page.\n" - "https://github.com/Unity-Technologies/ml-agents/releases" - ) - - @staticmethod - def _check_communication_compatibility( - unity_com_ver: str, python_api_version: str, unity_package_version: str - ) -> bool: - unity_communicator_version = StrictVersion(unity_com_ver) - api_version = StrictVersion(python_api_version) - if unity_communicator_version.version[0] == 0: - if ( - unity_communicator_version.version[0] != api_version.version[0] - or unity_communicator_version.version[1] != api_version.version[1] - ): - # Minor beta versions differ. - return False - elif unity_communicator_version.version[0] != api_version.version[0]: - # Major versions mismatch. - return False - else: - # Major versions match, so either: - # 1) The versions are identical, in which case there's no compatibility issues - # 2) The Unity version is newer, in which case we'll warn or fail on the Unity side if trying to use - # unsupported features - # 3) The trainer version is newer, in which case new trainer features might be available but unused by C# - # In any of the cases, there's no reason to warn about mismatch here. - logger.info( - f"Connected to Unity environment with package version {unity_package_version} " - f"and communication version {unity_com_ver}" - ) - return True - - @staticmethod - def _get_capabilities_proto() -> UnityRLCapabilitiesProto: - capabilities = UnityRLCapabilitiesProto() - capabilities.baseRLCapabilities = True - capabilities.concatenatedPngObservations = True - capabilities.compressedChannelMapping = True - capabilities.hybridActions = True - capabilities.trainingAnalytics = True - capabilities.variableLengthObservation = True - capabilities.multiAgentGroups = True - return capabilities - - @staticmethod - def _warn_csharp_base_capabilities( - caps: UnityRLCapabilitiesProto, unity_package_ver: str, python_package_ver: str - ) -> None: - if not caps.baseRLCapabilities: - logger.warning( - "WARNING: The Unity process is not running with the expected base Reinforcement Learning" - " capabilities. Please be sure upgrade the Unity Package to a version that is compatible with this " - "python package.\n" - f"Python package version: {python_package_ver}, C# package version: {unity_package_ver}" - f"Please find the versions that work best together from our release page.\n" - "https://github.com/Unity-Technologies/ml-agents/releases" - ) - - def __init__( - self, - file_name: Optional[str] = None, - worker_id: int = 0, - base_port: Optional[int] = None, - seed: int = 0, - no_graphics: bool = False, - timeout_wait: int = 60, - additional_args: Optional[List[str]] = None, - side_channels: Optional[List[SideChannel]] = None, - log_folder: Optional[str] = None, - num_areas: int = 1, - ): - """ - Starts a new unity environment and establishes a connection with the environment. - Notice: Currently communication between Unity and Python takes place over an open socket without authentication. - Ensure that the network where training takes place is secure. - - :string file_name: Name of Unity environment binary. - :int base_port: Baseline port number to connect to Unity environment over. worker_id increments over this. - If no environment is specified (i.e. file_name is None), the DEFAULT_EDITOR_PORT will be used. - :int worker_id: Offset from base_port. Used for training multiple environments simultaneously. - :bool no_graphics: Whether to run the Unity simulator in no-graphics mode - :int timeout_wait: Time (in seconds) to wait for connection from environment. - :list args: Addition Unity command line arguments - :list side_channels: Additional side channel for no-rl communication with Unity - :str log_folder: Optional folder to write the Unity Player log file into. Requires absolute path. - """ - atexit.register(self._close) - self._additional_args = additional_args or [] - self._no_graphics = no_graphics - # If base port is not specified, use BASE_ENVIRONMENT_PORT if we have - # an environment, otherwise DEFAULT_EDITOR_PORT - if base_port is None: - base_port = ( - self.BASE_ENVIRONMENT_PORT if file_name else self.DEFAULT_EDITOR_PORT - ) - self._port = base_port + worker_id - self._buffer_size = 12000 - # If true, this means the environment was successfully loaded - self._loaded = False - # The process that is started. If None, no process was started - self._process: Optional[subprocess.Popen] = None - self._timeout_wait: int = timeout_wait - self._communicator = self._get_communicator(worker_id, base_port, timeout_wait) - self._worker_id = worker_id - if side_channels is None: - side_channels = [] - default_training_side_channel: Optional[ - DefaultTrainingAnalyticsSideChannel - ] = None - if DefaultTrainingAnalyticsSideChannel.CHANNEL_ID not in [ - _.channel_id for _ in side_channels - ]: - default_training_side_channel = DefaultTrainingAnalyticsSideChannel() - side_channels.append(default_training_side_channel) - self._side_channel_manager = SideChannelManager(side_channels) - self._log_folder = log_folder - self.academy_capabilities: UnityRLCapabilitiesProto = None # type: ignore - - # If the environment name is None, a new environment will not be launched - # and the communicator will directly try to connect to an existing unity environment. - # If the worker-id is not 0 and the environment name is None, an error is thrown - if file_name is None and worker_id != 0: - raise UnityEnvironmentException( - "If the environment name is None, " - "the worker-id must be 0 in order to connect with the Editor." - ) - if file_name is not None: - try: - self._process = env_utils.launch_executable( - file_name, self._executable_args() - ) - except UnityEnvironmentException: - self._close(0) - raise - else: - logger.info( - f"Listening on port {self._port}. " - f"Start training by pressing the Play button in the Unity Editor." - ) - self._loaded = True - - rl_init_parameters_in = UnityRLInitializationInputProto( - seed=seed, - communication_version=self.API_VERSION, - package_version=mlagents_envs.__version__, - capabilities=UnityEnvironment._get_capabilities_proto(), - num_areas=num_areas, - ) - try: - aca_output = self._send_academy_parameters(rl_init_parameters_in) - aca_params = aca_output.rl_initialization_output - except UnityTimeOutException: - self._close(0) - raise - - if not UnityEnvironment._check_communication_compatibility( - aca_params.communication_version, - UnityEnvironment.API_VERSION, - aca_params.package_version, - ): - self._close(0) - UnityEnvironment._raise_version_exception(aca_params.communication_version) - - UnityEnvironment._warn_csharp_base_capabilities( - aca_params.capabilities, - aca_params.package_version, - UnityEnvironment.API_VERSION, - ) - - self._env_state: Dict[str, Tuple[DecisionSteps, TerminalSteps]] = {} - self._env_specs: Dict[str, BehaviorSpec] = {} - self._env_actions: Dict[str, ActionTuple] = {} - self._is_first_message = True - self._update_behavior_specs(aca_output) - self.academy_capabilities = aca_params.capabilities - if default_training_side_channel is not None: - default_training_side_channel.environment_initialized() - - @staticmethod - def _get_communicator(worker_id, base_port, timeout_wait): - return RpcCommunicator(worker_id, base_port, timeout_wait) - - def _executable_args(self) -> List[str]: - args: List[str] = [] - if self._no_graphics: - args += ["-nographics", "-batchmode"] - args += [UnityEnvironment._PORT_COMMAND_LINE_ARG, str(self._port)] - - # If the logfile arg isn't already set in the env args, - # try to set it to an output directory - logfile_set = "-logfile" in (arg.lower() for arg in self._additional_args) - if self._log_folder and not logfile_set: - log_file_path = os.path.join( - self._log_folder, f"Player-{self._worker_id}.log" - ) - args += ["-logFile", log_file_path] - # Add in arguments passed explicitly by the user. - args += self._additional_args - return args - - def _update_behavior_specs(self, output: UnityOutputProto) -> None: - init_output = output.rl_initialization_output - for brain_param in init_output.brain_parameters: - # Each BrainParameter in the rl_initialization_output should have at least one AgentInfo - # Get that agent, because we need some of its observations. - agent_infos = output.rl_output.agentInfos[brain_param.brain_name] - if agent_infos.value: - agent = agent_infos.value[0] - new_spec = behavior_spec_from_proto(brain_param, agent) - self._env_specs[brain_param.brain_name] = new_spec - logger.info(f"Connected new brain: {brain_param.brain_name}") - - def _update_state(self, output: UnityRLOutputProto) -> None: - """ - Collects experience information from all external brains in environment at current step. - """ - for brain_name in self._env_specs.keys(): - if brain_name in output.agentInfos: - agent_info_list = output.agentInfos[brain_name].value - self._env_state[brain_name] = steps_from_proto( - agent_info_list, self._env_specs[brain_name] - ) - else: - self._env_state[brain_name] = ( - DecisionSteps.empty(self._env_specs[brain_name]), - TerminalSteps.empty(self._env_specs[brain_name]), - ) - self._side_channel_manager.process_side_channel_message(output.side_channel) - - def reset(self) -> None: - if self._loaded: - outputs = self._communicator.exchange( - self._generate_reset_input(), self._poll_process - ) - if outputs is None: - raise UnityCommunicatorStoppedException("Communicator has exited.") - self._update_behavior_specs(outputs) - rl_output = outputs.rl_output - self._update_state(rl_output) - self._is_first_message = False - self._env_actions.clear() - else: - raise UnityEnvironmentException("No Unity environment is loaded.") - - @timed - def step(self) -> None: - if self._is_first_message: - return self.reset() - if not self._loaded: - raise UnityEnvironmentException("No Unity environment is loaded.") - # fill the blanks for missing actions - for group_name in self._env_specs: - if group_name not in self._env_actions: - n_agents = 0 - if group_name in self._env_state: - n_agents = len(self._env_state[group_name][0]) - self._env_actions[group_name] = self._env_specs[ - group_name - ].action_spec.empty_action(n_agents) - step_input = self._generate_step_input(self._env_actions) - with hierarchical_timer("communicator.exchange"): - outputs = self._communicator.exchange(step_input, self._poll_process) - if outputs is None: - raise UnityCommunicatorStoppedException("Communicator has exited.") - self._update_behavior_specs(outputs) - rl_output = outputs.rl_output - self._update_state(rl_output) - self._env_actions.clear() - - @property - def behavior_specs(self) -> MappingType[str, BehaviorSpec]: - return BehaviorMapping(self._env_specs) - - def _assert_behavior_exists(self, behavior_name: str) -> None: - if behavior_name not in self._env_specs: - raise UnityActionException( - f"The group {behavior_name} does not correspond to an existing " - f"agent group in the environment" - ) - - def set_actions(self, behavior_name: BehaviorName, action: ActionTuple) -> None: - self._assert_behavior_exists(behavior_name) - if behavior_name not in self._env_state: - return - action_spec = self._env_specs[behavior_name].action_spec - num_agents = len(self._env_state[behavior_name][0]) - action = action_spec._validate_action(action, num_agents, behavior_name) - self._env_actions[behavior_name] = action - - def set_action_for_agent( - self, behavior_name: BehaviorName, agent_id: AgentId, action: ActionTuple - ) -> None: - self._assert_behavior_exists(behavior_name) - if behavior_name not in self._env_state: - return - action_spec = self._env_specs[behavior_name].action_spec - action = action_spec._validate_action(action, 1, behavior_name) - if behavior_name not in self._env_actions: - num_agents = len(self._env_state[behavior_name][0]) - self._env_actions[behavior_name] = action_spec.empty_action(num_agents) - try: - index = np.where(self._env_state[behavior_name][0].agent_id == agent_id)[0][ - 0 - ] - except IndexError as ie: - raise IndexError( - "agent_id {} is did not request a decision at the previous step".format( - agent_id - ) - ) from ie - if action_spec.continuous_size > 0: - self._env_actions[behavior_name].continuous[index] = action.continuous[0, :] - if action_spec.discrete_size > 0: - self._env_actions[behavior_name].discrete[index] = action.discrete[0, :] - - def get_steps( - self, behavior_name: BehaviorName - ) -> Tuple[DecisionSteps, TerminalSteps]: - self._assert_behavior_exists(behavior_name) - return self._env_state[behavior_name] - - def _poll_process(self) -> None: - """ - Check the status of the subprocess. If it has exited, raise a UnityEnvironmentException - :return: None - """ - if not self._process: - return - poll_res = self._process.poll() - if poll_res is not None: - exc_msg = self._returncode_to_env_message(self._process.returncode) - raise UnityEnvironmentException(exc_msg) - - def close(self): - """ - Sends a shutdown signal to the unity environment, and closes the socket connection. - """ - if self._loaded: - self._close() - else: - raise UnityEnvironmentException("No Unity environment is loaded.") - - def _close(self, timeout: Optional[int] = None) -> None: - """ - Close the communicator and environment subprocess (if necessary). - - :int timeout: [Optional] Number of seconds to wait for the environment to shut down before - force-killing it. Defaults to `self.timeout_wait`. - """ - if timeout is None: - timeout = self._timeout_wait - self._loaded = False - self._communicator.close() - if self._process is not None: - # Wait a bit for the process to shutdown, but kill it if it takes too long - try: - self._process.wait(timeout=timeout) - logger.debug(self._returncode_to_env_message(self._process.returncode)) - except subprocess.TimeoutExpired: - logger.warning("Environment timed out shutting down. Killing...") - self._process.kill() - # Set to None so we don't try to close multiple times. - self._process = None - - @timed - def _generate_step_input( - self, vector_action: Dict[str, ActionTuple] - ) -> UnityInputProto: - rl_in = UnityRLInputProto() - for b in vector_action: - n_agents = len(self._env_state[b][0]) - if n_agents == 0: - continue - for i in range(n_agents): - action = AgentActionProto() - if vector_action[b].continuous is not None: - action.vector_actions_deprecated.extend( - vector_action[b].continuous[i] - ) - action.continuous_actions.extend(vector_action[b].continuous[i]) - if vector_action[b].discrete is not None: - action.vector_actions_deprecated.extend( - vector_action[b].discrete[i] - ) - action.discrete_actions.extend(vector_action[b].discrete[i]) - rl_in.agent_actions[b].value.extend([action]) - rl_in.command = STEP - rl_in.side_channel = bytes( - self._side_channel_manager.generate_side_channel_messages() - ) - return self._wrap_unity_input(rl_in) - - def _generate_reset_input(self) -> UnityInputProto: - rl_in = UnityRLInputProto() - rl_in.command = RESET - rl_in.side_channel = bytes( - self._side_channel_manager.generate_side_channel_messages() - ) - return self._wrap_unity_input(rl_in) - - def _send_academy_parameters( - self, init_parameters: UnityRLInitializationInputProto - ) -> UnityOutputProto: - inputs = UnityInputProto() - inputs.rl_initialization_input.CopyFrom(init_parameters) - return self._communicator.initialize(inputs, self._poll_process) - - @staticmethod - def _wrap_unity_input(rl_input: UnityRLInputProto) -> UnityInputProto: - result = UnityInputProto() - result.rl_input.CopyFrom(rl_input) - return result - - @staticmethod - def _returncode_to_signal_name(returncode: int) -> Optional[str]: - """ - Try to convert return codes into their corresponding signal name. - E.g. returncode_to_signal_name(-2) -> "SIGINT" - """ - try: - # A negative value -N indicates that the child was terminated by signal N (POSIX only). - s = signal.Signals(-returncode) - return s.name - except Exception: - # Should generally be a ValueError, but catch everything just in case. - return None - - @staticmethod - def _returncode_to_env_message(returncode: int) -> str: - signal_name = UnityEnvironment._returncode_to_signal_name(returncode) - signal_name = f" ({signal_name})" if signal_name else "" - return f"Environment shut down with return code {returncode}{signal_name}." diff --git a/3DOrangeTree/mlagents_envs/exception.py b/3DOrangeTree/mlagents_envs/exception.py deleted file mode 100644 index 324cdd0..0000000 --- a/3DOrangeTree/mlagents_envs/exception.py +++ /dev/null @@ -1,86 +0,0 @@ -class UnityException(Exception): - """ - Any error related to ml-agents environment. - """ - - pass - - -class UnityEnvironmentException(UnityException): - """ - Related to errors starting and closing environment. - """ - - pass - - -class UnityCommunicationException(UnityException): - """ - Related to errors with the communicator. - """ - - pass - - -class UnityCommunicatorStoppedException(UnityException): - """ - Raised when communicator has stopped gracefully. - """ - - pass - - -class UnityObservationException(UnityException): - """ - Related to errors with receiving observations. - """ - - pass - - -class UnityActionException(UnityException): - """ - Related to errors with sending actions. - """ - - pass - - -class UnityTimeOutException(UnityException): - """ - Related to errors with communication timeouts. - """ - - pass - - -class UnitySideChannelException(UnityException): - """ - Related to errors with side channels. - """ - - pass - - -class UnityWorkerInUseException(UnityException): - """ - This error occurs when the port for a certain worker ID is already reserved. - """ - - MESSAGE_TEMPLATE = ( - "Couldn't start socket communication because worker number {} is still in use. " - "You may need to manually close a previously opened environment " - "or use a different worker number." - ) - - def __init__(self, worker_id): - message = self.MESSAGE_TEMPLATE.format(str(worker_id)) - super().__init__(message) - - -class UnityPolicyException(UnityException): - """ - Related to errors with the Trainer. - """ - - pass diff --git a/3DOrangeTree/mlagents_envs/logging_util.py b/3DOrangeTree/mlagents_envs/logging_util.py deleted file mode 100644 index ddd4e3b..0000000 --- a/3DOrangeTree/mlagents_envs/logging_util.py +++ /dev/null @@ -1,63 +0,0 @@ -import logging # noqa I251 -import sys - -CRITICAL = logging.CRITICAL -FATAL = logging.FATAL -ERROR = logging.ERROR -WARNING = logging.WARNING -INFO = logging.INFO -DEBUG = logging.DEBUG -NOTSET = logging.NOTSET - -_loggers = set() -_log_level = NOTSET -DATE_FORMAT = "%Y-%m-%d %H:%M:%S" -DEBUG_LOG_FORMAT = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)d] %(message)s" -LOG_FORMAT = "[%(levelname)s] %(message)s" - - -def get_logger(name: str) -> logging.Logger: - """ - Create a logger with the specified name. The logger will use the log level - specified by set_log_level() - """ - logger = logging.getLogger(name=name) - - if _log_level == DEBUG: - formatter = logging.Formatter(fmt=DEBUG_LOG_FORMAT, datefmt=DATE_FORMAT) - else: - formatter = logging.Formatter(fmt=LOG_FORMAT) - handler = logging.StreamHandler(stream=sys.stdout) - handler.setFormatter(formatter) - logger.addHandler(handler) - - # If we've already set the log level, make sure new loggers use it - if _log_level != NOTSET: - logger.setLevel(_log_level) - - # Keep track of this logger so that we can change the log level later - _loggers.add(logger) - return logger - - -def set_log_level(log_level: int) -> None: - """ - Set the ML-Agents logging level. This will also configure the logging format (if it hasn't already been set). - """ - global _log_level - _log_level = log_level - - for logger in _loggers: - logger.setLevel(log_level) - - if log_level == DEBUG: - formatter = logging.Formatter(fmt=DEBUG_LOG_FORMAT, datefmt=DATE_FORMAT) - else: - formatter = logging.Formatter(LOG_FORMAT) - _set_formatter_for_all_loggers(formatter) - - -def _set_formatter_for_all_loggers(formatter: logging.Formatter) -> None: - for logger in _loggers: - for handler in logger.handlers[:]: - handler.setFormatter(formatter) diff --git a/3DOrangeTree/mlagents_envs/mock_communicator.py b/3DOrangeTree/mlagents_envs/mock_communicator.py deleted file mode 100644 index 0e425e2..0000000 --- a/3DOrangeTree/mlagents_envs/mock_communicator.py +++ /dev/null @@ -1,111 +0,0 @@ -from typing import Optional - -from .communicator import Communicator, PollCallback -from .environment import UnityEnvironment -from mlagents_envs.communicator_objects.unity_rl_output_pb2 import UnityRLOutputProto -from mlagents_envs.communicator_objects.brain_parameters_pb2 import ( - BrainParametersProto, - ActionSpecProto, -) -from mlagents_envs.communicator_objects.unity_rl_initialization_output_pb2 import ( - UnityRLInitializationOutputProto, -) -from mlagents_envs.communicator_objects.unity_input_pb2 import UnityInputProto -from mlagents_envs.communicator_objects.unity_output_pb2 import UnityOutputProto -from mlagents_envs.communicator_objects.agent_info_pb2 import AgentInfoProto -from mlagents_envs.communicator_objects.observation_pb2 import ( - ObservationProto, - NONE as COMPRESSION_TYPE_NONE, - PNG as COMPRESSION_TYPE_PNG, -) - - -class MockCommunicator(Communicator): - def __init__( - self, - discrete_action=False, - visual_inputs=0, - num_agents=3, - brain_name="RealFakeBrain", - vec_obs_size=3, - ): - """ - Python side of the grpc communication. Python is the client and Unity the server - """ - super().__init__() - self.is_discrete = discrete_action - self.steps = 0 - self.visual_inputs = visual_inputs - self.has_been_closed = False - self.num_agents = num_agents - self.brain_name = brain_name - self.vec_obs_size = vec_obs_size - - def initialize( - self, inputs: UnityInputProto, poll_callback: Optional[PollCallback] = None - ) -> UnityOutputProto: - if self.is_discrete: - action_spec = ActionSpecProto( - num_discrete_actions=2, discrete_branch_sizes=[3, 2] - ) - else: - action_spec = ActionSpecProto(num_continuous_actions=2) - bp = BrainParametersProto( - brain_name=self.brain_name, is_training=True, action_spec=action_spec - ) - rl_init = UnityRLInitializationOutputProto( - name="RealFakeAcademy", - communication_version=UnityEnvironment.API_VERSION, - package_version="mock_package_version", - log_path="", - brain_parameters=[bp], - ) - output = UnityRLOutputProto(agentInfos=self._get_agent_infos()) - return UnityOutputProto(rl_initialization_output=rl_init, rl_output=output) - - def _get_agent_infos(self): - dict_agent_info = {} - list_agent_info = [] - vector_obs = [1, 2, 3] - - observations = [ - ObservationProto( - compressed_data=None, - shape=[30, 40, 3], - compression_type=COMPRESSION_TYPE_PNG, - ) - for _ in range(self.visual_inputs) - ] - vector_obs_proto = ObservationProto( - float_data=ObservationProto.FloatData(data=vector_obs), - shape=[len(vector_obs)], - compression_type=COMPRESSION_TYPE_NONE, - ) - observations.append(vector_obs_proto) - - for i in range(self.num_agents): - list_agent_info.append( - AgentInfoProto( - reward=1, - done=(i == 2), - max_step_reached=False, - id=i, - observations=observations, - ) - ) - dict_agent_info["RealFakeBrain"] = UnityRLOutputProto.ListAgentInfoProto( - value=list_agent_info - ) - return dict_agent_info - - def exchange( - self, inputs: UnityInputProto, poll_callback: Optional[PollCallback] = None - ) -> UnityOutputProto: - result = UnityRLOutputProto(agentInfos=self._get_agent_infos()) - return UnityOutputProto(rl_output=result) - - def close(self): - """ - Sends a shutdown signal to the unity environment, and closes the grpc connection. - """ - self.has_been_closed = True diff --git a/3DOrangeTree/mlagents_envs/registry/__init__.py b/3DOrangeTree/mlagents_envs/registry/__init__.py deleted file mode 100644 index 74c0e8a..0000000 --- a/3DOrangeTree/mlagents_envs/registry/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from mlagents_envs.registry.unity_env_registry import ( # noqa F401 - default_registry, - UnityEnvRegistry, -) diff --git a/3DOrangeTree/mlagents_envs/registry/__pycache__/__init__.cpython-37.pyc b/3DOrangeTree/mlagents_envs/registry/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 14a70bd0bb370898753626b5b476288d5e5179aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 276 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 diff --git a/3DOrangeTree/mlagents_envs/registry/base_registry_entry.py b/3DOrangeTree/mlagents_envs/registry/base_registry_entry.py deleted file mode 100644 index f72009f..0000000 --- a/3DOrangeTree/mlagents_envs/registry/base_registry_entry.py +++ /dev/null @@ -1,56 +0,0 @@ -from abc import abstractmethod -from typing import Any, Optional -from mlagents_envs.base_env import BaseEnv - - -class BaseRegistryEntry: - def __init__( - self, - identifier: str, - expected_reward: Optional[float], - description: Optional[str], - ): - """ - BaseRegistryEntry allows launching a Unity Environment with its make method. - :param identifier: The name of the Unity Environment. - :param expected_reward: The cumulative reward that an Agent must receive - for the task to be considered solved. - :param description: A description of the Unity Environment. Contains human - readable information about potential special arguments that the make method can - take as well as information regarding the observation, reward, actions, - behaviors and number of agents in the Environment. - """ - self._identifier = identifier - self._expected_reward = expected_reward - self._description = description - - @property - def identifier(self) -> str: - """ - The unique identifier of the entry - """ - return self._identifier - - @property - def expected_reward(self) -> Optional[float]: - """ - The cumulative reward that an Agent must receive for the task to be considered - solved. - """ - return self._expected_reward - - @property - def description(self) -> Optional[str]: - """ - A description of the Unity Environment the entry can make. - """ - return self._description - - @abstractmethod - def make(self, **kwargs: Any) -> BaseEnv: - """ - This method creates a Unity BaseEnv (usually a UnityEnvironment). - """ - raise NotImplementedError( - f"The make() method not implemented for entry {self.identifier}" - ) diff --git a/3DOrangeTree/mlagents_envs/registry/binary_utils.py b/3DOrangeTree/mlagents_envs/registry/binary_utils.py deleted file mode 100644 index c75d8dd..0000000 --- a/3DOrangeTree/mlagents_envs/registry/binary_utils.py +++ /dev/null @@ -1,235 +0,0 @@ -import urllib.request -import tempfile -import os -import uuid -import shutil -import glob -import yaml -import hashlib - -from zipfile import ZipFile -from sys import platform -from typing import Tuple, Optional, Dict, Any - -from mlagents_envs.env_utils import validate_environment_path - -from mlagents_envs.logging_util import get_logger - -logger = get_logger(__name__) - -# The default logical block size is 8192 bytes (8 KB) for UFS file systems. -BLOCK_SIZE = 8192 - - -def get_local_binary_path(name: str, url: str) -> str: - """ - Returns the path to the executable previously downloaded with the name argument. If - None is found, the executable at the url argument will be downloaded and stored - under name for future uses. - :param name: The name that will be given to the folder containing the extracted data - :param url: The URL of the zip file - """ - NUMBER_ATTEMPTS = 5 - path = get_local_binary_path_if_exists(name, url) - if path is None: - logger.debug( - f"Local environment {name} not found, downloading environment from {url}" - ) - for attempt in range(NUMBER_ATTEMPTS): # Perform 5 attempts at downloading the file - if path is not None: - break - try: - download_and_extract_zip(url, name) - except Exception: - if attempt + 1 < NUMBER_ATTEMPTS: - logger.warning( - f"Attempt {attempt + 1} / {NUMBER_ATTEMPTS}" - ": Failed to download and extract binary." - ) - else: - raise - path = get_local_binary_path_if_exists(name, url) - - if path is None: - raise FileNotFoundError( - f"Binary not found, make sure {url} is a valid url to " - "a zip folder containing a valid Unity executable" - ) - return path - - -def get_local_binary_path_if_exists(name: str, url: str) -> Optional[str]: - """ - Recursively searches for a Unity executable in the extracted files folders. This is - platform dependent : It will only return a Unity executable compatible with the - computer's OS. If no executable is found, None will be returned. - :param name: The name/identifier of the executable - :param url: The url the executable was downloaded from (for verification) - """ - _, bin_dir = get_tmp_dir() - extension = None - - if platform == "linux" or platform == "linux2": - extension = "*.x86_64" - if platform == "darwin": - extension = "*.app" - if platform == "win32": - extension = "*.exe" - if extension is None: - raise NotImplementedError("No extensions found for this platform.") - url_hash = "-" + hashlib.md5(url.encode()).hexdigest() - path = os.path.join(bin_dir, name + url_hash, "**", extension) - candidates = glob.glob(path, recursive=True) - if len(candidates) == 0: - return None - else: - for c in candidates: - # Unity sometimes produces another .exe file that we must filter out - if "UnityCrashHandler64" not in c: - # If the file is not valid, return None and delete faulty directory - if validate_environment_path(c) is None: - shutil.rmtree(c) - return None - return c - return None - - -def get_tmp_dir() -> Tuple[str, str]: - """ - Returns the path to the folder containing the downloaded zip files and the extracted - binaries. If these folders do not exist, they will be created. - :retrun: Tuple containing path to : (zip folder, extracted files folder) - """ - TEMPDIR = "/tmp" if platform == "darwin" else tempfile.gettempdir() - MLAGENTS = "ml-agents-binaries" - TMP_FOLDER_NAME = "tmp" - BINARY_FOLDER_NAME = "binaries" - mla_directory = os.path.join(TEMPDIR, MLAGENTS) - if not os.path.exists(mla_directory): - os.makedirs(mla_directory) - os.chmod(mla_directory, 16877) - zip_directory = os.path.join(TEMPDIR, MLAGENTS, TMP_FOLDER_NAME) - if not os.path.exists(zip_directory): - os.makedirs(zip_directory) - os.chmod(zip_directory, 16877) - bin_directory = os.path.join(TEMPDIR, MLAGENTS, BINARY_FOLDER_NAME) - if not os.path.exists(bin_directory): - os.makedirs(bin_directory) - os.chmod(bin_directory, 16877) - return (zip_directory, bin_directory) - - -def download_and_extract_zip(url: str, name: str) -> None: - """ - Downloads a zip file under a URL, extracts its contents into a folder with the name - argument and gives chmod 755 to all the files it contains. Files are downloaded and - extracted into special folders in the temp folder of the machine. - :param url: The URL of the zip file - :param name: The name that will be given to the folder containing the extracted data - """ - zip_dir, bin_dir = get_tmp_dir() - url_hash = "-" + hashlib.md5(url.encode()).hexdigest() - binary_path = os.path.join(bin_dir, name + url_hash) - if os.path.exists(binary_path): - shutil.rmtree(binary_path) - - # Download zip - try: - request = urllib.request.urlopen(url, timeout=30) - except urllib.error.HTTPError as e: # type: ignore - e.msg += " " + url - raise - zip_size = int(request.headers["content-length"]) - zip_file_path = os.path.join(zip_dir, str(uuid.uuid4()) + ".zip") - with open(zip_file_path, "wb") as zip_file: - downloaded = 0 - while True: - buffer = request.read(BLOCK_SIZE) - if not buffer: - # There is nothing more to read - break - downloaded += len(buffer) - zip_file.write(buffer) - downloaded_percent = downloaded / zip_size * 100 - print_progress(f" Downloading {name}", downloaded_percent) - print("") - - # Extraction - with ZipFileWithProgress(zip_file_path, "r") as zip_ref: - zip_ref.extract_zip(f" Extracting {name}", binary_path) # type: ignore - print("") - - # Clean up zip - print_progress(f" Cleaning up {name}", 0) - os.remove(zip_file_path) - - # Give permission - for f in glob.glob(binary_path + "/**/*", recursive=True): - # 16877 is octal 40755, which denotes a directory with permissions 755 - os.chmod(f, 16877) - print_progress(f" Cleaning up {name}", 100) - print("") - - -def print_progress(prefix: str, percent: float) -> None: - """ - Displays a single progress bar in the terminal with value percent. - :param prefix: The string that will precede the progress bar. - :param percent: The percent progression of the bar (min is 0, max is 100) - """ - BAR_LEN = 20 - percent = min(100, max(0, percent)) - bar_progress = min(int(percent / 100 * BAR_LEN), BAR_LEN) - bar = "|" + "\u2588" * bar_progress + " " * (BAR_LEN - bar_progress) + "|" - str_percent = "%3.0f%%" % percent - print(f"{prefix} : {bar} {str_percent} \r", end="", flush=True) - - -def load_remote_manifest(url: str) -> Dict[str, Any]: - """ - Converts a remote yaml file into a Python dictionary - """ - tmp_dir, _ = get_tmp_dir() - try: - request = urllib.request.urlopen(url, timeout=30) - except urllib.error.HTTPError as e: # type: ignore - e.msg += " " + url - raise - manifest_path = os.path.join(tmp_dir, str(uuid.uuid4()) + ".yaml") - with open(manifest_path, "wb") as manifest: - while True: - buffer = request.read(BLOCK_SIZE) - if not buffer: - # There is nothing more to read - break - manifest.write(buffer) - try: - result = load_local_manifest(manifest_path) - finally: - os.remove(manifest_path) - return result - - -def load_local_manifest(path: str) -> Dict[str, Any]: - """ - Converts a local yaml file into a Python dictionary - """ - with open(path) as data_file: - return yaml.safe_load(data_file) - - -class ZipFileWithProgress(ZipFile): - """ - This is a helper class inheriting from ZipFile that allows to display a progress - bar while the files are being extracted. - """ - - def extract_zip(self, prefix: str, path: str) -> None: - members = self.namelist() - path = os.fspath(path) - total = len(members) - n = 0 - for zipinfo in members: - self.extract(zipinfo, path, None) # type: ignore - n += 1 - print_progress(prefix, n / total * 100) diff --git a/3DOrangeTree/mlagents_envs/registry/remote_registry_entry.py b/3DOrangeTree/mlagents_envs/registry/remote_registry_entry.py deleted file mode 100644 index c267f7d..0000000 --- a/3DOrangeTree/mlagents_envs/registry/remote_registry_entry.py +++ /dev/null @@ -1,71 +0,0 @@ -from sys import platform -from typing import Optional, Any, List -from mlagents_envs.environment import UnityEnvironment -from mlagents_envs.base_env import BaseEnv -from mlagents_envs.registry.binary_utils import get_local_binary_path -from mlagents_envs.registry.base_registry_entry import BaseRegistryEntry - - -class RemoteRegistryEntry(BaseRegistryEntry): - def __init__( - self, - identifier: str, - expected_reward: Optional[float], - description: Optional[str], - linux_url: Optional[str], - darwin_url: Optional[str], - win_url: Optional[str], - additional_args: Optional[List[str]] = None, - ): - """ - A RemoteRegistryEntry is an implementation of BaseRegistryEntry that uses a - Unity executable downloaded from the internet to launch a UnityEnvironment. - __Note__: The url provided must be a link to a `.zip` file containing a single - compressed folder with the executable inside. There can only be one executable - in the folder and it must be at the root of the folder. - :param identifier: The name of the Unity Environment. - :param expected_reward: The cumulative reward that an Agent must receive - for the task to be considered solved. - :param description: A description of the Unity Environment. Contains human - readable information about potential special arguments that the make method can - take as well as information regarding the observation, reward, actions, - behaviors and number of agents in the Environment. - :param linux_url: The url of the Unity executable for the Linux platform - :param darwin_url: The url of the Unity executable for the OSX platform - :param win_url: The url of the Unity executable for the Windows platform - """ - super().__init__(identifier, expected_reward, description) - self._linux_url = linux_url - self._darwin_url = darwin_url - self._win_url = win_url - self._add_args = additional_args - - def make(self, **kwargs: Any) -> BaseEnv: - """ - Returns the UnityEnvironment that corresponds to the Unity executable found at - the provided url. The arguments passed to this method will be passed to the - constructor of the UnityEnvironment (except for the file_name argument) - """ - url = None - if platform == "linux" or platform == "linux2": - url = self._linux_url - if platform == "darwin": - url = self._darwin_url - if platform == "win32": - url = self._win_url - if url is None: - raise FileNotFoundError( - f"The entry {self.identifier} does not contain a valid url for this " - "platform" - ) - path = get_local_binary_path(self.identifier, url) - if "file_name" in kwargs: - kwargs.pop("file_name") - args: List[str] = [] - if "additional_args" in kwargs: - if kwargs["additional_args"] is not None: - args += kwargs["additional_args"] - if self._add_args is not None: - args += self._add_args - kwargs["additional_args"] = args - return UnityEnvironment(file_name=path, **kwargs) diff --git a/3DOrangeTree/mlagents_envs/registry/unity_env_registry.py b/3DOrangeTree/mlagents_envs/registry/unity_env_registry.py deleted file mode 100644 index 639f857..0000000 --- a/3DOrangeTree/mlagents_envs/registry/unity_env_registry.py +++ /dev/null @@ -1,125 +0,0 @@ -from typing import Dict, Iterator, Any, List -from collections.abc import Mapping -from mlagents_envs.registry.base_registry_entry import BaseRegistryEntry -from mlagents_envs.registry.binary_utils import ( - load_local_manifest, - load_remote_manifest, -) -from mlagents_envs.registry.remote_registry_entry import RemoteRegistryEntry - - -class UnityEnvRegistry(Mapping): - """ - ### UnityEnvRegistry - Provides a library of Unity environments that can be launched without the need - of downloading the Unity Editor. - The UnityEnvRegistry implements a Map, to access an entry of the Registry, use: - ```python - registry = UnityEnvRegistry() - entry = registry[] - ``` - An entry has the following properties : - * `identifier` : Uniquely identifies this environment - * `expected_reward` : Corresponds to the reward an agent must obtained for the task - to be considered completed. - * `description` : A human readable description of the environment. - - To launch a Unity environment from a registry entry, use the `make` method: - ```python - registry = UnityEnvRegistry() - env = registry[].make() - ``` - """ - - def __init__(self): - self._REGISTERED_ENVS: Dict[str, BaseRegistryEntry] = {} - self._manifests: List[str] = [] - self._sync = True - - def register(self, new_entry: BaseRegistryEntry) -> None: - """ - Registers a new BaseRegistryEntry to the registry. The - BaseRegistryEntry.identifier value will be used as indexing key. - If two are more environments are registered under the same key, the most - recentry added will replace the others. - """ - self._REGISTERED_ENVS[new_entry.identifier] = new_entry - - def register_from_yaml(self, path_to_yaml: str) -> None: - """ - Registers the environments listed in a yaml file (either local or remote). Note - that the entries are registered lazily: the registration will only happen when - an environment is accessed. - The yaml file must have the following format : - ```yaml - environments: - - : - expected_reward: - description: | - - linux_url: - darwin_url: - win_url: - - - : - expected_reward: - description: | - - linux_url: - darwin_url: - win_url: - - - ... - ``` - :param path_to_yaml: A local path or url to the yaml file - """ - self._manifests.append(path_to_yaml) - self._sync = False - - def _load_all_manifests(self) -> None: - if not self._sync: - for path_to_yaml in self._manifests: - if path_to_yaml[:4] == "http": - manifest = load_remote_manifest(path_to_yaml) - else: - manifest = load_local_manifest(path_to_yaml) - for env in manifest["environments"]: - remote_entry_args = list(env.values())[0] - remote_entry_args["identifier"] = list(env.keys())[0] - self.register(RemoteRegistryEntry(**remote_entry_args)) - self._manifests = [] - self._sync = True - - def clear(self) -> None: - """ - Deletes all entries in the registry. - """ - self._REGISTERED_ENVS.clear() - self._manifests = [] - self._sync = True - - def __getitem__(self, identifier: str) -> BaseRegistryEntry: - """ - Returns the BaseRegistryEntry with the provided identifier. BaseRegistryEntry - can then be used to make a Unity Environment. - :param identifier: The identifier of the BaseRegistryEntry - :returns: The associated BaseRegistryEntry - """ - self._load_all_manifests() - if identifier not in self._REGISTERED_ENVS: - raise KeyError(f"The entry {identifier} is not present in the registry.") - return self._REGISTERED_ENVS[identifier] - - def __len__(self) -> int: - self._load_all_manifests() - return len(self._REGISTERED_ENVS) - - def __iter__(self) -> Iterator[Any]: - self._load_all_manifests() - yield from self._REGISTERED_ENVS - - -default_registry = UnityEnvRegistry() -default_registry.register_from_yaml( - "https://storage.googleapis.com/mlagents-test-environments/1.0.0/manifest.yaml" -) # noqa E501 diff --git a/3DOrangeTree/mlagents_envs/rpc_communicator.py b/3DOrangeTree/mlagents_envs/rpc_communicator.py deleted file mode 100644 index 7544800..0000000 --- a/3DOrangeTree/mlagents_envs/rpc_communicator.py +++ /dev/null @@ -1,158 +0,0 @@ -import grpc -from typing import Optional - -from multiprocessing import Pipe -from sys import platform -import socket -import time -from concurrent.futures import ThreadPoolExecutor - -from .communicator import Communicator, PollCallback -from mlagents_envs.communicator_objects.unity_to_external_pb2_grpc import ( - UnityToExternalProtoServicer, - add_UnityToExternalProtoServicer_to_server, -) -from mlagents_envs.communicator_objects.unity_message_pb2 import UnityMessageProto -from mlagents_envs.communicator_objects.unity_input_pb2 import UnityInputProto -from mlagents_envs.communicator_objects.unity_output_pb2 import UnityOutputProto -from .exception import UnityTimeOutException, UnityWorkerInUseException - - -class UnityToExternalServicerImplementation(UnityToExternalProtoServicer): - def __init__(self): - self.parent_conn, self.child_conn = Pipe() - - def Initialize(self, request, context): - self.child_conn.send(request) - return self.child_conn.recv() - - def Exchange(self, request, context): - self.child_conn.send(request) - return self.child_conn.recv() - - -class RpcCommunicator(Communicator): - def __init__(self, worker_id=0, base_port=5005, timeout_wait=30): - """ - Python side of the grpc communication. Python is the server and Unity the client - - - :int base_port: Baseline port number to connect to Unity environment over. worker_id increments over this. - :int worker_id: Offset from base_port. Used for training multiple environments simultaneously. - :int timeout_wait: Timeout (in seconds) to wait for a response before exiting. - """ - super().__init__(worker_id, base_port) - self.port = base_port + worker_id - self.worker_id = worker_id - self.timeout_wait = 9000000 #timeout_wait - self.server = None - self.unity_to_external = None - self.is_open = False - self.create_server() - - def create_server(self): - """ - Creates the GRPC server. - """ - self.check_port(self.port) - - try: - # Establish communication grpc - self.server = grpc.server( - thread_pool=ThreadPoolExecutor(max_workers=10), - options=(("grpc.so_reuseport", 1),), - ) - self.unity_to_external = UnityToExternalServicerImplementation() - add_UnityToExternalProtoServicer_to_server( - self.unity_to_external, self.server - ) - # Using unspecified address, which means that grpc is communicating on all IPs - # This is so that the docker container can connect. - self.server.add_insecure_port("[::]:" + str(self.port)) - self.server.start() - self.is_open = True - except Exception: - raise UnityWorkerInUseException(self.worker_id) - - def check_port(self, port): - """ - Attempts to bind to the requested communicator port, checking if it is already in use. - """ - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - if platform == "linux" or platform == "linux2": - # On linux, the port remains unusable for TIME_WAIT=60 seconds after closing - # SO_REUSEADDR frees the port right after closing the environment - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - try: - s.bind(("localhost", port)) - except OSError: - raise UnityWorkerInUseException(self.worker_id) - finally: - s.close() - - def poll_for_timeout(self, poll_callback: Optional[PollCallback] = None) -> None: - """ - Polls the GRPC parent connection for data, to be used before calling recv. This prevents - us from hanging indefinitely in the case where the environment process has died or was not - launched. - - Additionally, a callback can be passed to periodically check the state of the environment. - This is used to detect the case when the environment dies without cleaning up the connection, - so that we can stop sooner and raise a more appropriate error. - """ - deadline = time.monotonic() + self.timeout_wait - callback_timeout_wait = self.timeout_wait // 10 - while time.monotonic() < deadline: - if self.unity_to_external.parent_conn.poll(callback_timeout_wait): - # Got an acknowledgment from the connection - return - if poll_callback: - # Fire the callback - if it detects something wrong, it should raise an exception. - poll_callback() - - # Got this far without reading any data from the connection, so it must be dead. - raise UnityTimeOutException( - "The Unity environment took too long to respond. Make sure that :\n" - "\t The environment does not need user interaction to launch\n" - '\t The Agents\' Behavior Parameters > Behavior Type is set to "Default"\n' - "\t The environment and the Python interface have compatible versions.\n" - "\t If you're running on a headless server without graphics support, turn off display " - "by either passing --no-graphics option or build your Unity executable as server build." - ) - - def initialize( - self, inputs: UnityInputProto, poll_callback: Optional[PollCallback] = None - ) -> UnityOutputProto: - self.poll_for_timeout(poll_callback) - aca_param = self.unity_to_external.parent_conn.recv().unity_output - message = UnityMessageProto() - message.header.status = 200 - message.unity_input.CopyFrom(inputs) - self.unity_to_external.parent_conn.send(message) - self.unity_to_external.parent_conn.recv() - return aca_param - - def exchange( - self, inputs: UnityInputProto, poll_callback: Optional[PollCallback] = None - ) -> Optional[UnityOutputProto]: - message = UnityMessageProto() - message.header.status = 200 - message.unity_input.CopyFrom(inputs) - self.unity_to_external.parent_conn.send(message) - self.poll_for_timeout(poll_callback) - output = self.unity_to_external.parent_conn.recv() - if output.header.status != 200: - return None - return output.unity_output - - def close(self): - """ - Sends a shutdown signal to the unity environment, and closes the grpc connection. - """ - if self.is_open: - message_input = UnityMessageProto() - message_input.header.status = 400 - self.unity_to_external.parent_conn.send(message_input) - self.unity_to_external.parent_conn.close() - self.server.stop(False) - self.is_open = False diff --git a/3DOrangeTree/mlagents_envs/rpc_utils.py b/3DOrangeTree/mlagents_envs/rpc_utils.py deleted file mode 100644 index 5ea4db7..0000000 --- a/3DOrangeTree/mlagents_envs/rpc_utils.py +++ /dev/null @@ -1,431 +0,0 @@ -from mlagents_envs.base_env import ( - ActionSpec, - ObservationSpec, - DimensionProperty, - BehaviorSpec, - DecisionSteps, - TerminalSteps, - ObservationType, -) -from mlagents_envs.exception import UnityObservationException -from mlagents_envs.timers import hierarchical_timer, timed -from mlagents_envs.communicator_objects.agent_info_pb2 import AgentInfoProto -from mlagents_envs.communicator_objects.observation_pb2 import ( - ObservationProto, - NONE as COMPRESSION_TYPE_NONE, -) -from mlagents_envs.communicator_objects.brain_parameters_pb2 import BrainParametersProto -import numpy as np -import io -from typing import cast, List, Tuple, Collection, Optional, Iterable -from PIL import Image - - -PNG_HEADER = b"\x89PNG\r\n\x1a\n" - - -def behavior_spec_from_proto( - brain_param_proto: BrainParametersProto, agent_info: AgentInfoProto -) -> BehaviorSpec: - """ - Converts brain parameter and agent info proto to BehaviorSpec object. - :param brain_param_proto: protobuf object. - :param agent_info: protobuf object. - :return: BehaviorSpec object. - """ - observation_specs = [] - for obs in agent_info.observations: - observation_specs.append( - ObservationSpec( - name=obs.name, - shape=tuple(obs.shape), - observation_type=ObservationType(obs.observation_type), - dimension_property=tuple( - DimensionProperty(dim) for dim in obs.dimension_properties - ) - if len(obs.dimension_properties) > 0 - else (DimensionProperty.UNSPECIFIED,) * len(obs.shape), - ) - ) - - # proto from communicator < v1.3 does not set action spec, use deprecated fields instead - if ( - brain_param_proto.action_spec.num_continuous_actions == 0 - and brain_param_proto.action_spec.num_discrete_actions == 0 - ): - if brain_param_proto.vector_action_space_type_deprecated == 1: - action_spec = ActionSpec( - brain_param_proto.vector_action_size_deprecated[0], () - ) - else: - action_spec = ActionSpec( - 0, tuple(brain_param_proto.vector_action_size_deprecated) - ) - else: - action_spec_proto = brain_param_proto.action_spec - action_spec = ActionSpec( - action_spec_proto.num_continuous_actions, - tuple(branch for branch in action_spec_proto.discrete_branch_sizes), - ) - return BehaviorSpec(observation_specs, action_spec) - - -class OffsetBytesIO: - """ - Simple file-like class that wraps a bytes, and allows moving its "start" - position in the bytes. This is only used for reading concatenated PNGs, - because Pillow always calls seek(0) at the start of reading. - """ - - __slots__ = ["fp", "offset"] - - def __init__(self, data: bytes): - self.fp = io.BytesIO(data) - self.offset = 0 - - def seek(self, offset: int, whence: int = io.SEEK_SET) -> int: - if whence == io.SEEK_SET: - res = self.fp.seek(offset + self.offset) - return res - self.offset - raise NotImplementedError() - - def tell(self) -> int: - return self.fp.tell() - self.offset - - def read(self, size: int = -1) -> bytes: - return self.fp.read(size) - - def original_tell(self) -> int: - """ - Returns the offset into the original byte array - """ - return self.fp.tell() - - -@timed -def process_pixels( - image_bytes: bytes, expected_channels: int, mappings: Optional[List[int]] = None -) -> np.ndarray: - """ - Converts byte array observation image into numpy array, re-sizes it, - and optionally converts it to grey scale - :param image_bytes: input byte array corresponding to image - :param expected_channels: Expected output channels - :return: processed numpy array of observation from environment - """ - image_fp = OffsetBytesIO(image_bytes) - - image_arrays = [] - # Read the images back from the bytes (without knowing the sizes). - while True: - with hierarchical_timer("image_decompress"): - image = Image.open(image_fp) - # Normally Image loads lazily, load() forces it to do loading in the timer scope. - image.load() - image_arrays.append(np.array(image, dtype=np.float32) / 255.0) - - # Look for the next header, starting from the current stream location - try: - new_offset = image_bytes.index(PNG_HEADER, image_fp.original_tell()) - image_fp.offset = new_offset - except ValueError: - # Didn't find the header, so must be at the end. - break - - if mappings is not None and len(mappings) > 0: - return _process_images_mapping(image_arrays, mappings) - else: - return _process_images_num_channels(image_arrays, expected_channels) - - -def _process_images_mapping(image_arrays, mappings): - """ - Helper function for processing decompressed images with compressed channel mappings. - """ - image_arrays = np.concatenate(image_arrays, axis=2).transpose((2, 0, 1)) - - if len(mappings) != len(image_arrays): - raise UnityObservationException( - f"Compressed observation and its mapping had different number of channels - " - f"observation had {len(image_arrays)} channels but its mapping had {len(mappings)} channels" - ) - if len({m for m in mappings if m > -1}) != max(mappings) + 1: - raise UnityObservationException( - f"Invalid Compressed Channel Mapping: the mapping {mappings} does not have the correct format." - ) - if max(mappings) >= len(image_arrays): - raise UnityObservationException( - f"Invalid Compressed Channel Mapping: the mapping has index larger than the total " - f"number of channels in observation - mapping index {max(mappings)} is" - f"invalid for input observation with {len(image_arrays)} channels." - ) - - processed_image_arrays: List[np.array] = [[] for _ in range(max(mappings) + 1)] - for mapping_idx, img in zip(mappings, image_arrays): - if mapping_idx > -1: - processed_image_arrays[mapping_idx].append(img) - - for i, img_array in enumerate(processed_image_arrays): - processed_image_arrays[i] = np.mean(img_array, axis=0) - img = np.stack(processed_image_arrays, axis=2) - return img - - -def _process_images_num_channels(image_arrays, expected_channels): - """ - Helper function for processing decompressed images with number of expected channels. - This is for old API without mapping provided. Use the first n channel, n=expected_channels. - """ - if expected_channels == 1: - # Convert to grayscale - img = np.mean(image_arrays[0], axis=2) - img = np.reshape(img, [img.shape[0], img.shape[1], 1]) - else: - img = np.concatenate(image_arrays, axis=2) - # We can drop additional channels since they may need to be added to include - # numbers of observation channels not divisible by 3. - actual_channels = list(img.shape)[2] - if actual_channels > expected_channels: - img = img[..., 0:expected_channels] - return img - - -def _check_observations_match_spec( - obs_index: int, - observation_spec: ObservationSpec, - agent_info_list: Collection[AgentInfoProto], -) -> None: - """ - Check that all the observations match the expected size. - This gives a nicer error than a cryptic numpy error later. - """ - expected_obs_shape = tuple(observation_spec.shape) - for agent_info in agent_info_list: - agent_obs_shape = tuple(agent_info.observations[obs_index].shape) - if expected_obs_shape != agent_obs_shape: - raise UnityObservationException( - f"Observation at index={obs_index} for agent with " - f"id={agent_info.id} didn't match the ObservationSpec. " - f"Expected shape {expected_obs_shape} but got {agent_obs_shape}." - ) - - -@timed -def _observation_to_np_array( - obs: ObservationProto, expected_shape: Optional[Iterable[int]] = None -) -> np.ndarray: - """ - Converts observation proto into numpy array of the appropriate size. - :param obs: observation proto to be converted - :param expected_shape: optional shape information, used for sanity checks. - :return: processed numpy array of observation from environment - """ - if expected_shape is not None: - if list(obs.shape) != list(expected_shape): - raise UnityObservationException( - f"Observation did not have the expected shape - got {obs.shape} but expected {expected_shape}" - ) - expected_channels = obs.shape[2] - if obs.compression_type == COMPRESSION_TYPE_NONE: - img = np.array(obs.float_data.data, dtype=np.float32) - img = np.reshape(img, obs.shape) - return img - else: - img = process_pixels( - obs.compressed_data, expected_channels, list(obs.compressed_channel_mapping) - ) - # Compare decompressed image size to observation shape and make sure they match - if list(obs.shape) != list(img.shape): - raise UnityObservationException( - f"Decompressed observation did not have the expected shape - " - f"decompressed had {img.shape} but expected {obs.shape}" - ) - return img - - -@timed -def _process_maybe_compressed_observation( - obs_index: int, - observation_spec: ObservationSpec, - agent_info_list: Collection[AgentInfoProto], -) -> np.ndarray: - shape = cast(Tuple[int, int, int], observation_spec.shape) - if len(agent_info_list) == 0: - return np.zeros((0, shape[0], shape[1], shape[2]), dtype=np.float32) - - try: - batched_visual = [ - _observation_to_np_array(agent_obs.observations[obs_index], shape) - for agent_obs in agent_info_list - ] - except ValueError: - # Try to get a more useful error message - _check_observations_match_spec(obs_index, observation_spec, agent_info_list) - # If that didn't raise anything, raise the original error - raise - return np.array(batched_visual, dtype=np.float32) - - -def _raise_on_nan_and_inf(data: np.array, source: str) -> np.array: - # Check for NaNs or Infinite values in the observation or reward data. - # If there's a NaN in the observations, the np.mean() result will be NaN - # If there's an Infinite value (either sign) then the result will be Inf - # See https://stackoverflow.com/questions/6736590/fast-check-for-nan-in-numpy for background - # Note that a very large values (larger than sqrt(float_max)) will result in an Inf value here - # Raise a Runtime error in the case that NaNs or Infinite values make it into the data. - if data.size == 0: - return data - - d = np.mean(data) - has_nan = np.isnan(d) - has_inf = not np.isfinite(d) - - if has_nan: - raise RuntimeError(f"The {source} provided had NaN values.") - if has_inf: - raise RuntimeError(f"The {source} provided had Infinite values.") - - -@timed -def _process_rank_one_or_two_observation( - obs_index: int, - observation_spec: ObservationSpec, - agent_info_list: Collection[AgentInfoProto], -) -> np.ndarray: - if len(agent_info_list) == 0: - return np.zeros((0,) + observation_spec.shape, dtype=np.float32) - try: - np_obs = np.array( - [ - agent_obs.observations[obs_index].float_data.data - for agent_obs in agent_info_list - ], - dtype=np.float32, - ).reshape((len(agent_info_list),) + observation_spec.shape) - except ValueError: - # Try to get a more useful error message - _check_observations_match_spec(obs_index, observation_spec, agent_info_list) - # If that didn't raise anything, raise the original error - raise - _raise_on_nan_and_inf(np_obs, "observations") - return np_obs - - -@timed -def steps_from_proto( - agent_info_list: Collection[AgentInfoProto], behavior_spec: BehaviorSpec -) -> Tuple[DecisionSteps, TerminalSteps]: - decision_agent_info_list = [ - agent_info for agent_info in agent_info_list if not agent_info.done - ] - terminal_agent_info_list = [ - agent_info for agent_info in agent_info_list if agent_info.done - ] - decision_obs_list: List[np.ndarray] = [] - terminal_obs_list: List[np.ndarray] = [] - for obs_index, observation_spec in enumerate(behavior_spec.observation_specs): - is_visual = len(observation_spec.shape) == 3 - if is_visual: - decision_obs_list.append( - _process_maybe_compressed_observation( - obs_index, observation_spec, decision_agent_info_list - ) - ) - terminal_obs_list.append( - _process_maybe_compressed_observation( - obs_index, observation_spec, terminal_agent_info_list - ) - ) - else: - decision_obs_list.append( - _process_rank_one_or_two_observation( - obs_index, observation_spec, decision_agent_info_list - ) - ) - terminal_obs_list.append( - _process_rank_one_or_two_observation( - obs_index, observation_spec, terminal_agent_info_list - ) - ) - decision_rewards = np.array( - [agent_info.reward for agent_info in decision_agent_info_list], dtype=np.float32 - ) - terminal_rewards = np.array( - [agent_info.reward for agent_info in terminal_agent_info_list], dtype=np.float32 - ) - - decision_group_rewards = np.array( - [agent_info.group_reward for agent_info in decision_agent_info_list], - dtype=np.float32, - ) - terminal_group_rewards = np.array( - [agent_info.group_reward for agent_info in terminal_agent_info_list], - dtype=np.float32, - ) - - _raise_on_nan_and_inf(decision_rewards, "rewards") - _raise_on_nan_and_inf(terminal_rewards, "rewards") - _raise_on_nan_and_inf(decision_group_rewards, "group_rewards") - _raise_on_nan_and_inf(terminal_group_rewards, "group_rewards") - - decision_group_id = [agent_info.group_id for agent_info in decision_agent_info_list] - terminal_group_id = [agent_info.group_id for agent_info in terminal_agent_info_list] - - max_step = np.array( - [agent_info.max_step_reached for agent_info in terminal_agent_info_list], - dtype=np.bool, - ) - decision_agent_id = np.array( - [agent_info.id for agent_info in decision_agent_info_list], dtype=np.int32 - ) - terminal_agent_id = np.array( - [agent_info.id for agent_info in terminal_agent_info_list], dtype=np.int32 - ) - action_mask = None - if behavior_spec.action_spec.discrete_size > 0: - if any( - [agent_info.action_mask is not None] - for agent_info in decision_agent_info_list - ): - n_agents = len(decision_agent_info_list) - a_size = np.sum(behavior_spec.action_spec.discrete_branches) - mask_matrix = np.ones((n_agents, a_size), dtype=np.bool) - for agent_index, agent_info in enumerate(decision_agent_info_list): - if agent_info.action_mask is not None: - if len(agent_info.action_mask) == a_size: - mask_matrix[agent_index, :] = [ - False if agent_info.action_mask[k] else True - for k in range(a_size) - ] - action_mask = (1 - mask_matrix).astype(np.bool) - indices = _generate_split_indices( - behavior_spec.action_spec.discrete_branches - ) - action_mask = np.split(action_mask, indices, axis=1) - return ( - DecisionSteps( - decision_obs_list, - decision_rewards, - decision_agent_id, - action_mask, - decision_group_id, - decision_group_rewards, - ), - TerminalSteps( - terminal_obs_list, - terminal_rewards, - max_step, - terminal_agent_id, - terminal_group_id, - terminal_group_rewards, - ), - ) - - -def _generate_split_indices(dims): - if len(dims) <= 1: - return () - result = (dims[0],) - for i in range(len(dims) - 2): - result += (dims[i + 1] + result[i],) - return result diff --git a/3DOrangeTree/mlagents_envs/side_channel/__init__.py b/3DOrangeTree/mlagents_envs/side_channel/__init__.py deleted file mode 100644 index c9a1f5f..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from mlagents_envs.side_channel.incoming_message import IncomingMessage # noqa -from mlagents_envs.side_channel.outgoing_message import OutgoingMessage # noqa - -from mlagents_envs.side_channel.side_channel import SideChannel # noqa -from mlagents_envs.side_channel.default_training_analytics_side_channel import ( # noqa - DefaultTrainingAnalyticsSideChannel, # noqa -) # noqa diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/__init__.cpython-36.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/__init__.cpython-36.pyc deleted file mode 100644 index 0b925ff168ec3492537dcf6f47f8d940e3ba907f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 534 zcmaJ;yH3L}6t(lLpcOMS1B#I10Y-#)Eer*uX3Aoj#3V+3pxCLDfe+%BvNG`tOx&~u zB}*;&`p7zud+qbZ;@~Yme)+%%eWB6v0AItl7f?!6Vu=*aF&?ldJ>}>A2KzElVIFR9 zAR`s$G2n28lIRFgD#8`x>|B;S;dE|r`A8CBLhg)?5PPR=TWV zLId$eGub&&*b(h9ndN6nf~9tra=o^x1ru6qT~e{jrD_}83`6Zzm|a`{3Lg~x>7I;n zU=s}fw|m&-b|~t0Q&ILe7M&P{VDyQa7>-T($w+M!CrU_03R2Wur?%Ck)xvcoYdW`f rTSpnK$!fkGkDG1Qx!J*@uVFcNuKV2XGC?o`Z`~>t5-X)KtkA>Wsp^KiChmhrKp`9 zx?1bMqX8Yuqa8E02byNdKiW|puSF48sUmbEi`0k$Ao@b44cE&3e&SS1j#j0!lhbOVLf^(Lv2{vr>Cr+=ekeX+?jqtGl3nq4xdfNI_7WM%V4_(!z(Xz~OK>B6nuK`F5|_ti23(x?fcg`U|Z+ z4(Q**P!t436sIVh&p5>8+6pb0t<=t((7|TUPTkB4y{r;eGC%Z7o0C?vT39P}H?3!l zuz}GtL_J!$M6|-ZnH@GMK1D76J=}y&TDZ7#&J#U36j_$@B#v|<_|sovHZn@fF6yTV zWru@^bCwpH$2=BU!uvllrJ_D7Hh<1_UwkmYd3VoblyERT<>N#Oo-wYE;ff?mlPRO% zVL#!M*j&GSO!($eFF-J4LWXd0XftQ%Qfr1okJ{9Ehu@+erY`j^8)1d{V5_{ds86ex zPFP*@sL?uj)ZQWog>?wFQG9vCdQqP0<-0xMQ998{tk$BN@>&3ou>|ov;6M)|9Vo`B z3KHHEGAr{FL|u_<*kplT1RH2kuFGTw>_g~*5<#MaIO0K<1*z!w8EuyrP49IN4jx1g zqQ|@R(Lrx_Kico@KHiVJyX?{4{$BLZOb4b!o@6?gJjP{~5Hhm`!-k=5g3xG&hFDue zdxlN%A!dBiatc@FBPI)<5U7YIMEc-d)DC}ma&q$YM{;}whdYX;J(#P6#A&1yA%CL3 zRc9bF*2$7I>cpLRz<68byaNc)lg^o(=&|lRpXh<$XH4l%mI4^KRs;f99R(RAiwt(? zJn>|iC=xAGPuBg~qlv7;%iS^|nb?p!y?>3OwU?o_tisMzUsmC-ad`kJ%Oo9wt{NaT z^vw+a3IKx?IVaO+XHdgyToXtZvt-O@5Cz#B`$12NEGX-JKbYRtgG2>tAo7$3TJW^{r5F3EKSHQOEzJWH;mX^i7n8IPXs562*@(1JFuZV5C~fs;pxL` zWTgF(b5;O#;V9s^IY5V?Xn^M%0O$p#cnAFsOa_|0(j24x;Zj%ILkHLj`06+Jjiucg zdShSML+=7e03%(2wR7PNeXvz$sI=7p`t=KE1$_TRn*Jzo`@Napn}mekVXm~u!pb>+ z$;E5la*K^oiC;2iQUTS4TPqMREw@(|1M8JzQwtdnR?8dnC1v9zW<*a$4EV-Y6IC=8 z2SM`zb(s7X%_~P1b+SALdebDVaGpo;OKI{~G!@fCMz2YCqL~VBoH9A*&@*wWB@nEv z8MoW7a+b4IO|>9~uUc*ifx-d~HZTb55uYrb!UhC1rvzvj0L=z?%z;v3WP6RjO1A}f ze*tdlQxM4VEDPTSv^X$)%fmGo8+iK7b&&Hfr$gF+sCbkyLW&w8nV@-U^adfX@+e*G zR0yFW2D6jr2`!xS^W!6Fdb{KgX}%@WaH9MiMA2NZTFlZEa=dDWWzZ(xk`+zED3eg% zcC4Cpv$Ext_SS~nHa_=^*a1;&U#Vf6EkBlJ>lL3}-CgH6Y502nf~LUX>4DMFaIIlwd(rc&NKU+X%A&e P?_>B`4SWkX?1udhRv&+< diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/default_training_analytics_side_channel.cpython-37.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/default_training_analytics_side_channel.cpython-37.pyc deleted file mode 100644 index fa640a95e7ddff3797854c69186b72a7db10d645..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2169 zcma)7&2Aev5GMCeYyH?snjlRB1Y5KyAT*NFBz9u7D4NPaYoK+F+6Icf5UV96t+Pui zB-gG4=TZmAsZY=paE?9nh4$K0UZJNBS6ameQos~Q4u>O>GxN>2-?mzH1g&|}k3X*= z^p9Co%>m&X=!(KX5ydGA=Q9p*xwb+JW-GNbCv>pcvr{+oLNBX@wagFwQs<;ASv{a`d8c;RqIeIr{kL!v+G*qB_5n}yv@fzO=SdvtMDVA-#%yAQ zwp}##63Y7Hh;x<}Yuh{)S;9v@GNqysE7pF>^+>!^z^G<6g*>GZ^IQy zlqNGq!NPvRr?I)dYQ}xj)Xy+5WLyS!acDE=%%#>F9D3BI&TIS%4Ka18_p%w*m=C(z zYm54H<)ss@oU^FY23XWzAqRyGaJE@|vc-l`p6cptPk5A0brP#{-pzPDfMzs7Ja;(I z<46aJajJrZ4~5Li_yo~FtT9oTDm;rm|dZ0v*=pc@GFknF{Mk7YMsLNsKyE5#v;wdzf#dMx;2d2#iNSqd4CJJJ2PGnt4^6hG6l zGm4V5reZS=AfV8pc|5Hi(M5PPzSeUHvlMye2#s7e|+Z`Ykn zWdq#04qaI=Aa{2666x+%L1|lsovD#rfxpJ(0U(&!^geXegh4}9p5osCnh;!TXU6s+ z`*ChEilfiIlqlnnVR^Eb^2FTo%j zQ+x~k0mKB7y_6gy{pnIy+lLO2575u=?h8x1r|5-!VxM^@P}3Oc8myfY=gbG)${SSb z>VV|NiL=D9zatIY3*3Ec=C>vsq1Vrq7Fkg{;Lo@?=54oFox_qGF{yyL!YfN;Rhk=1 zjlo)FShPyOR?G0}d`a0+5;LNw69)8QtEnoQi-Vw+fC)VFsMdueiw3EVfl@O8E1X>@ z0BPb^v=q}sM#p3@g-Qso?lC#1#C@@+CGe#*--qJH^PJ^unNcl>p`W%}0-&&fQVj^g zM#QI;QP>2B<`oV&2FR>}#T+IjLT;X;qta|a#UF#2`Va zhT^1oZP8kgRLs&8V!SMc%4y?oNphxKlnJPBJ67GgR=eVr`u3{4Wo$k(gDI2Z=7k(~ zS@rEJ3$OU-;_i9kk%ofj4>So5H!qsPhjQ^n6_SWS$(`NzaM@&VzXVfwb0owlW!;Gs qS`6}G*QD6&8YGpEf9LPH?D}8LBm1=}4`ovCWB6H3d>uFKru`rN0dZRZ diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/incoming_message.cpython-36.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/incoming_message.cpython-36.pyc deleted file mode 100644 index 50d26ddc379518189cb7c7adee25384fa2fb1e2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3823 zcmd^COK%%D5GHq5vMgJ&tvv0#*h>HbfdwQ5iUvU%G(pk=tx+^-3J58P^^%g;UhOI* zH?9QvP$>NuIrQ4UwAUVr{D3~tL(v(ow2~E}m*(WsSc=c#@cV`{<2$ul^{BnQf3rr& zFJ!K`(0%})z6q5ef<~lA+mvG4iJZ3cga}u7uZi%+PTLjEQ_?KGg|(zfGw+K~o4o*g z)8awn0et!=s3d7qLE4U>uyaRxvLxI$j_^e3b*WtzSLBLZ5i2lK5vwp#5m#ji*5F80 ztii~txF)NzYDa3K4kK&gx?GplZIah^W>ajzOikR7by>F~=frs!*^r*N@P>+u;?irc zy$NSw@3Pp2-j>*ao3L!-^EgO)Vch*vYVCLB@P{gc@{I|j&d0IxD*~rgCt-!=zFIoplPqunt zzzZCbqu0FI63GJd678t~#l4p=Lku)rtK z?)C>+h4T<3alQs;X;g=JWjegPaEaaNvd4f~O~{U)Muxva@Uya#CRK5OaA85{P>_Z0 zLuic1AsG|3J_6VbJp@aI5f?sh47R>aP5@L7dcyq(Fz4O~?cW>zQNa5(m<52lpCpm= zV`h(?!8$dRoXHu!cl*Bbd+e05ciE#{_lXcNs#HrBb}T_M7A(n|Q=y?on*!9uoZ$Sz zciA(rvRoN7+;=p(1tw_aPE?qzojdHF}w!YNOJ? zWNT^M_k$yjHa0VzrmM<;yQ)H!xuBu7q`a!&*edGF5zhv6HLfG&3iX_ev`&ZHi{uxp z-#f>DE^r*f<2AAi@AmAI9OfkBQ)!kI#0;Y9SZ!c6=NM*ODs)7PTvjbR0Nb70H(+{^ z%$=oV+U38(a$DXzt-meM$~sZvoBsi)9m}c0SM^^wUALTC(C*y61;Q3ty}Fdu$%egx zPmC<+j;$;H3>p(xe0c;h?5Lv7cga(TZ19moItEAFB`5Cp*NroB#`F>Su5sdx+=;6u zV@k=(-EYarwbAeIMUErLQ_y|RaSc&@8vLdX^{ja5y(z!v0M@Le{J0CD(C_!bQL76u z2J?jzZdVW-9?2LIjnwp0lTp6-khkVZ=eXfx5Tns2pmW}Iz(Iq1ZqVTe|Hi)EnUTT< z(32G5_*3XiY`})&Dev$LLD(|wj+{&6M+nOhkm;D7K%j=;45KzUyA$?*Ut}Kw5@v2^ z+-+wiUk710&;86*XJsLSM98K$$NYwbtV>A20U$Jhr9OPkQlCSJ&s48Nl}F?Xy^1mU z%2LYn9Zjk*dkZjKz=FR;?uxP9LOa z+8kz@GZwoc5nRP(zEb|cf&hA0i^sHeF4?GcrQymy=2qx)nAA2^^oG|KFLi3=srwXO z%;w^dP#R1k!Al*L@K$?}@}RTJT!h$$)TPSUF#DoVVaZc^C)a{o**uIsE?Vk5NWep> zx`M3+rqQwAlbmN&&U=YSBW$m8{xbEW$;=ApA_-u)WP!+BKwGV%(jI1FY73ew_a@eb zS}&pyDz$^FTwq&W$1cOlCJZyEZ3~k-g-{_D8lzCf^PI*?qlSMw8;yFsZ0DO^RyKn^ fyx9Bzn|R>HIj2-e%qsWtE8RyR>^}+XwBr5)2mjM$ diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/incoming_message.cpython-37.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/incoming_message.cpython-37.pyc deleted file mode 100644 index e2dca4411053863d334faa2cce73eae9ffc55f93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3885 zcmd^C&2Jk;6rb5$JC0*JiTjzfw9BQEr6w*d0#Q|^YN{3_h$;#NS)kEoXKZh>-gRfj z4Yr&EO8FN!_23-&m-fm5^$*}f91!o#dTqzGxX@FXXvg#U=FR)PdGD9|<#LfgDGhi0 zYh^-y!A@3eXxxKOU4x1fPD9e64N9?Xg;v9QM7YhJ7lb>S7j6H?2)g0-YZ6X&x) z>0KXtS#h9o4?Z=5N{|NSq+xLiJ2!Atafjz#J;ep%#T z4UQD~3XClCcSKPX%}AM7U}S|~5hYRFAZcx8*7!Qil=)Rr5fw9XhM$FzRpIb+FDXCI zFT8LXYj76!F7gfNt@Bm5iJPo`8u@W2h+3ZurM#9H{7`hEe5Hdh(0$hrJ*C`cEL|x) z4$EBK7H%h9>mJHLYZ19Rc0Kn=z{O76iy{$j8yQc%uqTw;=_&2*2_wJ_U@-`YB^MG~ zefLmEkqJuoNeZT`SxJ7c*K7)z^zq7zVNlGcl){>N8|44-Z$8drQhE2Zu(o@ZoK9B2U>2mydbQD z9=d+(!A{J@VJr{SdpB-;Q165QO{5hQ(Q{Q-U}*-Yp{eV^7(X@!WxLx?3XBC&pcz{M zEfrpbIC(m_ICuT+Y}rGwcA1N&*9$d!j<6+pDRfUpJ{lSe8Xb*cjQ&0}hGaxeh%61k z;F^xW$A@I!hR->HSF%Bl01gLw-2M>IV$Kj>jx+dU0?ZfSPyowb9EZY-TyyLckj%wW zADAL@yX#4>ba&6atvyTn+Q*r1{D!L%yi*fQ$N(4JN3Diiba1?pJmX@w3p=E0w=e&ZPbIfros z&t8iby!f{tIE3tXP>^R^Mb|Fy9b1(+;lOWtE zpmA6zBA_Te-R(7>wvxZBTI4<=t3d7*1aE>a^7O~YX_ z&N$f(L~t3Gc~W|PV+7E{csvr`8M0As3C*N;$c)gZFsTexbO!ItU+UD#Q}?l9oAF@7 z;>kV`N%YxcdXU3g?E>Y&K$qBPVv|xADr3^@w-Xf>Jf+vT7Tn74F#2%Pl4n5z9!ljU zY*mp)M_xxTmJ}K5#Jm?`yTsVDo)?a1mKfu)55qZQh{OhK%VkvBK_({Gp()d7VnV2i zA`(p{H*u8>Xv-_ub+IypVQOmALUJe3RA>u@S*YMRR&}Xb#=p(gYNe7l^ED^Q>wXtr eYgKM5sTu>S!y;_Y1k diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/outgoing_message.cpython-36.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/outgoing_message.cpython-36.pyc deleted file mode 100644 index 8a8ef4125997209cbc2bf211e2a37b70cd7b2df4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2791 zcmbtWO^@3|81~qXH=9j%x9zs2Eky$tl&alG-2-S<0o5WQBv?Q#LJCEe^4z2ZI4{JApSuAlCPZj3!He~alF}&00I)(o{!h>JJ0ied9T%Kyy)KQy;*ad-<&f) z593d8>3!UUBUtK;SeG#xyQ$lC@$^z}B0tS|J4NyaSiiLxrO--=GVmy z%(sP)Gv6$>zM7apo@9eBrPk3v&VFfd{Ju3wnwTk%(@1OH&lO!Gh;cKNd{oL}92uTy zeykE>WX4U-BmN{2@?aQcnM`-BuE%N0MP#D0l1av)-=y+^%tR7pRy~wWbY(*uHHi%$ zv-K z{k~MC8G7%q?H233sgaRV(XahC9v(7Ld$<8QAqfXq3hcesMldLnz zKwamlnwlfi`Fd)GdG=Il(;1~8I5Rqw*^%yO@D#=+QJs9@g>XUb?s!_%!!UuSFx(=T zgxB$BZ(YE#TM5yLS+59`G!vD@Rvd58vxdu3bsK}Z<2%nC!=5AJ=Iq4%03snG9mILF z_9=0X$76T~?(F4xD#6oHluj0YAcAJ@qmK{Uo(iC{2uf!a{y2(Xv|WW1bJPaih^F$k zPJ#`J6d97v>zG%dZeIko6eCoLA|L-pNcS#5%6O6)iKJYCDXB227M*+(w+hcTEnL8} zQ63cf_8#8Beg){xYCu+w5cU5LqHiuC;{7y7@{}&(pBn@>a;_&iawv;s( znA<=_kmAprS2yPDQ|E`xA6=}wbC=d$?tF)WZFBzFWmd=p&--WD(YyTVP)`3XK}60K zoT%_pnW<|SVZlcE4#sK~Ls!o+WZ}LKSxpJ!_?xW3X7BwiRrVDM7X42&vF9M+gjr&k zvD6SbHq*U%nc?UyHp73uOcVS-MYoC`4EwJ%1g&M6Lwi$#Mt(?6C0Sk$c2!?s@pr5;PSq9S2SOhxxiEOa*(rotC; zdNCuLCG91q4x~%MYYn!^W^b=1yc9;BlW)$GP34m=8y{9Un zKb;ctL>k*IsoD^uizZWc$xI&e)BZw1No|y}Hb0WeVgSKYE?*&r$vf0QmwfGyBNdGn z3inSf?w7@XxiI_w0G@=~G`>VsbR3dNjrYovRed~4(I&-|49u&1oi$mR| z(Gq|iQ8QCMZZy!;8S1|8)`M;P->Gk}+ue4(2+VX$lvwrDQ;OT?J_B}%I|zgmd~qo% ge~Q9PQ8%$VR+%p9k4n%V(U*|ruF2|d)2(}d0$oPA!2kdN diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/outgoing_message.cpython-37.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/outgoing_message.cpython-37.pyc deleted file mode 100644 index 8494443cba7dcea04e99967bcb989c3c42fce655..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2853 zcmbtW&yU+g6rOP$Z#J9kZrg1OEk%Y4O4Z$zT?x>t0?JlGNU#(Y1PUN))}AD89Xp+w zbekxgwnwgTKpfg*|0Q2J@h@=Vd*gVsKLQAFWM|&^`OSRa`!ydmn{|e(G2IJaE;05S z3FTG6;6vPc7mtWVJYfUg;he@!;&dGRSCY!W?YNvtS5}XB$NQK?Zd857qUw>;S&Ezo ztmXZV?^%oI?x(Rf`xw-F(gaD?>q!;TyYf0-af%tqIy_=ng?B2E6IGtE4%Q&+zdDf@ zEj@EPo?L=lgS;HoA=l(Gly8;Pek;)2Dek z7y{?PsN0pQScbmaZ#nt$!PrQllo;n;@t&NkWzv1gR1K^C@pHSM4P-m)%d~xe9QK78 z+*jE{85-Rlj!i#HXX0t;8xk`W_BX|LxH%kVn<9K<)Mih_N!v(m+B^65vPd3g>XCl? z_U(7tg9NTgjSgh`M7K2<4zLr^K2q>>iTE~>%9S-4B1j0d< zB@zrj5y@!gL85lz-1%U?RZ(O+_X;=X?hq8T9EId$YK0y|aPe3s#X7~949MnX$R((2 zXF<)?2vw{oI{qW1o97^i=r zdS%M*vF}%Za4_#o9h!T*@ij`ltrp*%XN8vVv+hZD^p^i+UylDRK}604>?p4!GF6u_ z!i0_T4UE+yhAy6B$ijUKx|$M(xvRX+CvW~ORrV7K7X42&@#i4n1-Ha-18NGwY^GPH zMTVm**$n^bJWcQemFqHkkQ*u$Nix3WBU;Kxl4*!qX5&ccFph7b>O$(vV|%3r80w)Y z+Yd#eGm1mvV%Aztbe?$t=2dHSzvbp$VaL*~s7TlnQ__7E6P=aWQo$oRKAVw^g7yMa z8`=fo)jD70lh+m#UMM5a$v3CTrt(Q~X=Czr45lcaYP~3*6oIBf@rkZgme3!M33(um z?Xy&Eh|yVlD*9_G5B=lLL_tXnn6fr|B9+Aeg2%pmiWnyEQ0txZwL26_3}yy*k5}9+ zivN6K^6efx3AbsSVU#!wXi1Ilik+1w0Fj`}&-n#v5)Yg~n+g2_2%y>wYSo73V@@uD#0b9f!6oL`XYKlTlQJ5*} aCf3HHrSsaI0`&WIhO*o>c+F`zwaTAsQ_>ay diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel.cpython-36.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel.cpython-36.pyc deleted file mode 100644 index eb54468b34b75b2f5592dba77519f47923b3f848..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2108 zcmaJ?&2HO95ayB;Me8Sa(s2W@^H6y2y>gi+YoJNaJGi+ap~9`r9+ zH2BVuf$Uy6vJ33ei-yvB?To^I@C0Y%*50eH4(kUZF;T(I% zW_b9mQw7hFd0tLAW&~O0&!^crNOZD>5ka2jC4y8{k$`^DxNG*OLJ{bqlz1ktPgXoB z?ffp}R~XwaDTZT^d?}3Cgo-CvB<>q^%FAQ{DY9jGS}H_Sr8dK`n=>iv8(!l~rtT)? z^rZU`Z*zdd1-o!!XXfCD*~e@#5>-FG*;@~bR$1|H6;yz;zJYwI_i*~odUoRo#USVc+putvJ-5>QsbaCMEnj>_&N!;j1h<47$~2^qoq~L}<*d7Yw(IwvwIilKz~w2CMHfA{ z#0B_45~6Zh|Gq`_vX$M-6BL78Eum==yA7_wA|CU%)W0${%_~qT@OgRG$VUn*cxJZV zumMpQ#6)E3uH?-2?xi>#~QT%bGa^=ZPfMB=*LA9U!^bc{S-*KgFSbdaI+1NuSpp zr3FI(@2;XBBD#qyo8`JozMjykp#4!cXWs|74nJ@C`GWLdi1q_EV4;hn8+!i%u5dO# diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel.cpython-37.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel.cpython-37.pyc deleted file mode 100644 index b6c9ec2d014e758ab37a689c7a16b8f177a9d138..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2170 zcmaJ?&yU+g6!thy;>{-ArL-05rGvOMQg>58;!q((n*yo?OHo_3vMN~<&r9O1?J+as z?j~AJ?O(vT2RL%!5Aq3#6aNAy-WzAL$*N)`k3GNMeD8bTdwwt&^gL|+vvKlQ+w=aW z!Fdbt<7<4(OYEd4S?1*|V!0prjK+S}%7Z9y->s}2wQ(-UI(awh=3x}N`F6IG_o5#2 zpa;8eSk(W{lO5T8>&Y&#H?3$OTTi@U_z<4gI=x|G~JvA|}Rak=PvUT*)D;gYQ#g zk8pkOQIV)TEoMJ}F=7Vw-j9`?sf!8R+?#=oGc}umPRQ(eTf6fDXTXb?^deufs0G1s zTl(*qY{}ql5Ots{+p_b{mt7g+ID{SOt!8#)?`?o?>_Xq2+Qn0SIdF3W*+y5c)Voho z3FEma3dqESd0vlWdpZYhaDgYy3O}xl05ddB#eeeBNInHPIA4||M0MvIZCcH@h)^&oGQ75`j81-Kd*$fkM+PygZR z0lxnIbu?EwjFLGNqsI$8tMkWN5jry}T`*R|?a>PwDxJ&^#AnGtS*in(yt4XWCemz# zVYj2tAC8rT6Qy67Pw(FSVw7hn@xq!Iiq~dDM4cnu8XT63I*jAANNpTnBVS4C9_z5> zwGAyEo^K(aTe+Fl9Sye9#TH*JJn8tliXUg*vG*H0W5@pQ4AYq*WBzjDC?`$-L=<7n z_=+#;j=169P%SvGENWe<;R<3ym$8&6PURT6U64q_dnNw z9~tLEqwUL{u4KC@?L$6pa)LZxsheEQtIVdDvfQQ!onsbaszJ%q>BZ8@rzSgc5XdDZ zEoIso&!%td$s@MfDQ{ zkrtOFccCc6Nk2M#IRQ}~Uuef=_idbNl+sz=*!23MIAC$dJS#*Faa{M}7|UCg(RV+_ zav`$SN;i(BN^m-;s#Mm&vuBSU>OH!V2+@?Gn$k?;57*Pzv8%&X0bV#L8`5?_N#8oe zj&j1#DC`FQez4#5+11czZVkb;#3a!qc4xlsAh}qxHR)I1#IC-%RZ$K}pXU{&0Yd;U u@1kERnu#l$X1YtZZqTky^NV$NzYlO7e%bKz73skc?fb0HLLYlSZ2bqI4opJ; diff --git a/3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel_manager.cpython-36.pyc b/3DOrangeTree/mlagents_envs/side_channel/__pycache__/side_channel_manager.cpython-36.pyc deleted file mode 100644 index 5d77a10f0a2e6bca5726374f076229f456c08e16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3226 zcmaJ@-HzMF6`mm}imR36jbmiHNl*-e2Ca-jLYx8x93ybyH39>%8`O545@}g3XS7Q# zIn>UKc2_EO6S+WdTJ*Y29-w`gUKhMjCL50nX;yX9<^Jdu0gD|jj zFWbpmVatvi*>2tr+mw7lxX+s}32!c(u*2z7(hFX}8RSXNt-QlDF;(#Mu}KRVXO;J9 zs!h+ScAutPJUEG^6j^oSkxYs_mB){T*733E(dyv2OwIJ6JWo|2b0N*c%S2cq@UnF* zOq3PJ$3i7|(CTTx;660Xp%Vnn3LW7JPc#n50U1(Gx$}~SzG!lndtW)c!TpzB7>FI- z{EG5`@4&1jcCYq`w&;wyqA_$12yelTUEY4_EogXyyI^Riy18M<<5+_BDskX=eDELJ z188~=x{{1YNf)#v5$Fc{=@an9euVaDa7dKY9?=m;x4n7IB7E;@kqxWP)`q_k1pz1j z`|aSQ$i*N}vv`mUk`p2OdLjoC^yc81nwoPn_-txU3i(WEGsrVgSQ;G(d9DYW61OH% zUR%~5Ppcq`Qjiu!Ewsv-N@wr7{RkC(R?+^G-W!#h z30ZlQNy;nl`SVAIRl|C|^0iSDpp)H+#OOr`sH!29Dpb|_Wt>gK!+QKka&c+L3RAQ4 z0abZy)Gkbvk1KCp0~!_J8=wUl=OT)#=0&U|1hUsuZQS?d<#-K=*8G)3;#W z_S(>UPT;g)6`C8+*VjUl>KIk^fW>{nmS&%us`~@%raM*$z zl3yQw;mn=6d-;>n9l0>S4O|7RHS&PPXh}_DbgrOCmo02Gir1}-HygA(Cl ziGbo_3)hI;BkN#$v%jo^{h*M*TL!r^1CB@D+awgdiWJ@<@YbcK_{mk`VYD`EUCUi^ zJ<3{NL~7E%_L!?kKbd_5^a*U7zFoA~sjIa9mJ3&JPrV0ns#X-` z1)pTdX6-0CgGyU-o5J8KEMW>mtgynVx3T*nc0a;y0A1DA1}aXH3%F@glpLn79q*IHF?Z(Zp6n+~is ywk*EC{gqf9#%g ze0aOtyK6IkxeXF8AfAtlwEGBu49{pDISDBee*sTa_1IoJ?A=&X?vLr}>Z)J;s(-${ zT_f-`@`JG1B;+gXEFT*h_u*B)1HlQWG3l27v`e9H#a3c>?ZoLiNu^t%IA_OhQteg~ zuj`q<6K^H8Zq2kSaXo2t88WYixzv&(nwDqq$iQg(nO^C!C5Gb z5}2&@h4$mD-xo5(jh0UZ8u#H<9E2cvtga<&;fTr}*&{v5DYstIt}CkC=FXQEuW?c(OzK^_GuST92h zw#Ntm(d`HDsvQtHxga^cq&e}yHds#|gD-Y{JdXm0_+jZ0<#Tk~+t&=j_l^>Auh`yL z@HZkM;N-twbOu=>I^jU1ohMUJCzB^K8;Ve?&UmT^S-R+M_FiB&li}b_upizTkFz^L zIMVV?KZxRv7D{)1aCne$ahl1I`uL-de$+`~IBKeuFVYj$S+`}Q<0qw0+T&^A`F;dZ z^?d}XGESni_x|61?d5mq9ES%wC|oJ@M5ZgxRzU-5F`oSoG&r4GXaCAA4gNi+BO?Dj zeWB^l(soXBE4R3{Oa1^cJg40L6P?>Q@?$c$v~yA64t{fKe@5pHj8}GHyj+z#<*IoF zbU=G>9%D8R6?1twXLaux=0tXP)%i{<`muPj9alJ-i?U9>AP7TsmP0^7y_DbTrC z$rPZ69Zi`@^wla!A(*c*S0K;5qbVHBkHyTo7rl01aP}9_Bn3MS6bsl`W=F9|;J^U~ z_JEP4@+gJQ8nW8#Nh|^-SQ3l`Qxi~u?m7`t0WYzv#~yw9GlOUFQE3v36a!Wo2RedH z*lDB(X3fH%i>2+^AMtF@%qre@&+s**s< zI&`FqBX3^=8tLH-&_Ws{!uN~nX&_SwWUDG0xbQ8UcC%hj30>3{IP@dltuNsRc6S@g zj$w+OXi-a+5H-A5iW{i!eQ;O^;NRfZ<;UCbh59}S;yScRE&4w7=#F_C^d0CooCZk8 z@~j$+!fShU)>%W^q6W0TX_pq2H(`qqv5pVcEp&xpGc3=VoRc{{`z0^~y|6CHA^Gj$ zXV%=B+h;$_?V%0*+rU-8T0;j|jOJ8VE?iD^HHX@CiOdFLxtTlu;5q4&-1hC`o6mtA zfj_L-t5w2%5&%wR$sP+wVkgiBzhA=z3eq8t4JaAV%4P~1p2(7;C@o1TDY+*ASf+i* zq^n#BIAlr2jv!Bf46djH)4k;tTL{8H%3x}6R8%4@5>;$3<9$346CrPbzvO!$3I{PN zccIy;7yx0}P?K284{^G>08mj~D0mYY-v$B@$fegpL+yhSQ^iTerMGAUqF>6{$JfOF zn{~A;iBQ{wfej-F1p|XaXhaxBC~c!HdH-xbM;P3O(qs)Gj8H)KHC$(~2PMLOWt-w+ z3fGX_BdcILvoBV`KFCtwEsfk61IHuptrLn`Mhb5qcwduK{NyU}Fj{M8UFltLJ?dIr zVM@}!cAKk6Kc4*r=o8pDgqvUn^#FMJG<(CS74<5hiKR6x;!M5+P6AhAcn$BgY~$AM z%?(S;WvXlYDtsg260Z>V;Vr}JIVPoRkl;IZlg@6h9d()3UvpJ!?Z^*6Pf_#zB;%79 z*{tFF$53fYZj%^Xi6u;8h$U7y`7Vm@qWB()4v3 None: - # >>> uuid.uuid5(uuid.NAMESPACE_URL, "com.unity.ml-agents/TrainingAnalyticsSideChannel") - # UUID('b664a4a9-d86f-5a5f-95cb-e8353a7e8356') - # We purposefully use the SAME side channel as the TrainingAnalyticsSideChannel - - super().__init__(DefaultTrainingAnalyticsSideChannel.CHANNEL_ID) - - def on_message_received(self, msg: IncomingMessage) -> None: - raise UnityCommunicationException( - "The DefaultTrainingAnalyticsSideChannel received a message from Unity, " - + "this should not have happened." - ) - - def environment_initialized(self) -> None: - # Tuple of (major, minor, patch) - vi = sys.version_info - - msg = TrainingEnvironmentInitialized( - python_version=f"{vi[0]}.{vi[1]}.{vi[2]}", - mlagents_version="Custom", - mlagents_envs_version=mlagents_envs.__version__, - torch_version="Unknown", - torch_device_type="Unknown", - ) - any_message = Any() - any_message.Pack(msg) - - env_init_msg = OutgoingMessage() - env_init_msg.set_raw_bytes(any_message.SerializeToString()) # type: ignore - super().queue_message_to_send(env_init_msg) diff --git a/3DOrangeTree/mlagents_envs/side_channel/engine_configuration_channel.py b/3DOrangeTree/mlagents_envs/side_channel/engine_configuration_channel.py deleted file mode 100644 index ce1715b..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/engine_configuration_channel.py +++ /dev/null @@ -1,127 +0,0 @@ -from mlagents_envs.side_channel import SideChannel, OutgoingMessage, IncomingMessage -from mlagents_envs.exception import ( - UnityCommunicationException, - UnitySideChannelException, -) -import uuid -from typing import NamedTuple, Optional -from enum import IntEnum - - -class EngineConfig(NamedTuple): - width: Optional[int] - height: Optional[int] - quality_level: Optional[int] - time_scale: Optional[float] - target_frame_rate: Optional[int] - capture_frame_rate: Optional[int] - - @staticmethod - def default_config(): - return EngineConfig(80, 80, 1, 20.0, -1, 60) - - -class EngineConfigurationChannel(SideChannel): - """ - This is the SideChannel for engine configuration exchange. The data in the - engine configuration is as follows : - - int width; - - int height; - - int qualityLevel; - - float timeScale; - - int targetFrameRate; - - int captureFrameRate; - """ - - class ConfigurationType(IntEnum): - SCREEN_RESOLUTION = 0 - QUALITY_LEVEL = 1 - TIME_SCALE = 2 - TARGET_FRAME_RATE = 3 - CAPTURE_FRAME_RATE = 4 - - def __init__(self) -> None: - super().__init__(uuid.UUID("e951342c-4f7e-11ea-b238-784f4387d1f7")) - - def on_message_received(self, msg: IncomingMessage) -> None: - """ - Is called by the environment to the side channel. Can be called - multiple times per step if multiple messages are meant for that - SideChannel. - Note that Python should never receive an engine configuration from - Unity - """ - raise UnityCommunicationException( - "The EngineConfigurationChannel received a message from Unity, " - + "this should not have happened." - ) - - def set_configuration_parameters( - self, - width: Optional[int] = None, - height: Optional[int] = None, - quality_level: Optional[int] = None, - time_scale: Optional[float] = None, - target_frame_rate: Optional[int] = None, - capture_frame_rate: Optional[int] = None, - ) -> None: - """ - Sets the engine configuration. Takes as input the configurations of the - engine. - :param width: Defines the width of the display. (Must be set alongside height) - :param height: Defines the height of the display. (Must be set alongside width) - :param quality_level: Defines the quality level of the simulation. - :param time_scale: Defines the multiplier for the deltatime in the - simulation. If set to a higher value, time will pass faster in the - simulation but the physics might break. - :param target_frame_rate: Instructs simulation to try to render at a - specified frame rate. - :param capture_frame_rate: Instructs the simulation to consider time between - updates to always be constant, regardless of the actual frame rate. - """ - - if (width is None and height is not None) or ( - width is not None and height is None - ): - raise UnitySideChannelException( - "You cannot set the width/height of the screen resolution without also setting the height/width" - ) - - if width is not None and height is not None: - screen_msg = OutgoingMessage() - screen_msg.write_int32(self.ConfigurationType.SCREEN_RESOLUTION) - screen_msg.write_int32(width) - screen_msg.write_int32(height) - super().queue_message_to_send(screen_msg) - - if quality_level is not None: - quality_level_msg = OutgoingMessage() - quality_level_msg.write_int32(self.ConfigurationType.QUALITY_LEVEL) - quality_level_msg.write_int32(quality_level) - super().queue_message_to_send(quality_level_msg) - - if time_scale is not None: - time_scale_msg = OutgoingMessage() - time_scale_msg.write_int32(self.ConfigurationType.TIME_SCALE) - time_scale_msg.write_float32(time_scale) - super().queue_message_to_send(time_scale_msg) - - if target_frame_rate is not None: - target_frame_rate_msg = OutgoingMessage() - target_frame_rate_msg.write_int32(self.ConfigurationType.TARGET_FRAME_RATE) - target_frame_rate_msg.write_int32(target_frame_rate) - super().queue_message_to_send(target_frame_rate_msg) - - if capture_frame_rate is not None: - capture_frame_rate_msg = OutgoingMessage() - capture_frame_rate_msg.write_int32( - self.ConfigurationType.CAPTURE_FRAME_RATE - ) - capture_frame_rate_msg.write_int32(capture_frame_rate) - super().queue_message_to_send(capture_frame_rate_msg) - - def set_configuration(self, config: EngineConfig) -> None: - """ - Sets the engine configuration. Takes as input an EngineConfig. - """ - self.set_configuration_parameters(**config._asdict()) diff --git a/3DOrangeTree/mlagents_envs/side_channel/environment_parameters_channel.py b/3DOrangeTree/mlagents_envs/side_channel/environment_parameters_channel.py deleted file mode 100644 index ff516a5..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/environment_parameters_channel.py +++ /dev/null @@ -1,100 +0,0 @@ -from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage -from mlagents_envs.exception import UnityCommunicationException -import uuid -from enum import IntEnum -from typing import List, Tuple - - -class EnvironmentParametersChannel(SideChannel): - """ - This is the SideChannel for sending environment parameters to Unity. - You can send parameters to an environment with the command - set_float_parameter. - """ - - class EnvironmentDataTypes(IntEnum): - FLOAT = 0 - SAMPLER = 1 - - class SamplerTypes(IntEnum): - UNIFORM = 0 - GAUSSIAN = 1 - MULTIRANGEUNIFORM = 2 - - def __init__(self) -> None: - channel_id = uuid.UUID("534c891e-810f-11ea-a9d0-822485860400") - super().__init__(channel_id) - - def on_message_received(self, msg: IncomingMessage) -> None: - raise UnityCommunicationException( - "The EnvironmentParametersChannel received a message from Unity, " - + "this should not have happened." - ) - - def set_float_parameter(self, key: str, value: float) -> None: - """ - Sets a float environment parameter in the Unity Environment. - :param key: The string identifier of the parameter. - :param value: The float value of the parameter. - """ - msg = OutgoingMessage() - msg.write_string(key) - msg.write_int32(self.EnvironmentDataTypes.FLOAT) - msg.write_float32(value) - super().queue_message_to_send(msg) - - def set_uniform_sampler_parameters( - self, key: str, min_value: float, max_value: float, seed: int - ) -> None: - """ - Sets a uniform environment parameter sampler. - :param key: The string identifier of the parameter. - :param min_value: The minimum of the sampling distribution. - :param max_value: The maximum of the sampling distribution. - :param seed: The random seed to initialize the sampler. - """ - msg = OutgoingMessage() - msg.write_string(key) - msg.write_int32(self.EnvironmentDataTypes.SAMPLER) - msg.write_int32(seed) - msg.write_int32(self.SamplerTypes.UNIFORM) - msg.write_float32(min_value) - msg.write_float32(max_value) - super().queue_message_to_send(msg) - - def set_gaussian_sampler_parameters( - self, key: str, mean: float, st_dev: float, seed: int - ) -> None: - """ - Sets a gaussian environment parameter sampler. - :param key: The string identifier of the parameter. - :param mean: The mean of the sampling distribution. - :param st_dev: The standard deviation of the sampling distribution. - :param seed: The random seed to initialize the sampler. - """ - msg = OutgoingMessage() - msg.write_string(key) - msg.write_int32(self.EnvironmentDataTypes.SAMPLER) - msg.write_int32(seed) - msg.write_int32(self.SamplerTypes.GAUSSIAN) - msg.write_float32(mean) - msg.write_float32(st_dev) - super().queue_message_to_send(msg) - - def set_multirangeuniform_sampler_parameters( - self, key: str, intervals: List[Tuple[float, float]], seed: int - ) -> None: - """ - Sets a multirangeuniform environment parameter sampler. - :param key: The string identifier of the parameter. - :param intervals: The lists of min and max that define each uniform distribution. - :param seed: The random seed to initialize the sampler. - """ - msg = OutgoingMessage() - msg.write_string(key) - msg.write_int32(self.EnvironmentDataTypes.SAMPLER) - msg.write_int32(seed) - msg.write_int32(self.SamplerTypes.MULTIRANGEUNIFORM) - flattened_intervals = [value for interval in intervals for value in interval] - msg.write_float32_list(flattened_intervals) - super().queue_message_to_send(msg) diff --git a/3DOrangeTree/mlagents_envs/side_channel/float_properties_channel.py b/3DOrangeTree/mlagents_envs/side_channel/float_properties_channel.py deleted file mode 100644 index 6c67011..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/float_properties_channel.py +++ /dev/null @@ -1,62 +0,0 @@ -from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage -import uuid -from typing import Dict, Optional, List - - -class FloatPropertiesChannel(SideChannel): - """ - This is the SideChannel for float properties shared with Unity. - You can modify the float properties of an environment with the commands - set_property, get_property and list_properties. - """ - - def __init__(self, channel_id: uuid.UUID = None) -> None: - self._float_properties: Dict[str, float] = {} - if channel_id is None: - channel_id = uuid.UUID("60ccf7d0-4f7e-11ea-b238-784f4387d1f7") - super().__init__(channel_id) - - def on_message_received(self, msg: IncomingMessage) -> None: - """ - Is called by the environment to the side channel. Can be called - multiple times per step if multiple messages are meant for that - SideChannel. - """ - k = msg.read_string() - v = msg.read_float32() - self._float_properties[k] = v - - def set_property(self, key: str, value: float) -> None: - """ - Sets a property in the Unity Environment. - :param key: The string identifier of the property. - :param value: The float value of the property. - """ - self._float_properties[key] = value - msg = OutgoingMessage() - msg.write_string(key) - msg.write_float32(value) - super().queue_message_to_send(msg) - - def get_property(self, key: str) -> Optional[float]: - """ - Gets a property in the Unity Environment. If the property was not - found, will return None. - :param key: The string identifier of the property. - :return: The float value of the property or None. - """ - return self._float_properties.get(key) - - def list_properties(self) -> List[str]: - """ - Returns a list of all the string identifiers of the properties - currently present in the Unity Environment. - """ - return list(self._float_properties.keys()) - - def get_property_dict_copy(self) -> Dict[str, float]: - """ - Returns a copy of the float properties. - :return: - """ - return dict(self._float_properties) diff --git a/3DOrangeTree/mlagents_envs/side_channel/incoming_message.py b/3DOrangeTree/mlagents_envs/side_channel/incoming_message.py deleted file mode 100644 index 6c00f25..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/incoming_message.py +++ /dev/null @@ -1,93 +0,0 @@ -from typing import List -import struct - - -class IncomingMessage: - """ - Utility class for reading the message written to a SideChannel. - Values must be read in the order they were written. - """ - - def __init__(self, buffer: bytes, offset: int = 0): - """ - Create a new IncomingMessage from the bytes. - """ - self.buffer = buffer - self.offset = offset - - def read_bool(self, default_value: bool = False) -> bool: - """ - Read a boolean value from the message buffer. - :param default_value: Default value to use if the end of the message is reached. - :return: The value read from the message, or the default value if the end was reached. - """ - if self._at_end_of_buffer(): - return default_value - - val = struct.unpack_from(" int: - """ - Read an integer value from the message buffer. - :param default_value: Default value to use if the end of the message is reached. - :return: The value read from the message, or the default value if the end was reached. - """ - if self._at_end_of_buffer(): - return default_value - - val = struct.unpack_from(" float: - """ - Read a float value from the message buffer. - :param default_value: Default value to use if the end of the message is reached. - :return: The value read from the message, or the default value if the end was reached. - """ - if self._at_end_of_buffer(): - return default_value - - val = struct.unpack_from(" List[float]: - """ - Read a list of float values from the message buffer. - :param default_value: Default value to use if the end of the message is reached. - :return: The value read from the message, or the default value if the end was reached. - """ - if self._at_end_of_buffer(): - return [] if default_value is None else default_value - - list_len = self.read_int32() - output = [] - for _ in range(list_len): - output.append(self.read_float32()) - return output - - def read_string(self, default_value: str = "") -> str: - """ - Read a string value from the message buffer. - :param default_value: Default value to use if the end of the message is reached. - :return: The value read from the message, or the default value if the end was reached. - """ - if self._at_end_of_buffer(): - return default_value - - encoded_str_len = self.read_int32() - val = self.buffer[self.offset : self.offset + encoded_str_len].decode("ascii") - self.offset += encoded_str_len - return val - - def get_raw_bytes(self) -> bytes: - """ - Get a copy of the internal bytes used by the message. - """ - return bytearray(self.buffer) - - def _at_end_of_buffer(self) -> bool: - return self.offset >= len(self.buffer) diff --git a/3DOrangeTree/mlagents_envs/side_channel/outgoing_message.py b/3DOrangeTree/mlagents_envs/side_channel/outgoing_message.py deleted file mode 100644 index 83bbe34..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/outgoing_message.py +++ /dev/null @@ -1,66 +0,0 @@ -from typing import List -import struct - -from mlagents_envs.logging_util import get_logger - -logger = get_logger(__name__) - - -class OutgoingMessage: - """ - Utility class for forming the message that is written to a SideChannel. - All data is written in little-endian format using the struct module. - """ - - def __init__(self): - """ - Create an OutgoingMessage with an empty buffer. - """ - self.buffer = bytearray() - - def write_bool(self, b: bool) -> None: - """ - Append a boolean value. - """ - self.buffer += struct.pack(" None: - """ - Append an integer value. - """ - self.buffer += struct.pack(" None: - """ - Append a float value. It will be truncated to 32-bit precision. - """ - self.buffer += struct.pack(" None: - """ - Append a list of float values. They will be truncated to 32-bit precision. - """ - self.write_int32(len(float_list)) - for f in float_list: - self.write_float32(f) - - def write_string(self, s: str) -> None: - """ - Append a string value. Internally, it will be encoded to ascii, and the - encoded length will also be written to the message. - """ - encoded_key = s.encode("ascii") - self.write_int32(len(encoded_key)) - self.buffer += encoded_key - - def set_raw_bytes(self, buffer: bytearray) -> None: - """ - Set the internal buffer to a new bytearray. This will overwrite any existing data. - :param buffer: - :return: - """ - if self.buffer: - logger.warning( - "Called set_raw_bytes but the message already has been written to. This will overwrite data." - ) - self.buffer = bytearray(buffer) diff --git a/3DOrangeTree/mlagents_envs/side_channel/raw_bytes_channel.py b/3DOrangeTree/mlagents_envs/side_channel/raw_bytes_channel.py deleted file mode 100644 index d9f748f..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/raw_bytes_channel.py +++ /dev/null @@ -1,39 +0,0 @@ -from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage -from typing import List -import uuid - - -class RawBytesChannel(SideChannel): - """ - This is an example of what the SideChannel for raw bytes exchange would - look like. Is meant to be used for general research purpose. - """ - - def __init__(self, channel_id: uuid.UUID): - self._received_messages: List[bytes] = [] - super().__init__(channel_id) - - def on_message_received(self, msg: IncomingMessage) -> None: - """ - Is called by the environment to the side channel. Can be called - multiple times per step if multiple messages are meant for that - SideChannel. - """ - self._received_messages.append(msg.get_raw_bytes()) - - def get_and_clear_received_messages(self) -> List[bytes]: - """ - returns a list of bytearray received from the environment. - """ - result = list(self._received_messages) - self._received_messages = [] - return result - - def send_raw_data(self, data: bytearray) -> None: - """ - Queues a message to be sent by the environment at the next call to - step. - """ - msg = OutgoingMessage() - msg.set_raw_bytes(data) - super().queue_message_to_send(msg) diff --git a/3DOrangeTree/mlagents_envs/side_channel/side_channel.py b/3DOrangeTree/mlagents_envs/side_channel/side_channel.py deleted file mode 100644 index 469cb51..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/side_channel.py +++ /dev/null @@ -1,46 +0,0 @@ -from abc import ABC, abstractmethod -from typing import List -import uuid - -from mlagents_envs.side_channel import IncomingMessage, OutgoingMessage -from mlagents_envs.logging_util import get_logger - -logger = get_logger(__name__) - - -class SideChannel(ABC): - """ - The side channel just get access to a bytes buffer that will be shared - between C# and Python. For example, We will create a specific side channel - for properties that will be a list of string (fixed size) to float number, - that can be modified by both C# and Python. All side channels are passed - to the Env object at construction. - """ - - def __init__(self, channel_id: uuid.UUID): - self._channel_id: uuid.UUID = channel_id - self.message_queue: List[bytearray] = [] - - def queue_message_to_send(self, msg: OutgoingMessage) -> None: - """ - Queues a message to be sent by the environment at the next call to - step. - """ - self.message_queue.append(msg.buffer) - - @abstractmethod - def on_message_received(self, msg: IncomingMessage) -> None: - """ - Is called by the environment to the side channel. Can be called - multiple times per step if multiple messages are meant for that - SideChannel. - """ - pass - - @property - def channel_id(self) -> uuid.UUID: - """ - :return:The type of side channel used. Will influence how the data is - processed in the environment. - """ - return self._channel_id diff --git a/3DOrangeTree/mlagents_envs/side_channel/side_channel_manager.py b/3DOrangeTree/mlagents_envs/side_channel/side_channel_manager.py deleted file mode 100644 index a7783c6..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/side_channel_manager.py +++ /dev/null @@ -1,81 +0,0 @@ -import uuid -import struct -from typing import Dict, Optional, List -from mlagents_envs.side_channel import SideChannel, IncomingMessage -from mlagents_envs.exception import UnityEnvironmentException -from mlagents_envs.logging_util import get_logger - - -class SideChannelManager: - def __init__(self, side_channels=Optional[List[SideChannel]]): - self._side_channels_dict = self._get_side_channels_dict(side_channels) - - def process_side_channel_message(self, data: bytes) -> None: - """ - Separates the data received from Python into individual messages for each - registered side channel and calls on_message_received on them. - :param data: The packed message sent by Unity - """ - offset = 0 - while offset < len(data): - try: - channel_id = uuid.UUID(bytes_le=bytes(data[offset : offset + 16])) - offset += 16 - message_len, = struct.unpack_from(" bytearray: - """ - Gathers the messages that the registered side channels will send to Unity - and combines them into a single message ready to be sent. - """ - result = bytearray() - for channel_id, channel in self._side_channels_dict.items(): - for message in channel.message_queue: - result += channel_id.bytes_le - result += struct.pack(" Dict[uuid.UUID, SideChannel]: - """ - Converts a list of side channels into a dictionary of channel_id to SideChannel - :param side_channels: The list of side channels. - """ - side_channels_dict: Dict[uuid.UUID, SideChannel] = {} - if side_channels is not None: - for _sc in side_channels: - if _sc.channel_id in side_channels_dict: - raise UnityEnvironmentException( - f"There cannot be two side channels with " - f"the same channel id {_sc.channel_id}." - ) - side_channels_dict[_sc.channel_id] = _sc - return side_channels_dict diff --git a/3DOrangeTree/mlagents_envs/side_channel/stats_side_channel.py b/3DOrangeTree/mlagents_envs/side_channel/stats_side_channel.py deleted file mode 100644 index 9fbbfb2..0000000 --- a/3DOrangeTree/mlagents_envs/side_channel/stats_side_channel.py +++ /dev/null @@ -1,62 +0,0 @@ -import uuid -from typing import Tuple, List, Mapping -from enum import Enum -from collections import defaultdict - -from mlagents_envs.side_channel import SideChannel, IncomingMessage - - -# Determines the behavior of how multiple stats within the same summary period are combined. -class StatsAggregationMethod(Enum): - # Values within the summary period are averaged before reporting. - AVERAGE = 0 - - # Only the most recent value is reported. - MOST_RECENT = 1 - - # Values within the summary period are summed up before reporting. - SUM = 2 - - # All values within a summary period are reported as a histogram. - HISTOGRAM = 3 - - -StatList = List[Tuple[float, StatsAggregationMethod]] -EnvironmentStats = Mapping[str, StatList] - - -class StatsSideChannel(SideChannel): - """ - Side channel that receives (string, float) pairs from the environment, so that they can eventually - be passed to a StatsReporter. - """ - - def __init__(self) -> None: - # >>> uuid.uuid5(uuid.NAMESPACE_URL, "com.unity.ml-agents/StatsSideChannel") - # UUID('a1d8f7b7-cec8-50f9-b78b-d3e165a78520') - super().__init__(uuid.UUID("a1d8f7b7-cec8-50f9-b78b-d3e165a78520")) - - self.stats: EnvironmentStats = defaultdict(list) - - def on_message_received(self, msg: IncomingMessage) -> None: - """ - Receive the message from the environment, and save it for later retrieval. - - :param msg: - :return: - """ - key = msg.read_string() - val = msg.read_float32() - agg_type = StatsAggregationMethod(msg.read_int32()) - - self.stats[key].append((val, agg_type)) - - def get_and_reset_stats(self) -> EnvironmentStats: - """ - Returns the current stats, and resets the internal storage of the stats. - - :return: - """ - s = self.stats - self.stats = defaultdict(list) - return s diff --git a/3DOrangeTree/mlagents_envs/tests/__init__.py b/3DOrangeTree/mlagents_envs/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3DOrangeTree/mlagents_envs/tests/test_env_utils.py b/3DOrangeTree/mlagents_envs/tests/test_env_utils.py deleted file mode 100644 index e8b783f..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_env_utils.py +++ /dev/null @@ -1,64 +0,0 @@ -from unittest import mock -import pytest -from mlagents_envs.env_utils import validate_environment_path, launch_executable -from mlagents_envs.exception import UnityEnvironmentException -from mlagents_envs.logging_util import ( - set_log_level, - get_logger, - INFO, - ERROR, - FATAL, - CRITICAL, - DEBUG, -) - - -def mock_glob_method(path): - """ - Given a path input, returns a list of candidates - """ - if ".x86" in path: - return ["linux"] - if ".app" in path: - return ["darwin"] - if ".exe" in path: - return ["win32"] - if "*" in path: - return "Any" - return [] - - -@mock.patch("sys.platform") -@mock.patch("glob.glob") -def test_validate_path_empty(glob_mock, platform_mock): - glob_mock.return_value = None - path = validate_environment_path(" ") - assert path is None - - -@mock.patch("mlagents_envs.env_utils.get_platform") -@mock.patch("glob.glob") -def test_validate_path(glob_mock, platform_mock): - glob_mock.side_effect = mock_glob_method - for platform in ["linux", "darwin", "win32"]: - platform_mock.return_value = platform - path = validate_environment_path(" ") - assert path == platform - - -@mock.patch("glob.glob") -@mock.patch("subprocess.Popen") -def test_launch_executable(mock_popen, glob_mock): - with pytest.raises(UnityEnvironmentException): - launch_executable(" ", []) - glob_mock.return_value = ["FakeLaunchPath"] - launch_executable(" ", []) - mock_popen.side_effect = PermissionError("Fake permission error") - with pytest.raises(UnityEnvironmentException): - launch_executable(" ", []) - - -def test_set_logging_level(): - for level in [INFO, ERROR, FATAL, CRITICAL, DEBUG]: - set_log_level(level) - assert get_logger("test").level == level diff --git a/3DOrangeTree/mlagents_envs/tests/test_envs.py b/3DOrangeTree/mlagents_envs/tests/test_envs.py deleted file mode 100644 index 138ac6d..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_envs.py +++ /dev/null @@ -1,170 +0,0 @@ -from unittest import mock -import pytest - -from mlagents_envs.environment import UnityEnvironment -from mlagents_envs.base_env import DecisionSteps, TerminalSteps, ActionTuple -from mlagents_envs.exception import UnityEnvironmentException, UnityActionException -from mlagents_envs.mock_communicator import MockCommunicator - - -@mock.patch("mlagents_envs.environment.UnityEnvironment._get_communicator") -def test_handles_bad_filename(get_communicator): - with pytest.raises(UnityEnvironmentException): - UnityEnvironment(" ") - - -@mock.patch("mlagents_envs.env_utils.launch_executable") -@mock.patch("mlagents_envs.environment.UnityEnvironment._get_communicator") -def test_initialization(mock_communicator, mock_launcher): - mock_communicator.return_value = MockCommunicator( - discrete_action=False, visual_inputs=0 - ) - env = UnityEnvironment(" ") - assert list(env.behavior_specs.keys()) == ["RealFakeBrain"] - env.close() - - -@pytest.mark.parametrize( - "base_port,file_name,expected", - [ - # Non-None base port value will always be used - (6001, "foo.exe", 6001), - # No port specified and environment specified, so use BASE_ENVIRONMENT_PORT - (None, "foo.exe", UnityEnvironment.BASE_ENVIRONMENT_PORT), - # No port specified and no environment, so use DEFAULT_EDITOR_PORT - (None, None, UnityEnvironment.DEFAULT_EDITOR_PORT), - ], -) -@mock.patch("mlagents_envs.env_utils.launch_executable") -@mock.patch("mlagents_envs.environment.UnityEnvironment._get_communicator") -def test_port_defaults( - mock_communicator, mock_launcher, base_port, file_name, expected -): - mock_communicator.return_value = MockCommunicator( - discrete_action=False, visual_inputs=0 - ) - env = UnityEnvironment(file_name=file_name, worker_id=0, base_port=base_port) - assert expected == env._port - env.close() - - -@mock.patch("mlagents_envs.env_utils.launch_executable") -@mock.patch("mlagents_envs.environment.UnityEnvironment._get_communicator") -def test_log_file_path_is_set(mock_communicator, mock_launcher): - mock_communicator.return_value = MockCommunicator() - env = UnityEnvironment( - file_name="myfile", worker_id=0, log_folder="./some-log-folder-path" - ) - args = env._executable_args() - log_file_index = args.index("-logFile") - assert args[log_file_index + 1] == "./some-log-folder-path/Player-0.log" - env.close() - - -@mock.patch("mlagents_envs.env_utils.launch_executable") -@mock.patch("mlagents_envs.environment.UnityEnvironment._get_communicator") -def test_reset(mock_communicator, mock_launcher): - mock_communicator.return_value = MockCommunicator( - discrete_action=False, visual_inputs=0 - ) - env = UnityEnvironment(" ") - spec = env.behavior_specs["RealFakeBrain"] - env.reset() - decision_steps, terminal_steps = env.get_steps("RealFakeBrain") - env.close() - assert isinstance(decision_steps, DecisionSteps) - assert isinstance(terminal_steps, TerminalSteps) - assert len(spec.observation_specs) == len(decision_steps.obs) - assert len(spec.observation_specs) == len(terminal_steps.obs) - n_agents = len(decision_steps) - for sen_spec, obs in zip(spec.observation_specs, decision_steps.obs): - assert (n_agents,) + sen_spec.shape == obs.shape - n_agents = len(terminal_steps) - for sen_spec, obs in zip(spec.observation_specs, terminal_steps.obs): - assert (n_agents,) + sen_spec.shape == obs.shape - - -@mock.patch("mlagents_envs.env_utils.launch_executable") -@mock.patch("mlagents_envs.environment.UnityEnvironment._get_communicator") -def test_step(mock_communicator, mock_launcher): - mock_communicator.return_value = MockCommunicator( - discrete_action=False, visual_inputs=0 - ) - env = UnityEnvironment(" ") - spec = env.behavior_specs["RealFakeBrain"] - env.step() - decision_steps, terminal_steps = env.get_steps("RealFakeBrain") - n_agents = len(decision_steps) - env.set_actions("RealFakeBrain", spec.action_spec.empty_action(n_agents)) - env.step() - with pytest.raises(UnityActionException): - env.set_actions("RealFakeBrain", spec.action_spec.empty_action(n_agents - 1)) - decision_steps, terminal_steps = env.get_steps("RealFakeBrain") - n_agents = len(decision_steps) - _empty_act = spec.action_spec.empty_action(n_agents) - next_action = ActionTuple(_empty_act.continuous - 1, _empty_act.discrete - 1) - env.set_actions("RealFakeBrain", next_action) - env.step() - - env.close() - assert isinstance(decision_steps, DecisionSteps) - assert isinstance(terminal_steps, TerminalSteps) - assert len(spec.observation_specs) == len(decision_steps.obs) - assert len(spec.observation_specs) == len(terminal_steps.obs) - for spec, obs in zip(spec.observation_specs, decision_steps.obs): - assert (n_agents,) + spec.shape == obs.shape - assert 0 in decision_steps - assert 2 in terminal_steps - - -@mock.patch("mlagents_envs.env_utils.launch_executable") -@mock.patch("mlagents_envs.environment.UnityEnvironment._get_communicator") -def test_close(mock_communicator, mock_launcher): - comm = MockCommunicator(discrete_action=False, visual_inputs=0) - mock_communicator.return_value = comm - env = UnityEnvironment(" ") - assert env._loaded - env.close() - assert not env._loaded - assert comm.has_been_closed - - -def test_check_communication_compatibility(): - unity_ver = "1.0.0" - python_ver = "1.0.0" - unity_package_version = "0.15.0" - assert UnityEnvironment._check_communication_compatibility( - unity_ver, python_ver, unity_package_version - ) - unity_ver = "1.1.0" - assert UnityEnvironment._check_communication_compatibility( - unity_ver, python_ver, unity_package_version - ) - unity_ver = "2.0.0" - assert not UnityEnvironment._check_communication_compatibility( - unity_ver, python_ver, unity_package_version - ) - - unity_ver = "0.16.0" - python_ver = "0.16.0" - assert UnityEnvironment._check_communication_compatibility( - unity_ver, python_ver, unity_package_version - ) - unity_ver = "0.17.0" - assert not UnityEnvironment._check_communication_compatibility( - unity_ver, python_ver, unity_package_version - ) - unity_ver = "1.16.0" - assert not UnityEnvironment._check_communication_compatibility( - unity_ver, python_ver, unity_package_version - ) - - -def test_returncode_to_signal_name(): - assert UnityEnvironment._returncode_to_signal_name(-2) == "SIGINT" - assert UnityEnvironment._returncode_to_signal_name(42) is None - assert UnityEnvironment._returncode_to_signal_name("SIGINT") is None - - -if __name__ == "__main__": - pytest.main() diff --git a/3DOrangeTree/mlagents_envs/tests/test_registry.py b/3DOrangeTree/mlagents_envs/tests/test_registry.py deleted file mode 100644 index 12cfefa..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_registry.py +++ /dev/null @@ -1,44 +0,0 @@ -import shutil -import os - -from mlagents_envs.registry import default_registry, UnityEnvRegistry -from mlagents_envs.registry.remote_registry_entry import RemoteRegistryEntry -from mlagents_envs.registry.binary_utils import get_tmp_dir - -BASIC_ID = "Basic" - - -def delete_binaries(): - tmp_dir, bin_dir = get_tmp_dir() - shutil.rmtree(tmp_dir) - shutil.rmtree(bin_dir) - - -def create_registry(): - reg = UnityEnvRegistry() - entry = RemoteRegistryEntry( - BASIC_ID, - 0.0, - "Description", - "https://storage.googleapis.com/mlagents-test-environments/1.0.0/linux/Basic.zip", - "https://storage.googleapis.com/mlagents-test-environments/1.0.0/darwin/Basic.zip", - "https://storage.googleapis.com/mlagents-test-environments/1.0.0/windows/Basic.zip", - ) - reg.register(entry) - return reg - - -def test_basic_in_registry(): - assert BASIC_ID in default_registry - os.environ["TERM"] = "xterm" - delete_binaries() - registry = create_registry() - for worker_id in range(2): - assert BASIC_ID in registry - env = registry[BASIC_ID].make( - base_port=6002, worker_id=worker_id, no_graphics=True - ) - env.reset() - env.step() - assert len(env.behavior_specs) == 1 - env.close() diff --git a/3DOrangeTree/mlagents_envs/tests/test_rpc_communicator.py b/3DOrangeTree/mlagents_envs/tests/test_rpc_communicator.py deleted file mode 100644 index e912878..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_rpc_communicator.py +++ /dev/null @@ -1,82 +0,0 @@ -import pytest -from unittest import mock - -import grpc - -import mlagents_envs.rpc_communicator -from mlagents_envs.rpc_communicator import RpcCommunicator -from mlagents_envs.exception import ( - UnityWorkerInUseException, - UnityTimeOutException, - UnityEnvironmentException, -) -from mlagents_envs.communicator_objects.unity_input_pb2 import UnityInputProto - - -def test_rpc_communicator_checks_port_on_create(): - first_comm = RpcCommunicator() - with pytest.raises(UnityWorkerInUseException): - second_comm = RpcCommunicator() - second_comm.close() - first_comm.close() - - -def test_rpc_communicator_close(): - # Ensures it is possible to open a new RPC Communicators - # after closing one on the same worker_id - first_comm = RpcCommunicator() - first_comm.close() - second_comm = RpcCommunicator() - second_comm.close() - - -def test_rpc_communicator_create_multiple_workers(): - # Ensures multiple RPC communicators can be created with - # different worker_ids without causing an error. - first_comm = RpcCommunicator() - second_comm = RpcCommunicator(worker_id=1) - first_comm.close() - second_comm.close() - - -@mock.patch.object(grpc, "server") -@mock.patch.object( - mlagents_envs.rpc_communicator, "UnityToExternalServicerImplementation" -) -def test_rpc_communicator_initialize_OK(mock_impl, mock_grpc_server): - comm = RpcCommunicator(timeout_wait=0.25) - comm.unity_to_external.parent_conn.poll.return_value = True - input = UnityInputProto() - comm.initialize(input) - comm.unity_to_external.parent_conn.poll.assert_called() - - -@mock.patch.object(grpc, "server") -@mock.patch.object( - mlagents_envs.rpc_communicator, "UnityToExternalServicerImplementation" -) -def test_rpc_communicator_initialize_timeout(mock_impl, mock_grpc_server): - comm = RpcCommunicator(timeout_wait=0.25) - comm.unity_to_external.parent_conn.poll.return_value = None - input = UnityInputProto() - # Expect a timeout - with pytest.raises(UnityTimeOutException): - comm.initialize(input) - comm.unity_to_external.parent_conn.poll.assert_called() - - -@mock.patch.object(grpc, "server") -@mock.patch.object( - mlagents_envs.rpc_communicator, "UnityToExternalServicerImplementation" -) -def test_rpc_communicator_initialize_callback(mock_impl, mock_grpc_server): - def callback(): - raise UnityEnvironmentException - - comm = RpcCommunicator(timeout_wait=0.25) - comm.unity_to_external.parent_conn.poll.return_value = None - input = UnityInputProto() - # Expect a timeout - with pytest.raises(UnityEnvironmentException): - comm.initialize(input, poll_callback=callback) - comm.unity_to_external.parent_conn.poll.assert_called() diff --git a/3DOrangeTree/mlagents_envs/tests/test_rpc_utils.py b/3DOrangeTree/mlagents_envs/tests/test_rpc_utils.py deleted file mode 100644 index 1d03b21..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_rpc_utils.py +++ /dev/null @@ -1,503 +0,0 @@ -import io -import numpy as np -import pytest -from typing import List, Tuple, Any - -from mlagents_envs.communicator_objects.agent_info_pb2 import AgentInfoProto -from mlagents_envs.communicator_objects.observation_pb2 import ( - ObservationProto, - NONE, - PNG, -) -from mlagents_envs.communicator_objects.brain_parameters_pb2 import BrainParametersProto -from mlagents_envs.communicator_objects.agent_info_action_pair_pb2 import ( - AgentInfoActionPairProto, -) -from mlagents_envs.communicator_objects.agent_action_pb2 import AgentActionProto -from mlagents_envs.base_env import ( - BehaviorSpec, - ActionSpec, - DecisionSteps, - TerminalSteps, -) -from mlagents_envs.exception import UnityObservationException -from mlagents_envs.rpc_utils import ( - behavior_spec_from_proto, - process_pixels, - _process_maybe_compressed_observation, - _process_rank_one_or_two_observation, - steps_from_proto, -) -from PIL import Image -from mlagents.trainers.tests.dummy_config import create_observation_specs_with_shapes - - -def generate_list_agent_proto( - n_agent: int, - shape: List[Tuple[int]], - infinite_rewards: bool = False, - nan_observations: bool = False, -) -> List[AgentInfoProto]: - result = [] - for agent_index in range(n_agent): - ap = AgentInfoProto() - ap.reward = float("inf") if infinite_rewards else agent_index - ap.done = agent_index % 2 == 0 - ap.max_step_reached = agent_index % 4 == 0 - ap.id = agent_index - ap.action_mask.extend([True, False] * 5) - obs_proto_list = [] - for obs_index in range(len(shape)): - obs_proto = ObservationProto() - obs_proto.shape.extend(list(shape[obs_index])) - obs_proto.compression_type = NONE - obs_proto.float_data.data.extend( - ([float("nan")] if nan_observations else [0.1]) - * np.prod(shape[obs_index]) - ) - obs_proto_list.append(obs_proto) - ap.observations.extend(obs_proto_list) - result.append(ap) - return result - - -def generate_compressed_data(in_array: np.ndarray) -> bytes: - image_arr = (in_array * 255).astype(np.uint8) - bytes_out = bytes() - - num_channels = in_array.shape[2] - num_images = (num_channels + 2) // 3 - # Split the input image into batches of 3 channels. - for i in range(num_images): - sub_image = image_arr[..., 3 * i : 3 * i + 3] - if (i == num_images - 1) and (num_channels % 3) != 0: - # Pad zeros - zero_shape = list(in_array.shape) - zero_shape[2] = 3 - (num_channels % 3) - z = np.zeros(zero_shape, dtype=np.uint8) - sub_image = np.concatenate([sub_image, z], axis=2) - im = Image.fromarray(sub_image, "RGB") - byteIO = io.BytesIO() - im.save(byteIO, format="PNG") - bytes_out += byteIO.getvalue() - return bytes_out - - -# test helper function for old C# API (no compressed channel mapping) -def generate_compressed_proto_obs( - in_array: np.ndarray, grayscale: bool = False -) -> ObservationProto: - obs_proto = ObservationProto() - obs_proto.compressed_data = generate_compressed_data(in_array) - obs_proto.compression_type = PNG - if grayscale: - # grayscale flag is only used for old API without mapping - expected_shape = [in_array.shape[0], in_array.shape[1], 1] - obs_proto.shape.extend(expected_shape) - else: - obs_proto.shape.extend(in_array.shape) - return obs_proto - - -# test helper function for new C# API (with compressed channel mapping) -def generate_compressed_proto_obs_with_mapping( - in_array: np.ndarray, mapping: List[int] -) -> ObservationProto: - obs_proto = ObservationProto() - obs_proto.compressed_data = generate_compressed_data(in_array) - obs_proto.compression_type = PNG - if mapping is not None: - obs_proto.compressed_channel_mapping.extend(mapping) - expected_shape = [ - in_array.shape[0], - in_array.shape[1], - len({m for m in mapping if m >= 0}), - ] - obs_proto.shape.extend(expected_shape) - else: - obs_proto.shape.extend(in_array.shape) - return obs_proto - - -def generate_uncompressed_proto_obs(in_array: np.ndarray) -> ObservationProto: - obs_proto = ObservationProto() - obs_proto.float_data.data.extend(in_array.flatten().tolist()) - obs_proto.compression_type = NONE - obs_proto.shape.extend(in_array.shape) - return obs_proto - - -def proto_from_steps( - decision_steps: DecisionSteps, terminal_steps: TerminalSteps -) -> List[AgentInfoProto]: - agent_info_protos: List[AgentInfoProto] = [] - # Take care of the DecisionSteps first - for agent_id in decision_steps.agent_id: - agent_id_index = decision_steps.agent_id_to_index[agent_id] - reward = decision_steps.reward[agent_id_index] - done = False - max_step_reached = False - agent_mask: Any = None - if decision_steps.action_mask is not None: - agent_mask = [] - for _branch in decision_steps.action_mask: - agent_mask = np.concatenate( - (agent_mask, _branch[agent_id_index, :]), axis=0 - ) - agent_mask = agent_mask.astype(np.bool).tolist() - observations: List[ObservationProto] = [] - for all_observations_of_type in decision_steps.obs: - observation = all_observations_of_type[agent_id_index] - if len(observation.shape) == 3: - observations.append(generate_uncompressed_proto_obs(observation)) - else: - observations.append( - ObservationProto( - float_data=ObservationProto.FloatData(data=observation), - shape=[len(observation)], - compression_type=NONE, - ) - ) - agent_info_proto = AgentInfoProto( - reward=reward, - done=done, - id=agent_id, - max_step_reached=bool(max_step_reached), - action_mask=agent_mask, - observations=observations, - ) - agent_info_protos.append(agent_info_proto) - # Take care of the TerminalSteps second - for agent_id in terminal_steps.agent_id: - agent_id_index = terminal_steps.agent_id_to_index[agent_id] - reward = terminal_steps.reward[agent_id_index] - done = True - max_step_reached = terminal_steps.interrupted[agent_id_index] - - final_observations: List[ObservationProto] = [] - for all_observations_of_type in terminal_steps.obs: - observation = all_observations_of_type[agent_id_index] - if len(observation.shape) == 3: - final_observations.append(generate_uncompressed_proto_obs(observation)) - else: - final_observations.append( - ObservationProto( - float_data=ObservationProto.FloatData(data=observation), - shape=[len(observation)], - compression_type=NONE, - ) - ) - agent_info_proto = AgentInfoProto( - reward=reward, - done=done, - id=agent_id, - max_step_reached=bool(max_step_reached), - action_mask=None, - observations=final_observations, - ) - agent_info_protos.append(agent_info_proto) - - return agent_info_protos - - -# The arguments here are the DecisionSteps, TerminalSteps and continuous/discrete actions for a single agent name -def proto_from_steps_and_action( - decision_steps: DecisionSteps, - terminal_steps: TerminalSteps, - continuous_actions: np.ndarray, - discrete_actions: np.ndarray, -) -> List[AgentInfoActionPairProto]: - agent_info_protos = proto_from_steps(decision_steps, terminal_steps) - agent_action_protos = [] - num_agents = ( - len(continuous_actions) - if continuous_actions is not None - else len(discrete_actions) - ) - for i in range(num_agents): - proto = AgentActionProto() - if continuous_actions is not None: - proto.continuous_actions.extend(continuous_actions[i]) - proto.vector_actions_deprecated.extend(continuous_actions[i]) - if discrete_actions is not None: - proto.discrete_actions.extend(discrete_actions[i]) - proto.vector_actions_deprecated.extend(discrete_actions[i]) - agent_action_protos.append(proto) - agent_info_action_pair_protos = [ - AgentInfoActionPairProto(agent_info=agent_info_proto, action_info=action_proto) - for agent_info_proto, action_proto in zip( - agent_info_protos, agent_action_protos - ) - ] - return agent_info_action_pair_protos - - -def test_process_pixels(): - in_array = np.random.rand(128, 64, 3) - byte_arr = generate_compressed_data(in_array) - out_array = process_pixels(byte_arr, 3) - assert out_array.shape == (128, 64, 3) - assert np.sum(in_array - out_array) / np.prod(in_array.shape) < 0.01 - assert np.allclose(in_array, out_array, atol=0.01) - - -def test_process_pixels_multi_png(): - height = 128 - width = 64 - num_channels = 7 - in_array = np.random.rand(height, width, num_channels) - byte_arr = generate_compressed_data(in_array) - out_array = process_pixels(byte_arr, num_channels) - assert out_array.shape == (height, width, num_channels) - assert np.sum(in_array - out_array) / np.prod(in_array.shape) < 0.01 - assert np.allclose(in_array, out_array, atol=0.01) - - -def test_process_pixels_gray(): - in_array = np.random.rand(128, 64, 3) - byte_arr = generate_compressed_data(in_array) - out_array = process_pixels(byte_arr, 1) - assert out_array.shape == (128, 64, 1) - assert np.mean(in_array.mean(axis=2, keepdims=True) - out_array) < 0.01 - assert np.allclose(in_array.mean(axis=2, keepdims=True), out_array, atol=0.01) - - -def test_vector_observation(): - n_agents = 10 - shapes = [(3,), (4,)] - obs_specs = create_observation_specs_with_shapes(shapes) - list_proto = generate_list_agent_proto(n_agents, shapes) - for obs_index, shape in enumerate(shapes): - arr = _process_rank_one_or_two_observation( - obs_index, obs_specs[obs_index], list_proto - ) - assert list(arr.shape) == ([n_agents] + list(shape)) - assert np.allclose(arr, 0.1, atol=0.01) - - -def test_process_visual_observation(): - shape = (128, 64, 3) - in_array_1 = np.random.rand(*shape) - proto_obs_1 = generate_compressed_proto_obs(in_array_1) - in_array_2 = np.random.rand(*shape) - in_array_2_mapping = [0, 1, 2] - proto_obs_2 = generate_compressed_proto_obs_with_mapping( - in_array_2, in_array_2_mapping - ) - - ap1 = AgentInfoProto() - ap1.observations.extend([proto_obs_1]) - ap2 = AgentInfoProto() - ap2.observations.extend([proto_obs_2]) - ap_list = [ap1, ap2] - obs_spec = create_observation_specs_with_shapes([shape])[0] - arr = _process_maybe_compressed_observation(0, obs_spec, ap_list) - assert list(arr.shape) == [2, 128, 64, 3] - assert np.allclose(arr[0, :, :, :], in_array_1, atol=0.01) - assert np.allclose(arr[1, :, :, :], in_array_2, atol=0.01) - - -def test_process_visual_observation_grayscale(): - in_array_1 = np.random.rand(128, 64, 3) - proto_obs_1 = generate_compressed_proto_obs(in_array_1, grayscale=True) - expected_out_array_1 = np.mean(in_array_1, axis=2, keepdims=True) - in_array_2 = np.random.rand(128, 64, 3) - in_array_2_mapping = [0, 0, 0] - proto_obs_2 = generate_compressed_proto_obs_with_mapping( - in_array_2, in_array_2_mapping - ) - expected_out_array_2 = np.mean(in_array_2, axis=2, keepdims=True) - - ap1 = AgentInfoProto() - ap1.observations.extend([proto_obs_1]) - ap2 = AgentInfoProto() - ap2.observations.extend([proto_obs_2]) - ap_list = [ap1, ap2] - shape = (128, 64, 1) - obs_spec = create_observation_specs_with_shapes([shape])[0] - arr = _process_maybe_compressed_observation(0, obs_spec, ap_list) - assert list(arr.shape) == [2, 128, 64, 1] - assert np.allclose(arr[0, :, :, :], expected_out_array_1, atol=0.01) - assert np.allclose(arr[1, :, :, :], expected_out_array_2, atol=0.01) - - -def test_process_visual_observation_padded_channels(): - in_array_1 = np.random.rand(128, 64, 12) - in_array_1_mapping = [0, 1, 2, 3, -1, -1, 4, 5, 6, 7, -1, -1] - proto_obs_1 = generate_compressed_proto_obs_with_mapping( - in_array_1, in_array_1_mapping - ) - expected_out_array_1 = np.take(in_array_1, [0, 1, 2, 3, 6, 7, 8, 9], axis=2) - - ap1 = AgentInfoProto() - ap1.observations.extend([proto_obs_1]) - ap_list = [ap1] - shape = (128, 64, 8) - obs_spec = create_observation_specs_with_shapes([shape])[0] - - arr = _process_maybe_compressed_observation(0, obs_spec, ap_list) - assert list(arr.shape) == [1, 128, 64, 8] - assert np.allclose(arr[0, :, :, :], expected_out_array_1, atol=0.01) - - -def test_process_visual_observation_bad_shape(): - in_array_1 = np.random.rand(128, 64, 3) - proto_obs_1 = generate_compressed_proto_obs(in_array_1) - ap1 = AgentInfoProto() - ap1.observations.extend([proto_obs_1]) - ap_list = [ap1] - - shape = (128, 42, 3) - obs_spec = create_observation_specs_with_shapes([shape])[0] - - with pytest.raises(UnityObservationException): - _process_maybe_compressed_observation(0, obs_spec, ap_list) - - -def test_batched_step_result_from_proto(): - n_agents = 10 - shapes = [(3,), (4,)] - spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), ActionSpec.create_continuous(3) - ) - ap_list = generate_list_agent_proto(n_agents, shapes) - decision_steps, terminal_steps = steps_from_proto(ap_list, spec) - for agent_id in range(n_agents): - if agent_id in decision_steps: - # we set the reward equal to the agent id in generate_list_agent_proto - assert decision_steps[agent_id].reward == agent_id - elif agent_id in terminal_steps: - assert terminal_steps[agent_id].reward == agent_id - else: - raise Exception("Missing agent from the steps") - # We sort the AgentId since they are split between DecisionSteps and TerminalSteps - combined_agent_id = list(decision_steps.agent_id) + list(terminal_steps.agent_id) - combined_agent_id.sort() - assert combined_agent_id == list(range(n_agents)) - for agent_id in range(n_agents): - assert (agent_id in terminal_steps) == (agent_id % 2 == 0) - if agent_id in terminal_steps: - assert terminal_steps[agent_id].interrupted == (agent_id % 4 == 0) - assert decision_steps.obs[0].shape[1] == shapes[0][0] - assert decision_steps.obs[1].shape[1] == shapes[1][0] - assert terminal_steps.obs[0].shape[1] == shapes[0][0] - assert terminal_steps.obs[1].shape[1] == shapes[1][0] - - -def test_mismatch_observations_raise_in_step_result_from_proto(): - n_agents = 10 - shapes = [(3,), (4,)] - spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), ActionSpec.create_continuous(3) - ) - ap_list = generate_list_agent_proto(n_agents, shapes) - # Hack an observation to be larger, we should get an exception - ap_list[0].observations[0].shape[0] += 1 - ap_list[0].observations[0].float_data.data.append(0.42) - with pytest.raises(UnityObservationException): - steps_from_proto(ap_list, spec) - - -def test_action_masking_discrete(): - n_agents = 10 - shapes = [(3,), (4,)] - behavior_spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), ActionSpec.create_discrete((7, 3)) - ) - ap_list = generate_list_agent_proto(n_agents, shapes) - decision_steps, terminal_steps = steps_from_proto(ap_list, behavior_spec) - masks = decision_steps.action_mask - assert isinstance(masks, list) - assert len(masks) == 2 - assert masks[0].shape == (n_agents / 2, 7) # half agents are done - assert masks[1].shape == (n_agents / 2, 3) # half agents are done - assert masks[0][0, 0] - assert not masks[1][0, 0] - assert masks[1][0, 1] - - -def test_action_masking_discrete_1(): - n_agents = 10 - shapes = [(3,), (4,)] - behavior_spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), ActionSpec.create_discrete((10,)) - ) - ap_list = generate_list_agent_proto(n_agents, shapes) - decision_steps, terminal_steps = steps_from_proto(ap_list, behavior_spec) - masks = decision_steps.action_mask - assert isinstance(masks, list) - assert len(masks) == 1 - assert masks[0].shape == (n_agents / 2, 10) - assert masks[0][0, 0] - - -def test_action_masking_discrete_2(): - n_agents = 10 - shapes = [(3,), (4,)] - behavior_spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), - ActionSpec.create_discrete((2, 2, 6)), - ) - ap_list = generate_list_agent_proto(n_agents, shapes) - decision_steps, terminal_steps = steps_from_proto(ap_list, behavior_spec) - masks = decision_steps.action_mask - assert isinstance(masks, list) - assert len(masks) == 3 - assert masks[0].shape == (n_agents / 2, 2) - assert masks[1].shape == (n_agents / 2, 2) - assert masks[2].shape == (n_agents / 2, 6) - assert masks[0][0, 0] - - -def test_action_masking_continuous(): - n_agents = 10 - shapes = [(3,), (4,)] - behavior_spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), ActionSpec.create_continuous(10) - ) - ap_list = generate_list_agent_proto(n_agents, shapes) - decision_steps, terminal_steps = steps_from_proto(ap_list, behavior_spec) - masks = decision_steps.action_mask - assert masks is None - - -def test_agent_behavior_spec_from_proto(): - agent_proto = generate_list_agent_proto(1, [(3,), (4,)])[0] - bp = BrainParametersProto() - bp.vector_action_size_deprecated.extend([5, 4]) - bp.vector_action_space_type_deprecated = 0 - behavior_spec = behavior_spec_from_proto(bp, agent_proto) - assert behavior_spec.action_spec.is_discrete() - assert not behavior_spec.action_spec.is_continuous() - assert [spec.shape for spec in behavior_spec.observation_specs] == [(3,), (4,)] - assert behavior_spec.action_spec.discrete_branches == (5, 4) - assert behavior_spec.action_spec.discrete_size == 2 - bp = BrainParametersProto() - bp.vector_action_size_deprecated.extend([6]) - bp.vector_action_space_type_deprecated = 1 - behavior_spec = behavior_spec_from_proto(bp, agent_proto) - assert not behavior_spec.action_spec.is_discrete() - assert behavior_spec.action_spec.is_continuous() - assert behavior_spec.action_spec.continuous_size == 6 - - -def test_batched_step_result_from_proto_raises_on_infinite(): - n_agents = 10 - shapes = [(3,), (4,)] - behavior_spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), ActionSpec.create_continuous(3) - ) - ap_list = generate_list_agent_proto(n_agents, shapes, infinite_rewards=True) - with pytest.raises(RuntimeError): - steps_from_proto(ap_list, behavior_spec) - - -def test_batched_step_result_from_proto_raises_on_nan(): - n_agents = 10 - shapes = [(3,), (4,)] - behavior_spec = BehaviorSpec( - create_observation_specs_with_shapes(shapes), ActionSpec.create_continuous(3) - ) - ap_list = generate_list_agent_proto(n_agents, shapes, nan_observations=True) - with pytest.raises(RuntimeError): - steps_from_proto(ap_list, behavior_spec) diff --git a/3DOrangeTree/mlagents_envs/tests/test_set_action.py b/3DOrangeTree/mlagents_envs/tests/test_set_action.py deleted file mode 100644 index 227e074..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_set_action.py +++ /dev/null @@ -1,55 +0,0 @@ -from mlagents_envs.registry import default_registry -from mlagents_envs.side_channel.engine_configuration_channel import ( - EngineConfigurationChannel, -) -from mlagents_envs.base_env import ActionTuple -import numpy as np - -BALL_ID = "3DBall" - - -def test_set_action_single_agent(): - engine_config_channel = EngineConfigurationChannel() - env = default_registry[BALL_ID].make( - base_port=6000, - worker_id=0, - no_graphics=True, - side_channels=[engine_config_channel], - ) - engine_config_channel.set_configuration_parameters(time_scale=100) - for _ in range(3): - env.reset() - behavior_name = list(env.behavior_specs.keys())[0] - d, t = env.get_steps(behavior_name) - for _ in range(50): - for agent_id in d.agent_id: - action = np.ones((1, 2)) - action_tuple = ActionTuple() - action_tuple.add_continuous(action) - env.set_action_for_agent(behavior_name, agent_id, action_tuple) - env.step() - d, t = env.get_steps(behavior_name) - env.close() - - -def test_set_action_multi_agent(): - engine_config_channel = EngineConfigurationChannel() - env = default_registry[BALL_ID].make( - base_port=6001, - worker_id=0, - no_graphics=True, - side_channels=[engine_config_channel], - ) - engine_config_channel.set_configuration_parameters(time_scale=100) - for _ in range(3): - env.reset() - behavior_name = list(env.behavior_specs.keys())[0] - d, t = env.get_steps(behavior_name) - for _ in range(50): - action = np.ones((len(d), 2)) - action_tuple = ActionTuple() - action_tuple.add_continuous(action) - env.set_actions(behavior_name, action_tuple) - env.step() - d, t = env.get_steps(behavior_name) - env.close() diff --git a/3DOrangeTree/mlagents_envs/tests/test_side_channel.py b/3DOrangeTree/mlagents_envs/tests/test_side_channel.py deleted file mode 100644 index f9b1447..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_side_channel.py +++ /dev/null @@ -1,258 +0,0 @@ -import uuid -import pytest -from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage -from mlagents_envs.side_channel.side_channel_manager import SideChannelManager -from mlagents_envs.side_channel.float_properties_channel import FloatPropertiesChannel -from mlagents_envs.side_channel.raw_bytes_channel import RawBytesChannel -from mlagents_envs.side_channel.engine_configuration_channel import ( - EngineConfigurationChannel, - EngineConfig, -) -from mlagents_envs.side_channel.environment_parameters_channel import ( - EnvironmentParametersChannel, -) -from mlagents_envs.side_channel.stats_side_channel import ( - StatsSideChannel, - StatsAggregationMethod, -) -from mlagents_envs.exception import ( - UnitySideChannelException, - UnityCommunicationException, -) - - -class IntChannel(SideChannel): - def __init__(self): - self.list_int = [] - super().__init__(uuid.UUID("a85ba5c0-4f87-11ea-a517-784f4387d1f7")) - - def on_message_received(self, msg: IncomingMessage) -> None: - val = msg.read_int32() - self.list_int += [val] - - def send_int(self, value): - msg = OutgoingMessage() - msg.write_int32(value) - super().queue_message_to_send(msg) - - -def test_int_channel(): - sender = IntChannel() - receiver = IntChannel() - sender.send_int(5) - sender.send_int(6) - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - assert receiver.list_int[0] == 5 - assert receiver.list_int[1] == 6 - - -def test_float_properties(): - sender = FloatPropertiesChannel() - receiver = FloatPropertiesChannel() - - sender.set_property("prop1", 1.0) - - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - - val = receiver.get_property("prop1") - assert val == 1.0 - val = receiver.get_property("prop2") - assert val is None - sender.set_property("prop2", 2.0) - - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - - val = receiver.get_property("prop1") - assert val == 1.0 - val = receiver.get_property("prop2") - assert val == 2.0 - assert len(receiver.list_properties()) == 2 - assert "prop1" in receiver.list_properties() - assert "prop2" in receiver.list_properties() - val = sender.get_property("prop1") - assert val == 1.0 - - assert receiver.get_property_dict_copy() == {"prop1": 1.0, "prop2": 2.0} - assert receiver.get_property_dict_copy() == sender.get_property_dict_copy() - - -def test_raw_bytes(): - guid = uuid.uuid4() - sender = RawBytesChannel(guid) - receiver = RawBytesChannel(guid) - - sender.send_raw_data(b"foo") - sender.send_raw_data(b"bar") - - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - - messages = receiver.get_and_clear_received_messages() - assert len(messages) == 2 - assert messages[0].decode("ascii") == "foo" - assert messages[1].decode("ascii") == "bar" - - messages = receiver.get_and_clear_received_messages() - assert len(messages) == 0 - - -def test_message_bool(): - vals = [True, False] - msg_out = OutgoingMessage() - for v in vals: - msg_out.write_bool(v) - - msg_in = IncomingMessage(msg_out.buffer) - read_vals = [] - for _ in range(len(vals)): - read_vals.append(msg_in.read_bool()) - assert vals == read_vals - - # Test reading with defaults - assert msg_in.read_bool() is False - assert msg_in.read_bool(default_value=True) is True - - -def test_message_int32(): - val = 1337 - msg_out = OutgoingMessage() - msg_out.write_int32(val) - - msg_in = IncomingMessage(msg_out.buffer) - read_val = msg_in.read_int32() - assert val == read_val - - # Test reading with defaults - assert 0 == msg_in.read_int32() - assert val == msg_in.read_int32(default_value=val) - - -def test_message_float32(): - val = 42.0 - msg_out = OutgoingMessage() - msg_out.write_float32(val) - - msg_in = IncomingMessage(msg_out.buffer) - read_val = msg_in.read_float32() - # These won't be exactly equal in general, since python floats are 64-bit. - assert val == read_val - - # Test reading with defaults - assert 0.0 == msg_in.read_float32() - assert val == msg_in.read_float32(default_value=val) - - -def test_message_string(): - val = "mlagents!" - msg_out = OutgoingMessage() - msg_out.write_string(val) - - msg_in = IncomingMessage(msg_out.buffer) - read_val = msg_in.read_string() - assert val == read_val - - # Test reading with defaults - assert "" == msg_in.read_string() - assert val == msg_in.read_string(default_value=val) - - -def test_message_float_list(): - val = [1.0, 3.0, 9.0] - msg_out = OutgoingMessage() - msg_out.write_float32_list(val) - - msg_in = IncomingMessage(msg_out.buffer) - read_val = msg_in.read_float32_list() - # These won't be exactly equal in general, since python floats are 64-bit. - assert val == read_val - - # Test reading with defaults - assert [] == msg_in.read_float32_list() - assert val == msg_in.read_float32_list(default_value=val) - - -def test_engine_configuration(): - sender = EngineConfigurationChannel() - # We use a raw bytes channel to interpred the data - receiver = RawBytesChannel(sender.channel_id) - - config = EngineConfig.default_config() - sender.set_configuration(config) - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - - received_data = receiver.get_and_clear_received_messages() - assert len(received_data) == 5 # 5 different messages one for each setting - - sent_time_scale = 4.5 - sender.set_configuration_parameters(time_scale=sent_time_scale) - - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - - message = IncomingMessage(receiver.get_and_clear_received_messages()[0]) - message.read_int32() - time_scale = message.read_float32() - assert time_scale == sent_time_scale - - with pytest.raises(UnitySideChannelException): - sender.set_configuration_parameters(width=None, height=42) - - with pytest.raises(UnityCommunicationException): - # try to send data to the EngineConfigurationChannel - sender.set_configuration_parameters(time_scale=sent_time_scale) - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([sender]).process_side_channel_message(data) - - -def test_environment_parameters(): - sender = EnvironmentParametersChannel() - # We use a raw bytes channel to interpred the data - receiver = RawBytesChannel(sender.channel_id) - - sender.set_float_parameter("param-1", 0.1) - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - - message = IncomingMessage(receiver.get_and_clear_received_messages()[0]) - key = message.read_string() - dtype = message.read_int32() - value = message.read_float32() - assert key == "param-1" - assert dtype == EnvironmentParametersChannel.EnvironmentDataTypes.FLOAT - assert value - 0.1 < 1e-8 - - sender.set_float_parameter("param-1", 0.1) - sender.set_float_parameter("param-2", 0.1) - sender.set_float_parameter("param-3", 0.1) - - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([receiver]).process_side_channel_message(data) - - assert len(receiver.get_and_clear_received_messages()) == 3 - - with pytest.raises(UnityCommunicationException): - # try to send data to the EngineConfigurationChannel - sender.set_float_parameter("param-1", 0.1) - data = SideChannelManager([sender]).generate_side_channel_messages() - SideChannelManager([sender]).process_side_channel_message(data) - - -def test_stats_channel(): - receiver = StatsSideChannel() - message = OutgoingMessage() - message.write_string("stats-1") - message.write_float32(42.0) - message.write_int32(1) # corresponds to StatsAggregationMethod.MOST_RECENT - - receiver.on_message_received(IncomingMessage(message.buffer)) - - stats = receiver.get_and_reset_stats() - - assert len(stats) == 1 - val, method = stats["stats-1"][0] - assert val - 42.0 < 1e-8 - assert method == StatsAggregationMethod.MOST_RECENT diff --git a/3DOrangeTree/mlagents_envs/tests/test_steps.py b/3DOrangeTree/mlagents_envs/tests/test_steps.py deleted file mode 100644 index 0160380..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_steps.py +++ /dev/null @@ -1,136 +0,0 @@ -import pytest -import numpy as np - -from mlagents_envs.base_env import ( - DecisionSteps, - TerminalSteps, - ActionSpec, - BehaviorSpec, -) -from mlagents.trainers.tests.dummy_config import create_observation_specs_with_shapes - - -def test_decision_steps(): - ds = DecisionSteps( - obs=[np.array(range(12), dtype=np.float32).reshape(3, 4)], - reward=np.array(range(3), dtype=np.float32), - agent_id=np.array(range(10, 13), dtype=np.int32), - action_mask=[np.zeros((3, 4), dtype=np.bool)], - group_id=np.array(range(3), dtype=np.int32), - group_reward=np.array(range(3), dtype=np.float32), - ) - - assert ds.agent_id_to_index[10] == 0 - assert ds.agent_id_to_index[11] == 1 - assert ds.agent_id_to_index[12] == 2 - - with pytest.raises(KeyError): - assert ds.agent_id_to_index[-1] == -1 - - mask_agent = ds[10].action_mask - assert isinstance(mask_agent, list) - assert len(mask_agent) == 1 - assert np.array_equal(mask_agent[0], np.zeros((4), dtype=np.bool)) - - for agent_id in ds: - assert ds.agent_id_to_index[agent_id] in range(3) - - -def test_empty_decision_steps(): - specs = BehaviorSpec( - observation_specs=create_observation_specs_with_shapes([(3, 2), (5,)]), - action_spec=ActionSpec.create_continuous(3), - ) - ds = DecisionSteps.empty(specs) - assert len(ds.obs) == 2 - assert ds.obs[0].shape == (0, 3, 2) - assert ds.obs[1].shape == (0, 5) - - -def test_terminal_steps(): - ts = TerminalSteps( - obs=[np.array(range(12), dtype=np.float32).reshape(3, 4)], - reward=np.array(range(3), dtype=np.float32), - agent_id=np.array(range(10, 13), dtype=np.int32), - interrupted=np.array([1, 0, 1], dtype=np.bool), - group_id=np.array(range(3), dtype=np.int32), - group_reward=np.array(range(3), dtype=np.float32), - ) - - assert ts.agent_id_to_index[10] == 0 - assert ts.agent_id_to_index[11] == 1 - assert ts.agent_id_to_index[12] == 2 - - assert ts[10].interrupted - assert not ts[11].interrupted - assert ts[12].interrupted - - with pytest.raises(KeyError): - assert ts.agent_id_to_index[-1] == -1 - - for agent_id in ts: - assert ts.agent_id_to_index[agent_id] in range(3) - - -def test_empty_terminal_steps(): - specs = BehaviorSpec( - observation_specs=create_observation_specs_with_shapes([(3, 2), (5,)]), - action_spec=ActionSpec.create_continuous(3), - ) - ts = TerminalSteps.empty(specs) - assert len(ts.obs) == 2 - assert ts.obs[0].shape == (0, 3, 2) - assert ts.obs[1].shape == (0, 5) - - -def test_specs(): - specs = ActionSpec.create_continuous(3) - assert specs.discrete_branches == () - assert specs.discrete_size == 0 - assert specs.continuous_size == 3 - assert specs.empty_action(5).continuous.shape == (5, 3) - assert specs.empty_action(5).continuous.dtype == np.float32 - - specs = ActionSpec.create_discrete((3,)) - assert specs.discrete_branches == (3,) - assert specs.discrete_size == 1 - assert specs.continuous_size == 0 - assert specs.empty_action(5).discrete.shape == (5, 1) - assert specs.empty_action(5).discrete.dtype == np.int32 - - specs = ActionSpec(3, (3,)) - assert specs.continuous_size == 3 - assert specs.discrete_branches == (3,) - assert specs.discrete_size == 1 - assert specs.empty_action(5).continuous.shape == (5, 3) - assert specs.empty_action(5).continuous.dtype == np.float32 - assert specs.empty_action(5).discrete.shape == (5, 1) - assert specs.empty_action(5).discrete.dtype == np.int32 - - -def test_action_generator(): - # Continuous - action_len = 30 - specs = ActionSpec.create_continuous(action_len) - zero_action = specs.empty_action(4).continuous - assert np.array_equal(zero_action, np.zeros((4, action_len), dtype=np.float32)) - print(specs.random_action(4)) - random_action = specs.random_action(4).continuous - print(random_action) - assert random_action.dtype == np.float32 - assert random_action.shape == (4, action_len) - assert np.min(random_action) >= -1 - assert np.max(random_action) <= 1 - - # Discrete - action_shape = (10, 20, 30) - specs = ActionSpec.create_discrete(action_shape) - zero_action = specs.empty_action(4).discrete - assert np.array_equal(zero_action, np.zeros((4, len(action_shape)), dtype=np.int32)) - - random_action = specs.random_action(4).discrete - assert random_action.dtype == np.int32 - assert random_action.shape == (4, len(action_shape)) - assert np.min(random_action) >= 0 - for index, branch_size in enumerate(action_shape): - assert np.max(random_action[:, index]) < branch_size diff --git a/3DOrangeTree/mlagents_envs/tests/test_timers.py b/3DOrangeTree/mlagents_envs/tests/test_timers.py deleted file mode 100644 index 38de561..0000000 --- a/3DOrangeTree/mlagents_envs/tests/test_timers.py +++ /dev/null @@ -1,92 +0,0 @@ -from unittest import mock - -from mlagents_envs import timers - - -@timers.timed -def decorated_func(x: int = 0, y: float = 1.0) -> str: - timers.set_gauge("my_gauge", x + y) - return f"{x} + {y} = {x + y}" - - -def test_timers() -> None: - test_timer = timers.TimerStack() - with mock.patch("mlagents_envs.timers._get_thread_timer", return_value=test_timer): - # First, run some simple code - with timers.hierarchical_timer("top_level"): - for i in range(3): - with timers.hierarchical_timer("multiple"): - decorated_func(i, i) - - raised = False - try: - with timers.hierarchical_timer("raises"): - raise RuntimeError("timeout!") - except RuntimeError: - raised = True - - with timers.hierarchical_timer("post_raise"): - assert raised - pass - - # We expect the hierarchy to look like - # (root) - # top_level - # multiple - # decorated_func - # raises - # post_raise - root = test_timer.root - assert root.children.keys() == {"top_level"} - - top_level = root.children["top_level"] - assert top_level.children.keys() == {"multiple", "raises", "post_raise"} - - # make sure the scope was closed properly when the exception was raised - raises = top_level.children["raises"] - assert raises.count == 1 - - multiple = top_level.children["multiple"] - assert multiple.count == 3 - - timer_tree = test_timer.get_timing_tree() - - expected_tree = { - "name": "root", - "total": mock.ANY, - "count": 1, - "self": mock.ANY, - "children": { - "top_level": { - "total": mock.ANY, - "count": 1, - "self": mock.ANY, - "children": { - "multiple": { - "total": mock.ANY, - "count": 3, - "self": mock.ANY, - "children": { - "decorated_func": { - "total": mock.ANY, - "count": 3, - "self": mock.ANY, - } - }, - }, - "raises": {"total": mock.ANY, "count": 1, "self": mock.ANY}, - "post_raise": {"total": mock.ANY, "count": 1, "self": mock.ANY}, - }, - } - }, - "gauges": {"my_gauge": {"value": 4.0, "max": 4.0, "min": 0.0, "count": 3}}, - "metadata": { - "timer_format_version": timers.TIMER_FORMAT_VERSION, - "start_time_seconds": mock.ANY, - "end_time_seconds": mock.ANY, - "python_version": mock.ANY, - "command_line_arguments": mock.ANY, - }, - } - - assert timer_tree == expected_tree diff --git a/3DOrangeTree/mlagents_envs/timers.py b/3DOrangeTree/mlagents_envs/timers.py deleted file mode 100644 index 32b8602..0000000 --- a/3DOrangeTree/mlagents_envs/timers.py +++ /dev/null @@ -1,362 +0,0 @@ -""" -Lightweight, hierarchical timers for profiling sections of code. - -Example: - -@timed -def foo(t): - time.sleep(t) - -def main(): - for i in range(3): - foo(i + 1) - with hierarchical_timer("context"): - foo(1) - - print(get_timer_tree()) - -This would produce a timer tree like - (root) - "foo" - "context" - "foo" - -The total time and counts are tracked for each block of code; in this example "foo" and "context.foo" are considered -distinct blocks, and are tracked separately. - -The decorator and contextmanager are equivalent; the context manager may be more useful if you want more control -over the timer name, or are splitting up multiple sections of a large function. -""" - -import math -import sys -import time -import threading - -from contextlib import contextmanager -from typing import Any, Callable, Dict, Generator, Optional, TypeVar - -TIMER_FORMAT_VERSION = "0.1.0" - - -class TimerNode: - """ - Represents the time spent in a block of code. - """ - - __slots__ = ["children", "total", "count", "is_parallel"] - - def __init__(self): - # Note that since dictionary keys are the node names, we don't explicitly store the name on the TimerNode. - self.children: Dict[str, TimerNode] = {} - self.total: float = 0.0 - self.count: int = 0 - self.is_parallel = False - - def get_child(self, name: str) -> "TimerNode": - """ - Get the child node corresponding to the name (and create if it doesn't already exist). - """ - child = self.children.get(name) - if child is None: - child = TimerNode() - self.children[name] = child - return child - - def add_time(self, elapsed: float) -> None: - """ - Accumulate the time spent in the node (and increment the count). - """ - self.total += elapsed - self.count += 1 - - def merge( - self, other: "TimerNode", root_name: str = None, is_parallel: bool = True - ) -> None: - """ - Add the other node to this node, then do the same recursively on its children. - :param other: The other node to merge - :param root_name: Optional name of the root node being merged. - :param is_parallel: Whether or not the code block was executed in parallel. - :return: - """ - if root_name: - node = self.get_child(root_name) - else: - node = self - - node.total += other.total - node.count += other.count - node.is_parallel |= is_parallel - for other_child_name, other_child_node in other.children.items(): - child = node.get_child(other_child_name) - child.merge(other_child_node, is_parallel=is_parallel) - - -class GaugeNode: - """ - Tracks the most recent value of a metric. This is analogous to gauges in statsd. - """ - - __slots__ = ["value", "min_value", "max_value", "count", "_timestamp"] - - def __init__(self, value: float): - self.value = value - self.min_value = value - self.max_value = value - self.count = 1 - # Internal timestamp so we can determine priority. - self._timestamp = time.time() - - def update(self, new_value: float) -> None: - self.min_value = min(self.min_value, new_value) - self.max_value = max(self.max_value, new_value) - self.value = new_value - self.count += 1 - self._timestamp = time.time() - - def merge(self, other: "GaugeNode") -> None: - if self._timestamp < other._timestamp: - # Keep the "later" value - self.value = other.value - self._timestamp = other._timestamp - self.min_value = min(self.min_value, other.min_value) - self.max_value = max(self.max_value, other.max_value) - self.count += other.count - - def as_dict(self) -> Dict[str, float]: - return { - "value": self.value, - "min": self.min_value, - "max": self.max_value, - "count": self.count, - } - - -class TimerStack: - """ - Tracks all the time spent. Users shouldn't use this directly, they should use the contextmanager below to make - sure that pushes and pops are already matched. - """ - - __slots__ = ["root", "stack", "start_time", "gauges", "metadata"] - - def __init__(self): - self.root = TimerNode() - self.stack = [self.root] - self.start_time = time.perf_counter() - self.gauges: Dict[str, GaugeNode] = {} - self.metadata: Dict[str, str] = {} - self._add_default_metadata() - - def reset(self): - self.root = TimerNode() - self.stack = [self.root] - self.start_time = time.perf_counter() - self.gauges: Dict[str, GaugeNode] = {} - self.metadata: Dict[str, str] = {} - self._add_default_metadata() - - def push(self, name: str) -> TimerNode: - """ - Called when entering a new block of code that is timed (e.g. with a contextmanager). - """ - current_node: TimerNode = self.stack[-1] - next_node = current_node.get_child(name) - self.stack.append(next_node) - return next_node - - def pop(self) -> None: - """ - Called when exiting a new block of code that is timed (e.g. with a contextmanager). - """ - self.stack.pop() - - def get_root(self) -> TimerNode: - """ - Update the total time and count of the root name, and return it. - """ - root = self.root - root.total = time.perf_counter() - self.start_time - root.count = 1 - return root - - def get_timing_tree(self, node: TimerNode = None) -> Dict[str, Any]: - """ - Recursively build a tree of timings, suitable for output/archiving. - """ - res: Dict[str, Any] = {} - if node is None: - # Special case the root - total is time since it was created, and count is 1 - node = self.get_root() - res["name"] = "root" - - # Only output gauges at top level - if self.gauges: - res["gauges"] = self._get_gauges() - - if self.metadata: - self.metadata["end_time_seconds"] = str(int(time.time())) - res["metadata"] = self.metadata - - res["total"] = node.total - res["count"] = node.count - - if node.is_parallel: - # Note when the block ran in parallel, so that it's less confusing that a timer is less that its children. - res["is_parallel"] = True - - child_total = 0.0 - child_dict = {} - for child_name, child_node in node.children.items(): - child_res: Dict[str, Any] = self.get_timing_tree(child_node) - child_dict[child_name] = child_res - child_total += child_res["total"] - - # "self" time is total time minus all time spent on children - res["self"] = max(0.0, node.total - child_total) - if child_dict: - res["children"] = child_dict - - return res - - def set_gauge(self, name: str, value: float) -> None: - if math.isnan(value): - return - gauge_node = self.gauges.get(name) - if gauge_node: - gauge_node.update(value) - else: - self.gauges[name] = GaugeNode(value) - - def add_metadata(self, key: str, value: str) -> None: - self.metadata[key] = value - - def _get_gauges(self) -> Dict[str, Dict[str, float]]: - gauges = {} - for gauge_name, gauge_node in self.gauges.items(): - gauges[gauge_name] = gauge_node.as_dict() - return gauges - - def _add_default_metadata(self): - self.metadata["timer_format_version"] = TIMER_FORMAT_VERSION - self.metadata["start_time_seconds"] = str(int(time.time())) - self.metadata["python_version"] = sys.version - self.metadata["command_line_arguments"] = " ".join(sys.argv) - - -# Maintain a separate "global" timer per thread, so that they don't accidentally conflict with each other. -_thread_timer_stacks: Dict[int, TimerStack] = {} - - -def _get_thread_timer() -> TimerStack: - ident = threading.get_ident() - if ident not in _thread_timer_stacks: - timer_stack = TimerStack() - _thread_timer_stacks[ident] = timer_stack - return _thread_timer_stacks[ident] - - -def get_timer_stack_for_thread(t: threading.Thread) -> Optional[TimerStack]: - if t.ident is None: - # Thread hasn't started, shouldn't ever happen - return None - return _thread_timer_stacks.get(t.ident) - - -@contextmanager -def hierarchical_timer(name: str, timer_stack: TimerStack = None) -> Generator: - """ - Creates a scoped timer around a block of code. This time spent will automatically be incremented when - the context manager exits. - """ - timer_stack = timer_stack or _get_thread_timer() - timer_node = timer_stack.push(name) - start_time = time.perf_counter() - - try: - # The wrapped code block will run here. - yield timer_node - finally: - # This will trigger either when the context manager exits, or an exception is raised. - # We'll accumulate the time, and the exception (if any) gets raised automatically. - elapsed = time.perf_counter() - start_time - timer_node.add_time(elapsed) - timer_stack.pop() - - -# This is used to ensure the signature of the decorated function is preserved -# See also https://github.com/python/mypy/issues/3157 -FuncT = TypeVar("FuncT", bound=Callable[..., Any]) - - -def timed(func: FuncT) -> FuncT: - """ - Decorator for timing a function or method. The name of the timer will be the qualified name of the function. - Usage: - @timed - def my_func(x, y): - return x + y - Note that because this doesn't take arguments, the global timer stack is always used. - """ - - def wrapped(*args, **kwargs): - with hierarchical_timer(func.__qualname__): - return func(*args, **kwargs) - - return wrapped # type: ignore - - -def set_gauge(name: str, value: float, timer_stack: TimerStack = None) -> None: - """ - Updates the value of the gauge (or creates it if it hasn't been set before). - """ - timer_stack = timer_stack or _get_thread_timer() - timer_stack.set_gauge(name, value) - - -def merge_gauges(gauges: Dict[str, GaugeNode], timer_stack: TimerStack = None) -> None: - """ - Merge the gauges from another TimerStack with the provided one (or the - current thread's stack if none is provided). - :param gauges: - :param timer_stack: - :return: - """ - timer_stack = timer_stack or _get_thread_timer() - for n, g in gauges.items(): - if n in timer_stack.gauges: - timer_stack.gauges[n].merge(g) - else: - timer_stack.gauges[n] = g - - -def add_metadata(key: str, value: str, timer_stack: TimerStack = None) -> None: - timer_stack = timer_stack or _get_thread_timer() - timer_stack.add_metadata(key, value) - - -def get_timer_tree(timer_stack: TimerStack = None) -> Dict[str, Any]: - """ - Return the tree of timings from the TimerStack as a dictionary (or the - current thread's stack if none is provided) - """ - timer_stack = timer_stack or _get_thread_timer() - return timer_stack.get_timing_tree() - - -def get_timer_root(timer_stack: TimerStack = None) -> TimerNode: - """ - Get the root TimerNode of the timer_stack (or the current thread's - TimerStack if not specified) - """ - timer_stack = timer_stack or _get_thread_timer() - return timer_stack.get_root() - - -def reset_timers(timer_stack: TimerStack = None) -> None: - """ - Reset the timer_stack (or the current thread's TimerStack if not specified) - """ - timer_stack = timer_stack or _get_thread_timer() - timer_stack.reset() diff --git a/3DOrangeTree/moduleConspec.py b/3DOrangeTree/moduleConspec.py deleted file mode 100644 index bc2491e..0000000 --- a/3DOrangeTree/moduleConspec.py +++ /dev/null @@ -1,81 +0,0 @@ -from misc_util import orthogonal_init, xavier_uniform_init -import torch.nn as nn -import torch -import torch.nn.functional as F -import math -import numpy as np -import matplotlib.pyplot as plt -from a2c_ppo_acktr.utils import init -import traceback - -np.set_printoptions(threshold=10_000) -torch.set_printoptions(threshold=10_000) - - -class moduleCL(nn.Module): - def __init__(self, - input_size, hidden_size, head, device, args): - super(moduleCL, self).__init__() - self.head = head - self.input_size = input_size - self.hidden_size = hidden_size - self.layers = [None] * head - self.device = device - self.args = args - - - self.main = nn.ModuleList([nn.Sequential( - (nn.Linear(in_features=input_size, out_features=hidden_size, bias=False)), nn.ReLU(), - ) for i in range(head)]) - self.layers = nn.ModuleList([nn.Sequential( - (nn.Linear(in_features=hidden_size, out_features=hidden_size,bias=False)), nn.ReLU(), - ) for i in range(head)]) - - self.layers2 = nn.ParameterList([nn.Parameter( - torch.randn(1, self.hidden_size) * 1.) for i - in range(head)]) - - self.cos = nn.CosineSimilarity(dim=2, eps=1e-6) - - def forward(self, hidden, reward, keyused, obs, time, seed, doimage): - keysUsedOrig = keyused - out1 = [None] * self.head - cossim2 = [None] * self.head - ortho2 = [None] * self.head - minibatchsize = hidden.shape[1] - miniSuccesssize = int(hidden.shape[1] / 2) - - for iii in range(self.head): - out1[iii] = self.layers[iii](self.main[iii](hidden)) - s1, s2, s3 = out1[iii].shape - currentweights = self.layers2[iii].reshape(1, 1, -1).repeat(s1, 1, 1) - cossim2[iii] = self.cos(out1[iii], currentweights) - ortho2[iii] = F.softmax(cossim2[iii].squeeze() * 100., dim=0) - - cossimtotal = torch.stack(cossim2, dim=2) - orthototal = torch.stack(ortho2, dim=2) - cossimtotalmaxxx, indmaxes = ( torch.max(cossimtotal, dim=0)) # 16,3 - cossimtotalmax = cossimtotalmaxxx.squeeze() # minibatch,keys - - # ''' - costFit = ((torch.abs(1 - cossimtotalmax[:miniSuccesssize]).mean(0) + torch.abs( - cossimtotalmax[miniSuccesssize:]).mean(0)).squeeze()) * 1. - if keyused > -0.5: - costFitFinal = costFit[keysUsedOrig] - else: - costFitFinal = costFit.sum() - orthototalperm = orthototal.permute(1, 0, 2) - orthototalperm = F.normalize(orthototalperm, dim=1, p=2) - - - cosnorm = torch.abs(torch.matmul(orthototalperm.permute(0, 2, 1), orthototalperm)) - cosnormdiag = torch.diagonal(cosnorm, dim1=1, dim2=2) - orthogonality = (cosnorm[:, :, :])[:miniSuccesssize] - torch.diag_embed(cosnormdiag[:, :], dim1=1, dim2=2)[ - :miniSuccesssize] - orthogonalitycost = orthogonality.sum() - costfinal = costFitFinal * 1. + (orthogonalitycost * .2 ) /self.head - pos = torch.abs(cossimtotalmax[:miniSuccesssize]).mean(0) - neg = torch.abs(cossimtotalmax[miniSuccesssize:]).mean(0) - - return costfinal, cossimtotal, [pos, neg] - diff --git a/3DOrangeTree/requirements.txt b/3DOrangeTree/requirements.txt deleted file mode 100644 index 13ca8b3..0000000 --- a/3DOrangeTree/requirements.txt +++ /dev/null @@ -1,75 +0,0 @@ -absl-py==1.0.0 -astor==0.8.1 -atari-py==0.1.15 -cached-property==1.5.2 -cachetools==5.0.0 -certifi==2021.10.8 -charset-normalizer==2.0.12 -cloudpickle==1.2.2 -contextlib2==21.6.0 -cycler==0.11.0 -decorator==4.4.2 -dm-sonnet==1.34 -dm-tree==0.1.7 -fonttools==4.33.3 -gast==0.5.3 -google-api-core==2.7.3 -google-api-python-client==2.46.0 -google-auth==2.6.6 -google-auth-httplib2==0.1.0 -googleapis-common-protos==1.56.0 -grpcio==1.44.0 -grpcio-tools==1.44.0 -gym==0.12.6 -gym-notices==0.0.6 -h5py==3.6.0 -httplib2==0.20.4 -idna==3.3 -imageio==2.19.0 -imageio-ffmpeg==0.4.7 -importlib-metadata==4.11.3 -Keras-Applications==1.0.8 -Keras-Preprocessing==1.1.2 -kiwisolver==1.4.2 -kornia==0.6.6 -Markdown==3.3.7 -matplotlib==3.5.1 -mock==4.0.3 -moviepy==1.0.3 -numpy==1.21.6 -opencv-python==4.5.5.64 -packaging==21.3 -pandas==1.3.5 -Pillow==9.1.0 -plotly==5.9.0 -proglog==0.1.9 -protobuf==3.20.1 -psutil==5.9.0 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -pybullet==3.2.4 -pycolab==1.2 -pyglet==1.5.23 -pyparsing==3.0.8 -python-dateutil==2.8.2 -pytz==2022.1 -requests==2.27.1 -rsa==4.8 -scipy==1.7.3 -semantic-version==2.9.0 -six==1.16.0 -stable-baselines3==0.9.0 -tenacity==8.0.1 -tensorboard==1.13.1 -termcolor==1.1.0 -torch==1.10.1+cu111 -torchaudio==0.10.1+rocm4.1 -torchvision==0.11.2+cu111 -tqdm==4.64.0 -trfl==1.2.0 -typing_extensions==4.2.0 -uritemplate==4.1.1 -urllib3==1.26.9 -Werkzeug==2.1.2 -wrapt==1.14.1 -zipp==3.8.0 diff --git a/conspecfunction/Conspec/ConSpec.py b/Conspec/ConSpec.py similarity index 100% rename from conspecfunction/Conspec/ConSpec.py rename to Conspec/ConSpec.py diff --git a/conspecfunction/Conspec/modelConSpec.py b/Conspec/modelConSpec.py similarity index 100% rename from conspecfunction/Conspec/modelConSpec.py rename to Conspec/modelConSpec.py diff --git a/conspecfunction/Conspec/ppoConSpec.py b/Conspec/ppoConSpec.py similarity index 100% rename from conspecfunction/Conspec/ppoConSpec.py rename to Conspec/ppoConSpec.py diff --git a/conspecfunction/Conspec/prototype.py b/Conspec/prototype.py similarity index 100% rename from conspecfunction/Conspec/prototype.py rename to Conspec/prototype.py diff --git a/conspecfunction/Conspec/storageConSpec.py b/Conspec/storageConSpec.py similarity index 100% rename from conspecfunction/Conspec/storageConSpec.py rename to Conspec/storageConSpec.py diff --git a/3DOrangeTree/LICENSE b/LICENSE similarity index 100% rename from 3DOrangeTree/LICENSE rename to LICENSE diff --git a/Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py b/Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py deleted file mode 100644 index 0dfbf18..0000000 --- a/Multikeytodoor/a2c_ppo_acktr/algo/ppoConSpec.py +++ /dev/null @@ -1,208 +0,0 @@ -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim - - -class PPOConSpec(): - def __init__(self, - actor_critic,actor_criticCL, - clip_param, - ppo_epoch, - num_mini_batch, - value_loss_coef, - entropy_coef, - module, - choiceCLparams, - args, - lrCL=None, - lr=None, - eps=None, - max_grad_norm=None, - use_clipped_value_loss=True): - - self.actor_critic = actor_critic - self.actor_criticCL = actor_criticCL - - self.clip_param = clip_param - self.ppo_epoch = ppo_epoch - self.num_mini_batch = num_mini_batch - - self.value_loss_coef = value_loss_coef - self.entropy_coef = entropy_coef - - self.max_grad_norm = max_grad_norm - self.use_clipped_value_loss = use_clipped_value_loss - self.moduleCL = module - self.args = args - self.listparams = list(actor_criticCL.parameters()) + list(self.moduleCL.parameters()) - self.optimizer = optim.Adam(actor_critic.parameters(), lr=lr, eps=eps) - self.optimizerCL = optim.Adam(self.listparams, lr=lrCL, eps=eps) - - def fictitiousReward(self,rollouts,keysUsed,device,iteration): - #################Intrinsic reward - obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = rollouts.feed_attnR() - _, _, _, _, hidden = self.actor_criticCL.evaluate_actionsHiddens( - obs_batch, recurrent_hidden_states_batch, masks_batch, - actions_batch) - hidden = hidden.view(*obs_batchorig.size()[:2],-1) - _, attentionCLattn, _ = self.moduleCL(hidden, reward_batch, -1, obs_batchorig, 111, self.args.seed,0) - - attentionCLattnnp = attentionCLattn.view(*obs_batchorig.size()[:2],-1) # length, minibatch, keyhead - goodz,_ = torch.max(attentionCLattnnp, dim=0) # = minibatch, keyhead - size1, size2, size3 = attentionCLattnnp.size() - greater = (( attentionCLattnnp > 0.6)) * attentionCLattnnp #### - filterCorr = torch.tile(torch.reshape(keysUsed, (1,1, -1)), (size1, size2, 1)) - filterCorr1 = filterCorr * self.args.factorR - sendContrastvalue = (greater * filterCorr1) - #''' - roundhalf = 3 - round = roundhalf - allvalues = [] - for orthoit in range(round * 2 + 1): - temp = torch.roll(sendContrastvalue, orthoit - roundhalf, dims=0) - if orthoit - roundhalf > 0: - temp[:(orthoit - roundhalf)] = 0. - allvalues.append(temp) # 80,16,10 heads - allvalues = torch.stack(allvalues, dim=0) - allvaluesmax,_ = torch.max(allvalues, dim=0) - allvaluesdifference = sendContrastvalue - allvaluesmax - sendContrastvalue[allvaluesdifference < 0.] = 0. - sendContrastvalue[sendContrastvalue < 0.] = 0. - sendContrastvaluesummed = 0. - for orthoit in range(round): - temp = torch.roll(sendContrastvalue, orthoit + 1, dims=0) * (.5 ** (orthoit)) - temp[:orthoit] = 0. - sendContrastvaluesummed += temp - sendContrastvaluesummed = sendContrastvaluesummed - sendContrastvalue = sendContrastvalue - sendContrastvaluesummed - sendContrastvalue[sendContrastvalue < 0.] = 0. - sendContrastvalue = sendContrastvalue.sum(2) - #''' - print('intrinsic R!') - - rollouts.contrastvalueReward(sendContrastvalue) - - def update(self, rollouts, head, keysUsed, goodones,iterate): - """ - Learning RL update and ConsPec - """ - advantages = rollouts.returns[:-1] - rollouts.value_preds[:-1] - advantages = (advantages - advantages.mean()) / ( - advantages.std() + 1e-5) - - value_loss_epoch = 0 - action_loss_epoch = 0 - dist_entropy_epoch = 0 - wwtotalpos = [] - wwtotalneg = [] - attentionCL = [] - costCL = 0 - ################# ConSpec module is learned - if rollouts.stepS > rollouts.success -1: - - ######################## - for iii in range(head): - - #''' - if keysUsed[iii] > 0.5: - obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = rollouts.feed_attnRSFheads(iii) - _, _, _, _, hidden = self.actor_criticCL.evaluate_actionsHiddens( - obs_batch, recurrent_hidden_states_batch, masks_batch, - actions_batch) - hidden = hidden.view(*obs_batchorig.size()[:2], -1) - costCL0, attentionCL0, ww = self.moduleCL(hidden, reward_batch, iii, obs_batchorig, iterate, self.args.seed, 1) - attentionCL.append(attentionCL0[:,:,iii].squeeze().transpose(1,0)) - costCL += costCL0 - wwtotalpos.append(ww[0][iii].detach().cpu()) - wwtotalneg.append(ww[1][iii].detach().cpu()) - else: - obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch = rollouts.feed_attnRSF() - - _, _, _, _, hidden = self.actor_criticCL.evaluate_actionsHiddens( - obs_batch, recurrent_hidden_states_batch, masks_batch, - actions_batch) - hidden = hidden.view(*obs_batchorig.size()[:2], -1) - costCL0, attentionCL0, ww = self.moduleCL(hidden, reward_batch, iii, obs_batchorig, iterate, self.args.seed,0) - cossimtotalmaxxx, _ = (torch.max(attentionCL0, dim=0)) ## not necessary - attentionCL.append(attentionCL0[:,:,iii].squeeze().transpose(1,0)) - costCL += costCL0 - wwtotalpos.append(ww[0][iii].detach().cpu()) - wwtotalneg.append(ww[1][iii].detach().cpu()) - #''' - - for indall in range(head): - if (wwtotalpos[indall] - wwtotalneg[indall] > 0.6) and wwtotalpos[indall] > 0.6: - goodones[indall] += 1 #indall (i) - else: - goodones[indall] = 0 - for iii in range(head): - if goodones[iii] > 25 and keysUsed[iii] < 0.1: ## goodones[prototype] > 25 if the the agent has satsified the criterion of 0.6 more than 25 consequitive times then promote it to be frozen in the success RB - keysUsed[iii] = 1. # specifies that which prototype has satisfied the criterion - rollouts.storeheadsSF(iii) # take a snapshot of trajectories that lead critical prototypes(iii) of sucesses and failures - if self.args.factorR < 0.01: - pass - else: - self.optimizerCL.zero_grad() - costCL.backward() - self.optimizerCL.step() - print('trained!') - - ## RL algorithm is learned (default ppo code) - for e in range(self.ppo_epoch): - if self.actor_critic.is_recurrent: - data_generator = rollouts.recurrent_generator( - advantages, self.num_mini_batch) - else: - data_generator = rollouts.feed_forward_generator( - advantages, self.num_mini_batch) - - for sample in data_generator: - obs_batch, recurrent_hidden_states_batch, actions_batch, \ - value_preds_batch, return_batch, masks_batch, old_action_log_probs_batch, \ - adv_targ = sample - - # Reshape to do in a single forward pass for all steps - values, action_log_probs, dist_entropy, _ = self.actor_critic.evaluate_actions( - obs_batch, recurrent_hidden_states_batch, masks_batch, - actions_batch) - - - ratio = torch.exp(action_log_probs - - old_action_log_probs_batch) - surr1 = ratio * adv_targ - surr2 = torch.clamp(ratio, 1.0 - self.clip_param, - 1.0 + self.clip_param) * adv_targ - action_loss = -torch.min(surr1, surr2).mean() - - if self.use_clipped_value_loss: - value_pred_clipped = value_preds_batch + \ - (values - value_preds_batch).clamp(-self.clip_param, self.clip_param) - value_losses = (values - return_batch).pow(2) - value_losses_clipped = ( - value_pred_clipped - return_batch).pow(2) - value_loss = 0.5 * torch.max(value_losses, - value_losses_clipped).mean() - else: - value_loss = 0.5 * (return_batch - values).pow(2).mean() - #''' - - self.optimizer.zero_grad() - (value_loss * self.value_loss_coef + action_loss - - dist_entropy * self.entropy_coef ).backward() - nn.utils.clip_grad_norm_(self.actor_critic.parameters(), - self.max_grad_norm) - self.optimizer.step() - #''' - - value_loss_epoch += value_loss.item() - action_loss_epoch += action_loss.item() - dist_entropy_epoch += dist_entropy.item() - - num_updates = self.ppo_epoch * self.num_mini_batch - - value_loss_epoch /= num_updates - action_loss_epoch /= num_updates - dist_entropy_epoch /= num_updates - - return value_loss_epoch, action_loss_epoch, dist_entropy_epoch, keysUsed, goodones diff --git a/Multikeytodoor/a2c_ppo_acktr/envs.py b/Multikeytodoor/a2c_ppo_acktr/envs.py deleted file mode 100644 index 32e6ce6..0000000 --- a/Multikeytodoor/a2c_ppo_acktr/envs.py +++ /dev/null @@ -1,258 +0,0 @@ -import os - -import gym -import numpy as np -import torch -from gym.spaces.box import Box -from gym.wrappers.clip_action import ClipAction -from stable_baselines3.common.atari_wrappers import (ClipRewardEnv, - EpisodicLifeEnv, - FireResetEnv, - MaxAndSkipEnv, - NoopResetEnv, WarpFrame) -from stable_baselines3.common.monitor import Monitor -from stable_baselines3.common.vec_env import (DummyVecEnv, SubprocVecEnv, - VecEnvWrapper) -from stable_baselines3.common.vec_env.vec_normalize import \ - VecNormalize as VecNormalize_ -# try: -# import dmc2gym -# except ImportError: -# pass - -# try: -# import roboschool -# except ImportError: -# pass - -# try: -# import pybullet_envs -# except ImportError: -# pass - - -def make_env(env_id, seed, rank, log_dir, allow_early_resets): - def _thunk(): - if env_id.startswith("dm"): - _, domain, task = env_id.split('.') - env = dmc2gym.make(domain_name=domain, task_name=task) - env = ClipAction(env) - else: - env = gym.make(env_id) - - is_atari = hasattr(gym.envs, 'atari') and isinstance( - env.unwrapped, gym.envs.atari.atari_env.AtariEnv) - if is_atari: - env = NoopResetEnv(env, noop_max=30) - env = MaxAndSkipEnv(env, skip=4) - - env.seed(seed + rank) - - if str(env.__class__.__name__).find('TimeLimit') >= 0: - env = TimeLimitMask(env) - - #if log_dir is not None: - env = Monitor(env, - os.path.join(log_dir, str(rank)), - allow_early_resets=allow_early_resets) - - if is_atari: - if len(env.observation_space.shape) == 3: - env = EpisodicLifeEnv(env) - if "FIRE" in env.unwrapped.get_action_meanings(): - env = FireResetEnv(env) - env = WarpFrame(env, width=84, height=84) - env = ClipRewardEnv(env) - elif len(env.observation_space.shape) == 3: - raise NotImplementedError( - "CNN models work only for atari,\n" - "please use a custom wrapper for a custom pixel input env.\n" - "See wrap_deepmind for an example.") - - # If the input has shape (W,H,3), wrap for PyTorch convolutions - obs_shape = env.observation_space.shape - if len(obs_shape) == 3 and obs_shape[2] in [1, 3]: - env = TransposeImage(env, op=[2, 0, 1]) - - return env - - return _thunk - - -def make_vec_envs(env_name, - seed, - num_processes, - gamma, - log_dir, - device, - allow_early_resets, - num_frame_stack=None): - envs = [ - make_env(env_name, seed, i, log_dir, allow_early_resets) - for i in range(num_processes) - ] - - if len(envs) > 1: - envs = SubprocVecEnv(envs) - else: - envs = DummyVecEnv(envs) - - if len(envs.observation_space.shape) == 1: - if gamma is None: - envs = VecNormalize(envs, norm_reward=False) - else: - envs = VecNormalize(envs, gamma=gamma) - - envs = VecPyTorch(envs, device) - - if num_frame_stack is not None: - envs = VecPyTorchFrameStack(envs, num_frame_stack, device) - elif len(envs.observation_space.shape) == 3: - envs = VecPyTorchFrameStack(envs, 4, device) - - return envs - - -# Checks whether done was caused my timit limits or not -class TimeLimitMask(gym.Wrapper): - def step(self, action): - obs, rew, done, info = self.env.step(action) - if done and self.env._max_episode_steps == self.env._elapsed_steps: - info['bad_transition'] = True - - return obs, rew, done, info - - def reset(self, **kwargs): - return self.env.reset(**kwargs) - - -# Can be used to test recurrent policies for Reacher-v2 -class MaskGoal(gym.ObservationWrapper): - def observation(self, observation): - if self.env._elapsed_steps > 0: - observation[-2:] = 0 - return observation - - -class TransposeObs(gym.ObservationWrapper): - def __init__(self, env=None): - """ - Transpose observation space (base class) - """ - super(TransposeObs, self).__init__(env) - - -class TransposeImage(TransposeObs): - def __init__(self, env=None, op=[2, 0, 1]): - """ - Transpose observation space for images - """ - super(TransposeImage, self).__init__(env) - assert len(op) == 3, "Error: Operation, " + str(op) + ", must be dim3" - self.op = op - obs_shape = self.observation_space.shape - self.observation_space = Box( - self.observation_space.low[0, 0, 0], - self.observation_space.high[0, 0, 0], [ - obs_shape[self.op[0]], obs_shape[self.op[1]], - obs_shape[self.op[2]] - ], - dtype=self.observation_space.dtype) - - def observation(self, ob): - return ob.transpose(self.op[0], self.op[1], self.op[2]) - - -class VecPyTorch(VecEnvWrapper): - def __init__(self, venv, device): - """Return only every `skip`-th frame""" - super(VecPyTorch, self).__init__(venv) - self.device = device - # TODO: Fix data types - - def reset(self): - obs = self.venv.reset() - obs = torch.from_numpy(obs).float().to(self.device) - return obs - - def step_async(self, actions): - if isinstance(actions, torch.LongTensor): - # Squeeze the dimension for discrete actions - actions = actions.squeeze(1) - actions = actions.cpu().numpy() - self.venv.step_async(actions) - - def step_wait(self): - obs, reward, done, info = self.venv.step_wait() - obs = torch.from_numpy(obs).float().to(self.device) - reward = torch.from_numpy(reward).unsqueeze(dim=1).float() - return obs, reward, done, info - - -class VecNormalize(VecNormalize_): - def __init__(self, *args, **kwargs): - super(VecNormalize, self).__init__(*args, **kwargs) - self.training = True - - def _obfilt(self, obs, update=True): - if self.obs_rms: - if self.training and update: - self.obs_rms.update(obs) - obs = np.clip((obs - self.obs_rms.mean) / - np.sqrt(self.obs_rms.var + self.epsilon), - -self.clip_obs, self.clip_obs) - return obs - else: - return obs - - def train(self): - self.training = True - - def eval(self): - self.training = False - - -# Derived from -# https://github.com/openai/baselines/blob/master/baselines/common/vec_env/vec_frame_stack.py -class VecPyTorchFrameStack(VecEnvWrapper): - def __init__(self, venv, nstack, device=None): - self.venv = venv - self.nstack = nstack - - wos = venv.observation_space # wrapped ob space - self.shape_dim0 = wos.shape[0] - - low = np.repeat(wos.low, self.nstack, axis=0) - high = np.repeat(wos.high, self.nstack, axis=0) - - if device is None: - device = torch.device('cpu') - self.stacked_obs = torch.zeros((venv.num_envs, ) + - low.shape).to(device) - - observation_space = gym.spaces.Box(low=low, - high=high, - dtype=venv.observation_space.dtype) - VecEnvWrapper.__init__(self, venv, observation_space=observation_space) - - def step_wait(self): - obs, rews, news, infos = self.venv.step_wait() - self.stacked_obs[:, :-self.shape_dim0] = \ - self.stacked_obs[:, self.shape_dim0:].clone() - for (i, new) in enumerate(news): - if new: - self.stacked_obs[i] = 0 - self.stacked_obs[:, -self.shape_dim0:] = obs - return self.stacked_obs, rews, news, infos - - def reset(self): - obs = self.venv.reset() - if torch.backends.cudnn.deterministic: - self.stacked_obs = torch.zeros(self.stacked_obs.shape) - else: - self.stacked_obs.zero_() - self.stacked_obs[:, -self.shape_dim0:] = obs - return self.stacked_obs - - def close(self): - self.venv.close() diff --git a/Multikeytodoor/a2c_ppo_acktr/storageConSpec.py b/Multikeytodoor/a2c_ppo_acktr/storageConSpec.py deleted file mode 100644 index 13ae426..0000000 --- a/Multikeytodoor/a2c_ppo_acktr/storageConSpec.py +++ /dev/null @@ -1,501 +0,0 @@ -import torch -from torch.utils.data.sampler import BatchSampler, SubsetRandomSampler -import numpy as np - -def _flatten_helper(T, N, _tensor): - return _tensor.view(T * N, *_tensor.size()[2:]) - - -class RolloutStorage(object): - def __init__(self, num_steps, num_processes, obs_shape, action_space, - recurrent_hidden_state_size, num_prototype): - self.obs = torch.zeros(num_steps + 1, num_processes, *obs_shape) - - self.num_processes = num_processes - self.recurrent_hidden_states = torch.zeros( - num_steps + 1, num_processes, recurrent_hidden_state_size) - - self.rewards = torch.zeros(num_steps, num_processes, 1) - self.rewardsORIG = torch.zeros(num_steps, num_processes, 1) - self.value_preds = torch.zeros(num_steps + 1, num_processes, 1) - self.returns = torch.zeros(num_steps + 1, num_processes, 1) - self.action_log_probs = torch.zeros(num_steps, num_processes, 1) - action_shape = 1 - self.actions = torch.zeros(num_steps, num_processes, action_shape) - self.actions = self.actions.long() - - self.masks = torch.ones(num_steps + 1, num_processes, 1) - - # Masks that indicate whether it's a true terminal state - # or time limit end state - self.bad_masks = torch.ones(num_steps + 1, num_processes, 1) - - self.num_steps = num_steps - self.obs_shape = obs_shape - self.step = 0 - - self.recurrent_hidden_state_size = recurrent_hidden_state_size - self.heads = num_prototype - self.success = 16 # size of both success anf failure buffers - self.successTake = 16 # how many trajectories you take from the success and failure buffers - self.hidden_state_size = 256 - - self.obs_batchheadsS = [None] * self.heads - self.r_batchheadsS = [None] * self.heads - self.recurrent_hidden_statesbatchheadsS = [None] * self.heads - self.act_batchheadsS = [None] * self.heads - self.masks_batchheadsS = [None] * self.heads - self.stepheadsS = 0 - - self.obs_batchheadsF = [None] * self.heads - self.r_batchheadsF = [None] * self.heads - self.recurrent_hidden_statesbatchheadsF = [None] * self.heads - self.act_batchheadsF = [None] * self.heads - self.masks_batchheadsF = [None] * self.heads - self.stepheadsF = 0 - - self.obs_batchS = torch.zeros(self.num_steps + 1, self.success, *self.obs_shape) - self.r_batchS = torch.zeros(self.num_steps, self.success, 1) - self.recurrent_hidden_statesS = torch.zeros(self.num_steps + 1, self.success, self.recurrent_hidden_state_size) - self.act_batchS = torch.zeros(self.num_steps, self.success, action_shape) - self.act_batchS = self.act_batchS.long() - self.masks_batchS = torch.zeros(self.num_steps + 1, self.success, 1) - self.stepS = 0 - self.obs_batchF = torch.zeros(self.num_steps + 1, self.success, *self.obs_shape) - self.r_batchF = torch.zeros(self.num_steps, self.success, 1) - self.recurrent_hidden_statesF = torch.zeros(self.num_steps + 1, self.success, self.recurrent_hidden_state_size) - self.act_batchF = torch.zeros(self.num_steps, self.success, action_shape) - self.act_batchF = self.act_batchF.long() - self.masks_batchF = torch.zeros(self.num_steps + 1, self.success, 1) - self.stepF = 0 - for i in range(self.heads): - self.obs_batchheadsS[i] = torch.zeros(self.num_steps + 1, self.success, *self.obs_shape) - self.r_batchheadsS[i] = torch.zeros(self.num_steps, self.success, 1) - self.recurrent_hidden_statesbatchheadsS[i] = torch.zeros(self.num_steps + 1, self.success, - self.recurrent_hidden_state_size) - self.act_batchheadsS[i] = torch.zeros(self.num_steps, self.success, action_shape) - self.act_batchheadsS[i] = self.act_batchheadsS[i].long() - self.masks_batchheadsS[i] = torch.zeros(self.num_steps + 1, self.success, 1) - self.obs_batchheadsF[i] = torch.zeros(self.num_steps + 1, self.success, *self.obs_shape) - self.r_batchheadsF[i] = torch.zeros(self.num_steps, self.success, 1) - self.recurrent_hidden_statesbatchheadsF[i] = torch.zeros(self.num_steps + 1, self.success, - self.recurrent_hidden_state_size) - self.act_batchheadsF[i] = torch.zeros(self.num_steps, self.success, action_shape) - self.act_batchheadsF[i] = self.act_batchheadsF[i].long() - self.masks_batchheadsF[i] = torch.zeros(self.num_steps + 1, self.success, 1) - - def contrastvalueReward(self, contrastval): - self.rewardsORIG = torch.clone(self.rewards) - self.rewards = self.rewards + contrastval.unsqueeze(-1) - - def retrievestepS(self): - return self.stepS - - def retrieveR(self): - return self.rewards - - def retrieveobs(self): - return self.obs - - def retrieveeverything(self): - return torch.cat((self.obs_batchS, self.obs_batchF), dim=1), torch.cat((self.r_batchS, self.r_batchF), - dim=1), torch.cat( - (self.masks_batchS, self.masks_batchF), dim=1), torch.cat((self.act_batchS, self.act_batchF), dim=1) - - def retrieveRS(self): - return self.r_batchS, self.r_batchF - - def correctR(self): - totalreward = self.rewards.sum(0) # [500, 8, 1] - totalreward = totalreward.squeeze() - rewardssortbad = torch.nonzero(totalreward > -50.).reshape(-1, ) - if rewardssortbad.shape[0] > 0: - self.rewards[-2, rewardssortbad, :] = -30000. - return self.rewards - - def storeheadsSF(self, head): - self.obs_batchheadsS[head] = self.obs_batchS - self.r_batchheadsS[head] = self.r_batchS - self.recurrent_hidden_statesbatchheadsS[head] = self.recurrent_hidden_statesS - self.act_batchheadsS[head] = self.act_batchS - self.masks_batchheadsS[head] = self.masks_batchS - self.obs_batchheadsF[head] = self.obs_batchF - self.r_batchheadsF[head] = self.r_batchF - self.recurrent_hidden_statesbatchheadsF[head] = self.recurrent_hidden_statesF - self.act_batchheadsF[head] = self.act_batchF - self.masks_batchheadsF[head] = self.masks_batchF - - def addPosNeg(self, ForS, device, args): - totalreward = self.rewards[-10:].sum(0) - - if ForS == 1: ## for success, record trajectories of successful trajectories - rewardssortgood = torch.nonzero(totalreward > 0.5).reshape(-1, ) - indicesrewardbatch = rewardssortgood[0::2] - obsxx = self.obs[:, indicesrewardbatch].to(device) - numberaddedxx = obsxx.shape[1] - if numberaddedxx >1: - indicesrewardbatch = rewardssortgood[0:4:2] - else: - rewardssortbad = torch.nonzero(totalreward < 0.5).reshape(-1, ) - indicesrewardbatch = rewardssortbad[0::2] - obs = self.obs[:, indicesrewardbatch].to(device) - rec = self.recurrent_hidden_states[:, indicesrewardbatch].to(device) - masks = self.masks[:, indicesrewardbatch].to(device) - act = self.actions[:, indicesrewardbatch].to(device) - rew = self.rewards[:, indicesrewardbatch].to(device) - numberadded = obs.shape[1] - - # ''' - if numberadded > 0: - if ForS == 1: - numcareabout = self.stepS - elif ForS == 0: - numcareabout = self.stepF - if numberadded + numcareabout <= self.obs_batchS.shape[1]: - if ForS == 1: - self.obs_batchS[:, self.stepS:self.stepS + numberadded] = obs - self.r_batchS[:, self.stepS:self.stepS + numberadded] = rew - self.recurrent_hidden_statesS[:, self.stepS:self.stepS + numberadded] = rec - self.act_batchS[:, self.stepS:self.stepS + numberadded] = act - self.masks_batchS[:, self.stepS:self.stepS + numberadded] = masks - self.stepS = (self.stepS + numberadded) - elif ForS == 0: - self.obs_batchF[:, self.stepF:self.stepF + numberadded] = obs - self.r_batchF[:, self.stepF:self.stepF + numberadded] = rew - self.recurrent_hidden_statesF[:, self.stepF:self.stepF + numberadded] = rec - self.act_batchF[:, self.stepF:self.stepF + numberadded] = act - self.masks_batchF[:, self.stepF:self.stepF + numberadded] = masks - self.stepF = (self.stepF + numberadded) - #''' - elif (numberadded + numcareabout >= self.obs_batchS.shape[1]) and ( - numcareabout < self.obs_batchS.shape[1]): - - if ForS == 1: - numbertoadd = self.obs_batchS.shape[1] - self.stepS - self.obs_batchS[:, self.stepS:self.stepS + numbertoadd, :] = obs[:, :numbertoadd] - self.r_batchS[:, self.stepS:self.stepS + numbertoadd] = rew[:, :numbertoadd] - self.recurrent_hidden_statesS[:, self.stepS:self.stepS + numbertoadd] = rec[:, :numbertoadd] - self.act_batchS[:, self.stepS:self.stepS + numbertoadd] = act[:, :numbertoadd] - self.masks_batchS[:, self.stepS:self.stepS + numbertoadd] = masks[:, :numbertoadd] - self.stepS = (self.stepS + numbertoadd) - - elif ForS == 0: - numbertoadd = self.obs_batchS.shape[1] - self.stepF - self.obs_batchF[:, self.stepF:self.stepF + numbertoadd, :] = obs[:, :numbertoadd] - self.r_batchF[:, self.stepF:self.stepF + numbertoadd] = rew[:, :numbertoadd] - self.recurrent_hidden_statesF[:, self.stepF:self.stepF + numbertoadd] = rec[:, :numbertoadd] - self.act_batchF[:, self.stepF:self.stepF + numbertoadd] = act[:, :numbertoadd] - self.masks_batchF[:, self.stepF:self.stepF + numbertoadd] = masks[:, :numbertoadd] - self.stepF = (self.stepF + numbertoadd) - - elif numcareabout == self.obs_batchS.shape[ - 1]: - hidden_state = rec - masks = masks - - if ForS == 1: - lenconsider = obs.shape[1] - self.obs_batchS = torch.cat((self.obs_batchS , obs),1) - self.r_batchS = torch.cat((self.r_batchS , rew),1) - self.recurrent_hidden_statesS = torch.cat((self.recurrent_hidden_statesS , rec),1) - self.act_batchS = torch.cat((self.act_batchS , act),1) - self.masks_batchS = torch.cat((self.masks_batchS , masks),1) - self.obs_batchS = self.obs_batchS[:,lenconsider:] - self.r_batchS = self.r_batchS[:,lenconsider:] - self.recurrent_hidden_statesS = self.recurrent_hidden_statesS[:,lenconsider:] - self.act_batchS = self.act_batchS[:,lenconsider:] - self.masks_batchS = self.masks_batchS[:,lenconsider:] - - elif ForS == 0: - lenconsider = obs.shape[1] - self.obs_batchF = torch.cat((self.obs_batchF, obs), - 1) - self.r_batchF = torch.cat((self.r_batchF, rew), - 1) - self.recurrent_hidden_statesF = torch.cat((self.recurrent_hidden_statesF, rec), - 1) - self.act_batchF = torch.cat((self.act_batchF, act), - 1) - self.masks_batchF = torch.cat((self.masks_batchF, masks), - 1) - self.obs_batchF = self.obs_batchF[:, lenconsider:] - self.r_batchF = self.r_batchF[:, lenconsider:] - self.recurrent_hidden_statesF = self.recurrent_hidden_statesF[:, lenconsider:] - self.act_batchF = self.act_batchF[:, lenconsider:] - self.masks_batchF = self.masks_batchF[:, lenconsider:] - - def to(self, device): - self.obs = self.obs.to(device) - self.recurrent_hidden_states = self.recurrent_hidden_states.to(device) - self.rewards = self.rewards.to(device) - self.value_preds = self.value_preds.to(device) - self.returns = self.returns.to(device) - self.action_log_probs = self.action_log_probs.to(device) - self.actions = self.actions.to(device) - self.masks = self.masks.to(device) - self.bad_masks = self.bad_masks.to(device) - - self.obs_batchS = self.obs_batchS.to(device) - self.r_batchS = self.r_batchS.to(device) - self.recurrent_hidden_statesS = self.recurrent_hidden_statesS.to(device) - self.act_batchS = self.act_batchS.to(device) - self.masks_batchS = self.masks_batchS.to(device) - self.obs_batchF = self.obs_batchF.to(device) - self.r_batchF = self.r_batchF.to(device) - self.recurrent_hidden_statesF = self.recurrent_hidden_statesF.to(device) - self.act_batchF = self.act_batchF.to(device) - self.masks_batchF = self.masks_batchF.to(device) - for i in range(self.heads): - self.obs_batchheadsS[i] = self.obs_batchheadsS[i].to(device) - self.r_batchheadsS[i] = self.r_batchheadsS[i].to(device) - self.recurrent_hidden_statesbatchheadsS[i] = self.recurrent_hidden_statesbatchheadsS[i].to(device) - self.act_batchheadsS[i] = self.act_batchheadsS[i].to(device) - self.masks_batchheadsS[i] = self.masks_batchheadsS[i].to(device) - self.obs_batchheadsF[i] = self.obs_batchheadsF[i].to(device) - self.r_batchheadsF[i] = self.r_batchheadsF[i].to(device) - self.recurrent_hidden_statesbatchheadsF[i] = self.recurrent_hidden_statesbatchheadsF[i].to(device) - self.act_batchheadsF[i] = self.act_batchheadsF[i].to(device) - self.masks_batchheadsF[i] = self.masks_batchheadsF[i].to(device) - - def insert(self, obs, recurrent_hidden_states, actions, action_log_probs, - value_preds, rewards, masks, bad_masks): - self.obs[self.step + 1].copy_(obs) - self.recurrent_hidden_states[self.step + - 1].copy_(recurrent_hidden_states) - self.actions[self.step].copy_(actions) - self.action_log_probs[self.step].copy_(action_log_probs) - self.value_preds[self.step].copy_(value_preds) - self.rewards[self.step].copy_(rewards) - self.masks[self.step + 1].copy_(masks) - self.bad_masks[self.step + 1].copy_(bad_masks) - self.step = (self.step + 1) % self.num_steps - - def after_update(self): - self.obs[0].copy_(self.obs[-1]) - self.recurrent_hidden_states[0].copy_(self.recurrent_hidden_states[-1]) - self.masks[0].copy_(self.masks[-1]) - self.bad_masks[0].copy_(self.bad_masks[-1]) - - def compute_returns(self, - next_value, - use_gae, - gamma, - gae_lambda, - use_proper_time_limits=True): - if use_proper_time_limits: - if use_gae: - self.value_preds[-1] = next_value - gae = 0 - for step in reversed(range(self.rewards.size(0))): - delta = self.rewards[step] + gamma * self.value_preds[ - step + 1] * self.masks[step + - 1] - self.value_preds[step] - gae = delta + gamma * gae_lambda * self.masks[step + - 1] * gae - gae = gae * self.bad_masks[step + 1] - self.returns[step] = gae + self.value_preds[step] - else: - self.returns[-1] = next_value - for step in reversed(range(self.rewards.size(0))): - self.returns[step] = (self.returns[step + 1] * \ - gamma * self.masks[step + 1] + self.rewards[step]) * self.bad_masks[step + 1] \ - + (1 - self.bad_masks[step + 1]) * self.value_preds[step] - else: - if use_gae: - self.value_preds[-1] = next_value - gae = 0 - for step in reversed(range(self.rewards.size(0))): - delta = self.rewards[step] + gamma * self.value_preds[ - step + 1] * self.masks[step + - 1] - self.value_preds[step] - gae = delta + gamma * gae_lambda * self.masks[step + - 1] * gae - self.returns[step] = gae + self.value_preds[step] - else: - self.returns[-1] = next_value - for step in reversed(range(self.rewards.size(0))): - self.returns[step] = self.returns[step + 1] * \ - gamma * self.masks[step + 1] + self.rewards[step] - - def feed_attnR(self): - obs_batch = self.obs[:-1].view(-1, *self.obs.size()[2:]) - obs_batchorig = self.obs[:-1] - recurrent_hidden_states_batch = self.recurrent_hidden_states[:-1].view( - -1, self.recurrent_hidden_states.size(-1)) - actions_batch = self.actions.view(-1, - self.actions.size(-1)) - masks_batch = self.masks[:-1].view(-1, 1) - reward_batch = self.rewards.squeeze() - - return obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch - - def releaseB(self): - return self.obs, self.rewardsORIG, self.recurrent_hidden_states, self.actions, self.masks - - def releaseheadsSF(self, head): - permS = torch.randperm(self.success) - permF = torch.randperm(self.success) - permS = permS[:self.successTake] - permF = permF[:self.successTake] - rew_batch = torch.cat((self.r_batchheadsS[head][:, permS], self.r_batchheadsF[head][:, permF]), dim=1) - obs_batch = torch.cat((self.obs_batchheadsS[head][:, permS], self.obs_batchheadsF[head][:, permF]), dim=1) - recurrent_hidden_states = torch.cat((self.recurrent_hidden_statesbatchheadsS[head][:, permS], - self.recurrent_hidden_statesbatchheadsF[head][:, permF]), dim=1) - act_batch = torch.cat((self.act_batchheadsS[head][:, permS], self.act_batchheadsF[head][:, permF]), dim=1) - masks_batch = torch.cat((self.masks_batchheadsS[head][:, permS], self.masks_batchheadsF[head][:, permF]), dim=1) - return obs_batch, rew_batch, recurrent_hidden_states, act_batch, masks_batch - - def releaseSF(self): - permS = torch.randperm(self.success) - permF = torch.randperm(self.success) - permS = permS[:self.successTake] - permF = permF[:self.successTake] - - rew_batch = torch.cat((self.r_batchS[:, permS], self.r_batchF[:, permF]), dim=1) - obs_batch = torch.cat((self.obs_batchS[:, permS], self.obs_batchF[:, permF]), dim=1) - recurrent_hidden_states = torch.cat( - (self.recurrent_hidden_statesS[:, permS], self.recurrent_hidden_statesF[:, permF]), dim=1) - act_batch = torch.cat((self.act_batchS[:, permS], self.act_batchF[:, permF]), dim=1) - masks_batch = torch.cat((self.masks_batchS[:, permS], self.masks_batchF[:, permF]), dim=1) - return obs_batch, rew_batch, recurrent_hidden_states, act_batch, masks_batch - - def feed_attnRB(self): - obs_batchx, rew_batchx, recurrent_hidden_statesx, act_batchx, masks_batchx = self.releaseB() - obs_batch = obs_batchx[:-1].view(-1, *self.obs.size()[2:]) - obs_batchorig = obs_batchx[:-1] - recurrent_hidden_states_batch = recurrent_hidden_statesx[:-1].view(-1, self.recurrent_hidden_states.size(-1)) - actions_batch = act_batchx.view(-1, self.actions.size(-1)) - masks_batch = masks_batchx[:-1].view(-1, 1) - reward_batch = rew_batchx.squeeze() # [:-1]#.view(-1, 1) - return obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch - - def feed_attnRSF(self): - obs_batchx, rew_batchx, recurrent_hidden_statesx, act_batchx, masks_batchx = self.releaseSF() - obs_batch = obs_batchx[:-1].view(-1, *self.obs.size()[2:]) - obs_batchorig = obs_batchx[:-1] - recurrent_hidden_states_batch = recurrent_hidden_statesx[:-1].view(-1, self.recurrent_hidden_states.size(-1)) - actions_batch = act_batchx.view(-1, self.actions.size(-1)) - masks_batch = masks_batchx[:-1].view(-1, 1) - reward_batch = rew_batchx.squeeze() # [:-1]#.view(-1, 1) - return obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch - - def feed_attnRSFheads(self, head): - obs_batchx, rew_batchx, recurrent_hidden_statesx, act_batchx, masks_batchx = self.releaseheadsSF(head) - obs_batch = obs_batchx[:-1].view(-1, *self.obs.size()[2:]) - obs_batchorig = obs_batchx[:-1] - recurrent_hidden_states_batch = recurrent_hidden_statesx[:-1].view(-1, self.recurrent_hidden_states.size(-1)) - actions_batch = act_batchx.view(-1, self.actions.size(-1)) - masks_batch = masks_batchx[:-1].view(-1, 1) - reward_batch = rew_batchx.squeeze() # [:-1]#.view(-1, 1) - return obs_batch, recurrent_hidden_states_batch, masks_batch, actions_batch, obs_batchorig, reward_batch - - def feed_forward_generator(self, - advantages, - num_mini_batch=None, - mini_batch_size=None): - num_steps, num_processes = self.rewards.size()[0:2] - batch_size = num_processes * num_steps - - - if mini_batch_size is None: - assert batch_size >= num_mini_batch, ( - "PPO requires the number of processes ({}) " - "* number of steps ({}) = {} " - "to be greater than or equal to the number of PPO mini batches ({})." - "".format(num_processes, num_steps, num_processes * num_steps, - num_mini_batch)) - mini_batch_size = batch_size // num_mini_batch - sampler = BatchSampler( - SubsetRandomSampler(range(batch_size)), - mini_batch_size, - drop_last=True) - for indices in sampler: - obs_batch = self.obs[:-1].view(-1, *self.obs.size()[2:])[indices] - recurrent_hidden_states_batch = self.recurrent_hidden_states[:-1].view( - -1, self.recurrent_hidden_states.size(-1))[indices] - actions_batch = self.actions.view(-1, - self.actions.size(-1))[indices] - value_preds_batch = self.value_preds[:-1].view(-1, 1)[indices] - return_batch = self.returns[:-1].view(-1, 1)[indices] - masks_batch = self.masks[:-1].view(-1, 1)[indices] - old_action_log_probs_batch = self.action_log_probs.view(-1, - 1)[indices] - if advantages is None: - adv_targ = None - else: - adv_targ = advantages.view(-1, 1)[indices] - - yield obs_batch, recurrent_hidden_states_batch, actions_batch, \ - value_preds_batch, return_batch, masks_batch, old_action_log_probs_batch, adv_targ - - def recurrent_generator(self, advantages, num_mini_batch): - num_processes = self.rewards.size(1) - assert num_processes >= num_mini_batch, ( - "PPO requires the number of processes ({}) " - "to be greater than or equal to the number of " - "PPO mini batches ({}).".format(num_processes, num_mini_batch)) - num_envs_per_batch = num_processes // num_mini_batch - perm = torch.randperm(num_processes) - for start_ind in range(0, num_processes, num_envs_per_batch): - obs_batch = [] - recurrent_hidden_states_batch = [] - actions_batch = [] - value_preds_batch = [] - return_batch = [] - masks_batch = [] - old_action_log_probs_batch = [] - adv_targ = [] - - for offset in range(num_envs_per_batch): - ind = perm[start_ind + offset] - obs_batch.append(self.obs[:-1, ind]) - recurrent_hidden_states_batch.append( - self.recurrent_hidden_states[0:1, ind]) - actions_batch.append(self.actions[:, ind]) - value_preds_batch.append(self.value_preds[:-1, ind]) - return_batch.append(self.returns[:-1, ind]) - masks_batch.append(self.masks[:-1, ind]) - old_action_log_probs_batch.append( - self.action_log_probs[:, ind]) - adv_targ.append(advantages[:, ind]) - - T, N = self.num_steps, num_envs_per_batch - # These are all tensors of size (T, N, -1) - obs_batch = torch.stack(obs_batch, 1) - actions_batch = torch.stack(actions_batch, 1) - value_preds_batch = torch.stack(value_preds_batch, 1) - return_batch = torch.stack(return_batch, 1) - masks_batch = torch.stack(masks_batch, 1) - old_action_log_probs_batch = torch.stack( - old_action_log_probs_batch, 1) - adv_targ = torch.stack(adv_targ, 1) - - # States is just a (N, -1) tensor - recurrent_hidden_states_batch = torch.stack( - recurrent_hidden_states_batch, 1).view(N, -1) - - # Flatten the (T, N, ...) tensors to (T * N, ...) - obs_batch = _flatten_helper(T, N, obs_batch) - actions_batch = _flatten_helper(T, N, actions_batch) - value_preds_batch = _flatten_helper(T, N, value_preds_batch) - return_batch = _flatten_helper(T, N, return_batch) - masks_batch = _flatten_helper(T, N, masks_batch) - old_action_log_probs_batch = _flatten_helper(T, N, \ - old_action_log_probs_batch) - adv_targ = _flatten_helper(T, N, adv_targ) - - yield obs_batch, recurrent_hidden_states_batch, actions_batch, \ - value_preds_batch, return_batch, masks_batch, old_action_log_probs_batch, adv_targ - - def save(self, filename): - data={'success_traj_protos': self.obs_batchheadsS, - 'fail_traj_protos':self.obs_batchheadsF, - 'success_traj':self.obs_batchS, - 'replay':self.obs, - 'success_traj_rewards':self.r_batchS, - 'length':self.step, - 'success_proto_length':self.stepheadsF, - 'success_length': self.stepS, - 'fail_length': self.stepF, - } - np.savez_compressed(filename, **data) \ No newline at end of file diff --git a/Multikeytodoor/main.py b/Multikeytodoor/main.py deleted file mode 100644 index 0067ebc..0000000 --- a/Multikeytodoor/main.py +++ /dev/null @@ -1,338 +0,0 @@ -import os -import time -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim -import time -import numpy as np -import tensorflow.compat.v1 as tf -from six.moves import range -from six.moves import zip -from collections import deque -from a2c_ppo_acktr import algo, utils -from a2c_ppo_acktr.algo import gail -from a2c_ppo_acktr.argumentstvt import get_args -from a2c_ppo_acktr.modelRL import Policy -from a2c_ppo_acktr.modelConSpec import PolicyCL -from a2c_ppo_acktr.storageConSpec import RolloutStorage -from evaluation import evaluate -from moduleConSpec import moduleCL -from tvt import batch_env -from tvt.pycolab import env as pycolab_env -import wandb -from tqdm import trange -import pickle - -def main(args): - print(args.wandb_group, args.wandb_project, args.exp_name) - wandb.init(project=args.wandb_project, name=args.exp_name, tags=['multikeydoor']) - wandb.config.update(args) - #wandb.run.summary.update(slurm_infos()) - - prototypes = np.zeros((args.num_prototype,)) - protos_thresh = np.zeros((args.num_prototype,)) - - torch.manual_seed(args.seed) - torch.cuda.manual_seed_all(args.seed) - - if args.cuda and torch.cuda.is_available() and args.cuda_deterministic: - torch.backends.cudnn.benchmark = False - torch.backends.cudnn.deterministic = True - - log_dir = os.path.expanduser(args.log_dir) - eval_log_dir = log_dir + "_eval" - utils.cleanup_log_dir(log_dir) - utils.cleanup_log_dir(eval_log_dir) - - torch.set_num_threads(1) - device = torch.device("cuda:0" if args.cuda else "cpu") - - if args.expansion == 500: - args.pycolab_game = 'key_to_door5_2keyseasy' - elif args.expansion == 5000: - args.pycolab_game = 'key_to_door5_4keyseasy' - elif args.expansion == 50000: - args.pycolab_game = 'key_to_door5_3keyseasy' - elif args.expansion == 24: - args.pycolab_game = 'key_to_doormany4' - - - env_builder = pycolab_env.PycolabEnvironment - env_kwargs = { - 'game': args.pycolab_game, - 'num_apples': args.pycolab_num_apples, - 'apple_reward': [args.pycolab_apple_reward_min, - args.pycolab_apple_reward_max], - 'fix_apple_reward_in_episode': args.pycolab_fix_apple_reward_in_episode, - 'final_reward': args.pycolab_final_reward, - 'crop': args.pycolab_crop} - - env = batch_env.BatchEnv(args.num_processes, env_builder, **env_kwargs) - ep_length = env.episode_length - args.num_steps = ep_length - - envs = env - - obsspace = (3,5,5) #env.observation_shape - - actor_critic = Policy( - obsspace, - env.num_actions, - base_kwargs={'recurrent': args.recurrent_policy}) # envs.observation_space.shape, - actor_critic.to(device) - - actor_criticCL = PolicyCL( - obsspace, - env.num_actions, - base_kwargs={'recurrent': args.recurrent_policy}) # envs.observation_space.shape, - actor_criticCL.to(device) - - moduleuse = moduleCL(input_size=512, hidden_size=1010, head=args.num_prototype, device=device, args=args) - moduleuse.to(device) - - prototypes_gpu = torch.FloatTensor(prototypes).to(device=device) - - if args.algo == 'a2c': - agent = algo.A2C_ACKTR( - actor_critic, - args.value_loss_coef, - args.entropy_coef, - lr=args.lr, - eps=args.eps, - alpha=args.alpha, - max_grad_norm=args.max_grad_norm) - - elif args.algo == 'ppoConSpec': - agent = algo.PPOConSpec( - actor_critic, actor_criticCL, - args.clip_param, - args.ppo_epoch, - args.num_mini_batch, - args.value_loss_coef, - args.entropy_coef, - moduleuse, - args.choiceCLparams, - args, - lrCL=args.lrCL, - lr=args.lr, - eps=args.eps, - max_grad_norm=args.max_grad_norm) - - rollouts = RolloutStorage(args.num_steps, args.num_processes, - obsspace, env.num_actions, - actor_critic.recurrent_hidden_state_size, args.num_prototype) # envs.observation_space.shape - - rollouts.to(device) - obs, _ = envs.reset() - - obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) - rollouts.obs[0].copy_(obs) - rollouts.to(device) - episode_rewards = deque(maxlen=10) - - start = time.time() - num_updates = int( - args.num_env_steps) // args.num_steps // args.num_processes - - # training RL - # for j in range(args.num_iterations) as pbar: - with trange(args.num_iterations) as pbar: - for iteration in pbar: - obs, _ = envs.reset() - obs = (torch.from_numpy(obs)).permute((0, 3, 1, 2)).to(device) - rollouts.obs[0].copy_(obs) - donetotal = np.zeros((args.num_processes,)) # .to(device) - if args.use_linear_lr_decay: - # decrease learning rate linearly - utils.update_linear_schedule( - agent.optimizer, iteration, num_updates, - agent.optimizer.lr if args.algo == "acktr" else args.lr) - - for step in range(args.num_steps): - # print(step) - # Sample actions - with torch.no_grad(): - value, action, action_log_prob, recurrent_hidden_states = actor_critic.act( - rollouts.obs[step], rollouts.recurrent_hidden_states[step], - rollouts.masks[step]) - - obs, reward = envs.step(action) - obs = torch.from_numpy(obs).permute((0, 3, 1, 2)).to(device) - reward = torch.from_numpy(reward).reshape(-1, 1) - done = donetotal - masks = torch.FloatTensor( - [[0.0] if done_ else [1.0] for done_ in done]) - bad_masks = masks #torch.FloatTensor([[1.0]]) - rollouts.insert(obs, recurrent_hidden_states, action, - action_log_prob, value, reward, masks, bad_masks) - try: - with torch.no_grad(): - next_value = actor_critic.get_value( - rollouts.obs[-1], rollouts.recurrent_hidden_states[-1], - rollouts.masks[-1]).detach() - - ############################### CONSPEC - with torch.no_grad(): - # now compute new rewards - rewardstotal = rollouts.retrieveR() - episode_rewards.append(rewardstotal.sum(0).mean().cpu().detach().numpy()) - - rollouts.addPosNeg(1, device, args) # add a new traj to positive memory buffer ## dongyan: change these for procgen - rollouts.addPosNeg(0, device, args) # add a new traj to negatove memory buffer ## dongyan: change these for procgen - - agent.fictitiousReward(rollouts, prototypes_gpu, device, iteration) # calculate the intrinsic reward - - ############################### - # part of ppo, after you add the fictitious reward (reward for acieving a prototype) - rollouts.compute_returns(next_value, args.use_gae, args.gamma, args.gae_lambda, args.use_proper_time_limits) - # compute the return based on those real and intrinsic rewards - # usual ppo update - value_loss, action_loss, dist_entropy, prototypes, protos_thresh = agent.update(rollouts, args.num_prototype, prototypes, protos_thresh, iteration) - - #keys used to be the prorotypes - prototypes_gpu = torch.FloatTensor(prototypes).to(device=device) #list of prototypes that have satisfied the prototype (being frozen) - - rollouts.after_update() - - # logging information - if (iteration % args.save_interval == 0 or iteration == num_updates - 1) and args.save_dir != "": - save_path = os.path.join(args.save_dir, args.algo) - - pbar.set_postfix(value_loss=f"{value_loss:.2f}", action_loss=f"{action_loss:.2f}", dist_entropy=f"{dist_entropy:.2f}", prototypes=f"{prototypes:.2f}", protos_thresh=f"{protos_thresh:.2f}") - - try: - os.makedirs(save_path) - except OSError: - pass - torch.save([actor_critic, getattr(utils.get_vec_normalize(envs), 'obs_rms', None)], os.path.join(save_path, args.env_name + ".pt")) - - if iteration % args.log_interval == 0 and len(episode_rewards) > 1: - total_num_steps = (iteration + 1) * args.num_processes * args.num_steps - end = time.time() - print( - "Updates {}, num timesteps {}, FPS {} \n Last {} training episodes: mean/median reward {:.1f}/{:.1f}, min/max reward {:.1f}/{:.1f}\n" - .format(iteration, total_num_steps, - int(total_num_steps / (end - start)), - len(episode_rewards), rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy(), - np.median(episode_rewards), np.min(episode_rewards), - np.max(episode_rewards), dist_entropy, value_loss, - action_loss)) - wandb.log({"number_episodes": iteration, - "total_num_steps": total_num_steps, - "FPS": int(total_num_steps / (end - start)), - "mean_reward": rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy(), - "median_reward": np.median(episode_rewards), - "min_reward": np.min(episode_rewards), - "max_reward": np.max(episode_rewards), - "dist_entropy": dist_entropy, - "value_loss": value_loss, - "action_loss": action_loss, - "prototypes": prototypes, - "protos_thresh": protos_thresh}, step=iteration) - - LOGFILE = './Results' + str(args.algo) + 'lr' + str(args.lr) + 'lrCL' + str(args.lrCL) + 'exp'+ str(args.expansion) + 'factor' + str(args.factorR)+ 'factorC' + str(args.factorC)+ 'finalR' + str(args.pycolab_final_reward) + 'entropy' + str(args.entropy_coef) + 'seed' + str(args.seed)+ '.txt' - print(LOGFILE) - try: - printlog1 = f'final costs {total_num_steps} {rewardstotal[-10:,:].sum(0).mean().cpu().detach().numpy()} {episode_rewards[-1]} {episode_rewards[-1]} {np.mean(episode_rewards)} {np.median(episode_rewards)} {dist_entropy} {value_loss} {action_loss} \n' - with open(LOGFILE, 'a') as f: - f.write(printlog1) - except: - pass - if (args.eval_interval is not None and len(episode_rewards) > 1 and iteration % args.eval_interval == 0): # a - obs_rms = utils.get_vec_normalize(envs).obs_rms - evaluate(actor_critic, obs_rms, args.env_name, args.seed, - args.num_processes, eval_log_dir, device) - except: - pass - - # with open(os.path.join(wandb.run.dir, 'agent.pkl'), 'wb') as f: - # pickle.dump(agent, f) - wandb.save('agent.pkl', policy='now') - - # with open(os.path.join(wandb.run.dir, 'actor_critic.pkl'), params=actor_critic.params) as f: - # pickle.dump(agent, f) - wandb.save('actor_critic.pth', policy='now') - - # with open(os.path.join(wandb.run.dir, 'actor_criticCL.pkl'), params=params) as f: - # pickle.dump(agent, f) - wandb.save('actor_criticCL.pth', policy='now') - # with open(os.path.join(wandb.run.dir, 'moduleuse.pkl'), params=params) as f: - # pickle.dump(agent, f) - wandb.save('moduleuse.pth', policy='now') - rollouts.save(args.output_folder / 'rollouts.npz') - - wandb.log() - wandb.finish() - - - #wandb.save(agent) - -if __name__ == "__main__": - import argparse - from pathlib import Path - parser = argparse.ArgumentParser(description='multi-key-door-conspec') - parser.add_argument('--num_prototype', type=int, default=8, help='number of prototypes(default: 8)') - parser.add_argument('--choiceCLparams', type=int, default=0, help='CL params (default: 0)') - parser.add_argument('--expansion', type=int, default=24, help='gail batch size (default: 24)') - - parser.add_argument('--pycolab_game', default='key_to_doormany4', help='name of the environment (default: key_to_doormany4)') - parser.add_argument('--pycolab_apple_reward_min', type=float, default=1., help='pycolab apple reward min (default: 1.)') - parser.add_argument('--pycolab_apple_reward_max', type=float, default=2., help='pycolab apple reward max (default: 2.)') - parser.add_argument('--pycolab_final_reward', type=float, default=50., help='RMSprop optimizer epsilon (default: 1e-5)') - parser.add_argument('--pycolab_num_apples', type=int, default=10, help='gail batch size (default: 128)') - parser.add_argument('--pycolab_fix_apple_reward_in_episode', action='store_false', default=True, help='use generalized advantage estimation') - parser.add_argument('--pycolab_crop', action='store_true', default=False, help='use generalized advantage estimation') - - parser.add_argument('--skip', type=int, default=4, help='gail batch size (default: 128)') - parser.add_argument('--lrCL', type=float, default=7e-4, help='Conspec learning rate (default: 7e-4)') - parser.add_argument('--algo', default='ppoCL', help='algorithm to use: a2c | ppo | acktr') - parser.add_argument('--gail', action='store_true', default=False, help='do imitation learning with gail') - parser.add_argument('--gail-experts-dir', default='./gail_experts', help='directory that contains expert demonstrations for gail') - parser.add_argument('--gail-batch-size', type=int, default=128, help='gail batch size (default: 128)') - parser.add_argument('--gail-epoch', type=int, default=5, help='gail epochs (default: 5)') - parser.add_argument('--lr', type=float, default=7e-4, help='learning rate (default: 7e-4)') - parser.add_argument('--eps', type=float, default=1e-5, help='RMSprop optimizer epsilon (default: 1e-5)') - parser.add_argument('--alpha', type=float, default=0.99, help='RMSprop optimizer apha (default: 0.99)') - parser.add_argument('--factorR', type=float, default=0.2, help='discount factor for rewards (default: 0.99)') - parser.add_argument('--factorC', type=float, default=5000., help='discount factor for rewards (default: 0.99)') - parser.add_argument('--gamma', type=float, default=0.99, help='discount factor for rewards (default: 0.99)') - parser.add_argument('--use-gae', action='store_true', default=False, help='use generalized advantage estimation') - parser.add_argument('--gae-lambda', type=float, default=0.95, help='gae lambda parameter (default: 0.95)') - parser.add_argument('--entropy-coef', type=float, default=0.01, help='entropy term coefficient (default: 0.01)') - parser.add_argument('--value-loss-coef', type=float, default=0.5, help='value loss coefficient (default: 0.5)') - parser.add_argument('--max-grad-norm', type=float, default=0.5, help='max norm of gradients (default: 0.5)') - - parser.add_argument('--seed', type=int, default=1, help='random seed (default: 1)') - parser.add_argument('--cuda-deterministic', action='store_true', default=False, help="sets flags for determinism when using CUDA (potentially slow!)") - parser.add_argument('--num_iterations', type=int, default=10000, help='Number of iterations (default: %(default)s)') - parser.add_argument('--num-processes', type=int, default=16, help='how many training CPU processes to use (default: 16)') - parser.add_argument('--num-steps', type=int, default=5, help='number of forward steps in A2C (default: 5)') - parser.add_argument('--ppo-epoch', type=int, default=4, help='number of ppo epochs (default: 4)') - parser.add_argument('--num-mini-batch', type=int, default=32, help='number of batches for ppo (default: 32)') - parser.add_argument('--clip-param', type=float, default=0.2, help='ppo clip parameter (default: 0.2)') - parser.add_argument('--log-interval', type=int, default=10, help='log interval, one log per n updates (default: 10)') - parser.add_argument('--save-interval', type=int, default=100, help='save interval, one save per n updates (default: 100)') - parser.add_argument('--eval-interval', type=int, default=None, help='eval interval, one eval per n updates (default: None)') - parser.add_argument('--num-env-steps', type=int, default=10e8, help='number of environment steps to train (default: 10e6)') - parser.add_argument('--env_name', default='PongNoFrameskip-v4', help='environment to train on (default: PongNoFrameskip-v4)') - parser.add_argument('--log-dir', default='/tmp/gym/', help='directory to save agent logs (default: /tmp/gym)') - parser.add_argument('--save-dir', default='trained_models', help='directory to save agent logs (default: ./trained_models/)') - parser.add_argument('--no-cuda',action='store_true', default=False, help='disables CUDA training') - parser.add_argument('--use-proper-time-limits', action='store_true', default=False, help='compute returns taking into account time limits') - parser.add_argument('--recurrent-policy', action='store_false', default=True, help='use a recurrent policy') - parser.add_argument('--use-linear-lr-decay', action='store_true', default=False, help='use a linear schedule on the learning rate') - parser.add_argument('--output_folder', type=Path, default='output', help='Output folder (default: %(default)s)') - parser.add_argument("--wandb_project",type=str,default='gfn-conspec',help="Wandb project name") - parser.add_argument("--wandb_group",type=str,default='blake-richards',help="Wandb group name") - parser.add_argument("--wandb_dir",type=str,default=f'{os.environ["SCRATCH"]}/exploringConsPec',help="Wandb logdir") - parser.add_argument("--exp_name",type=str,default='exp-conspec',help="experiment name") - parser.add_argument("--exp_group",type=str,default='exp-conspec',help="conspec") - parser.add_argument("--exp_job_type",type=str,default='exp-conspec',help='conspec training') - - - args = parser.parse_args() - args.cuda = not args.no_cuda and torch.cuda.is_available() - - main(args) - diff --git a/Multikeytodoor/moduleConSpec.py b/Multikeytodoor/moduleConSpec.py deleted file mode 100644 index 0a7fcaa..0000000 --- a/Multikeytodoor/moduleConSpec.py +++ /dev/null @@ -1,84 +0,0 @@ -from misc_util import orthogonal_init, xavier_uniform_init -import torch.nn as nn -import torch -import torch.nn.functional as F -import math -import numpy as np -import matplotlib.pyplot as plt -from a2c_ppo_acktr.utils import init -import traceback - -np.set_printoptions(threshold=10_000) -torch.set_printoptions(threshold=10_000) - -class moduleCL(nn.Module): - def __init__(self, - input_size, hidden_size, head, device, args): - super(moduleCL, self).__init__() - self.head = head - self.input_size = input_size - self.hidden_size = hidden_size - self.layers = [None] * head - self.device = device - self.args = args - - self.main = nn.ModuleList([nn.Sequential( - (nn.Linear(in_features=input_size, out_features=hidden_size, bias=False)), nn.ReLU(), - ) for i in range(head)]) - self.layers = nn.ModuleList([nn.Sequential( - (nn.Linear(in_features=hidden_size, out_features=hidden_size,bias=False)), nn.ReLU(), - ) for i in range(head)]) - - self.layers2 = nn.ParameterList([nn.Parameter( - torch.randn(1, self.hidden_size) * 1.) for i - in range(head)]) - - self.cos = nn.CosineSimilarity(dim=2, eps=1e-6) - - def forward(self, hidden, reward, keyused, obs, time, seed, doimage): # obs = [600, 16, 1, 54, 64 - #################ConSpec module is implemented here - keysUsedOrig = keyused - out1 = [None] * self.head - cossim2 = [None] * self.head - ortho2 = [None] * self.head - minibatchsize = hidden.shape[1] - miniSuccesssize = int(hidden.shape[1] / 2) - - for iii in range(self.head): - - out1[iii] = self.layers[iii](self.main[iii](hidden)) # hidden = length, minibatch, latent #keyhead - s1, s2, s3 = out1[iii].shape - currentweights = self.layers2[iii].reshape(1, 1, -1).repeat(s1, 1, 1) - cossim2[iii] = self.cos(out1[iii], currentweights) - ortho2[iii] = F.softmax(cossim2[iii].squeeze() * 100., dim=0) # length,minibatch,1 --> length,minibatch - - cossimtotal = torch.stack(cossim2, - dim=2) - orthototal = torch.stack(ortho2, dim=2) # length,minibatch,keys - - cossimtotalmaxxx, indmaxes = ( - torch.max(cossimtotal, dim=0)) - cossimtotalmax = cossimtotalmaxxx.squeeze() # minibatch,keys - - # ''' - costFit = ((torch.abs(1 - cossimtotalmax[:miniSuccesssize]).mean(0) + torch.abs( - cossimtotalmax[miniSuccesssize:]).mean(0)).squeeze()) * 1. - if keyused > -0.5: - costFitFinal = costFit[keysUsedOrig] - else: - costFitFinal = costFit.sum() - orthototalperm = orthototal.permute(1, 0, 2) - orthototalperm = F.normalize(orthototalperm, dim=1, p=2) - cosnorm = torch.abs(torch.matmul(orthototalperm.permute(0, 2, 1), orthototalperm)) - cosnormdiag = torch.diagonal(cosnorm, dim1=1, dim2=2) - orthogonality = (cosnorm[:, :, :])[:miniSuccesssize] - torch.diag_embed(cosnormdiag[:, :], dim1=1, dim2=2)[ - :miniSuccesssize] - orthogonalitycost = orthogonality.sum() - - costfinal = costFitFinal * 1. + (orthogonalitycost * .2) /self.head - pos = torch.abs(cossimtotalmax[:miniSuccesssize]).mean(0) - neg = torch.abs(cossimtotalmax[miniSuccesssize:]).mean(0) - - return costfinal, cossimtotal, [pos, neg] - - diff --git a/Multikeytodoor/requirements.txt b/Multikeytodoor/requirements.txt deleted file mode 100644 index 9dfe590..0000000 --- a/Multikeytodoor/requirements.txt +++ /dev/null @@ -1,119 +0,0 @@ -absl-py==1.0.0 -argon2-cffi==21.3.0 -argon2-cffi-bindings==21.2.0 -astor==0.8.1 -attrs==21.4.0 -backcall==0.2.0 -beautifulsoup4==4.11.1 -bleach==5.0.0 -cached-property==1.5.2 -certifi==2021.10.8 -cffi==1.15.0 -charset-normalizer==2.0.12 -cloudpickle<=2.0.0 -contextlib2==21.6.0 -cycler==0.11.0 -debugpy==1.6.0 -decorator==4.4.2 -defusedxml==0.7.1 -dm-sonnet==1.34 -dm-tree==0.1.7 -entrypoints==0.4 -fastjsonschema==2.15.3 -fonttools==4.33.3 -future==0.18.2 -gast==0.2.2 -google-pasta==0.2.0 -grpcio==1.46.0 -gym>=0.16.0 -gym-notices==0.0.6 -h5py==3.6.0 -idna==3.3 -imageio==2.19.0 -imageio-ffmpeg==0.4.7 -importlib-metadata==4.11.3 -importlib-resources==5.7.1 -ipykernel==6.13.0 -ipython==7.33.0 -ipython-genutils==0.2.0 -ipywidgets==7.7.0 -jedi==0.18.1 -Jinja2==3.1.2 -jsonschema==4.5.1 -jupyter==1.0.0 -jupyter-client==7.3.0 -jupyter-console==6.4.3 -jupyter-core==4.10.0 -jupyterlab-pygments==0.2.2 -jupyterlab-widgets==1.1.0 -Keras-Applications==1.0.8 -Keras-Preprocessing==1.1.2 -kiwisolver==1.4.2 -Markdown==3.3.7 -MarkupSafe==2.1.1 -matplotlib==3.5.2 -matplotlib-inline==0.1.3 -mistune==0.8.4 -moviepy==1.0.3 -nbclient==0.6.2 -nbconvert==6.5.0 -nbformat==5.4.0 -nest-asyncio==1.5.5 -notebook==6.4.11 -numpy==1.21.5 -opt-einsum==3.3.0 -packaging==21.3 -pandas==1.1.5 -pandocfilters==1.5.0 -parso==0.8.3 -pexpect==4.8.0 -pickleshare==0.7.5 -Pillow==9.1.0 -pip==21.2.2 -proglog==0.1.10 -prometheus-client==0.14.1 -prompt-toolkit==3.0.29 -protobuf==3.20.1 -psutil==5.9.0 -ptyprocess==0.7.0 -pybullet==3.2.2 -pycolab==1.2 -pycparser==2.21 -pyglet==1.5.0 -Pygments==2.12.0 -pyparsing==3.0.8 -pyrsistent==0.18.1 -python-dateutil==2.8.2 -pytz==2022.1 -pyzmq==22.3.0 -qtconsole==5.3.0 -QtPy==2.1.0 -requests==2.27.1 -scipy==1.7.3 -semantic-version==2.9.0 -Send2Trash==1.8.0 -setuptools==61.2.0 -six==1.16.0 -soupsieve==2.3.2.post1 -stable-baselines3==0.9.0 -tensorboard==1.15.0 -tensorflow==1.15.0 -tensorflow-estimator==1.15.1 -tensorflow-probability==0.7.0 -termcolor==1.1.0 -terminado==0.13.3 -tinycss2==1.1.1 -torch==1.11.0 -tornado==6.1 -tqdm==4.64.0 -traitlets==5.1.1 -trfl==1.2.0 -typing_extensions==4.2.0 -urllib3==1.26.9 -wcwidth==0.2.5 -webencodings==0.5.1 -Werkzeug==2.1.2 -wheel==0.37.1 -widgetsnbextension==3.6.0 -wrapt==1.14 -zipp==3.8.0 diff --git a/README.md b/README.md index 5c39cee..f12ac40 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,55 @@ - # Contrastive Retrospection (ConSpec) ### Chen Sun, Wannan Yang, Thomas Jiralerspong, Dane Malenfant, Benjamin Alsbury-Nealy, Yoshua Bengio, Blake Richards 2023 This repository implements Contrastive Retrospection (ConSpec) as detailed in the paper: https://arxiv.org/pdf/2210.05845.pdf -**The conspecfunction subfolder implements ConSpec as a self-contained Class that can be added onto any RL agent of choice and trained autonomously.** It has documentation, and should be easy to use for interested researchers. **It also contains a working example of ConSpec helping train a 4-key gridworld task as seen in the paper from fig. 4.** +**ConSpec is implemented as a self-contained Class that can be added onto any RL agent of choice and trained autonomously.** It contains a working example of ConSpec helping train a 4-key gridworld task as seen in the paper from fig. 4. + +![conspeccartoon](Diagram.png) +![movie](Movietask.gif) + +## Information +The basic PPO code was taken from the repository: https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail + +The pycolab tasks codebase was taken from the repository: https://github.com/deepmind/deepmind-research/tree/master/tvt + +## Installation +To create the environment install the packages from the requirements.txt file in a python 3.7 environment. + +## Quick Start + +To see ConSpec in action with an underlying PPO agent on a 4-key task (fig. 4 of the paper), run: +```bash +python -u main.py --pycolab_game key_to_door4 +``` + +## Using ConSpec on top of any other RL agent of choice + +ConSpec is designed to be a self-contained function that can be added to any RL agent of choice. +To use this function in any RL backbone, follow these 3 simple steps: + +1. **Load the ConSpec module**: The `Conspec/` folder contains all necessary files. + +2. **Import and initialize ConSpec** in your main training script: +```python +from Conspec.ConSpec import ConSpec +conspecfunction = ConSpec(args, obsspace, env.num_actions, device) +``` + +3. **Add ConSpec to your RL training loop**: +```python +obstotal, rewardtotal, recurrent_hidden_statestotal, actiontotal, maskstotal = rollouts.release() +reward_intrinsic_extrinsic = conspecfunction.do_everything(obstotal, recurrent_hidden_statestotal, actiontotal, rewardtotal, maskstotal) +rollouts.storereward(reward_intrinsic_extrinsic) +``` -The 3DOrangeTree subfolder implements ConSpec in the OrangeTree task described in the paper but **is a much older repository** - will clean up at a later date. +The purpose of these 3 lines is to: +- retrieve the current minibatch of trajectory (including observations, rewards, hidden states, actions, masks) +- "do everything" that ConSpec needs to do internally for training, and output the intrinsic + extrinsic reward for the current minibatch of trajectories +- store this total reward in the memory buffer +**A working example showing these lines of code added into an RL training loop is seen in main.py** -# ![conspeccartoon](Diagram.png) -# ![movie](Movietask.gif) diff --git a/3DOrangeTree/a2c_ppo_acktr/__init__.py b/a2c_ppo_acktr/__init__.py similarity index 100% rename from 3DOrangeTree/a2c_ppo_acktr/__init__.py rename to a2c_ppo_acktr/__init__.py diff --git a/conspecfunction/a2c_ppo_acktr/algo/__init__.py b/a2c_ppo_acktr/algo/__init__.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/algo/__init__.py rename to a2c_ppo_acktr/algo/__init__.py diff --git a/conspecfunction/a2c_ppo_acktr/algo/a2c_acktr.py b/a2c_ppo_acktr/algo/a2c_acktr.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/algo/a2c_acktr.py rename to a2c_ppo_acktr/algo/a2c_acktr.py diff --git a/3DOrangeTree/a2c_ppo_acktr/algo/gail.py b/a2c_ppo_acktr/algo/gail.py similarity index 100% rename from 3DOrangeTree/a2c_ppo_acktr/algo/gail.py rename to a2c_ppo_acktr/algo/gail.py diff --git a/conspecfunction/a2c_ppo_acktr/algo/ppo.py b/a2c_ppo_acktr/algo/ppo.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/algo/ppo.py rename to a2c_ppo_acktr/algo/ppo.py diff --git a/conspecfunction/a2c_ppo_acktr/algo/ppoConSpec.py b/a2c_ppo_acktr/algo/ppoConSpec.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/algo/ppoConSpec.py rename to a2c_ppo_acktr/algo/ppoConSpec.py diff --git a/conspecfunction/a2c_ppo_acktr/arguments.py b/a2c_ppo_acktr/arguments.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/arguments.py rename to a2c_ppo_acktr/arguments.py diff --git a/3DOrangeTree/a2c_ppo_acktr/distributions.py b/a2c_ppo_acktr/distributions.py similarity index 100% rename from 3DOrangeTree/a2c_ppo_acktr/distributions.py rename to a2c_ppo_acktr/distributions.py diff --git a/conspecfunction/a2c_ppo_acktr/envs.py b/a2c_ppo_acktr/envs.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/envs.py rename to a2c_ppo_acktr/envs.py diff --git a/conspecfunction/a2c_ppo_acktr/modelRL.py b/a2c_ppo_acktr/modelRL.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/modelRL.py rename to a2c_ppo_acktr/modelRL.py diff --git a/conspecfunction/a2c_ppo_acktr/storage.py b/a2c_ppo_acktr/storage.py similarity index 100% rename from conspecfunction/a2c_ppo_acktr/storage.py rename to a2c_ppo_acktr/storage.py diff --git a/3DOrangeTree/a2c_ppo_acktr/utils.py b/a2c_ppo_acktr/utils.py similarity index 100% rename from 3DOrangeTree/a2c_ppo_acktr/utils.py rename to a2c_ppo_acktr/utils.py diff --git a/conspecfunction/analysis.py b/analysis.py similarity index 100% rename from conspecfunction/analysis.py rename to analysis.py diff --git a/conspecfunction/collect_data.py b/collect_data.py similarity index 100% rename from conspecfunction/collect_data.py rename to collect_data.py diff --git a/conspecfunction/LICENSE b/conspecfunction/LICENSE deleted file mode 100644 index 73fa275..0000000 --- a/conspecfunction/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Ilya Kostrikov - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/conspecfunction/README.md b/conspecfunction/README.md deleted file mode 100644 index 9b373ed..0000000 --- a/conspecfunction/README.md +++ /dev/null @@ -1,47 +0,0 @@ - - - -# ConSpec - -## Information -The basic PPO code was taken from the repository: https://github.com/ikostrikov/pytorch-a2c-ppo-acktr-gail - -The pycolab tasks codebase was taken from the repository: https://github.com/deepmind/deepmind-research/tree/master/tvt - -## Installation -To create the environment install the packages from the requirements.txt file in a python 3.7 environment. - - - -### Launching - -To see conspecfunction in action with an underlying PPO agent on a 4-key task (fig. 4 of the paper), run: -``` -python -u main.py --pycolab_game key_to_door4 -``` - -### Using ConSpec on top of any other RL agent of choice - -This function (conspecfunction) is meant to be a self-contained function and can be added to any RL agent of choice. -To use this function in any RL backbone, 3 simple steps need to be done (stated below). **A working example showing these lines of code added into an RL training loop is seen in main.py** - - -1. Load the "Conspec" subfolder into your codebase. This subfolder contains 5 files. - -2. In your main training script, import the following. All the relevant ConSpec functions and objects are contained in this class. -``` -from Conspec.ConSpec import ConSpec -conspecfunction = ConSpec(args, obsspace, env.num_actions, device) -``` - -3. In your RL training loop, simply add the 3 lines below. -``` - obstotal, rewardtotal, recurrent_hidden_statestotal, actiontotal, maskstotal = rollouts.release() - reward_intrinsic_extrinsic = conspecfunction.do_everything(obstotal, recurrent_hidden_statestotal, actiontotal, rewardtotal, maskstotal) - rollouts.storereward(reward_intrinsic_extrinsic) -``` -the purpose of these last 3 lines is to: -i. retrieve the current minibatch of trajectory (including its observations, rewards, hidden states, actions, masks) -ii. "do everything" that ConSpec needs to do internally for training, and output the intrinsic + extrinsic reward for the current minibatch of trajectories -iii. store this total reward in the memory buffer - diff --git a/conspecfunction/a2c_ppo_acktr/__init__.py b/conspecfunction/a2c_ppo_acktr/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/conspecfunction/a2c_ppo_acktr/algo/gail.py b/conspecfunction/a2c_ppo_acktr/algo/gail.py deleted file mode 100644 index aa85380..0000000 --- a/conspecfunction/a2c_ppo_acktr/algo/gail.py +++ /dev/null @@ -1,166 +0,0 @@ -import h5py -import numpy as np -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.utils.data -from torch import autograd - -from stable_baselines3.common.running_mean_std import RunningMeanStd - -class Discriminator(nn.Module): - def __init__(self, input_dim, hidden_dim, device): - super(Discriminator, self).__init__() - - self.device = device - - self.trunk = nn.Sequential( - nn.Linear(input_dim, hidden_dim), nn.Tanh(), - nn.Linear(hidden_dim, hidden_dim), nn.Tanh(), - nn.Linear(hidden_dim, 1)).to(device) - - self.trunk.train() - - self.optimizer = torch.optim.Adam(self.trunk.parameters()) - - self.returns = None - self.ret_rms = RunningMeanStd(shape=()) - - def compute_grad_pen(self, - expert_state, - expert_action, - policy_state, - policy_action, - lambda_=10): - alpha = torch.rand(expert_state.size(0), 1) - expert_data = torch.cat([expert_state, expert_action], dim=1) - policy_data = torch.cat([policy_state, policy_action], dim=1) - - alpha = alpha.expand_as(expert_data).to(expert_data.device) - - mixup_data = alpha * expert_data + (1 - alpha) * policy_data - mixup_data.requires_grad = True - - disc = self.trunk(mixup_data) - ones = torch.ones(disc.size()).to(disc.device) - grad = autograd.grad( - outputs=disc, - inputs=mixup_data, - grad_outputs=ones, - create_graph=True, - retain_graph=True, - only_inputs=True)[0] - - grad_pen = lambda_ * (grad.norm(2, dim=1) - 1).pow(2).mean() - return grad_pen - - def update(self, expert_loader, rollouts, obsfilt=None): - self.train() - - policy_data_generator = rollouts.feed_forward_generator( - None, mini_batch_size=expert_loader.batch_size) - - loss = 0 - n = 0 - for expert_batch, policy_batch in zip(expert_loader, - policy_data_generator): - policy_state, policy_action = policy_batch[0], policy_batch[2] - policy_d = self.trunk( - torch.cat([policy_state, policy_action], dim=1)) - - expert_state, expert_action = expert_batch - expert_state = obsfilt(expert_state.numpy(), update=False) - expert_state = torch.FloatTensor(expert_state).to(self.device) - expert_action = expert_action.to(self.device) - expert_d = self.trunk( - torch.cat([expert_state, expert_action], dim=1)) - - expert_loss = F.binary_cross_entropy_with_logits( - expert_d, - torch.ones(expert_d.size()).to(self.device)) - policy_loss = F.binary_cross_entropy_with_logits( - policy_d, - torch.zeros(policy_d.size()).to(self.device)) - - gail_loss = expert_loss + policy_loss - grad_pen = self.compute_grad_pen(expert_state, expert_action, - policy_state, policy_action) - - loss += (gail_loss + grad_pen).item() - n += 1 - - self.optimizer.zero_grad() - (gail_loss + grad_pen).backward() - self.optimizer.step() - return loss / n - - def predict_reward(self, state, action, gamma, masks, update_rms=True): - with torch.no_grad(): - self.eval() - d = self.trunk(torch.cat([state, action], dim=1)) - s = torch.sigmoid(d) - reward = s.log() - (1 - s).log() - if self.returns is None: - self.returns = reward.clone() - - if update_rms: - self.returns = self.returns * masks * gamma + reward - self.ret_rms.update(self.returns.cpu().numpy()) - - return reward / np.sqrt(self.ret_rms.var[0] + 1e-8) - - -class ExpertDataset(torch.utils.data.Dataset): - def __init__(self, file_name, num_trajectories=4, subsample_frequency=20): - all_trajectories = torch.load(file_name) - - perm = torch.randperm(all_trajectories['states'].size(0)) - idx = perm[:num_trajectories] - - self.trajectories = {} - - # See https://github.com/pytorch/pytorch/issues/14886 - # .long() for fixing bug in torch v0.4.1 - start_idx = torch.randint( - 0, subsample_frequency, size=(num_trajectories, )).long() - - for k, v in all_trajectories.items(): - data = v[idx] - - if k != 'lengths': - samples = [] - for i in range(num_trajectories): - samples.append(data[i, start_idx[i]::subsample_frequency]) - self.trajectories[k] = torch.stack(samples) - else: - self.trajectories[k] = data // subsample_frequency - - self.i2traj_idx = {} - self.i2i = {} - - self.length = self.trajectories['lengths'].sum().item() - - traj_idx = 0 - i = 0 - - self.get_idx = [] - - for j in range(self.length): - - while self.trajectories['lengths'][traj_idx].item() <= i: - i -= self.trajectories['lengths'][traj_idx].item() - traj_idx += 1 - - self.get_idx.append((traj_idx, i)) - - i += 1 - - - def __len__(self): - return self.length - - def __getitem__(self, i): - traj_idx, i = self.get_idx[i] - - return self.trajectories['states'][traj_idx][i], self.trajectories[ - 'actions'][traj_idx][i] diff --git a/conspecfunction/a2c_ppo_acktr/distributions.py b/conspecfunction/a2c_ppo_acktr/distributions.py deleted file mode 100644 index a705431..0000000 --- a/conspecfunction/a2c_ppo_acktr/distributions.py +++ /dev/null @@ -1,109 +0,0 @@ -import math - -import torch -import torch.nn as nn -import torch.nn.functional as F - -from a2c_ppo_acktr.utils import AddBias, init - -""" -Modify standard PyTorch distributions so they are compatible with this code. -""" - -# -# Standardize distribution interfaces -# - -# Categorical -class FixedCategorical(torch.distributions.Categorical): - def sample(self): - return super().sample().unsqueeze(-1) - - def log_probs(self, actions): - return ( - super() - .log_prob(actions.squeeze(-1)) - .view(actions.size(0), -1) - .sum(-1) - .unsqueeze(-1) - ) - - def mode(self): - return self.probs.argmax(dim=-1, keepdim=True) - - -# Normal -class FixedNormal(torch.distributions.Normal): - def log_probs(self, actions): - return super().log_prob(actions).sum(-1, keepdim=True) - - def entropy(self): - return super().entropy().sum(-1) - - def mode(self): - return self.mean - - -# Bernoulli -class FixedBernoulli(torch.distributions.Bernoulli): - def log_probs(self, actions): - return super.log_prob(actions).view(actions.size(0), -1).sum(-1).unsqueeze(-1) - - def entropy(self): - return super().entropy().sum(-1) - - def mode(self): - return torch.gt(self.probs, 0.5).float() - - -class Categorical(nn.Module): - def __init__(self, num_inputs, num_outputs): - super(Categorical, self).__init__() - - init_ = lambda m: init( - m, - nn.init.orthogonal_, - lambda x: nn.init.constant_(x, 0), - gain=0.01) - - self.linear = init_(nn.Linear(num_inputs, num_outputs)) - - def forward(self, x): - x = self.linear(x) - return FixedCategorical(logits=x) - - -class DiagGaussian(nn.Module): - def __init__(self, num_inputs, num_outputs): - super(DiagGaussian, self).__init__() - - init_ = lambda m: init(m, nn.init.orthogonal_, lambda x: nn.init. - constant_(x, 0)) - - self.fc_mean = init_(nn.Linear(num_inputs, num_outputs)) - self.logstd = AddBias(torch.zeros(num_outputs)) - - def forward(self, x): - action_mean = self.fc_mean(x) - - # An ugly hack for my KFAC implementation. - zeros = torch.zeros(action_mean.size()) - if x.is_cuda: - zeros = zeros.cuda() - - action_logstd = self.logstd(zeros) - return FixedNormal(action_mean, action_logstd.exp()) - - -class Bernoulli(nn.Module): - def __init__(self, num_inputs, num_outputs): - super(Bernoulli, self).__init__() - - init_ = lambda m: init(m, nn.init.orthogonal_, lambda x: nn.init. - constant_(x, 0)) - - self.linear = init_(nn.Linear(num_inputs, num_outputs)) - - def forward(self, x): - x = self.linear(x) - return FixedBernoulli(logits=x) diff --git a/conspecfunction/a2c_ppo_acktr/utils.py b/conspecfunction/a2c_ppo_acktr/utils.py deleted file mode 100644 index 328d3a6..0000000 --- a/conspecfunction/a2c_ppo_acktr/utils.py +++ /dev/null @@ -1,65 +0,0 @@ -import glob -import os - -import torch -import torch.nn as nn - -from a2c_ppo_acktr.envs import VecNormalize - - -# Get a render function -def get_render_func(venv): - if hasattr(venv, 'envs'): - return venv.envs[0].render - elif hasattr(venv, 'venv'): - return get_render_func(venv.venv) - elif hasattr(venv, 'env'): - return get_render_func(venv.env) - - return None - - -def get_vec_normalize(venv): - if isinstance(venv, VecNormalize): - return venv - elif hasattr(venv, 'venv'): - return get_vec_normalize(venv.venv) - - return None - - -# Necessary for my KFAC implementation. -class AddBias(nn.Module): - def __init__(self, bias): - super(AddBias, self).__init__() - self._bias = nn.Parameter(bias.unsqueeze(1)) - - def forward(self, x): - if x.dim() == 2: - bias = self._bias.t().view(1, -1) - else: - bias = self._bias.t().view(1, -1, 1, 1) - - return x + bias - - -def update_linear_schedule(optimizer, epoch, total_num_epochs, initial_lr): - """Decreases the learning rate linearly""" - lr = initial_lr - (initial_lr * (epoch / float(total_num_epochs))) - for param_group in optimizer.param_groups: - param_group['lr'] = lr - - -def init(module, weight_init, bias_init, gain=1): - weight_init(module.weight.data, gain=gain) - bias_init(module.bias.data) - return module - - -def cleanup_log_dir(log_dir): - try: - os.makedirs(log_dir) - except OSError: - files = glob.glob(os.path.join(log_dir, '*.monitor.csv')) - for f in files: - os.remove(f) diff --git a/conspecfunction/requirements.txt b/conspecfunction/requirements.txt deleted file mode 100644 index 3fd7b3f..0000000 --- a/conspecfunction/requirements.txt +++ /dev/null @@ -1,121 +0,0 @@ -Package Version ----------------------- ----------- -absl-py 1.0.0 -argon2-cffi 21.3.0 -argon2-cffi-bindings 21.2.0 -astor 0.8.1 -attrs 21.4.0 -backcall 0.2.0 -beautifulsoup4 4.11.1 -bleach 5.0.0 -cached-property 1.5.2 -certifi 2021.10.8 -cffi 1.15.0 -charset-normalizer 2.0.12 -cloudpickle 2.0.0 -contextlib2 21.6.0 -cycler 0.11.0 -debugpy 1.6.0 -decorator 4.4.2 -defusedxml 0.7.1 -dm-sonnet 1.34 -dm-tree 0.1.7 -entrypoints 0.4 -fastjsonschema 2.15.3 -fonttools 4.33.3 -future 0.18.2 -gast 0.5.3 -google-pasta 0.2.0 -grpcio 1.46.0 -gym 0.16.0 -gym-notices 0.0.6 -h5py 3.6.0 -idna 3.3 -imageio 2.19.0 -imageio-ffmpeg 0.4.7 -importlib-metadata 4.11.3 -importlib-resources 5.7.1 -ipykernel 6.13.0 -ipython 7.33.0 -ipython-genutils 0.2.0 -ipywidgets 7.7.0 -jedi 0.18.1 -Jinja2 3.1.2 -jsonschema 4.5.1 -jupyter 1.0.0 -jupyter-client 7.3.0 -jupyter-console 6.4.3 -jupyter-core 4.10.0 -jupyterlab-pygments 0.2.2 -jupyterlab-widgets 1.1.0 -Keras-Applications 1.0.8 -Keras-Preprocessing 1.1.2 -kiwisolver 1.4.2 -Markdown 3.3.7 -MarkupSafe 2.1.1 -matplotlib 3.5.2 -matplotlib-inline 0.1.3 -mistune 0.8.4 -moviepy 1.0.3 -nbclient 0.6.2 -nbconvert 6.5.0 -nbformat 5.4.0 -nest-asyncio 1.5.5 -notebook 6.4.11 -numpy 1.21.5 -opt-einsum 3.3.0 -packaging 21.3 -pandas 1.1.5 -pandocfilters 1.5.0 -parso 0.8.3 -pexpect 4.8.0 -pickleshare 0.7.5 -Pillow 9.1.0 -pip 21.2.2 -proglog 0.1.10 -prometheus-client 0.14.1 -prompt-toolkit 3.0.29 -protobuf 3.20.1 -psutil 5.9.0 -ptyprocess 0.7.0 -pybullet 3.2.2 -pycolab 1.2 -pycparser 2.21 -pyglet 1.5.0 -Pygments 2.12.0 -pyparsing 3.0.8 -pyrsistent 0.18.1 -python-dateutil 2.8.2 -pytz 2022.1 -pyzmq 22.3.0 -qtconsole 5.3.0 -QtPy 2.1.0 -requests 2.27.1 -scipy 1.7.3 -semantic-version 2.9.0 -Send2Trash 1.8.0 -setuptools 61.2.0 -six 1.16.0 -soupsieve 2.3.2.post1 -stable-baselines3 0.9.0 -tensorboard 1.15.0 -tensorflow 1.15.0 -tensorflow-estimator 1.15.1 -tensorflow-probability 0.7.0 -termcolor 1.1.0 -terminado 0.13.3 -tinycss2 1.1.1 -torch 1.11.0 -tornado 6.1 -tqdm 4.64.0 -traitlets 5.1.1 -trfl 1.2.0 -typing_extensions 4.2.0 -urllib3 1.26.9 -wcwidth 0.2.5 -webencodings 0.5.1 -Werkzeug 2.1.2 -wheel 0.37.1 -widgetsnbextension 3.6.0 -wrapt 1.14.1 -zipp 3.8.0 diff --git a/conspecfunction/data/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png b/data/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png similarity index 100% rename from conspecfunction/data/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png rename to data/max-cos-states-20240319-212006_key_to_door3_1_2500-epoch-70.png diff --git a/conspecfunction/data_collection.py b/data_collection.py similarity index 100% rename from conspecfunction/data_collection.py rename to data_collection.py diff --git a/conspecfunction/evaluation.py b/evaluation.py similarity index 100% rename from conspecfunction/evaluation.py rename to evaluation.py diff --git a/conspecfunction/generate_tmux_yaml.py b/generate_tmux_yaml.py similarity index 100% rename from conspecfunction/generate_tmux_yaml.py rename to generate_tmux_yaml.py diff --git a/conspecfunction/main.py b/main.py similarity index 100% rename from conspecfunction/main.py rename to main.py diff --git a/conspecfunction/main_eval.py b/main_eval.py similarity index 100% rename from conspecfunction/main_eval.py rename to main_eval.py diff --git a/conspecfunction/misc.py b/misc.py similarity index 100% rename from conspecfunction/misc.py rename to misc.py diff --git a/conspecfunction/misc_util.py b/misc_util.py similarity index 100% rename from conspecfunction/misc_util.py rename to misc_util.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..48bbc24 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,31 @@ +# Core dependencies for ConSpec +torch>=1.10.0 +torchvision>=0.11.0 +numpy>=1.21.0 +matplotlib>=3.5.0 +tqdm>=4.64.0 + +# RL and environment dependencies +gym>=0.16.0 +pycolab>=1.2 +stable-baselines3>=0.9.0 + +# DeepMind dependencies for pycolab environments +dm-sonnet>=1.34 +dm-tree>=0.1.7 +trfl>=1.2.0 + +# TensorFlow (for some utilities) +tensorflow>=1.15.0 +tensorboard>=1.15.0 + +# Image processing +Pillow>=9.1.0 +imageio>=2.19.0 +moviepy>=1.0.3 + +# Utilities +scipy>=1.7.0 +pandas>=1.1.0 +psutil>=5.9.0 +protobuf>=3.20.0 \ No newline at end of file diff --git a/conspecfunction/run.sh b/run.sh similarity index 100% rename from conspecfunction/run.sh rename to run.sh diff --git a/conspecfunction/run_eval.sh b/run_eval.sh similarity index 100% rename from conspecfunction/run_eval.sh rename to run_eval.sh diff --git a/conspecfunction/tvt/__init__.py b/tvt/__init__.py similarity index 100% rename from conspecfunction/tvt/__init__.py rename to tvt/__init__.py diff --git a/conspecfunction/tvt/batch_env.py b/tvt/batch_env.py similarity index 100% rename from conspecfunction/tvt/batch_env.py rename to tvt/batch_env.py diff --git a/conspecfunction/tvt/dmlab/README.md b/tvt/dmlab/README.md similarity index 100% rename from conspecfunction/tvt/dmlab/README.md rename to tvt/dmlab/README.md diff --git a/conspecfunction/tvt/dmlab/active_visual_match.lua b/tvt/dmlab/active_visual_match.lua similarity index 100% rename from conspecfunction/tvt/dmlab/active_visual_match.lua rename to tvt/dmlab/active_visual_match.lua diff --git a/conspecfunction/tvt/dmlab/image_utils.lua b/tvt/dmlab/image_utils.lua similarity index 100% rename from conspecfunction/tvt/dmlab/image_utils.lua rename to tvt/dmlab/image_utils.lua diff --git a/conspecfunction/tvt/dmlab/key_to_door.lua b/tvt/dmlab/key_to_door.lua similarity index 100% rename from conspecfunction/tvt/dmlab/key_to_door.lua rename to tvt/dmlab/key_to_door.lua diff --git a/conspecfunction/tvt/dmlab/key_to_door_bluekey.lua b/tvt/dmlab/key_to_door_bluekey.lua similarity index 100% rename from conspecfunction/tvt/dmlab/key_to_door_bluekey.lua rename to tvt/dmlab/key_to_door_bluekey.lua diff --git a/conspecfunction/tvt/dmlab/key_to_door_factory.lua b/tvt/dmlab/key_to_door_factory.lua similarity index 100% rename from conspecfunction/tvt/dmlab/key_to_door_factory.lua rename to tvt/dmlab/key_to_door_factory.lua diff --git a/conspecfunction/tvt/dmlab/key_to_door_to_match.lua b/tvt/dmlab/key_to_door_to_match.lua similarity index 100% rename from conspecfunction/tvt/dmlab/key_to_door_to_match.lua rename to tvt/dmlab/key_to_door_to_match.lua diff --git a/conspecfunction/tvt/dmlab/latent_information_acquisition.lua b/tvt/dmlab/latent_information_acquisition.lua similarity index 100% rename from conspecfunction/tvt/dmlab/latent_information_acquisition.lua rename to tvt/dmlab/latent_information_acquisition.lua diff --git a/conspecfunction/tvt/dmlab/latent_information_acquisition_factory.lua b/tvt/dmlab/latent_information_acquisition_factory.lua similarity index 100% rename from conspecfunction/tvt/dmlab/latent_information_acquisition_factory.lua rename to tvt/dmlab/latent_information_acquisition_factory.lua diff --git a/conspecfunction/tvt/dmlab/passive_visual_match.lua b/tvt/dmlab/passive_visual_match.lua similarity index 100% rename from conspecfunction/tvt/dmlab/passive_visual_match.lua rename to tvt/dmlab/passive_visual_match.lua diff --git a/conspecfunction/tvt/dmlab/two_keys_to_choose_factory.lua b/tvt/dmlab/two_keys_to_choose_factory.lua similarity index 100% rename from conspecfunction/tvt/dmlab/two_keys_to_choose_factory.lua rename to tvt/dmlab/two_keys_to_choose_factory.lua diff --git a/conspecfunction/tvt/dmlab/two_negative_keys.lua b/tvt/dmlab/two_negative_keys.lua similarity index 100% rename from conspecfunction/tvt/dmlab/two_negative_keys.lua rename to tvt/dmlab/two_negative_keys.lua diff --git a/conspecfunction/tvt/dmlab/visual_match_factory.lua b/tvt/dmlab/visual_match_factory.lua similarity index 100% rename from conspecfunction/tvt/dmlab/visual_match_factory.lua rename to tvt/dmlab/visual_match_factory.lua diff --git a/conspecfunction/tvt/images/avm_notvt.png b/tvt/images/avm_notvt.png similarity index 100% rename from conspecfunction/tvt/images/avm_notvt.png rename to tvt/images/avm_notvt.png diff --git a/conspecfunction/tvt/images/avm_notvt_gamma1.png b/tvt/images/avm_notvt_gamma1.png similarity index 100% rename from conspecfunction/tvt/images/avm_notvt_gamma1.png rename to tvt/images/avm_notvt_gamma1.png diff --git a/conspecfunction/tvt/images/avm_tvt.png b/tvt/images/avm_tvt.png similarity index 100% rename from conspecfunction/tvt/images/avm_tvt.png rename to tvt/images/avm_tvt.png diff --git a/conspecfunction/tvt/images/ktd_notvt.png b/tvt/images/ktd_notvt.png similarity index 100% rename from conspecfunction/tvt/images/ktd_notvt.png rename to tvt/images/ktd_notvt.png diff --git a/conspecfunction/tvt/images/ktd_notvt_gamma1.png b/tvt/images/ktd_notvt_gamma1.png similarity index 100% rename from conspecfunction/tvt/images/ktd_notvt_gamma1.png rename to tvt/images/ktd_notvt_gamma1.png diff --git a/conspecfunction/tvt/images/ktd_tvt.png b/tvt/images/ktd_tvt.png similarity index 100% rename from conspecfunction/tvt/images/ktd_tvt.png rename to tvt/images/ktd_tvt.png diff --git a/conspecfunction/tvt/nest_utils.py b/tvt/nest_utils.py similarity index 100% rename from conspecfunction/tvt/nest_utils.py rename to tvt/nest_utils.py diff --git a/conspecfunction/tvt/pycolab/common.py b/tvt/pycolab/common.py similarity index 100% rename from conspecfunction/tvt/pycolab/common.py rename to tvt/pycolab/common.py diff --git a/conspecfunction/tvt/pycolab/env.py b/tvt/pycolab/env.py similarity index 100% rename from conspecfunction/tvt/pycolab/env.py rename to tvt/pycolab/env.py diff --git a/conspecfunction/tvt/pycolab/game.py b/tvt/pycolab/game.py similarity index 100% rename from conspecfunction/tvt/pycolab/game.py rename to tvt/pycolab/game.py diff --git a/conspecfunction/tvt/pycolab/human_player.py b/tvt/pycolab/human_player.py similarity index 100% rename from conspecfunction/tvt/pycolab/human_player.py rename to tvt/pycolab/human_player.py diff --git a/conspecfunction/tvt/pycolab/key_to_door2.py b/tvt/pycolab/key_to_door2.py similarity index 100% rename from conspecfunction/tvt/pycolab/key_to_door2.py rename to tvt/pycolab/key_to_door2.py diff --git a/conspecfunction/tvt/pycolab/key_to_door3.py b/tvt/pycolab/key_to_door3.py similarity index 100% rename from conspecfunction/tvt/pycolab/key_to_door3.py rename to tvt/pycolab/key_to_door3.py diff --git a/conspecfunction/tvt/pycolab/key_to_door4.py b/tvt/pycolab/key_to_door4.py similarity index 100% rename from conspecfunction/tvt/pycolab/key_to_door4.py rename to tvt/pycolab/key_to_door4.py diff --git a/conspecfunction/tvt/pycolab/objects.py b/tvt/pycolab/objects.py similarity index 100% rename from conspecfunction/tvt/pycolab/objects.py rename to tvt/pycolab/objects.py