Port TRPO, PPO, GAIL
This commit is contained in:
232
scratch/etienne/trpo/.gitignore
vendored
Normal file
232
scratch/etienne/trpo/.gitignore
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
PyTorch-Reparam-Module
|
||||
cg.ipynb
|
||||
vec-env.ipynb
|
||||
*.zip
|
||||
*.pt
|
||||
*.mp4
|
||||
*.pkl
|
||||
runs/
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/linux,macos,python,visualstudiocode
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=linux,macos,python,visualstudiocode
|
||||
|
||||
### Linux ###
|
||||
*~
|
||||
|
||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||
.fuse_hidden*
|
||||
|
||||
# KDE directory preferences
|
||||
.directory
|
||||
|
||||
# Linux trash folder which might appear on any partition or disk
|
||||
.Trash-*
|
||||
|
||||
# .nfs files are created when an open file is removed but is still being accessed
|
||||
.nfs*
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
# Support for Project snippet scope
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/linux,macos,python,visualstudiocode
|
||||
78
scratch/etienne/trpo/bc-intersimple-setobs2.py
Normal file
78
scratch/etienne/trpo/bc-intersimple-setobs2.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# %%
|
||||
import torch
|
||||
from core.policy import SetPolicy
|
||||
from tqdm import tqdm
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
states, actions, _, dones = expert_data
|
||||
|
||||
policy = SetPolicy(actions.shape[-1])
|
||||
|
||||
policy = policy.cuda()
|
||||
optim = torch.optim.Adam(policy.parameters(), lr=1e-4)
|
||||
states = states[~dones].cuda()
|
||||
actions = actions[~dones].cuda()
|
||||
|
||||
for _ in tqdm(range(10000)):
|
||||
optim.zero_grad()
|
||||
loss = -policy.log_prob(policy(states), actions).mean()
|
||||
loss.backward()
|
||||
optim.step()
|
||||
|
||||
print('Loss', loss)
|
||||
|
||||
torch.save(policy.state_dict(), 'bc-intersimple-setobs2.pt')
|
||||
|
||||
# %%
|
||||
import numpy as np
|
||||
from core.policy import SetPolicy
|
||||
from wrappers import Setobs, TransformObservation, CollisionPenaltyWrapper
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
policy = SetPolicy(actions.shape[-1])
|
||||
policy.load_state_dict(torch.load('bc-intersimple-setobs2.pt'))
|
||||
|
||||
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)
|
||||
|
||||
env = Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
)
|
||||
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
74
scratch/etienne/trpo/core/discriminator.py
Normal file
74
scratch/etienne/trpo/core/discriminator.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
|
||||
class Discriminator(nn.Module):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.nn = nn.Sequential(
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(1),
|
||||
)
|
||||
|
||||
def forward(self, states, actions):
|
||||
return self.nn(torch.cat((states, actions), dim=-1)).squeeze(-1)
|
||||
|
||||
class DeepsetDiscriminator(nn.Module):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.elem = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
)
|
||||
self.glob = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(1),
|
||||
)
|
||||
|
||||
def forward(self, states, actions):
|
||||
actions = actions.unsqueeze(-2)
|
||||
actions = actions.expand(*actions.shape[:-2], states.shape[-2], actions.shape[-1])
|
||||
sa = torch.cat((states, actions), dim=-1)
|
||||
return self.glob(self.elem(sa).sum(-2)).squeeze(-1)
|
||||
|
||||
class RecurrentDiscriminator(nn.Module):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.state_dim = 10
|
||||
self.state = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(self.state_dim),
|
||||
)
|
||||
self.glob = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(1),
|
||||
)
|
||||
|
||||
def forward(self, states, actions):
|
||||
actions = actions.unsqueeze(-2)
|
||||
batch_size = actions.shape[:-2]
|
||||
set_size = states.shape[-2]
|
||||
action_dim = actions.shape[-1]
|
||||
actions = actions.expand(*batch_size, set_size, action_dim)
|
||||
sa = torch.cat((states, actions), dim=-1)
|
||||
|
||||
state = torch.zeros((*batch_size, self.state_dim))
|
||||
for i in range(set_size):
|
||||
state = state + self.state(torch.cat((state, sa[..., i, :]), dim=-1))
|
||||
|
||||
return self.glob(state).squeeze(-1)
|
||||
125
scratch/etienne/trpo/core/gail.py
Normal file
125
scratch/etienne/trpo/core/gail.py
Normal file
@@ -0,0 +1,125 @@
|
||||
import torch
|
||||
import torch.nn.functional as F
|
||||
from dataclasses import dataclass
|
||||
from core.reparam_module import ReparamPolicy
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo_step
|
||||
from core.ppo import ppo_step
|
||||
from tqdm import tqdm
|
||||
|
||||
class TerminalLogger:
|
||||
def add_scalar(self, key, scalar, i=None):
|
||||
if i is not None:
|
||||
print('Iteration', i, end=' ')
|
||||
print(key, scalar)
|
||||
|
||||
@dataclass
|
||||
class Buffer:
|
||||
states: torch.Tensor
|
||||
actions: torch.Tensor
|
||||
rewards: torch.Tensor
|
||||
dones: torch.Tensor
|
||||
|
||||
def roll_buffer(buffer, *args, **kwargs):
|
||||
return Buffer(
|
||||
torch.roll(buffer.states, *args, **kwargs),
|
||||
torch.roll(buffer.actions, *args, **kwargs),
|
||||
torch.roll(buffer.rewards, *args, **kwargs),
|
||||
torch.roll(buffer.dones, *args, **kwargs),
|
||||
)
|
||||
|
||||
def gail(env_fn, expert_data, discriminator, disc_opt, disc_iters, policy, value,
|
||||
v_opt, v_iters, epochs, rollout_episodes, rollout_steps, gamma,
|
||||
gae_lambda, delta, backtrack_coeff, backtrack_iters, cg_iters=10, cg_damping=0.1, wasserstein=False, wasserstein_c=None, logger=TerminalLogger()):
|
||||
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
|
||||
logger.add_scalar('expert/mean_episode_length', (~expert_data.dones).sum() / expert_data.states.shape[0])
|
||||
logger.add_scalar('expert/mean_reward_per_episode', expert_data.rewards[~expert_data.dones].sum() / expert_data.states.shape[0])
|
||||
|
||||
for epoch in tqdm(range(epochs)):
|
||||
generator_data = Buffer(*rollout(env_fn, policy, rollout_episodes, rollout_steps))
|
||||
|
||||
logger.add_scalar('gen/mean_episode_length', (~generator_data.dones).sum() / generator_data.states.shape[0], epoch)
|
||||
logger.add_scalar('gen/mean_reward_per_episode', generator_data.rewards[~generator_data.dones].sum() / generator_data.states.shape[0], epoch)
|
||||
|
||||
discriminator, loss = train_discriminator(expert_data, generator_data, discriminator, disc_opt, disc_iters, wasserstein, wasserstein_c)
|
||||
if wasserstein:
|
||||
generator_data.rewards = discriminator(generator_data.states, generator_data.actions)
|
||||
else:
|
||||
generator_data.rewards = -F.logsigmoid(discriminator(generator_data.states, generator_data.actions))
|
||||
logger.add_scalar('disc/final_loss', loss, epoch)
|
||||
logger.add_scalar('disc/mean_reward_per_episode', generator_data.rewards[~generator_data.dones].sum() / generator_data.states.shape[0], epoch)
|
||||
|
||||
value, policy = trpo_step(value, policy, generator_data.states, generator_data.actions, generator_data.rewards, generator_data.dones, gamma, gae_lambda, delta, backtrack_coeff, backtrack_iters, v_opt, v_iters, cg_iters, cg_damping)
|
||||
expert_data = roll_buffer(expert_data, shifts=-3, dims=0)
|
||||
|
||||
return value, policy
|
||||
|
||||
def gail_ppo(env_fn, expert_data, discriminator, disc_opt, disc_iters, policy, value,
|
||||
v_opt, v_iters, epochs, rollout_episodes, rollout_steps, gamma,
|
||||
gae_lambda, clip_ratio, pi_opt, pi_iters, target_kl=None, max_grad_norm=None, wasserstein=False, wasserstein_c=None, logger=TerminalLogger()):
|
||||
|
||||
logger.add_scalar('expert/mean_episode_length', (~expert_data.dones).sum() / expert_data.states.shape[0])
|
||||
logger.add_scalar('expert/mean_reward_per_episode', expert_data.rewards[~expert_data.dones].sum() / expert_data.states.shape[0])
|
||||
|
||||
for epoch in range(epochs):
|
||||
generator_data = Buffer(*rollout(env_fn, policy, rollout_episodes, rollout_steps))
|
||||
|
||||
logger.add_scalar('gen/mean_episode_length', (~generator_data.dones).sum() / generator_data.states.shape[0], epoch)
|
||||
logger.add_scalar('gen/mean_reward_per_episode', generator_data.rewards[~generator_data.dones].sum() / generator_data.states.shape[0], epoch)
|
||||
|
||||
discriminator, loss = train_discriminator(expert_data, generator_data, discriminator, disc_opt, disc_iters, wasserstein, wasserstein_c)
|
||||
if wasserstein:
|
||||
generator_data.rewards = discriminator(generator_data.states, generator_data.actions)
|
||||
else:
|
||||
generator_data.rewards = -F.logsigmoid(discriminator(generator_data.states, generator_data.actions))
|
||||
logger.add_scalar('disc/final_loss', loss, epoch)
|
||||
logger.add_scalar('disc/mean_reward_per_episode', generator_data.rewards[~generator_data.dones].sum() / generator_data.states.shape[0], epoch)
|
||||
|
||||
value, policy = ppo_step(value, policy, generator_data.states, generator_data.actions, generator_data.rewards, generator_data.dones, clip_ratio, gamma, gae_lambda, pi_opt, pi_iters, v_opt, v_iters, target_kl, max_grad_norm)
|
||||
expert_data = roll_buffer(expert_data, shifts=-3, dims=0)
|
||||
|
||||
return value, policy
|
||||
|
||||
def train_discriminator(expert_data, generator_data, discriminator, disc_opt, disc_iters, wasserstein, wasserstein_c=None):
|
||||
|
||||
n_expert_samples = (~expert_data.dones).sum()
|
||||
n_generator_samples = (~generator_data.dones).sum()
|
||||
n_samples = torch.minimum(n_expert_samples, n_generator_samples)
|
||||
|
||||
gen_states = generator_data.states[~generator_data.dones][:n_samples]
|
||||
gen_actions = generator_data.actions[~generator_data.dones][:n_samples]
|
||||
exp_states = expert_data.states[~expert_data.dones][:n_samples]
|
||||
exp_actions = expert_data.actions[~expert_data.dones][:n_samples]
|
||||
|
||||
states = torch.cat((exp_states, gen_states), dim=0).detach()
|
||||
actions = torch.cat((exp_actions, gen_actions), dim=0).detach()
|
||||
labels = torch.cat((torch.zeros(n_samples), torch.ones(n_samples))).detach()
|
||||
|
||||
# print('Batch augmentation on')
|
||||
# random_states = torch.rand_like(gen_states)
|
||||
# random_actions = torch.rand_like(gen_actions)
|
||||
# states = torch.cat((exp_states, gen_states, random_states), dim=0).detach()
|
||||
# actions = torch.cat((exp_actions, gen_actions, random_actions), dim=0).detach()
|
||||
# labels = torch.cat((torch.zeros(n_samples), torch.ones(n_samples), torch.ones(n_samples))).detach()
|
||||
|
||||
for _ in range(disc_iters):
|
||||
disc_opt.zero_grad()
|
||||
pred = discriminator(states, actions)
|
||||
|
||||
if wasserstein:
|
||||
loss = -(pred * (1 - labels) - pred * labels).mean()
|
||||
else:
|
||||
loss = F.binary_cross_entropy(torch.sigmoid(pred), labels)
|
||||
|
||||
loss.backward()
|
||||
disc_opt.step()
|
||||
|
||||
if wasserstein_c is not None:
|
||||
with torch.no_grad():
|
||||
for param in discriminator.parameters():
|
||||
param.clamp_(-wasserstein_c, wasserstein_c)
|
||||
|
||||
return discriminator, loss
|
||||
39
scratch/etienne/trpo/core/optimization.py
Normal file
39
scratch/etienne/trpo/core/optimization.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import torch
|
||||
|
||||
def conjugate_gradient(A, b, max_iters, res_tol=1e-10):
|
||||
x = torch.zeros_like(b)
|
||||
r = b - A(x)
|
||||
p = r
|
||||
|
||||
rTr = r.T @ r
|
||||
|
||||
for _ in range(max_iters):
|
||||
Ap = A(p)
|
||||
alpha = rTr / (p.T @ Ap)
|
||||
x = x + alpha * p
|
||||
|
||||
r = r - alpha * Ap
|
||||
if torch.norm(r) < res_tol:
|
||||
break
|
||||
|
||||
rTrnew = r.T @ r
|
||||
beta = rTrnew / rTr
|
||||
p = r + beta * p
|
||||
rTr = rTrnew
|
||||
|
||||
return x
|
||||
|
||||
def line_search(f, x0, dx, g0, alpha, condition, max_steps=10, c1=0.1):
|
||||
assert 0 < alpha < 1
|
||||
|
||||
f0 = f(x0)
|
||||
for _ in range(max_steps):
|
||||
x = x0 + dx
|
||||
|
||||
if (f(x) > f0 + c1 * g0.T @ dx) and condition(x):
|
||||
return x
|
||||
|
||||
dx *= alpha
|
||||
|
||||
print('Line search failed, returning x0')
|
||||
return x0
|
||||
96
scratch/etienne/trpo/core/policy.py
Normal file
96
scratch/etienne/trpo/core/policy.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from torch.distributions import Independent, Normal, Categorical
|
||||
from torch.distributions.kl import kl_divergence
|
||||
|
||||
class BasePolicy(nn.Module):
|
||||
|
||||
def __init__(self, action_dim):
|
||||
super().__init__()
|
||||
self.action_dim = action_dim
|
||||
|
||||
def torch_dist(self, dist):
|
||||
return Independent(Normal(dist[..., :self.action_dim], dist[..., self.action_dim:].exp()), 1)
|
||||
|
||||
def sample(self, dist):
|
||||
return self.torch_dist(dist).sample()
|
||||
|
||||
def predict(self, states):
|
||||
return self.sample(self.forward(states))
|
||||
|
||||
def log_prob(self, dist, actions):
|
||||
return self.torch_dist(dist).log_prob(actions)
|
||||
|
||||
def kl_divergence(self, dist1, dist2):
|
||||
d1 = self.torch_dist(dist1)
|
||||
d2 = self.torch_dist(dist2)
|
||||
return kl_divergence(d1, d2)
|
||||
|
||||
class Policy(BasePolicy):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.nn = nn.Sequential(
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(2 * self.action_dim),
|
||||
)
|
||||
|
||||
def forward(self, states):
|
||||
return self.nn(states)
|
||||
|
||||
class DiscretePolicy(BasePolicy):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.nn = nn.Sequential(
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(self.action_dim),
|
||||
)
|
||||
|
||||
def forward(self, states):
|
||||
return self.nn(states)
|
||||
|
||||
def torch_dist(self, dist):
|
||||
return Categorical(logits=dist)
|
||||
|
||||
class SetPolicy(Policy):
|
||||
|
||||
def forward(self, states):
|
||||
batch_size = states.shape[:-2]
|
||||
states = torch.cat((states[..., :1, [0, 1]], states[..., :, [2, 5]]), axis=-2).reshape(*batch_size, -1)
|
||||
return super().forward(states)
|
||||
|
||||
class SetDiscretePolicy(DiscretePolicy):
|
||||
|
||||
def forward(self, states):
|
||||
batch_size = states.shape[:-2]
|
||||
states = torch.cat((states[..., :1, [0, 1]], states[..., :, [2, 5]]), axis=-2).reshape(*batch_size, -1)
|
||||
return super().forward(states)
|
||||
|
||||
class DeepSetPolicy(BasePolicy):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.elem = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
)
|
||||
self.glob = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(2 * self.action_dim),
|
||||
)
|
||||
|
||||
def forward(self, states):
|
||||
return self.glob(self.elem(states).sum(-2))
|
||||
72
scratch/etienne/trpo/core/ppo.py
Normal file
72
scratch/etienne/trpo/core/ppo.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import torch
|
||||
from core.sampling import rollout
|
||||
from core.value_estimation import gae
|
||||
|
||||
def ppo(env_fn, value, policy, epochs, rollout_episodes, rollout_steps, gamma, gae_lambda, clip_ratio, pi_opt, pi_iters, v_opt, v_iters, target_kl=None, max_grad_norm=None):
|
||||
|
||||
for epoch in range(epochs):
|
||||
policy.eval()
|
||||
states, actions, rewards, dones = rollout(env_fn, policy, rollout_episodes, rollout_steps)
|
||||
|
||||
print('mean', states[~dones].mean(0))
|
||||
print('std', states[~dones].std(0))
|
||||
|
||||
print(f'Iteration {epoch} mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Iteration {epoch} mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
|
||||
policy.train()
|
||||
value.train()
|
||||
value, policy = ppo_step(value, policy, states, actions, rewards, dones, clip_ratio, gamma, gae_lambda, pi_opt, pi_iters, v_opt, v_iters, target_kl, max_grad_norm)
|
||||
|
||||
return value, policy
|
||||
|
||||
def ppo_step(value, policy, states, actions, rewards, dones, clip_ratio, gamma, gae_lambda, pi_opt, pi_iters, v_opt, v_iters, target_kl, max_grad_norm):
|
||||
|
||||
states = states.detach()
|
||||
actions = actions.detach()
|
||||
rewards = rewards.detach()
|
||||
dones = dones.detach()
|
||||
|
||||
advantages, returns, valid = gae(states, rewards, value(states), dones, gamma, gae_lambda)
|
||||
advantages = advantages.detach()
|
||||
returns = returns.detach()
|
||||
|
||||
# update value function
|
||||
|
||||
for _ in range(v_iters):
|
||||
v_opt.zero_grad()
|
||||
value_loss = (value(states) - returns).pow(2)[valid].mean()
|
||||
value_loss.backward()
|
||||
v_opt.step()
|
||||
|
||||
# update policy
|
||||
|
||||
old_dist = policy(states).detach()
|
||||
old_logprob = policy.log_prob(old_dist, actions).detach()
|
||||
|
||||
def g(advantages, clip_ratio):
|
||||
return torch.where(advantages >= 0, (1 + clip_ratio) * advantages, (1 - clip_ratio) * advantages)
|
||||
|
||||
def L(states, actions, advantages, clip_ratio):
|
||||
return torch.minimum(
|
||||
(policy.log_prob(policy(states), actions) - old_logprob).exp() * advantages,
|
||||
g(advantages, clip_ratio)
|
||||
)[valid].mean()
|
||||
|
||||
for _ in range(pi_iters):
|
||||
pi_opt.zero_grad()
|
||||
ppo_loss = -L(states, actions, advantages, clip_ratio)
|
||||
ppo_loss.backward()
|
||||
|
||||
if max_grad_norm:
|
||||
torch.nn.utils.clip_grad_norm(policy.parameters(), max_grad_norm)
|
||||
|
||||
pi_opt.step()
|
||||
|
||||
kl = policy.kl_divergence(policy(states), old_dist)[valid].mean()
|
||||
if target_kl and kl > target_kl:
|
||||
break
|
||||
|
||||
print('KL', kl.item())
|
||||
|
||||
return value, policy
|
||||
162
scratch/etienne/trpo/core/reparam_module.py
Normal file
162
scratch/etienne/trpo/core/reparam_module.py
Normal file
@@ -0,0 +1,162 @@
|
||||
# Source: https://github.com/SsnL/PyTorch-Reparam-Module
|
||||
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import warnings
|
||||
import types
|
||||
from collections import namedtuple
|
||||
from contextlib import contextmanager
|
||||
|
||||
class ReparamModule(nn.Module):
|
||||
def __init__(self, module):
|
||||
super(ReparamModule, self).__init__()
|
||||
self.module = module
|
||||
|
||||
param_infos = []
|
||||
shared_param_memo = {}
|
||||
shared_param_infos = []
|
||||
params = []
|
||||
param_numels = []
|
||||
param_shapes = []
|
||||
for m in self.modules():
|
||||
for n, p in m.named_parameters(recurse=False):
|
||||
if p is not None:
|
||||
if p in shared_param_memo:
|
||||
shared_m, shared_n = shared_param_memo[p]
|
||||
shared_param_infos.append((m, n, shared_m, shared_n))
|
||||
else:
|
||||
shared_param_memo[p] = (m, n)
|
||||
param_infos.append((m, n))
|
||||
params.append(p.detach())
|
||||
param_numels.append(p.numel())
|
||||
param_shapes.append(p.size())
|
||||
|
||||
assert len(set(p.dtype for p in params)) <= 1, \
|
||||
"expects all parameters in module to have same dtype"
|
||||
|
||||
# store the info for unflatten
|
||||
self._param_infos = tuple(param_infos)
|
||||
self._shared_param_infos = tuple(shared_param_infos)
|
||||
self._param_numels = tuple(param_numels)
|
||||
self._param_shapes = tuple(param_shapes)
|
||||
|
||||
# flatten
|
||||
flat_param = nn.Parameter(torch.cat([p.reshape(-1) for p in params], 0))
|
||||
self.register_parameter('flat_param', flat_param)
|
||||
self.param_numel = flat_param.numel()
|
||||
del params
|
||||
del shared_param_memo
|
||||
|
||||
# deregister the names as parameters
|
||||
for m, n in self._param_infos:
|
||||
delattr(m, n)
|
||||
for m, n, _, _ in self._shared_param_infos:
|
||||
delattr(m, n)
|
||||
|
||||
# register the views as plain attributes
|
||||
self._unflatten_param(self.flat_param)
|
||||
|
||||
# now buffers
|
||||
# they are not reparametrized. just store info as (module, name, buffer)
|
||||
buffer_infos = []
|
||||
for m in self.modules():
|
||||
for n, b in m.named_buffers(recurse=False):
|
||||
if b is not None:
|
||||
buffer_infos.append((m, n, b))
|
||||
|
||||
self._buffer_infos = tuple(buffer_infos)
|
||||
self._traced_self = None
|
||||
|
||||
def trace(self, example_input, **trace_kwargs):
|
||||
assert self._traced_self is None, 'This ReparamModule is already traced'
|
||||
|
||||
if isinstance(example_input, torch.Tensor):
|
||||
example_input = (example_input,)
|
||||
example_input = tuple(example_input)
|
||||
example_param = (self.flat_param.detach().clone(),)
|
||||
example_buffers = (tuple(b.detach().clone() for _, _, b in self._buffer_infos),)
|
||||
|
||||
self._traced_self = torch.jit.trace_module(
|
||||
self,
|
||||
inputs=dict(
|
||||
_forward_with_param=example_param + example_input,
|
||||
_forward_with_param_and_buffers=example_param + example_buffers + example_input,
|
||||
),
|
||||
**trace_kwargs,
|
||||
)
|
||||
|
||||
# replace forwards with traced versions
|
||||
self._forward_with_param = self._traced_self._forward_with_param
|
||||
self._forward_with_param_and_buffers = self._traced_self._forward_with_param_and_buffers
|
||||
return self
|
||||
|
||||
def clear_views(self):
|
||||
for m, n in self._param_infos:
|
||||
setattr(m, n, None) # This will set as plain attr
|
||||
|
||||
def _apply(self, *args, **kwargs):
|
||||
if self._traced_self is not None:
|
||||
self._traced_self._apply(*args, **kwargs)
|
||||
return self
|
||||
return super(ReparamModule, self)._apply(*args, **kwargs)
|
||||
|
||||
def _unflatten_param(self, flat_param):
|
||||
ps = (t.view(s) for (t, s) in zip(flat_param.split(self._param_numels), self._param_shapes))
|
||||
for (m, n), p in zip(self._param_infos, ps):
|
||||
setattr(m, n, p) # This will set as plain attr
|
||||
for (m, n, shared_m, shared_n) in self._shared_param_infos:
|
||||
setattr(m, n, getattr(shared_m, shared_n))
|
||||
|
||||
@contextmanager
|
||||
def unflattened_param(self, flat_param):
|
||||
saved_views = [getattr(m, n) for m, n in self._param_infos]
|
||||
self._unflatten_param(flat_param)
|
||||
yield
|
||||
# Why not just `self._unflatten_param(self.flat_param)`?
|
||||
# 1. because of https://github.com/pytorch/pytorch/issues/17583
|
||||
# 2. slightly faster since it does not require reconstruct the split+view
|
||||
# graph
|
||||
for (m, n), p in zip(self._param_infos, saved_views):
|
||||
setattr(m, n, p)
|
||||
for (m, n, shared_m, shared_n) in self._shared_param_infos:
|
||||
setattr(m, n, getattr(shared_m, shared_n))
|
||||
|
||||
@contextmanager
|
||||
def replaced_buffers(self, buffers):
|
||||
for (m, n, _), new_b in zip(self._buffer_infos, buffers):
|
||||
setattr(m, n, new_b)
|
||||
yield
|
||||
for m, n, old_b in self._buffer_infos:
|
||||
setattr(m, n, old_b)
|
||||
|
||||
def _forward_with_param_and_buffers(self, flat_param, buffers, *inputs, **kwinputs):
|
||||
with self.unflattened_param(flat_param):
|
||||
with self.replaced_buffers(buffers):
|
||||
return self.module(*inputs, **kwinputs)
|
||||
|
||||
def _forward_with_param(self, flat_param, *inputs, **kwinputs):
|
||||
with self.unflattened_param(flat_param):
|
||||
return self.module(*inputs, **kwinputs)
|
||||
|
||||
def forward(self, *inputs, flat_param=None, buffers=None, **kwinputs):
|
||||
if flat_param is None:
|
||||
flat_param = self.flat_param
|
||||
if buffers is None:
|
||||
return self._forward_with_param(flat_param, *inputs, **kwinputs)
|
||||
else:
|
||||
return self._forward_with_param_and_buffers(flat_param, tuple(buffers), *inputs, **kwinputs)
|
||||
|
||||
|
||||
class ReparamPolicy(ReparamModule):
|
||||
|
||||
def sample(self, *args, **kwargs):
|
||||
return self.module.sample(*args, **kwargs)
|
||||
|
||||
def log_prob(self, *args, **kwargs):
|
||||
return self.module.log_prob(*args, **kwargs)
|
||||
|
||||
def kl_divergence(self, *args, **kwargs):
|
||||
return self.module.kl_divergence(*args, **kwargs)
|
||||
|
||||
def predict(self, *args, **kwargs):
|
||||
return self.module.predict(*args, **kwargs)
|
||||
73
scratch/etienne/trpo/core/sampling.py
Normal file
73
scratch/etienne/trpo/core/sampling.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import torch
|
||||
import gym
|
||||
from stable_baselines3.common.vec_env import DummyVecEnv as VecEnv
|
||||
from tqdm import tqdm
|
||||
|
||||
def rollout(env_fn, policy, n_episodes, max_steps_per_episode):
|
||||
env = env_fn(0)
|
||||
states = torch.zeros(n_episodes, max_steps_per_episode + 1, *env.observation_space.shape)
|
||||
actions = torch.zeros(n_episodes, max_steps_per_episode + 1, *env.action_space.shape)
|
||||
rewards = torch.zeros(n_episodes, max_steps_per_episode + 1)
|
||||
dones = torch.ones(n_episodes, max_steps_per_episode + 1, dtype=bool)
|
||||
|
||||
env = VecEnv(list(map(lambda i: (lambda: env_fn(i)), range(n_episodes))))
|
||||
|
||||
states[:, 0] = torch.tensor(env.reset()).clone().detach()
|
||||
dones[:, 0] = False
|
||||
|
||||
for s in range(max_steps_per_episode):
|
||||
actions[:, s] = policy.sample(policy(states[:, s])).clone().detach()
|
||||
|
||||
clipped_actions = actions[:, s]
|
||||
if isinstance(env.action_space, gym.spaces.Box):
|
||||
clipped_actions = torch.clamp(clipped_actions, torch.from_numpy(env.action_space.low), torch.from_numpy(env.action_space.high))
|
||||
|
||||
o, r, d, _ = env.step(clipped_actions)
|
||||
states[:, s + 1] = torch.tensor(o).clone().detach()
|
||||
rewards[:, s] = torch.tensor(r).clone().detach()
|
||||
dones[:, s + 1] = torch.tensor(d).clone().detach()
|
||||
|
||||
dones = dones.cumsum(1) > 0
|
||||
|
||||
states = states[:, :max_steps_per_episode]
|
||||
actions = actions[:, :max_steps_per_episode]
|
||||
rewards = rewards[:, :max_steps_per_episode]
|
||||
dones = dones[:, :max_steps_per_episode]
|
||||
|
||||
return states, actions, rewards, dones
|
||||
|
||||
|
||||
def rollout_sb3(env, policy, n_episodes, max_steps_per_episode):
|
||||
states = torch.zeros(n_episodes, max_steps_per_episode + 1, *env.observation_space.shape)
|
||||
actions = torch.zeros(n_episodes, max_steps_per_episode + 1, *env.action_space.shape)
|
||||
rewards = torch.zeros(n_episodes, max_steps_per_episode + 1)
|
||||
dones = torch.ones(n_episodes, max_steps_per_episode + 1, dtype=bool)
|
||||
|
||||
for e in tqdm(range(n_episodes)):
|
||||
states[e, 0] = torch.tensor(env.reset()).clone().detach()
|
||||
dones[e, 0] = False
|
||||
|
||||
for s in range(max_steps_per_episode):
|
||||
action, _ = policy.predict(states[e, s])
|
||||
actions[e, s] = torch.tensor(action).clone().detach()
|
||||
|
||||
clipped_actions = actions[e, s]
|
||||
if isinstance(env.action_space, gym.spaces.Box):
|
||||
clipped_actions = torch.clamp(clipped_actions, torch.from_numpy(env.action_space.low), torch.from_numpy(env.action_space.high))
|
||||
|
||||
o, r, d, _ = env.step(clipped_actions)
|
||||
states[e, s + 1] = torch.tensor(o).clone().detach()
|
||||
rewards[e, s] = torch.tensor(r).clone().detach()
|
||||
dones[e, s + 1] = torch.tensor(d).clone().detach()
|
||||
|
||||
if d:
|
||||
break
|
||||
|
||||
dones = dones.cumsum(1) > 0
|
||||
|
||||
states = states[:, :max_steps_per_episode]
|
||||
actions = actions[:, :max_steps_per_episode]
|
||||
rewards = rewards[:, :max_steps_per_episode]
|
||||
dones = dones[:, :max_steps_per_episode]
|
||||
|
||||
return states, actions, rewards, dones
|
||||
23
scratch/etienne/trpo/core/test_optimization.py
Normal file
23
scratch/etienne/trpo/core/test_optimization.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import torch
|
||||
from optimization import conjugate_gradient
|
||||
|
||||
def test_cg_eye():
|
||||
A = torch.eye(2)
|
||||
b = torch.tensor([1., 2.])
|
||||
x1 = conjugate_gradient(lambda x: A @ x, b, 2)
|
||||
x2 = torch.inverse(A) @ b
|
||||
assert torch.allclose(x1, x2)
|
||||
|
||||
def test_cg_eyep1():
|
||||
A = torch.eye(2) + 1
|
||||
b = torch.tensor([1., 2.])
|
||||
x1 = conjugate_gradient(lambda x: A @ x, b, 2)
|
||||
x2 = torch.inverse(A) @ b
|
||||
assert torch.allclose(x1, x2, atol=1e-7)
|
||||
|
||||
def test_cg3():
|
||||
A = torch.tensor([[4., 2.], [2., 4.]])
|
||||
b = torch.tensor([2., 1.])
|
||||
x1 = conjugate_gradient(lambda x: A @ x, b, 100)
|
||||
x2 = torch.inverse(A) @ b
|
||||
assert torch.allclose(x1, x2)
|
||||
79
scratch/etienne/trpo/core/trpo.py
Normal file
79
scratch/etienne/trpo/core/trpo.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import torch
|
||||
from core.reparam_module import ReparamPolicy
|
||||
from core.sampling import rollout
|
||||
from core.value_estimation import gae
|
||||
from core.optimization import conjugate_gradient, line_search
|
||||
|
||||
def trpo(env_fn, value, policy, epochs, rollout_episodes, rollout_steps, gamma, gae_lambda, delta, backtrack_coeff, backtrack_iters, v_opt, v_iters, cg_iters=10, cg_damping=0.1):
|
||||
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
|
||||
for epoch in range(epochs):
|
||||
policy.eval()
|
||||
states, actions, rewards, dones = rollout(env_fn, policy, rollout_episodes, rollout_steps)
|
||||
|
||||
print('mean', states[~dones].mean(0))
|
||||
print('std', states[~dones].std(0))
|
||||
|
||||
print(f'Iteration {epoch} mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Iteration {epoch} mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
|
||||
policy.train()
|
||||
value.train()
|
||||
value, policy = trpo_step(value, policy, states, actions, rewards, dones, gamma, gae_lambda, delta, backtrack_coeff, backtrack_iters, v_opt, v_iters, cg_iters, cg_damping)
|
||||
|
||||
return value, policy
|
||||
|
||||
def trpo_step(value, policy, states, actions, rewards, dones, gamma, gae_lambda, delta, backtrack_coeff, backtrack_iters, v_opt, v_iters, cg_iters=10, cg_damping=0.1):
|
||||
|
||||
states = states.detach()
|
||||
actions = actions.detach()
|
||||
rewards = rewards.detach()
|
||||
dones = dones.detach()
|
||||
|
||||
advantages, returns, valid = gae(states, rewards, value(states), dones, gamma, gae_lambda)
|
||||
advantages = advantages.detach()
|
||||
returns = returns.detach()
|
||||
|
||||
# update value function
|
||||
|
||||
for _ in range(v_iters):
|
||||
v_opt.zero_grad()
|
||||
value_loss = (value(states) - returns).pow(2)[valid].mean()
|
||||
value_loss.backward()
|
||||
v_opt.step()
|
||||
|
||||
# compute policy gradient
|
||||
|
||||
plogprob = policy.log_prob(policy(states), actions)
|
||||
surrogate_advantage = (plogprob * advantages)[valid].sum() / states.shape[0]
|
||||
g = torch.cat(torch.autograd.grad(surrogate_advantage, policy.flat_param)).detach()
|
||||
|
||||
def Hx(x):
|
||||
kl = policy.kl_divergence(policy(states), policy(states).detach())[valid].mean()
|
||||
dKL = torch.cat(torch.autograd.grad(kl, policy.flat_param, create_graph=True))
|
||||
H_x = torch.cat(torch.autograd.grad(dKL.T @ x, policy.flat_param)).detach()
|
||||
return H_x + cg_damping * x
|
||||
|
||||
x = conjugate_gradient(Hx, g, cg_iters)
|
||||
npg = torch.sqrt(2 * delta / (x.T @ Hx(x))) * x
|
||||
|
||||
# perform line search
|
||||
|
||||
def L(theta):
|
||||
rplogprob = policy.log_prob(policy(states, flat_param=theta), actions)
|
||||
return ((rplogprob - plogprob.detach()).exp() * advantages)[valid].sum() / advantages.shape[0]
|
||||
|
||||
condition = lambda theta: policy.kl_divergence(policy(states, flat_param=theta), policy(states))[valid].mean() < delta
|
||||
|
||||
x0 = policy.flat_param
|
||||
g0 = torch.cat(torch.autograd.grad(L(x0), x0))
|
||||
theta = line_search(L, x0, npg, g0, backtrack_coeff, condition, max_steps=backtrack_iters)
|
||||
|
||||
# update policy parameters
|
||||
|
||||
with torch.no_grad():
|
||||
policy.flat_param.copy_(theta)
|
||||
|
||||
return value, policy
|
||||
48
scratch/etienne/trpo/core/value.py
Normal file
48
scratch/etienne/trpo/core/value.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from torch.distributions import Normal
|
||||
from torch.distributions.kl import kl_divergence
|
||||
|
||||
class Value(nn.Module):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.nn = nn.Sequential(
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(50),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(1),
|
||||
)
|
||||
|
||||
def forward(self, states):
|
||||
return self.nn(states).squeeze(-1)
|
||||
|
||||
class SetValue(Value):
|
||||
|
||||
def forward(self, states):
|
||||
batch_size = states.shape[:-2]
|
||||
states = torch.cat((states[..., :1, [0, 1]], states[..., :, [2, 5]]), axis=-2).reshape(*batch_size, -1)
|
||||
return super().forward(states)
|
||||
|
||||
class DeepSetValue(nn.Module):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.elem = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
)
|
||||
self.glob = nn.Sequential(
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(10),
|
||||
nn.Tanh(),
|
||||
nn.LazyLinear(1),
|
||||
)
|
||||
|
||||
def forward(self, states):
|
||||
return self.glob(self.elem(states).sum(-2)).squeeze(-1)
|
||||
40
scratch/etienne/trpo/core/value_estimation.py
Normal file
40
scratch/etienne/trpo/core/value_estimation.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from operator import index
|
||||
import torch
|
||||
|
||||
def gae(states, rewards, values, dones, gamma, gae_lambda):
|
||||
assert rewards.shape == values.shape == dones.shape
|
||||
n_episodes, n_steps = rewards.shape
|
||||
|
||||
valid = ~dones
|
||||
valid[..., -1] = False
|
||||
|
||||
td = rewards + gamma * torch.roll(values, shifts=-1, dims=1) - values
|
||||
adv = td.repeat(n_steps, 1, 1).transpose(0, 1)
|
||||
assert adv.shape == (n_episodes, n_steps, n_steps)
|
||||
|
||||
step_start, step = torch.meshgrid(torch.arange(n_steps), torch.arange(n_steps), indexing='ij')
|
||||
past = step < step_start
|
||||
|
||||
# add up discounted temporal differences
|
||||
discount = torch.minimum(torch.tensor(gamma).log() * (step - step_start), torch.tensor(0.)).exp()
|
||||
discount = discount * ~past
|
||||
discount = discount * valid.unsqueeze(1)
|
||||
|
||||
adv = adv * discount
|
||||
adv = adv.cumsum(2) # eq. (14)
|
||||
assert adv.shape == (n_episodes, n_steps, n_steps)
|
||||
|
||||
# add up discounted k-advantages
|
||||
lambda_discount = torch.minimum(torch.tensor(gae_lambda).log() * (step - step_start), torch.tensor(0.)).exp()
|
||||
lambda_discount = lambda_discount * ~past
|
||||
lambda_discount = lambda_discount * valid.unsqueeze(1)
|
||||
|
||||
adv = adv * lambda_discount
|
||||
adv = adv.sum(2) / (lambda_discount.sum(2) + 1e-10) # eq. (16)
|
||||
|
||||
adv = (adv - adv[valid].mean()) / adv[valid].std()
|
||||
assert adv.shape == rewards.shape == values.shape
|
||||
|
||||
returns = adv + values
|
||||
|
||||
return adv, returns, valid
|
||||
74
scratch/etienne/trpo/gail-intersimple-minobs.py
Normal file
74
scratch/etienne/trpo/gail-intersimple-minobs.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-intersimple-minobs.pt')
|
||||
100
scratch/etienne/trpo/gail-intersimple-minobs2.py
Normal file
100
scratch/etienne/trpo/gail-intersimple-minobs2.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from core.reparam_module import ReparamPolicy
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-5)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=800,
|
||||
rollout_episodes=50,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
logger=SummaryWriter(comment='minobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-intersimple-minobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('gail-intersimple-minobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
env.random_skip = False
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
74
scratch/etienne/trpo/gail-intersimple-normobs.py
Normal file
74
scratch/etienne/trpo/gail-intersimple-normobs.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-4)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-normobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-intersimple-normobs.pt')
|
||||
74
scratch/etienne/trpo/gail-intersimple-setobs.py
Normal file
74
scratch/etienne/trpo/gail-intersimple-setobs.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetPolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-intersimple-setobs.pt')
|
||||
97
scratch/etienne/trpo/gail-intersimple-setobs2-recurrent.py
Normal file
97
scratch/etienne/trpo/gail-intersimple-setobs2-recurrent.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetPolicy
|
||||
from core.discriminator import RecurrentDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = RecurrentDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-5)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=800,
|
||||
rollout_episodes=50,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-intersimple-setobs-recurrent.pt')
|
||||
|
||||
# %%
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('gail-intersimple-setobs-recurrent.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
101
scratch/etienne/trpo/gail-intersimple-setobs2.py
Normal file
101
scratch/etienne/trpo/gail-intersimple-setobs2.py
Normal file
@@ -0,0 +1,101 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetPolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from core.reparam_module import ReparamPolicy
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
random_skip=True,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-5)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=800,
|
||||
rollout_episodes=50,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
logger=SummaryWriter(comment='setobs2-batchaug'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-intersimple-setobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('gail-intersimple-setobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
env.random_skip = False
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
54
scratch/etienne/trpo/gail-intersimple.py
Normal file
54
scratch/etienne/trpo/gail-intersimple.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
|
||||
envs = [CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-4)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-intersimple.pt')
|
||||
97
scratch/etienne/trpo/gail-options-minobs.py
Normal file
97
scratch/etienne/trpo/gail-options-minobs.py
Normal file
@@ -0,0 +1,97 @@
|
||||
import gym
|
||||
from options.options import gail
|
||||
from core.gail import Buffer
|
||||
from core.value import Value
|
||||
from core.policy import DiscretePolicy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Minobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Minobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=50,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
logger=SummaryWriter(comment='-options-minobs'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-options-minobs.pt')
|
||||
|
||||
# %%
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('gail-options-minobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
97
scratch/etienne/trpo/gail-options-setobs.py
Normal file
97
scratch/etienne/trpo/gail-options-setobs.py
Normal file
@@ -0,0 +1,97 @@
|
||||
import gym
|
||||
from options.options import gail
|
||||
from core.gail import Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=150,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
logger=SummaryWriter(comment='gail-options-setobs'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-options-setobs.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('gail-options-setobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
98
scratch/etienne/trpo/gail-options-setobs2.py
Normal file
98
scratch/etienne/trpo/gail-options-setobs2.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# %%
|
||||
import gym
|
||||
from options.options import gail
|
||||
from core.gail import Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (6, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-4)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=200,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
logger=SummaryWriter(comment='gail-options-setobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-options-setobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('gail-options-setobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
39
scratch/etienne/trpo/gail-pendulum.py
Normal file
39
scratch/etienne/trpo/gail-pendulum.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
|
||||
env_fn = lambda _: gym.make('Pendulum-v0')
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('trpo-pendulum-expert-data.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=100,
|
||||
rollout_episodes=20,
|
||||
rollout_steps=250,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
)
|
||||
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-pendulum.pt')
|
||||
75
scratch/etienne/trpo/gail-ppo-intersimple-minobs.py
Normal file
75
scratch/etienne/trpo/gail-ppo-intersimple-minobs.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-ppo-intersimple-minobs.pt')
|
||||
75
scratch/etienne/trpo/gail-ppo-intersimple-normobs.py
Normal file
75
scratch/etienne/trpo/gail-ppo-intersimple-normobs.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-normobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-ppo-intersimple-normobs.pt')
|
||||
102
scratch/etienne/trpo/gail-ppo-intersimple-setobs2.py
Normal file
102
scratch/etienne/trpo/gail-ppo-intersimple-setobs2.py
Normal file
@@ -0,0 +1,102 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetPolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from core.reparam_module import ReparamPolicy
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
random_skip=True,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-5)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=800,
|
||||
rollout_episodes=50,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
logger=SummaryWriter(comment='-ppo-setobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-ppo-intersimple-setobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('gail-ppo-intersimple-setobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
env.random_skip = False
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
55
scratch/etienne/trpo/gail-ppo-intersimple.py
Normal file
55
scratch/etienne/trpo/gail-ppo-intersimple.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
|
||||
envs = [CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=3e-4)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-ppo-intersimple.pt')
|
||||
96
scratch/etienne/trpo/gail-ppo-options-minobs.py
Normal file
96
scratch/etienne/trpo/gail-ppo-options-minobs.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import gym
|
||||
from options.options import gail_ppo, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import DiscretePolicy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Minobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Minobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=50,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
logger=SummaryWriter(comment='gail-ppo-options-minobs'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-ppo-options-minobs.pt')
|
||||
|
||||
# %%
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy.load_state_dict(torch.load('gail-ppo-options-minobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
96
scratch/etienne/trpo/gail-ppo-options-setobs.py
Normal file
96
scratch/etienne/trpo/gail-ppo-options-setobs.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import gym
|
||||
from options.options import gail_ppo, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=150,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
logger=SummaryWriter(comment='gail-ppo-options-setobs'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-ppo-options-setobs.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy.load_state_dict(torch.load('gail-ppo-options-setobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
97
scratch/etienne/trpo/gail-ppo-options-setobs2.py
Normal file
97
scratch/etienne/trpo/gail-ppo-options-setobs2.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# %%
|
||||
import gym
|
||||
from options.options import gail_ppo, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (6, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-4)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=200,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
logger=SummaryWriter(comment='gail-ppo-options-setobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-ppo-options-setobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy.load_state_dict(torch.load('gail-ppo-options-setobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
175
scratch/etienne/trpo/intersimple-expert-action-profiles.ipynb
Normal file
175
scratch/etienne/trpo/intersimple-expert-action-profiles.ipynb
Normal file
File diff suppressed because one or more lines are too long
54
scratch/etienne/trpo/intersimple-expert-rollout-minobs.py
Normal file
54
scratch/etienne/trpo/intersimple-expert-rollout-minobs.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import torch
|
||||
import functools
|
||||
from core.sampling import rollout_sb3
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
from intersim.expert import NormalizedIntersimpleExpert
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
env = IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
)
|
||||
|
||||
policy = NormalizedIntersimpleExpert(env, mu=0.001)
|
||||
|
||||
env = Minobs(TransformObservation(
|
||||
CollisionPenaltyWrapper(
|
||||
env,
|
||||
collision_distance=6, collision_penalty=100
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)
|
||||
))
|
||||
expert_data = rollout_sb3(env, policy, n_episodes=64, max_steps_per_episode=200)
|
||||
|
||||
states, actions, rewards, dones = expert_data
|
||||
print(f'Expert mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Expert mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
print(f'Observation mean', states[~dones].mean(0))
|
||||
print(f'Observation std', states[~dones].std(0))
|
||||
|
||||
torch.save(expert_data, 'intersimple-expert-data-minobs.pt')
|
||||
53
scratch/etienne/trpo/intersimple-expert-rollout-minobs2.py
Normal file
53
scratch/etienne/trpo/intersimple-expert-rollout-minobs2.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import torch
|
||||
import functools
|
||||
from core.sampling import rollout_sb3
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
from intersim.expert import NormalizedIntersimpleExpert
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
env = IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
)
|
||||
|
||||
policy = NormalizedIntersimpleExpert(env, mu=0.001)
|
||||
|
||||
env = Minobs(TransformObservation(
|
||||
CollisionPenaltyWrapper(
|
||||
env,
|
||||
collision_distance=6, collision_penalty=100
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)
|
||||
))
|
||||
expert_data = rollout_sb3(env, policy, n_episodes=2048, max_steps_per_episode=200)
|
||||
|
||||
states, actions, rewards, dones = expert_data
|
||||
print(f'Expert mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Expert mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
print(f'Observation mean', states[~dones].mean(0))
|
||||
print(f'Observation std', states[~dones].std(0))
|
||||
|
||||
torch.save(expert_data, 'intersimple-expert-data-minobs2.pt')
|
||||
54
scratch/etienne/trpo/intersimple-expert-rollout-normobs.py
Normal file
54
scratch/etienne/trpo/intersimple-expert-rollout-normobs.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import torch
|
||||
import functools
|
||||
from core.sampling import rollout_sb3
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
from intersim.expert import NormalizedIntersimpleExpert
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
env = IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
)
|
||||
|
||||
policy = NormalizedIntersimpleExpert(env, mu=0.001)
|
||||
|
||||
env = TransformObservation(
|
||||
CollisionPenaltyWrapper(
|
||||
env,
|
||||
collision_distance=6, collision_penalty=100
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)
|
||||
)
|
||||
expert_data = rollout_sb3(env, policy, n_episodes=64, max_steps_per_episode=200)
|
||||
|
||||
states, actions, rewards, dones = expert_data
|
||||
print(f'Expert mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Expert mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
print(f'Observation mean', states[~dones].mean(0))
|
||||
print(f'Observation std', states[~dones].std(0))
|
||||
|
||||
torch.save(expert_data, 'intersimple-expert-data-normobs.pt')
|
||||
54
scratch/etienne/trpo/intersimple-expert-rollout-setobs.py
Normal file
54
scratch/etienne/trpo/intersimple-expert-rollout-setobs.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import torch
|
||||
import functools
|
||||
from core.sampling import rollout_sb3
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
from intersim.expert import NormalizedIntersimpleExpert
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
env = IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
)
|
||||
|
||||
policy = NormalizedIntersimpleExpert(env, mu=0.001)
|
||||
|
||||
env = Setobs(TransformObservation(
|
||||
CollisionPenaltyWrapper(
|
||||
env,
|
||||
collision_distance=6, collision_penalty=100
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)
|
||||
))
|
||||
expert_data = rollout_sb3(env, policy, n_episodes=64, max_steps_per_episode=200)
|
||||
|
||||
states, actions, rewards, dones = expert_data
|
||||
print(f'Expert mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Expert mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
print(f'Observation mean', states[~dones].mean(0))
|
||||
print(f'Observation std', states[~dones].std(0))
|
||||
|
||||
torch.save(expert_data, 'intersimple-expert-data-setobs.pt')
|
||||
53
scratch/etienne/trpo/intersimple-expert-rollout-setobs2.py
Normal file
53
scratch/etienne/trpo/intersimple-expert-rollout-setobs2.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import torch
|
||||
import functools
|
||||
from core.sampling import rollout_sb3
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
from intersim.expert import NormalizedIntersimpleExpert
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
env = IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
)
|
||||
|
||||
policy = NormalizedIntersimpleExpert(env, mu=0.001)
|
||||
|
||||
env = Setobs(TransformObservation(
|
||||
CollisionPenaltyWrapper(
|
||||
env,
|
||||
collision_distance=6, collision_penalty=100
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)
|
||||
))
|
||||
expert_data = rollout_sb3(env, policy, n_episodes=2048, max_steps_per_episode=200)
|
||||
|
||||
states, actions, rewards, dones = expert_data
|
||||
print(f'Expert mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Expert mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
print(f'Observation mean', states[~dones].mean(0))
|
||||
print(f'Observation std', states[~dones].std(0))
|
||||
|
||||
torch.save(expert_data, 'intersimple-expert-data-setobs2.pt')
|
||||
25
scratch/etienne/trpo/intersimple-expert-rollout.py
Normal file
25
scratch/etienne/trpo/intersimple-expert-rollout.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import torch
|
||||
import functools
|
||||
from core.sampling import rollout_sb3
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
from intersim.expert import NormalizedIntersimpleExpert
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
|
||||
env = CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
), collision_distance=6, collision_penalty=100)
|
||||
policy = NormalizedIntersimpleExpert(env.env, mu=0.001)
|
||||
|
||||
expert_data = rollout_sb3(env, policy, n_episodes=64, max_steps_per_episode=200)
|
||||
|
||||
states, actions, rewards, dones = expert_data
|
||||
print(f'Expert mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Expert mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
|
||||
torch.save(expert_data, 'intersimple-expert-data.pt')
|
||||
201
scratch/etienne/trpo/options/options.py
Normal file
201
scratch/etienne/trpo/options/options.py
Normal file
@@ -0,0 +1,201 @@
|
||||
import gym
|
||||
import numpy as np
|
||||
import torch
|
||||
from stable_baselines3.common.vec_env import DummyVecEnv as VecEnv
|
||||
|
||||
from core.reparam_module import ReparamPolicy
|
||||
from tqdm import tqdm
|
||||
from core.gail import Buffer, train_discriminator, roll_buffer, TerminalLogger
|
||||
from dataclasses import dataclass
|
||||
from core.trpo import trpo_step
|
||||
from core.ppo import ppo_step
|
||||
import torch.nn.functional as F
|
||||
|
||||
@dataclass
|
||||
class OptionsRollout:
|
||||
hl: Buffer
|
||||
ll: Buffer
|
||||
|
||||
def gail(env_fn, expert_data, discriminator, disc_opt, disc_iters, policy, value,
|
||||
v_opt, v_iters, epochs, rollout_episodes, rollout_steps, gamma,
|
||||
gae_lambda, delta, backtrack_coeff, backtrack_iters, cg_iters=10, cg_damping=0.1, wasserstein=False, wasserstein_c=None, logger=TerminalLogger()):
|
||||
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
|
||||
logger.add_scalar('expert/mean_episode_length', (~expert_data.dones).sum() / expert_data.states.shape[0])
|
||||
logger.add_scalar('expert/mean_reward_per_episode', expert_data.rewards[~expert_data.dones].sum() / expert_data.states.shape[0])
|
||||
|
||||
for epoch in tqdm(range(epochs)):
|
||||
hl_data, ll_data = rollout(env_fn, policy, rollout_episodes, rollout_steps)
|
||||
generator_data = OptionsRollout(Buffer(*hl_data), Buffer(*ll_data))
|
||||
|
||||
generator_data.ll.actions += 0.1 * torch.randn_like(generator_data.ll.actions)
|
||||
|
||||
logger.add_scalar('gen/mean_episode_length', (~generator_data.ll.dones).sum() / generator_data.ll.states.shape[0], epoch)
|
||||
logger.add_scalar('gen/mean_reward_per_episode', generator_data.hl.rewards[~generator_data.hl.dones].sum() / generator_data.hl.states.shape[0], epoch)
|
||||
|
||||
discriminator, loss = train_discriminator(expert_data, generator_data.ll, discriminator, disc_opt, disc_iters, wasserstein, wasserstein_c)
|
||||
if wasserstein:
|
||||
generator_data.ll.rewards = discriminator(generator_data.ll.states, generator_data.ll.actions)
|
||||
else:
|
||||
generator_data.ll.rewards = -F.logsigmoid(discriminator(generator_data.ll.states, generator_data.ll.actions))
|
||||
logger.add_scalar('disc/final_loss', loss, epoch)
|
||||
logger.add_scalar('disc/mean_reward_per_episode', generator_data.ll.rewards[~generator_data.ll.dones].sum() / generator_data.ll.states.shape[0], epoch)
|
||||
|
||||
#assert generator_data.ll.rewards.shape == generator_data.ll.dones.shape
|
||||
generator_data.hl.rewards = torch.where(~generator_data.ll.dones, generator_data.ll.rewards, torch.tensor(0.)).sum(-1)
|
||||
|
||||
value, policy = trpo_step(value, policy, generator_data.hl.states, generator_data.hl.actions, generator_data.hl.rewards, generator_data.hl.dones, gamma, gae_lambda, delta, backtrack_coeff, backtrack_iters, v_opt, v_iters, cg_iters, cg_damping)
|
||||
expert_data = roll_buffer(expert_data, shifts=-3, dims=0)
|
||||
|
||||
return value, policy
|
||||
|
||||
def gail_ppo(env_fn, expert_data, discriminator, disc_opt, disc_iters, policy, value,
|
||||
v_opt, v_iters, epochs, rollout_episodes, rollout_steps, gamma,
|
||||
gae_lambda, clip_ratio, pi_opt, pi_iters, target_kl=None, max_grad_norm=None, wasserstein=False, wasserstein_c=None, logger=TerminalLogger()):
|
||||
|
||||
logger.add_scalar('expert/mean_episode_length', (~expert_data.dones).sum() / expert_data.states.shape[0])
|
||||
logger.add_scalar('expert/mean_reward_per_episode', expert_data.rewards[~expert_data.dones].sum() / expert_data.states.shape[0])
|
||||
|
||||
for epoch in range(epochs):
|
||||
hl_data, ll_data = rollout(env_fn, policy, rollout_episodes, rollout_steps)
|
||||
generator_data = OptionsRollout(Buffer(*hl_data), Buffer(*ll_data))
|
||||
|
||||
generator_data.ll.actions += 0.1 * torch.randn_like(generator_data.ll.actions)
|
||||
|
||||
logger.add_scalar('gen/mean_episode_length', (~generator_data.ll.dones).sum() / generator_data.ll.states.shape[0], epoch)
|
||||
logger.add_scalar('gen/mean_reward_per_episode', generator_data.hl.rewards[~generator_data.hl.dones].sum() / generator_data.hl.states.shape[0], epoch)
|
||||
|
||||
discriminator, loss = train_discriminator(expert_data, generator_data.ll, discriminator, disc_opt, disc_iters, wasserstein, wasserstein_c)
|
||||
if wasserstein:
|
||||
generator_data.ll.rewards = discriminator(generator_data.ll.states, generator_data.ll.actions)
|
||||
else:
|
||||
generator_data.ll.rewards = -F.logsigmoid(discriminator(generator_data.ll.states, generator_data.ll.actions))
|
||||
logger.add_scalar('disc/final_loss', loss, epoch)
|
||||
logger.add_scalar('disc/mean_reward_per_episode', generator_data.ll.rewards[~generator_data.ll.dones].sum() / generator_data.ll.states.shape[0], epoch)
|
||||
|
||||
#assert generator_data.ll.rewards.shape == generator_data.ll.dones.shape
|
||||
generator_data.hl.rewards = torch.where(~generator_data.ll.dones, generator_data.ll.rewards, torch.tensor(0.)).sum(-1)
|
||||
|
||||
value, policy = ppo_step(value, policy, generator_data.hl.states, generator_data.hl.actions, generator_data.hl.rewards, generator_data.hl.dones, clip_ratio, gamma, gae_lambda, pi_opt, pi_iters, v_opt, v_iters, target_kl, max_grad_norm)
|
||||
expert_data = roll_buffer(expert_data, shifts=-3, dims=0)
|
||||
|
||||
return value, policy
|
||||
|
||||
def rollout(env_fn, policy, n_episodes, max_steps_per_episode):
|
||||
env = env_fn(0)
|
||||
|
||||
states = torch.zeros(n_episodes, max_steps_per_episode + 1, *env.observation_space.shape)
|
||||
actions = torch.zeros(n_episodes, max_steps_per_episode + 1, *env.action_space.shape)
|
||||
rewards = torch.zeros(n_episodes, max_steps_per_episode + 1)
|
||||
dones = torch.ones(n_episodes, max_steps_per_episode + 1, dtype=bool)
|
||||
|
||||
ll_states = torch.zeros(n_episodes, max_steps_per_episode, env.max_plan_length + 1, *env.observation_space.shape)
|
||||
ll_actions = torch.zeros(n_episodes, max_steps_per_episode, env.max_plan_length + 1, *env.ll_action_space.shape)
|
||||
ll_rewards = torch.zeros(n_episodes, max_steps_per_episode, env.max_plan_length + 1)
|
||||
ll_dones = torch.ones(n_episodes, max_steps_per_episode, env.max_plan_length + 1, dtype=bool)
|
||||
|
||||
env = VecEnv(list(map(lambda i: (lambda: env_fn(i)), range(n_episodes))))
|
||||
|
||||
states[:, 0] = torch.tensor(env.reset()).clone().detach()
|
||||
dones[:, 0] = False
|
||||
|
||||
for s in tqdm(range(max_steps_per_episode), 'Rollout'):
|
||||
actions[:, s] = policy.sample(policy(states[:, s])).clone().detach()
|
||||
|
||||
clipped_actions = actions[:, s]
|
||||
if isinstance(env.action_space, gym.spaces.Box):
|
||||
clipped_actions = torch.clamp(clipped_actions, torch.from_numpy(env.action_space.low), torch.from_numpy(env.action_space.high))
|
||||
|
||||
o, r, d, info = env.step(clipped_actions)
|
||||
states[:, s + 1] = torch.tensor(o).clone().detach()
|
||||
rewards[:, s] = torch.tensor(r).clone().detach()
|
||||
dones[:, s + 1] = torch.tensor(d).clone().detach()
|
||||
|
||||
ll_states[:, s] = torch.from_numpy(np.stack([i['ll']['observations'] for i in info])).clone().detach()
|
||||
ll_actions[:, s] = torch.from_numpy(np.stack([i['ll']['actions'] for i in info])).clone().detach()
|
||||
ll_rewards[:, s] = torch.from_numpy(np.stack([i['ll']['rewards'] for i in info])).clone().detach()
|
||||
ll_dones[:, s] = torch.from_numpy(np.stack([i['ll']['plan_done'] for i in info])).clone().detach()
|
||||
|
||||
dones = dones.cumsum(1) > 0
|
||||
|
||||
states = states[:, :max_steps_per_episode]
|
||||
actions = actions[:, :max_steps_per_episode]
|
||||
rewards = rewards[:, :max_steps_per_episode]
|
||||
dones = dones[:, :max_steps_per_episode]
|
||||
|
||||
return (states, actions, rewards, dones), (ll_states, ll_actions, ll_rewards, ll_dones)
|
||||
|
||||
class OptionsEnv(gym.Wrapper):
|
||||
|
||||
def __init__(self, env, options):
|
||||
super().__init__(env)
|
||||
self.ll_action_space = env.action_space
|
||||
self.options = options
|
||||
self.action_space = gym.spaces.Discrete(len(options))
|
||||
self.max_plan_length = max(t for _, t in options)
|
||||
|
||||
def plan(self, option):
|
||||
target_v, t = option
|
||||
current_v = self.env._env.state[self.env._agent, 1].item()
|
||||
dt = self.env._env._dt
|
||||
a = (target_v - current_v) / (t * dt)
|
||||
a = self.env._normalize(a)
|
||||
a = a * np.ones((t,))
|
||||
a += 0.01 * np.random.randn(*a.shape)
|
||||
a = np.clip(a, self.ll_action_space.low, self.ll_action_space.high)
|
||||
return a
|
||||
|
||||
def execute_plan(self, obs, option, render_mode=None):
|
||||
observations = np.zeros((self.max_plan_length + 1, *self.env.observation_space.shape))
|
||||
actions = np.zeros((self.max_plan_length + 1, *self.ll_action_space.shape))
|
||||
rewards = np.zeros((self.max_plan_length + 1,))
|
||||
env_done = np.ones((self.max_plan_length + 1,), dtype=bool)
|
||||
plan_done = np.ones((self.max_plan_length + 1,), dtype=bool)
|
||||
infos = []
|
||||
|
||||
observations[0] = obs
|
||||
env_done[0] = False
|
||||
for k, u in enumerate(self.plan(option)):
|
||||
plan_done[k] = False
|
||||
o, r, d, i = super().step(u)
|
||||
actions[k] = u
|
||||
rewards[k] = r
|
||||
env_done[k+1] = d
|
||||
infos.append(i)
|
||||
observations[k+1] = o
|
||||
|
||||
if render_mode is not None:
|
||||
self.env.render(render_mode)
|
||||
|
||||
if d:
|
||||
break
|
||||
|
||||
n_steps = k + 1
|
||||
return observations, actions, rewards, env_done, plan_done, infos, n_steps
|
||||
|
||||
def step(self, action, render_mode=None):
|
||||
a = int(action)
|
||||
assert a == action
|
||||
ll_obs, ll_actions, ll_rewards, ll_env_done, ll_plan_done, ll_infos, ll_steps = self.execute_plan(self.last_obs, self.options[a], render_mode)
|
||||
hl_obs = ll_obs[ll_steps]
|
||||
hl_reward = (ll_rewards * ~ll_plan_done).sum().item()
|
||||
hl_done = ll_env_done[ll_steps].item()
|
||||
hl_infos = {
|
||||
'll': {
|
||||
'observations': ll_obs,
|
||||
'actions': ll_actions,
|
||||
'rewards': ll_rewards,
|
||||
'env_done': ll_env_done,
|
||||
'plan_done': ll_plan_done,
|
||||
'infos': ll_infos,
|
||||
'steps': ll_steps,
|
||||
}
|
||||
}
|
||||
self.last_obs = hl_obs
|
||||
return hl_obs, hl_reward, hl_done, hl_infos
|
||||
|
||||
def reset(self, *args, **kwargs):
|
||||
self.last_obs = super().reset(*args, **kwargs)
|
||||
return self.last_obs
|
||||
54
scratch/etienne/trpo/options/test_options.py
Normal file
54
scratch/etienne/trpo/options/test_options.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from options import OptionsEnv
|
||||
import gym
|
||||
import numpy as np
|
||||
|
||||
def test_obs_shape():
|
||||
options = [(0, 5), (5, 5), (10, 5)]
|
||||
env = OptionsEnv(IntersimpleLidarFlat(n_rays=5), options)
|
||||
assert env.reset().shape == (36,)
|
||||
|
||||
def test_act_space():
|
||||
options = [(0, 5), (5, 5), (10, 5)]
|
||||
env = OptionsEnv(IntersimpleLidarFlat(n_rays=5), options)
|
||||
assert env.action_space == gym.spaces.Discrete(3)
|
||||
|
||||
def test_plan():
|
||||
options = [(0, 5), (5, 5), (10, 5)]
|
||||
env = OptionsEnv(IntersimpleLidarFlat(n_rays=5), options)
|
||||
env.reset()
|
||||
plan = env.plan(options[0])
|
||||
assert np.allclose(plan, -13.998268127441406 * np.ones((5,)))
|
||||
|
||||
def test_plan2():
|
||||
options = [(0, 5), (5, 5), (10, 5)]
|
||||
env = OptionsEnv(IntersimpleLidarFlat(n_rays=5), options)
|
||||
obs = env.reset()
|
||||
states, actions, rewards, dones, plan_done, infos, n_steps = env.execute_plan(obs, options[0])
|
||||
assert states.shape == (6, 36)
|
||||
assert rewards.shape == (6,)
|
||||
assert dones.shape == (6,)
|
||||
assert len(infos) == 5
|
||||
|
||||
def test_step():
|
||||
options = [(0, 5), (5, 5), (10, 5)]
|
||||
env = OptionsEnv(IntersimpleLidarFlat(n_rays=5), options)
|
||||
env.reset()
|
||||
obs, reward, done, _ = env.step(0)
|
||||
assert obs.shape == (36,)
|
||||
assert reward == 5.0
|
||||
assert done == False
|
||||
|
||||
def test_ll_step():
|
||||
options = [(0, 5), (5, 5), (10, 5)]
|
||||
env = OptionsEnv(IntersimpleLidarFlat(n_rays=5), options)
|
||||
env.reset()
|
||||
_, _, _, info = env.step(0)
|
||||
assert info['ll']['observations'].shape == (6, 36)
|
||||
assert info['ll']['actions'].shape == (6, 1)
|
||||
assert info['ll']['rewards'].shape == (6,)
|
||||
assert info['ll']['env_done'].shape == (6,)
|
||||
assert info['ll']['plan_done'].shape == (6,)
|
||||
assert info['ll']['plan_done'][5] == True
|
||||
assert info['ll']['steps'] == 5
|
||||
assert len(info['ll']['infos']) == 5
|
||||
63
scratch/etienne/trpo/ppo-intersimple-minobs.py
Normal file
63
scratch/etienne/trpo/ppo-intersimple-minobs.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
from core.ppo import ppo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
from wrappers import Minobs
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(30)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
value, policy = ppo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=50,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'ppo-intersimple.pt')
|
||||
62
scratch/etienne/trpo/ppo-intersimple-minobs2.py
Normal file
62
scratch/etienne/trpo/ppo-intersimple-minobs2.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
from core.ppo import ppo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
from wrappers import Minobs
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=1000
|
||||
),
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(30)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
value, policy = ppo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=50,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'ppo-intersimple.pt')
|
||||
61
scratch/etienne/trpo/ppo-intersimple-normobs.py
Normal file
61
scratch/etienne/trpo/ppo-intersimple-normobs.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
from core.ppo import ppo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [TransformObservation(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=10
|
||||
),
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)) for _ in range(30)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
value, policy = ppo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=50,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'ppo-intersimple.pt')
|
||||
41
scratch/etienne/trpo/ppo-intersimple.py
Normal file
41
scratch/etienne/trpo/ppo-intersimple.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
from core.ppo import ppo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
|
||||
envs = [IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=10
|
||||
),
|
||||
) for _ in range(30)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
value, policy = ppo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=50,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'ppo-intersimple.pt')
|
||||
89
scratch/etienne/trpo/ppo-options-minobs.py
Normal file
89
scratch/etienne/trpo/ppo-options-minobs.py
Normal file
@@ -0,0 +1,89 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.ppo import ppo
|
||||
from core.value import Value
|
||||
from core.policy import DiscretePolicy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import numpy as np
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation
|
||||
|
||||
from wrappers import Minobs
|
||||
from options.options import OptionsEnv
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Minobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (5, 5), (10, 5)]) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
value = Value()
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
# %%
|
||||
value, policy = ppo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=50,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=20,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'ppo-options-minobs.pt')
|
||||
|
||||
# %%
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy.load_state_dict(torch.load('ppo-options-minobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
27
scratch/etienne/trpo/ppo-pendulum.py
Normal file
27
scratch/etienne/trpo/ppo-pendulum.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import gym
|
||||
from core.ppo import ppo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
|
||||
env_fn = lambda _: gym.make('Pendulum-v0')
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
ppo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=300,
|
||||
rollout_episodes=100,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
7
scratch/etienne/trpo/readme.md
Normal file
7
scratch/etienne/trpo/readme.md
Normal file
@@ -0,0 +1,7 @@
|
||||
| | TRPO | PPO | GAIL | GAIL PPO | WGAIL | WGAIL PPO |
|
||||
|---------------------|------|-------|-------|----------|-------|-----------|
|
||||
| Pendulum | -120 | -1000 | -120 | -1000 | -120 | -1000 |
|
||||
| intersimple-minobs | +1@30| | +6@26 | +1@20 | -7000@26, -2000@60 | -6000@30, -5000@60 |
|
||||
| intersimple-setobs | | | -200@20 | | | |
|
||||
| intersimple-minobs2 | | | -1500@800 | | | |
|
||||
| intersimple-setobs2 | | | -500@800 | -750@800 | -1300@800 | -2500@600, unstable |
|
||||
55
scratch/etienne/trpo/sb3/sb3-ppo-intersimple-nocollision.py
Normal file
55
scratch/etienne/trpo/sb3/sb3-ppo-intersimple-nocollision.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from stable_baselines3 import PPO
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from gym import Wrapper
|
||||
|
||||
model_name = "ppo_speed_lidar_nocollision"
|
||||
|
||||
env = IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
)
|
||||
|
||||
class CollisionPenaltyWrapper(Wrapper):
|
||||
|
||||
def __init__(self, env, collision_distance, collision_penalty, *args, **kwargs):
|
||||
super().__init__(env, *args, **kwargs)
|
||||
self.penalty = collision_penalty
|
||||
self.distance = collision_distance
|
||||
|
||||
def step(self, action):
|
||||
obs, reward, done, info = super().step(action)
|
||||
reward = -self.penalty if (obs.reshape(-1, 6)[1:, 0] < self.distance).any() else reward
|
||||
|
||||
self.env._rewards.pop()
|
||||
self.env._rewards.append(reward)
|
||||
|
||||
return obs, reward, done, info
|
||||
|
||||
env = CollisionPenaltyWrapper(env, collision_distance=6, collision_penalty=100)
|
||||
|
||||
model = PPO(
|
||||
"MlpPolicy", env,
|
||||
learning_rate=1e-4,
|
||||
verbose=1,
|
||||
)
|
||||
model.learn(total_timesteps=100000)
|
||||
model.save(model_name)
|
||||
|
||||
model = PPO.load(model_name)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(200):
|
||||
action, _ = model.predict(obs)
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'front distance', obs.reshape(-1, 6)[3, 0], 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
58
scratch/etienne/trpo/sb3/sb3-ppo-intersimple-nocollision2.py
Normal file
58
scratch/etienne/trpo/sb3/sb3-ppo-intersimple-nocollision2.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from stable_baselines3 import PPO
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from gym import Wrapper
|
||||
|
||||
model_name = "ppo_speed_lidar_nocollision"
|
||||
|
||||
env = IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
)
|
||||
|
||||
class CollisionPenaltyWrapper(Wrapper):
|
||||
|
||||
def __init__(self, env, collision_distance, collision_penalty, last_reward_weight, *args, **kwargs):
|
||||
super().__init__(env, *args, **kwargs)
|
||||
self.penalty = collision_penalty
|
||||
self.distance = collision_distance
|
||||
self.last_reward = -collision_penalty
|
||||
self.last_reward_weight = last_reward_weight
|
||||
|
||||
def step(self, action):
|
||||
obs, reward, done, info = super().step(action)
|
||||
reward = -self.penalty if (obs.reshape(-1, 6)[1:, 0] < self.distance).any() else reward
|
||||
reward = self.last_reward_weight * self.last_reward + (1 - self.last_reward_weight) * self.last_reward
|
||||
|
||||
self.env._rewards.pop()
|
||||
self.env._rewards.append(reward)
|
||||
|
||||
return obs, reward, done, info
|
||||
|
||||
env = CollisionPenaltyWrapper(env, collision_distance=6, collision_penalty=10, last_reward_weight=0.9)
|
||||
|
||||
model = PPO(
|
||||
"MlpPolicy", env,
|
||||
learning_rate=1e-4,
|
||||
verbose=1,
|
||||
)
|
||||
model.learn(total_timesteps=100000)
|
||||
model.save(model_name)
|
||||
|
||||
model = PPO.load(model_name)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(200):
|
||||
action, _ = model.predict(obs)
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'front distance', obs.reshape(-1, 6)[3, 0], 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
28
scratch/etienne/trpo/sb3/sb3-ppo-intersimple-rollout.py
Normal file
28
scratch/etienne/trpo/sb3/sb3-ppo-intersimple-rollout.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import sys
|
||||
sys.path.append('..')
|
||||
|
||||
from stable_baselines3 import PPO
|
||||
from core.sampling import rollout_sb3
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import torch
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
|
||||
model = PPO.load('sb3-ppo-intersimple')
|
||||
env = CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
), collision_distance=6, collision_penalty=100)
|
||||
|
||||
expert_data = rollout_sb3(env, model, n_episodes=200, max_steps_per_episode=200)
|
||||
|
||||
states, actions, rewards, dones = expert_data
|
||||
print(f'Expert mean episode length {(~dones).sum() / states.shape[0]}')
|
||||
print(f'Expert mean reward per episode {rewards[~dones].sum() / states.shape[0]}')
|
||||
|
||||
torch.save(expert_data, 'sb3-ppo-intersimple-expert-data.pt')
|
||||
23
scratch/etienne/trpo/sb3/sb3-ppo-intersimple.py
Normal file
23
scratch/etienne/trpo/sb3/sb3-ppo-intersimple.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from stable_baselines3 import PPO
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
env = IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
)
|
||||
|
||||
model = PPO(
|
||||
"MlpPolicy", env,
|
||||
learning_rate=1e-4,
|
||||
verbose=1,
|
||||
use_sde=False,
|
||||
sde_sample_freq=4,
|
||||
)
|
||||
model.learn(total_timesteps=100000)
|
||||
model.save('sb3-ppo-intersimple')
|
||||
6
scratch/etienne/trpo/sb3/sb3-ppo-pendulum.py
Normal file
6
scratch/etienne/trpo/sb3/sb3-ppo-pendulum.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from stable_baselines3 import PPO
|
||||
from stable_baselines3.common.env_util import make_vec_env
|
||||
|
||||
env = make_vec_env("Pendulum-v0", n_envs=4)
|
||||
model = PPO("MlpPolicy", env, verbose=1)
|
||||
model.learn(total_timesteps=250000)
|
||||
16
scratch/etienne/trpo/sb3/sb3-trpo-intersimple.py
Normal file
16
scratch/etienne/trpo/sb3/sb3-trpo-intersimple.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from sb3_contrib import TRPO
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
env = IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
)
|
||||
|
||||
model = TRPO("MlpPolicy", env, use_sde=False, sde_sample_freq=4, verbose=1)
|
||||
model.learn(total_timesteps=250000)
|
||||
8
scratch/etienne/trpo/sb3/sb3-trpo-pendulum.py
Normal file
8
scratch/etienne/trpo/sb3/sb3-trpo-pendulum.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from sb3_contrib import TRPO
|
||||
import gym
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
env = TransformObservation(gym.make('Pendulum-v0'), lambda obs: obs)
|
||||
|
||||
model = TRPO("MlpPolicy", env, verbose=1)
|
||||
model.learn(total_timesteps=250000)
|
||||
88
scratch/etienne/trpo/trpo-intersimple-minobs.py
Normal file
88
scratch/etienne/trpo/trpo-intersimple-minobs.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
from wrappers import Minobs
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
# %%
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=50,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.9,
|
||||
backtrack_iters=50,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
cg_damping=0.1,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'trpo-intersimple-minobs.pt')
|
||||
|
||||
# %%
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('trpo-intersimple-minobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
87
scratch/etienne/trpo/trpo-intersimple-minobs2.py
Normal file
87
scratch/etienne/trpo/trpo-intersimple-minobs2.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
from wrappers import Minobs
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
# %%
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=200,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.9,
|
||||
backtrack_iters=50,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
cg_damping=0.1,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'trpo-intersimple-minobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('trpo-intersimple-minobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
62
scratch/etienne/trpo/trpo-intersimple-normobs.py
Normal file
62
scratch/etienne/trpo/trpo-intersimple-normobs.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [TransformObservation(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=10
|
||||
),
|
||||
), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10)) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.9,
|
||||
backtrack_iters=50,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
cg_damping=0.1,
|
||||
)
|
||||
|
||||
#rollout(env_fn, policy, n_episodes=9, max_steps_per_episode=200, render=True)
|
||||
90
scratch/etienne/trpo/trpo-intersimple-setobs.py
Normal file
90
scratch/etienne/trpo/trpo-intersimple-setobs.py
Normal file
@@ -0,0 +1,90 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo
|
||||
from core.value import SetValue
|
||||
from core.policy import DeepSetPolicy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
from wrappers import Setobs
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = DeepSetPolicy(env_fn(0).action_space.shape[0])
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
# %%
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=150,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.9,
|
||||
backtrack_iters=50,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
cg_damping=0.1,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'trpo-intersimple-setobs.pt')
|
||||
|
||||
# %%
|
||||
policy = DeepSetPolicy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('trpo-intersimple-setobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
87
scratch/etienne/trpo/trpo-intersimple-setobs2.py
Normal file
87
scratch/etienne/trpo/trpo-intersimple-setobs2.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo
|
||||
from core.value import DeepSetValue
|
||||
from core.policy import DeepSetPolicy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
from wrappers import Setobs
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = DeepSetPolicy(env_fn(0).action_space.shape[0])
|
||||
value = DeepSetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
# %%
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=200,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.9,
|
||||
backtrack_iters=50,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
cg_damping=0.1,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'trpo-intersimple-setobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = DeepSetPolicy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('trpo-intersimple-setobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action)
|
||||
env.render(mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
42
scratch/etienne/trpo/trpo-intersimple.py
Normal file
42
scratch/etienne/trpo/trpo-intersimple.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
|
||||
envs = [IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=10
|
||||
),
|
||||
) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.9,
|
||||
backtrack_iters=50,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
cg_damping=0.1,
|
||||
)
|
||||
|
||||
#rollout(env_fn, policy, n_episodes=9, max_steps_per_episode=200, render=True)
|
||||
91
scratch/etienne/trpo/trpo-options-minobs.py
Normal file
91
scratch/etienne/trpo/trpo-options-minobs.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# %%
|
||||
import gym
|
||||
from core.sampling import rollout
|
||||
from core.trpo import trpo
|
||||
from core.value import Value
|
||||
from core.policy import DiscretePolicy
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
import numpy as np
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
from wrappers import Minobs
|
||||
from options.options import OptionsEnv
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Minobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (5, 5), (10, 5)]) for _ in range(50)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
# %%
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=50,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=20,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.95,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.9,
|
||||
backtrack_iters=50,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
cg_damping=0.1,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'trpo-options-minobs.pt')
|
||||
|
||||
# %%
|
||||
policy = DiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('trpo-options-minobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
|
||||
# %%
|
||||
17
scratch/etienne/trpo/trpo-pendulum-rollout.py
Normal file
17
scratch/etienne/trpo/trpo-pendulum-rollout.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import gym
|
||||
from core.gail import gail
|
||||
from core.reparam_module import ReparamPolicy
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from core.sampling import rollout
|
||||
|
||||
env_fn = lambda _: gym.make('Pendulum-v0')
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('trpo-pendulum.pt'))
|
||||
|
||||
expert_data = rollout(env_fn, policy, n_episodes=20, max_steps_per_episode=200)
|
||||
torch.save(expert_data, 'trpo-pendulum-expert-data.pt')
|
||||
30
scratch/etienne/trpo/trpo-pendulum.py
Normal file
30
scratch/etienne/trpo/trpo-pendulum.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import gym
|
||||
from gym.wrappers import TransformObservation
|
||||
from core.trpo import trpo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
|
||||
env_fn = lambda _: TransformObservation(gym.make('Pendulum-v0'), lambda obs: obs)
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3, weight_decay=1e-4)
|
||||
|
||||
value, policy = trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=100,
|
||||
rollout_episodes=20,
|
||||
rollout_steps=250,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
|
||||
|
||||
torch.save(policy.state_dict(), 'trpo-pendulum.pt')
|
||||
26
scratch/etienne/trpo/trpo-walker.py
Normal file
26
scratch/etienne/trpo/trpo-walker.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import gym
|
||||
from core.trpo import trpo
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
import torch.optim
|
||||
|
||||
env_fn = lambda _: gym.make('BipedalWalker-v3')
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-2)
|
||||
|
||||
trpo(
|
||||
env_fn=env_fn,
|
||||
value=value,
|
||||
policy=policy,
|
||||
epochs=1000,
|
||||
rollout_episodes=20,
|
||||
rollout_steps=250,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
)
|
||||
76
scratch/etienne/trpo/wgail-intersimple-minobs.py
Normal file
76
scratch/etienne/trpo/wgail-intersimple-minobs.py
Normal file
@@ -0,0 +1,76 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-2)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-intersimple-minobs.pt')
|
||||
75
scratch/etienne/trpo/wgail-intersimple-minobs2.py
Normal file
75
scratch/etienne/trpo/wgail-intersimple-minobs2.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.RMSprop(discriminator.parameters(), lr=1e-3, weight_decay=1e-5)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=50,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
wasserstein=True,
|
||||
wasserstein_c=0.1,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-intersimple-minobs2.pt')
|
||||
77
scratch/etienne/trpo/wgail-intersimple-setobs2.py
Normal file
77
scratch/etienne/trpo/wgail-intersimple-setobs2.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetPolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.RMSprop(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=800,
|
||||
rollout_episodes=50,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
wasserstein=True,
|
||||
wasserstein_c=100.,
|
||||
logger=SummaryWriter(comment='-wgail-setobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-intersimple-setobs2.pt')
|
||||
56
scratch/etienne/trpo/wgail-intersimple.py
Normal file
56
scratch/etienne/trpo/wgail-intersimple.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper
|
||||
|
||||
envs = [CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.RMSprop(discriminator.parameters(), lr=1e-4)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-intersimple.pt')
|
||||
101
scratch/etienne/trpo/wgail-options-setobs.py
Normal file
101
scratch/etienne/trpo/wgail-options-setobs.py
Normal file
@@ -0,0 +1,101 @@
|
||||
# %%
|
||||
import gym
|
||||
from options.options import gail
|
||||
from core.gail import Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=150,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
logger=SummaryWriter(comment='wgail-options-setobs'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-options-setobs.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('wgail-options-setobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
100
scratch/etienne/trpo/wgail-options-setobs2.py
Normal file
100
scratch/etienne/trpo/wgail-options-setobs2.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# %%
|
||||
import gym
|
||||
from options.options import gail
|
||||
from core.gail import Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
from core.reparam_module import ReparamPolicy
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (6, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=200,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
logger=SummaryWriter(comment='wgail-options-setobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-options-setobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy = ReparamPolicy(policy)
|
||||
policy.load_state_dict(torch.load('wgail-options-setobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
#action, _ = policy.predict(torch.tensor(obs))
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
40
scratch/etienne/trpo/wgail-pendulum.py
Normal file
40
scratch/etienne/trpo/wgail-pendulum.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import gym
|
||||
from core.gail import gail, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
|
||||
env_fn = lambda _: gym.make('Pendulum-v0')
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('trpo-pendulum-expert-data.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
gail(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=100,
|
||||
rollout_episodes=20,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
delta=0.01,
|
||||
backtrack_coeff=0.8,
|
||||
backtrack_iters=10,
|
||||
wasserstein=True,
|
||||
wasserstein_c=100.,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-pendulum.pt')
|
||||
77
scratch/etienne/trpo/wgail-ppo-intersimple-minobs.py
Normal file
77
scratch/etienne/trpo/wgail-ppo-intersimple-minobs.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Minobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
|
||||
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)
|
||||
|
||||
envs = [Minobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.RMSprop(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.RMSprop(discriminator.parameters(), lr=1e-3, weight_decay=1e-5)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-minobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-ppo-intersimple-minobs.pt')
|
||||
78
scratch/etienne/trpo/wgail-ppo-intersimple-setobs2.py
Normal file
78
scratch/etienne/trpo/wgail-ppo-intersimple-setobs2.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetPolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, Setobs
|
||||
import numpy as np
|
||||
from gym.wrappers import TransformObservation
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [Setobs(TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))) for _ in range(50)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetPolicy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-4, weight_decay=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.RMSprop(discriminator.parameters(), lr=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=500,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=800,
|
||||
rollout_episodes=50,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
wasserstein=True,
|
||||
wasserstein_c=100.,
|
||||
logger=SummaryWriter(comment='-wgail-ppo-setobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-ppo-intersimple-setobs2.pt')
|
||||
57
scratch/etienne/trpo/wgail-ppo-intersimple.py
Normal file
57
scratch/etienne/trpo/wgail-ppo-intersimple.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from collision_penalty import CollisionPenaltyWrapper
|
||||
|
||||
envs = [CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100) for _ in range(30)]
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.RMSprop(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.RMSprop(discriminator.parameters(), lr=3e-4)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=4000,
|
||||
rollout_episodes=30,
|
||||
rollout_steps=100,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-ppo-intersimple.pt')
|
||||
98
scratch/etienne/trpo/wgail-ppo-options-setobs.py
Normal file
98
scratch/etienne/trpo/wgail-ppo-options-setobs.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import gym
|
||||
from options.options import gail_ppo, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlat
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlat(
|
||||
n_rays=5,
|
||||
agent=51,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=150,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
logger=SummaryWriter(comment='wgail-ppo-options-setobs'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-ppo-options-setobs.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy.load_state_dict(torch.load('wgail-ppo-options-setobs.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
99
scratch/etienne/trpo/wgail-ppo-options-setobs2.py
Normal file
99
scratch/etienne/trpo/wgail-ppo-options-setobs2.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# %%
|
||||
import gym
|
||||
from options.options import gail_ppo, Buffer
|
||||
from core.value import SetValue
|
||||
from core.policy import SetDiscretePolicy
|
||||
from core.discriminator import DeepsetDiscriminator
|
||||
import torch.optim
|
||||
from intersim.envs import IntersimpleLidarFlatRandom
|
||||
from intersim.envs.intersimple import speed_reward
|
||||
import functools
|
||||
from wrappers import CollisionPenaltyWrapper, TransformObservation, Setobs
|
||||
import numpy as np
|
||||
from options.options import OptionsEnv
|
||||
from torch.utils.tensorboard import SummaryWriter
|
||||
|
||||
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)
|
||||
|
||||
envs = [OptionsEnv(Setobs(
|
||||
TransformObservation(CollisionPenaltyWrapper(IntersimpleLidarFlatRandom(
|
||||
n_rays=5,
|
||||
reward=functools.partial(
|
||||
speed_reward,
|
||||
collision_penalty=0
|
||||
),
|
||||
stop_on_collision=False,
|
||||
), collision_distance=6, collision_penalty=100), lambda obs: (obs - obs_min) / (obs_max - obs_min + 1e-10))
|
||||
), options=[(0, 5), (1, 5), (2, 5), (4, 5), (6, 5), (8, 5)]) for _ in range(60)]
|
||||
|
||||
env_fn = lambda i: envs[i]
|
||||
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
pi_opt = torch.optim.Adam(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = SetValue()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = DeepsetDiscriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('intersimple-expert-data-setobs2.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
# %%
|
||||
value, policy = gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=100,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=200,
|
||||
rollout_episodes=60,
|
||||
rollout_steps=60,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
wasserstein=True,
|
||||
wasserstein_c=1.,
|
||||
logger=SummaryWriter(comment='wgail-ppo-options-setobs2'),
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'wgail-ppo-options-setobs2.pt')
|
||||
|
||||
# %%
|
||||
policy = SetDiscretePolicy(env_fn(0).action_space.n)
|
||||
policy(torch.zeros(env_fn(0).observation_space.shape))
|
||||
policy.load_state_dict(torch.load('wgail-ppo-options-setobs2.pt'))
|
||||
|
||||
env = env_fn(0)
|
||||
obs = env.reset()
|
||||
env.render(mode='post')
|
||||
for i in range(300):
|
||||
action = policy.sample(policy(torch.tensor(obs, dtype=torch.float32)))
|
||||
obs, reward, done, _ = env.step(action, render_mode='post')
|
||||
print('step', i, 'reward', reward)
|
||||
if done:
|
||||
break
|
||||
env.close()
|
||||
44
scratch/etienne/trpo/wgail-ppo-pendulum.py
Normal file
44
scratch/etienne/trpo/wgail-ppo-pendulum.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import gym
|
||||
from core.gail import gail_ppo, Buffer
|
||||
from core.value import Value
|
||||
from core.policy import Policy
|
||||
from core.discriminator import Discriminator
|
||||
import torch.optim
|
||||
|
||||
env_fn = lambda _: gym.make('Pendulum-v0')
|
||||
|
||||
policy = Policy(env_fn(0).action_space.shape[0])
|
||||
pi_opt = torch.optim.RMSprop(policy.parameters(), lr=3e-4)
|
||||
|
||||
value = Value()
|
||||
v_opt = torch.optim.Adam(value.parameters(), lr=1e-3)
|
||||
|
||||
discriminator = Discriminator()
|
||||
disc_opt = torch.optim.Adam(discriminator.parameters(), lr=1e-3, weight_decay=1e-3)
|
||||
|
||||
expert_data = torch.load('trpo-pendulum-expert-data.pt')
|
||||
expert_data = Buffer(*expert_data)
|
||||
|
||||
gail_ppo(
|
||||
env_fn=env_fn,
|
||||
expert_data=expert_data,
|
||||
discriminator=discriminator,
|
||||
disc_opt=disc_opt,
|
||||
disc_iters=10,
|
||||
policy=policy,
|
||||
value=value,
|
||||
v_opt=v_opt,
|
||||
v_iters=1000,
|
||||
epochs=100,
|
||||
rollout_episodes=20,
|
||||
rollout_steps=200,
|
||||
gamma=0.99,
|
||||
gae_lambda=0.9,
|
||||
clip_ratio=0.2,
|
||||
pi_opt=pi_opt,
|
||||
pi_iters=100,
|
||||
wasserstein=True,
|
||||
wasserstein_c=100.,
|
||||
)
|
||||
|
||||
torch.save(policy.state_dict(), 'gail-pendulum.pt')
|
||||
74
scratch/etienne/trpo/wrappers.py
Normal file
74
scratch/etienne/trpo/wrappers.py
Normal file
@@ -0,0 +1,74 @@
|
||||
import numpy as np
|
||||
import gym
|
||||
|
||||
class Wrapper(gym.Wrapper):
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.env, name)
|
||||
|
||||
class TransformObservation(gym.wrappers.TransformObservation):
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.env, name)
|
||||
|
||||
class CollisionPenaltyWrapper(Wrapper):
|
||||
|
||||
def __init__(self, env, collision_distance, collision_penalty, *args, **kwargs):
|
||||
super().__init__(env, *args, **kwargs)
|
||||
self.penalty = collision_penalty
|
||||
self.distance = collision_distance
|
||||
|
||||
def step(self, action):
|
||||
obs, reward, done, info = super().step(action)
|
||||
reward = -self.penalty if (obs.reshape(-1, 6)[1:, 0] < self.distance).any() else reward
|
||||
|
||||
self.env._rewards.pop()
|
||||
self.env._rewards.append(reward)
|
||||
|
||||
return obs, reward, done, info
|
||||
|
||||
class Minobs(Wrapper):
|
||||
""" Meant to be used as wrapper around LidarObservation """
|
||||
|
||||
def __init__(self, env, *args, **kwargs):
|
||||
super().__init__(env, *args, **kwargs)
|
||||
n_rays = int(self.observation_space.shape[0] / 6) - 1
|
||||
self.observation_space = gym.spaces.Box(low=-np.inf, high=np.inf, shape=((1 + n_rays) * 2,))
|
||||
|
||||
def minobs(self, obs):
|
||||
""" ego v, psidot ; (for each ray,) rel. distance, rel. velocity in ego forward direction """
|
||||
obs = obs.reshape(-1, 6)
|
||||
obs = np.concatenate((obs[:1, [2, 4]], obs[1:, [0, 2]]), axis=0)
|
||||
return obs.reshape(-1)
|
||||
|
||||
def reset(self):
|
||||
return self.minobs(super().reset())
|
||||
|
||||
def step(self, action):
|
||||
obs, reward, done, info = super().step(action)
|
||||
return self.minobs(obs), reward, done, info
|
||||
|
||||
class Setobs(Wrapper):
|
||||
""" Meant to be used as wrapper around LidarObservation """
|
||||
|
||||
def __init__(self, env, *args, **kwargs):
|
||||
super().__init__(env, *args, **kwargs)
|
||||
self.n_rays = int(self.observation_space.shape[0] / 6) - 1
|
||||
self.observation_space = gym.spaces.Box(low=-np.inf, high=np.inf, shape=(self.n_rays, 6))
|
||||
|
||||
def obs(self, obs):
|
||||
obs = obs.reshape(-1, 6)
|
||||
|
||||
ego = obs[:1, [2, 4]] # v, psidot
|
||||
ego = np.tile(ego, (self.n_rays, 1))
|
||||
|
||||
other = obs[1:, [0, 1, 2]] # distance, angle, velocity component in ego forward direction
|
||||
other = np.stack((other[:, 0], np.cos(other[:, 1]), np.sin(other[:, 1]), other[:, 2]), axis=-1)
|
||||
|
||||
obs = np.concatenate((ego, other), axis=-1)
|
||||
return obs
|
||||
|
||||
def reset(self):
|
||||
return self.obs(super().reset())
|
||||
|
||||
def step(self, action):
|
||||
obs, reward, done, info = super().step(action)
|
||||
return self.obs(obs), reward, done, info
|
||||
Reference in New Issue
Block a user