Implement ValueDICE and some restructuring

This commit is contained in:
Johannes Fischer
2021-08-04 19:34:49 +02:00
parent cba42c6e4d
commit 5c40de66fa
8 changed files with 442 additions and 86 deletions

View File

@@ -4,16 +4,13 @@ from torch import nn
from src.nets.deepsets import DeepSetsModule, Phi
class Policy:
pass
class DeepSetsPolicy(Policy, nn.Module):
class IntersimStateNet(nn.Module):
def __init__(self, config):
"""
Args:
config (dict): dictionary for configuring the deep sets policy
"""
super(DeepSetsPolicy, self).__init__()
super(IntersimStateNet, self).__init__()
ego_config = config['ego_encoder']
deepsets_config = config['deepsets']
pathnet_config = config['path_encoder']
@@ -40,7 +37,7 @@ class DeepSetsPolicy(Policy, nn.Module):
Returns:
x (torch.tensor): (head_output_dim,) output of common head network
"""
ego = self.ego_net(sample["state"])
ego = self.ego_net(sample["ego_state"])
relative = self.deepsets_net(sample["relative_state"])
# cat path_x, path_y to tensor of dim (B, 2*P)
path = torch.cat([sample["path_x"], sample["path_y"]], dim=-1)
@@ -48,3 +45,122 @@ class DeepSetsPolicy(Policy, nn.Module):
x = torch.cat([ego, relative, path], dim=-1)
x = self.head(x)
return x
class IntersimStateActionNet(nn.Module):
def __init__(self, config):
"""
Args:
config (dict): dictionary for configuring the deep sets policy
"""
super(IntersimStateActionNet, self).__init__()
ego_config = config['ego_encoder']
deepsets_config = config['deepsets']
pathnet_config = config['path_encoder']
self.ego_net = Phi.from_config(ego_config)
self.deepsets_net = DeepSetsModule.from_config(deepsets_config)
self.path_net = Phi.from_config(pathnet_config)
self.action_dim = config["action_dim"]
cat_dim = self.ego_net.output_dim + self.deepsets_net.output_dim + self.path_net.output_dim + self.action_dim
# head has number of concatenated features as input
head_config = config['head']
head_config["input_dim"] = cat_dim
self.head = Phi.from_config(head_config)
def forward(self, sample):
"""
Args:
sample (dict): sample dictionary with the following entries:
state (torch.tensor): (B, 5) raw state
relative_state (torch.tensor): (B, max_nv, d) relative state (padded with nans)
path_x (torch.tensor): (B, P) tensor of P future path x positions
path_y (torch.tensor): (B, P) tensor of P future path y positions
action (torch.tensor): (B, 1) actions taken from each state
Returns:
x (torch.tensor): (head_output_dim,) output of common head network
"""
ego = self.ego_net(sample["ego_state"])
relative = self.deepsets_net(sample["relative_state"])
# cat path_x, path_y to tensor of dim (B, 2*P)
path = torch.cat([sample["path_x"], sample["path_y"]], dim=-1)
path = self.path_net(path)
action = sample["action"]
x = torch.cat([ego, relative, path, action], dim=-1)
x = self.head(x)
return x
class IntersimPolicy():
"""
Base class for intersim policies
"""
def __init__(self, config, transforms):
super(IntersimPolicy, self).__init__()
self._config = config
self._transforms = transforms
@property
def transforms(self):
return self._transforms
@transforms.setter
def transforms(self, transforms):
self._transforms=transforms
@property
def policy(self):
return self._policy
@policy.setter
def policy(self, policy):
self._policy = policy
def transform_observation(self, ob):
# run observation through transforms
transformed_ob = {}
for key in ['ego_state', 'relative_state', 'path', 'action']:
if key in self._transforms.keys():
transformed_ob[key] = self._transforms[key].transform(ob[key])
return transformed_ob
def __call__(self, ob):
if 'action' in ob.keys():
# extract state from dataloader samples
pass
else:
# extract state from observation (using simulator)
ob['path_x'] = ob['paths'][0]
ob['path_y'] = ob['paths'][1]
ob = transform_observation(ob)
# run transformed state through model
action = self._policy(ob)
assert action.ndim == 2, 'action has incorrect shape'
# untransform action
if 'action' in self._transforms.keys():
action = self._transforms['action'].inverse_transform(action)
return action
def generate_transforms(dataset):
"""
Generate transform dictionary from dataset
Args:
dataset (Dataset): dataset of demo observations and actions
"""
transforms = {
'action': MinMaxScaler(),
'state': MinMaxScaler(),
'relative_state': MinMaxScaler(reduce_dim=2),
'path_x': MinMaxScaler(reduce_dim=2),
'path_y': MinMaxScaler(reduce_dim=2),
}
for key in transforms.keys():
transforms[key].fit(dataset[:][key])
return transforms