-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBBRL_Agents.py
More file actions
84 lines (69 loc) · 2.63 KB
/
Copy pathBBRL_Agents.py
File metadata and controls
84 lines (69 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import torch
import torch.nn as nn
from bbrl.agents import Agent
from bbrl_utils.nn import build_mlp
from torch.distributions import Normal
import math
class ContinuousQAgent(Agent):
def __init__(self, state_dim, hidden_layers, action_dim):
super().__init__()
self.is_q_function = True
self.model = build_mlp(
[state_dim + action_dim] + list(hidden_layers) + [1], activation=nn.ReLU()
)
def forward(self, t):
# Get the current state $s_t$ and the chosen action $a_t$
obs = self.get(("env/env_obs", t)) # shape B x D_{obs}
action = self.get(("action", t)) # shape B x D_{action}
# Compute the Q-value(s_t, a_t)
obs_act = torch.cat((obs, action), dim=1) # shape B x (D_{obs} + D_{action})
# Get the q-value (and remove the last dimension since it is a scalar)
q_value = self.model(obs_act).squeeze(-1)
self.set((f"{self.prefix}q_value", t), q_value)
def predict_value(self, obs, action):
obs_act = torch.cat((obs, action), dim=0)
q_value = self.model(obs_act)
return q_value
class ContinuousDeterministicActor(Agent):
def __init__(self, state_dim, hidden_layers, action_dim):
super().__init__()
layers = [state_dim] + list(hidden_layers) + [action_dim]
self.model = build_mlp(
layers, activation=nn.ReLU(), output_activation=nn.Tanh()
)
def forward(self, t, **kwargs):
obs = self.get(("env/env_obs", t))
action = self.model(obs)
self.set(("action", t), action)
def predict_action(self, obs, stochastic):
assert (
not stochastic
), "ContinuousDeterministicActor cannot provide stochastic predictions"
return self.model(obs)
class AddGaussianNoise(Agent):
def __init__(self, sigma):
super().__init__()
self.sigma = sigma
def forward(self, t, **kwargs):
act = self.get(("action", t))
dist = Normal(act, self.sigma)
action = dist.sample()
self.set(("action", t), action)
class AddOUNoise(Agent):
"""
Ornstein Uhlenbeck process noise for actions as suggested by DDPG paper
"""
def __init__(self, std_dev, theta=0.15, dt=1e-2):
self.theta = theta
self.std_dev = std_dev
self.dt = dt
self.x_prev = 0
def forward(self, t, **kwargs):
act = self.get(("action", t))
x = (
self.x_prev
+ self.theta * (act - self.x_prev) * self.dt
+ self.std_dev * math.sqrt(self.dt) * torch.randn(act.shape)
)
self.x_prev = x
self.set(("action", t), x)