removing gail-trpo since performance is about the same as gail, adding experiment evaluation script, updating metric averaging to work
This commit is contained in:
74
eval_experiments.py
Normal file
74
eval_experiments.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import os
|
||||
from src.eval_main import eval_main
|
||||
from src.evaluation.utils import load_and_average
|
||||
|
||||
def main(method:str='expert', folder:str=None, locations=[(0,0)], skip_running=False):
|
||||
|
||||
policy_kwargs = {}
|
||||
if method in ['expert', 'idm']:
|
||||
env, env_kwargs ='NRasterizedRouteIncrementingAgent', {}
|
||||
elif method in ['bc','gail']:
|
||||
env='NormalizedContinuousEvalEnv'
|
||||
env_kwargs={stop_on_collision:True, max_episode_steps:1000}
|
||||
elif method in ['hail']:
|
||||
env = 'NormalizedOptionsEvalEnv'
|
||||
env_kwargs={stop_on_collision:True, max_episode_steps:1000}
|
||||
elif method in ['shail']:
|
||||
env = 'NormalizedSafeOptionsEvalEnv'
|
||||
env_kwargs={stop_on_collision:True, max_episode_steps:1000}
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
files = ['']
|
||||
|
||||
if folder is not None:
|
||||
files = [os.path.join(folder, f) for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f))]
|
||||
print('%i folders found in %s folder' %(len(files), folder))
|
||||
|
||||
if not skip_running:
|
||||
for policy_file in files:
|
||||
# run metrics on that file
|
||||
outbase = eval_main(locations=locations,
|
||||
method=method,
|
||||
policy_file=policy_file,
|
||||
policy_kwargs=policy_kwargs,
|
||||
env=env,
|
||||
env_kwargs=env_kwargs)
|
||||
outfolder = os.path.dirname(outbase)
|
||||
else:
|
||||
locstr = 'loc_'+'_'.join([f'r{ro}t{tr}' for (ro,tr) in locations])
|
||||
outfolder = os.path.join('out',method,locstr)
|
||||
|
||||
import pdb
|
||||
pdb.set_trace()
|
||||
# load metrics from save_path
|
||||
average_metrics = load_and_average(outfolder)
|
||||
if method in ['expert', 'idm']:
|
||||
latex_print(average_metrics, light=True)
|
||||
else:
|
||||
latex_print(average_metrics)
|
||||
|
||||
def latex_print(am, light=False):
|
||||
"""
|
||||
print latex line
|
||||
|
||||
am (Dict[str,tuple]): dict mapping metric_name to (mean, std)
|
||||
"""
|
||||
|
||||
print('success rate, distance travelled, RWSE_10, |DeltaV|, AccelJSD')
|
||||
if light:
|
||||
print("%2.1f& %2.1f & --- & --- & "
|
||||
"--- \\\\" %( 100*am['success rate'][0], am['mean travel distance'][0]))
|
||||
return
|
||||
|
||||
print("%2.1f \\scriptstyle\\pm %2.1f & %2.1f \\scriptstyle\\pm %2.1f & "
|
||||
"%1.2f \\scriptstyle\\pm %1.2f & %2.1f \\scriptstyle\\pm %1.1f & "
|
||||
"%0.3f \\scriptstyle\\pm %0.3f \\\\" %( 100*am['success rate'][0], 100*am['success rate'][1],
|
||||
am['mean travel distance'][0] , am['mean travel distance'][1] ,
|
||||
am['rwse_10s'][0] , am['rwse_10s'][1] ,
|
||||
am['average absolute average velocity'][0] , am['average absolute average velocity'][1] ,
|
||||
am['acceleration distribution divergence'][0] , am['acceleration distribution divergence'][1] ))
|
||||
|
||||
if __name__=='__main__':
|
||||
import fire
|
||||
fire.Fire(main)
|
||||
@@ -1,79 +1,14 @@
|
||||
# eval_main inputs
|
||||
# locations: List[Tuple[int,int]]= [(0,0)],
|
||||
# method: str='expert',
|
||||
# policy_file: str='',
|
||||
# policy_kwargs: dict={},
|
||||
# env: str='NRasterizedRouteIncrementingAgent',
|
||||
# env_kwargs: dict={},
|
||||
# seed: int=0
|
||||
# can add --skip_running if you've run before
|
||||
|
||||
# expert
|
||||
python -m src.eval_main
|
||||
|
||||
# idm
|
||||
python -m src.eval_main --method=idm
|
||||
|
||||
# behavior cloning
|
||||
python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=0
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=1
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=2
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=3
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=4
|
||||
#python -m src.evaluation.utils load_and_average out/bc
|
||||
|
||||
# GAIL
|
||||
python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=0
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=1
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=2
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=3
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=4
|
||||
#python -m src.evaluation.utils load_and_average out/gail
|
||||
|
||||
# options GAIL
|
||||
python -m src.eval_main --method=ogail --policy_file='checkpoints/gail-options-setobs2-Feb15_18-49-05.pt' --env='NormalizedOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}'
|
||||
|
||||
# options GAIL-PPO
|
||||
python -m src.eval_main --method=ogail-ppo --policy_file='checkpoints/gail-ppo-options-setobs2-Feb15_22-05-38.pt' --env='NormalizedOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}'
|
||||
|
||||
# SHAIL
|
||||
python -m src.eval_main --method=sgail --policy_file='checkpoints/sgail-options-setobs2-Feb21_13-30-45.pt' --env='NormalizedSafeOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}'
|
||||
|
||||
# SHAIL-PPO
|
||||
python -m src.eval_main --method=sgail-ppo --policy_file='checkpoints/sgail-ppo-options-setobs2-17-02-2022.pt' --env='NormalizedSafeOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}'
|
||||
|
||||
|
||||
|
||||
### Same checkpoint files applied out of distribution (e.g. to track 5)
|
||||
# expert
|
||||
python -m src.eval_main --locations='[(0,4)]'
|
||||
|
||||
# idm
|
||||
python -m src.eval_main --method=idm --locations='[(0,4)]'
|
||||
|
||||
# behavior cloning
|
||||
python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=0 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=1 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=2 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=3 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=bc --policy_file='checkpoints/bc-intersimple-setobs2.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=4 --locations='[(0,4)]'
|
||||
#python -m src.evaluation.utils load_and_average out/bc
|
||||
|
||||
# GAIL
|
||||
python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=0 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=1 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=2 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=3 --locations='[(0,4)]'
|
||||
#python -m src.eval_main --method=gail --policy_file='checkpoints/gail-intersimple-setobs2-03-02-22.pt' --env='NormalizedContinuousEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --seed=4 --locations='[(0,4)]'
|
||||
#python -m src.evaluation.utils load_and_average out/gail
|
||||
|
||||
# options GAIL
|
||||
python -m src.eval_main --method=ogail --policy_file='checkpoints/gail-options-setobs2-Feb15_18-49-05.pt' --env='NormalizedOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --locations='[(0,4)]'
|
||||
|
||||
# options GAIL-PPO
|
||||
python -m src.eval_main --method=ogail-ppo --policy_file='checkpoints/gail-ppo-options-setobs2-Feb15_22-05-38.pt' --env='NormalizedOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --locations='[(0,4)]'
|
||||
|
||||
# SHAIL
|
||||
python -m src.eval_main --method=sgail --policy_file='checkpoints/sgail-options-setobs2-Feb21_13-30-45.pt' --env='NormalizedSafeOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --locations='[(0,4)]'
|
||||
|
||||
# SHAIL-PPO
|
||||
python -m src.eval_main --method=sgail-ppo --policy_file='checkpoints/sgail-ppo-options-setobs2-17-02-2022.pt' --env='NormalizedSafeOptionsEvalEnv' --env_kwargs='{stop_on_collision:True,max_episode_steps:1000}' --locations='[(0,4)]'
|
||||
python -m eval_experiments
|
||||
python -m eval_experiments --locations='[(0,4)]'
|
||||
python -m eval_experiments --method idm
|
||||
python -m eval_experiments --method idm --locations='[(0,4)]'
|
||||
python -m eval_experiments --method bc --folder='test_policies/bc/expA'
|
||||
python -m eval_experiments --method bc --folder='test_policies/bc/expB' --locations='[(0,4)]'
|
||||
python -m eval_experiments --method gail --folder='test_policies/gail/expA'
|
||||
python -m eval_experiments --method gail --folder='test_policies/gail/expB'--locations='[(0,4)]'
|
||||
python -m eval_experiments --method hail
|
||||
python -m eval_experiments --method hail --locations='[(0,4)]'
|
||||
python -m eval_experiments --method shail
|
||||
python -m eval_experiments --method shail --locations='[(0,4)]'
|
||||
@@ -1,235 +0,0 @@
|
||||
# %%
|
||||
import os
|
||||
|
||||
import gym
|
||||
from src.core.gail import gail, Buffer
|
||||
from src.core.value import SetValue
|
||||
from src.core.policy import SetPolicy
|
||||
from src.core.discriminator import DeepsetDiscriminator
|
||||
import torch
|
||||
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from src.util.wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
from ray import tune
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
activations = [torch.nn.Tanh, torch.nn.LeakyReLU]
|
||||
|
||||
obs_min = np.array([
|
||||
[-1000, -1000, 0, -np.pi, -1e-1, 0.],
|
||||
[0, -np.pi, -20, -20, -np.pi, -1e-1],
|
||||
[0, -np.pi, -20, -20, -np.pi, -1e-1],
|
||||
[0, -np.pi, -20, -20, -np.pi, -1e-1],
|
||||
[0, -np.pi, -20, -20, -np.pi, -1e-1],
|
||||
[0, -np.pi, -20, -20, -np.pi, -1e-1],
|
||||
]).reshape(-1)
|
||||
|
||||
obs_max = np.array([
|
||||
[1000, 1000, 20, np.pi, 1e-1, 0.],
|
||||
[50, np.pi, 20, 20, np.pi, 1e-1],
|
||||
[50, np.pi, 20, 20, np.pi, 1e-1],
|
||||
[50, np.pi, 20, 20, np.pi, 1e-1],
|
||||
[50, np.pi, 20, 20, np.pi, 1e-1],
|
||||
[50, np.pi, 20, 20, np.pi, 1e-1],
|
||||
]).reshape(-1)
|
||||
|
||||
def training_function(config):
|
||||
np.random.seed(config['seed'])
|
||||
torch.manual_seed(config['seed'])
|
||||
|
||||
if config['experiment'] == 'A':
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(
|
||||
IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
check_collisions=True,
|
||||
stop_on_collision=config['trainenv']['stop_on_collision'],
|
||||
), collision_distance=6, collision_penalty=100),
|
||||
lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)
|
||||
)) for _ in range(60)]
|
||||
|
||||
elif config['experiment'] == 'B':
|
||||
envs = sum([[Setobs(TransformObservation(CollisionPenaltyWrapper(
|
||||
IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
check_collisions=True,
|
||||
stop_on_collision=config['trainenv']['stop_on_collision'],
|
||||
track=track,
|
||||
), collision_distance=6, collision_penalty=100),
|
||||
lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)
|
||||
)) for _ in range(15)] for track in range(4)],[])
|
||||
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0],
|
||||
n_hidden_layers=config['policy']['n_hidden_layers'],
|
||||
hidden_layer_size=config['policy']['hidden_layer_size'],
|
||||
activation=activations[config['policy']['activation']] ) # config net architecture
|
||||
|
||||
value = SetValue() # config net architecture
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=config['value']['learning_rate'], weight_decay=config['value']['weight_decay'])
|
||||
|
||||
discriminator = DeepsetDiscriminator(
|
||||
n_hidden_layers_element=config['discriminator']['n_hidden_layers_element'],
|
||||
n_hidden_layers_global=config['discriminator']['n_hidden_layers_global'],
|
||||
hidden_layer_size=config['discriminator']['hidden_layer_size'],
|
||||
activation=activations[config['discriminator']['activation']],
|
||||
)
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=config['discriminator']['learning_rate'], weight_decay=config['discriminator']['weight_decay'])
|
||||
|
||||
if config['experiment'] == 'A':
|
||||
expert_data = torch.load(os.path.join(DIR, 'intersimple-expert-data-setobs2-loc0-track0.pt'))
|
||||
elif config['experiment'] == 'B':
|
||||
expert_data = [
|
||||
torch.load(os.path.join(DIR, 'intersimple-expert-data-setobs2-loc0-track0.pt')),
|
||||
torch.load(os.path.join(DIR, 'intersimple-expert-data-setobs2-loc0-track1.pt')),
|
||||
torch.load(os.path.join(DIR, 'intersimple-expert-data-setobs2-loc0-track2.pt')),
|
||||
torch.load(os.path.join(DIR, 'intersimple-expert-data-setobs2-loc0-track3.pt')),
|
||||
]
|
||||
d0 = [d[0] for d in expert_data]
|
||||
d1 = [d[1] for d in expert_data]
|
||||
d2 = [d[2] for d in expert_data]
|
||||
d3 = [d[3] for d in expert_data]
|
||||
expert_data = (torch.cat(d0), torch.cat(d1), torch.cat(d2), torch.cat(d3))
|
||||
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
def callback(info):
|
||||
tune.report(gen_mean_reward_per_episode=info['gen/mean_reward_per_episode'],
|
||||
disc_mean_reward_per_episode=info['disc/mean_reward_per_episode'],
|
||||
mean_episode_length=info['gen/mean_episode_length'],
|
||||
gen_collision_rate=info['gen/collision_rate'])
|
||||
|
||||
# save model checkpoints
|
||||
ep = info['epoch'] + 1
|
||||
if (ep % 25 == 0):
|
||||
torch.save(info['policy'].state_dict(), f'policy_epoch{ep}.pt')
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=config['discriminator']['iterations_per_epoch'],
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=config['value']['iterations_per_epoch'],
|
||||
epochs=config['train_epochs'],
|
||||
rollout_episodes=60,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=config['policy']['delta'],
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
logger=SummaryWriter(comment='gail-trpo-options-setobs2'),
|
||||
callback=callback,
|
||||
)
|
||||
|
||||
# save model
|
||||
torch.save(policy.state_dict(), 'policy_final.pt')
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--train', choices=['A', 'B'])
|
||||
parser.add_argument('--epochs', type=int, default=200)
|
||||
parser.add_argument('--test', type=str, help='path to config file to run final training on')
|
||||
parser.add_argument('--test_seeds', type=int, default=5)
|
||||
parser.add_argument('--test_cpus', type=int, help='number of cpus available to split test seed training over')
|
||||
args = parser.parse_args()
|
||||
|
||||
assert (args.train is None) ^ (args.test is None), 'Must either train on an experiment or test with a config file'
|
||||
|
||||
# if no test config specified, train
|
||||
if args.test is None:
|
||||
print('Running Tuning for Experiment %s'%(args.train))
|
||||
analysis = tune.run(
|
||||
training_function,
|
||||
config={
|
||||
'experiment': args.train,
|
||||
'trainenv': {
|
||||
'stop_on_collision': False,
|
||||
},
|
||||
'policy': {
|
||||
'learning_rate': 3e-4,
|
||||
'learning_rate_decay': 1.0,
|
||||
'delta': 0.01,
|
||||
'iterations_per_epoch': 100,
|
||||
'hidden_layer_size': tune.grid_search([20, 40]),
|
||||
'n_hidden_layers': tune.grid_search([2, 3]),
|
||||
'activation':0,
|
||||
},
|
||||
'value': {
|
||||
'learning_rate': 1e-4,
|
||||
'weight_decay': 1e-3,
|
||||
'iterations_per_epoch': 1000,
|
||||
},
|
||||
'discriminator': {
|
||||
'learning_rate': 1e-3,
|
||||
'weight_decay': 1e-4,
|
||||
'iterations_per_epoch': 100,
|
||||
'n_hidden_layers_element': tune.grid_search([3,4]),
|
||||
'n_hidden_layers_global': tune.grid_search([1,2]),
|
||||
'hidden_layer_size': 10,
|
||||
'activation': 0,
|
||||
},
|
||||
'train_epochs': args.epochs,
|
||||
'seed': 0,
|
||||
}
|
||||
)
|
||||
best_config = analysis.get_best_config(metric='gen_collision_rate', mode='min')
|
||||
print('Best config: ', best_config)
|
||||
|
||||
# safe best_config
|
||||
if not os.path.isdir(os.path.join(DIR, 'best_configs')):
|
||||
os.mkdir(os.path.join(DIR, 'best_configs'))
|
||||
|
||||
# save gail
|
||||
with open(os.path.join(DIR, 'best_configs',f'gail-trpo_exp{args.train}.json'), 'w', encoding='utf-8') as f:
|
||||
json.dump(best_config, f, ensure_ascii=False, indent=4)
|
||||
|
||||
# if config file specified, rerun it with appropriate number of seeds
|
||||
else:
|
||||
with open(args.test, 'rb') as f:
|
||||
config = json.load(f)
|
||||
|
||||
print(f'Retraining {args.test} with {args.test_seeds} seeds on experiment {config["experiment"]}')
|
||||
|
||||
# rerun with appropriate number of seeds
|
||||
rpt = {'cpu': int(args.test_cpus/args.test_seeds)} if (args.test_cpus is not None) else None
|
||||
config['seed'] = tune.grid_search(list(range(1,args.test_seeds+1)))
|
||||
analysis = tune.run(training_function, config=config, resources_per_trial=rpt)
|
||||
|
||||
# move final policies to appropriate directory
|
||||
split_ = os.path.basename(args.test).split('_')
|
||||
model = split_[0]
|
||||
exper = split_[-1].split('.')[0]
|
||||
savepath = os.path.join('test_policies',model,exper)
|
||||
|
||||
if not os.path.isdir(savepath):
|
||||
os.makedirs(savepath)
|
||||
|
||||
import shutil
|
||||
for i in range(args.test_seeds):
|
||||
s = analysis._checkpoints[i]['config']['seed']
|
||||
check_dir = analysis._checkpoints[i]['logdir']
|
||||
shutil.copyfile(os.path.join(check_dir,'policy_final.pt'),
|
||||
os.path.join(savepath, f'policy_seed{s}.pt'))
|
||||
@@ -15,7 +15,7 @@ from src.options import envs as options_envs2
|
||||
from src.safe_options.policy import SetMaskedDiscretePolicy
|
||||
from src.safe_options import options as options_envs3
|
||||
from src.util.wrappers import IntersimpleTimeLimit
|
||||
|
||||
import os
|
||||
from typing import Optional, List, Dict, Tuple
|
||||
import torch
|
||||
import numpy as np
|
||||
@@ -44,29 +44,29 @@ def load_policy(method:str,
|
||||
policy = SetPolicy(env.action_space.shape[-1])
|
||||
policy.load_state_dict(torch.load(policy_file, map_location=ml))
|
||||
policy.eval()
|
||||
elif method == 'gail':
|
||||
elif method == 'gail-trpo':
|
||||
policy = SetPolicy(env.action_space.shape[-1])
|
||||
policy(torch.zeros(env.observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load(policy_file, map_location=ml))
|
||||
policy.eval()
|
||||
elif method == 'gail-ppo':
|
||||
elif method == 'gail':
|
||||
policy = SetPolicy(env.action_space.shape[-1])
|
||||
policy.load_state_dict(torch.load(policy_file, map_location=ml))
|
||||
policy.eval()
|
||||
elif method == 'rail':
|
||||
raise NotImplementedError
|
||||
elif method == 'ogail':
|
||||
elif method == 'hail-trpo':
|
||||
policy = SetDiscretePolicy(env.action_space.n)
|
||||
policy(torch.zeros(env.observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load(policy_file, map_location=ml))
|
||||
policy.eval()
|
||||
elif method == 'ogail-ppo':
|
||||
elif method == 'hail':
|
||||
policy = SetDiscretePolicy(env.action_space.n)
|
||||
policy.load_state_dict(torch.load(policy_file, map_location=ml))
|
||||
policy.eval()
|
||||
elif method == 'sgail':
|
||||
elif method == 'shail-trpo':
|
||||
policy = SetMaskedDiscretePolicy(env.action_space.n)
|
||||
policy(
|
||||
torch.zeros(env.observation_space['observation'].shape),
|
||||
@@ -75,7 +75,7 @@ def load_policy(method:str,
|
||||
policy = ReparamSafePolicy(policy)
|
||||
policy.load_state_dict(torch.load(policy_file, map_location=ml))
|
||||
policy.eval()
|
||||
elif method == 'sgail-ppo':
|
||||
elif method == 'shail':
|
||||
policy = SetMaskedDiscretePolicy(env.action_space.n)
|
||||
policy.load_state_dict(torch.load(policy_file, map_location=ml))
|
||||
policy.eval()
|
||||
@@ -375,6 +375,9 @@ def eval_main(
|
||||
policy_file (str): path to saved policy
|
||||
env (str): environment class
|
||||
method (str): method (expert, bc, gail, rail, hgail, hrail)
|
||||
|
||||
Returns:
|
||||
outbase (str): string to outbase
|
||||
"""
|
||||
print(f'#############################################################################')
|
||||
print(f'Evaluating {method} from file {policy_file} on {env} at locations {locations}')
|
||||
@@ -383,9 +386,17 @@ def eval_main(
|
||||
# set seed
|
||||
np.random.seed(seed)
|
||||
torch.manual_seed(seed)
|
||||
pfilename = policy_file.split('/')[-1].split('.')[0]
|
||||
locstr = 'loc_'+'_'.join([f'r{ro}t{tr}' for (ro,tr) in locations])
|
||||
outbase = f'out/{method}/{locstr}/{pfilename}_seed{seed}'
|
||||
if policy_file == '':
|
||||
method_path = method
|
||||
name_base = method
|
||||
else:
|
||||
path_items = policy_file.split('/')
|
||||
name_base = path_items[-1].split('.')[0]
|
||||
method_path = ('/').join(path_items[1:-1])
|
||||
outfolder = os.path.join('out',method_path,locstr)
|
||||
filebase = name_base + f'_tseed{seed}'
|
||||
outbase = os.path.join(outfolder,filebase)
|
||||
|
||||
# load expert metrics
|
||||
expert_metrics = generate_expert_metrics(locations)
|
||||
@@ -405,6 +416,8 @@ def eval_main(
|
||||
cmetrics = comparison_metrics(policy_metrics, expert_metrics, outbase=outbase)
|
||||
save_metrics(cmetrics, outbase+'_comparison.pkl')
|
||||
|
||||
return outbase
|
||||
|
||||
if __name__=='__main__':
|
||||
import fire
|
||||
fire.Fire(eval_main)
|
||||
|
||||
@@ -34,13 +34,20 @@ def load_metrics(filestr:str):
|
||||
metrics = pickle.load(f)
|
||||
return metrics
|
||||
|
||||
def average_metrics(metric_list:List[Dict[str,float]]):
|
||||
def average_metrics(metric_list:List[Dict[str,float]], verbose:bool=True) ->Dict[str, tuple]:
|
||||
"""
|
||||
Average all the metrics in the list
|
||||
|
||||
Args:
|
||||
metric_list (list of dicts): list of metric dicts which each map a string to a float
|
||||
verbose (bool): whether to print avg metrics
|
||||
Returns:
|
||||
average_metrics (Dict[str, tuple])
|
||||
"""
|
||||
average_metrics = {}
|
||||
if len(metric_list) == 0:
|
||||
return average_metrics
|
||||
|
||||
keys = list(metric_list[0].keys())
|
||||
N = len(metric_list)
|
||||
master_dict = {key:[] for key in keys}
|
||||
@@ -50,29 +57,39 @@ def average_metrics(metric_list:List[Dict[str,float]]):
|
||||
master_dict[key] = np.array(master_dict[key])
|
||||
mu = np.nanmean(master_dict[key])
|
||||
std2 = np.nanstd(master_dict[key])*2
|
||||
if verbose:
|
||||
print(f'{key}: {mu} \pm {std2}')
|
||||
average_metrics[key] = (mu, std2)
|
||||
return average_metrics
|
||||
|
||||
|
||||
def load_and_average(path:str):
|
||||
def load_and_average(path:str, verbose:bool=True):
|
||||
"""
|
||||
Load and average all metric files in a particular folder
|
||||
|
||||
Args:
|
||||
path (str)
|
||||
verbose (bool): whether to print avg metrics
|
||||
Returns:
|
||||
avg_metrics (Dict[str, tuple])
|
||||
"""
|
||||
assert os.path.isdir(path)
|
||||
|
||||
# summary metrics
|
||||
summary_files = [os.path.join(path,f) for f in os.listdir(path) if f.endswith('summary.pkl')]
|
||||
if verbose:
|
||||
print(*summary_files, sep='\n')
|
||||
all_summary_metrics = [load_metrics(f) for f in summary_files]
|
||||
average_metrics(all_summary_metrics)
|
||||
avg_metrics = average_metrics(all_summary_metrics, verbose=verbose)
|
||||
|
||||
# comparison metrics
|
||||
comp_files = [os.path.join(path,f) for f in os.listdir(path) if f.endswith('comparison.pkl')]
|
||||
if verbose:
|
||||
print(*comp_files, sep='\n')
|
||||
all_comp_metrics = [load_metrics(f) for f in comp_files]
|
||||
average_metrics(all_comp_metrics)
|
||||
comp_avg = average_metrics(all_comp_metrics, verbose=verbose)
|
||||
avg_metrics.update(comp_avg)
|
||||
return avg_metrics
|
||||
|
||||
if __name__=='__main__':
|
||||
import fire
|
||||
|
||||
Reference in New Issue
Block a user