Download action_conditioned_model.py from world-model/world-model-implementation-lab: direct link, hf CLI and curl.
- Browser
- Download file 2.16 kB
-
https://huggingface.co/spaces/world-model/world-model-implementation-lab/resolve/main/action_conditioned_model.py
- Command line
-
hf download hf://spaces/world-model/world-model-implementation-lab/action_conditioned_model.py
-
curl -L -o action_conditioned_model.py https://huggingface.co/spaces/world-model/world-model-implementation-lab/resolve/main/action_conditioned_model.py
2.16 kB
| """ | |
| Action-conditioned world model with reconstruction. | |
| The model learns: | |
| observation_t -> latent_t | |
| latent_t + action_t -> latent_t+1 | |
| latent_t+1 -> predicted observation_t+1 | |
| """ | |
| import torch | |
| from torch import nn | |
| class ActionConditionedWorldModel(nn.Module): | |
| def __init__( | |
| self, | |
| obs_dim: int, | |
| action_dim: int, | |
| latent_dim: int = 32, | |
| hidden_dim: int = 128, | |
| ): | |
| super().__init__() | |
| self.encoder = nn.Sequential( | |
| nn.Linear(obs_dim, hidden_dim), | |
| nn.ReLU(), | |
| nn.Linear(hidden_dim, latent_dim), | |
| ) | |
| self.action_encoder = nn.Sequential( | |
| nn.Linear(action_dim, 32), | |
| nn.ReLU(), | |
| ) | |
| self.dynamics = nn.Sequential( | |
| nn.Linear(latent_dim + 32, hidden_dim), | |
| nn.ReLU(), | |
| nn.Linear(hidden_dim, latent_dim), | |
| ) | |
| self.decoder = nn.Sequential( | |
| nn.Linear(latent_dim, hidden_dim), | |
| nn.ReLU(), | |
| nn.Linear(hidden_dim, obs_dim), | |
| ) | |
| def step( | |
| self, | |
| latent: torch.Tensor, | |
| action: torch.Tensor, | |
| ) -> torch.Tensor: | |
| action_features = self.action_encoder(action) | |
| x = torch.cat([latent, action_features], dim=-1) | |
| delta = self.dynamics(x) | |
| return latent + delta | |
| def forward( | |
| self, | |
| obs: torch.Tensor, | |
| action: torch.Tensor, | |
| ): | |
| latent = self.encoder(obs) | |
| next_latent = self.step(latent, action) | |
| next_obs_pred = self.decoder(next_latent) | |
| return next_obs_pred, next_latent | |
| if __name__ == "__main__": | |
| torch.manual_seed(0) | |
| model = ActionConditionedWorldModel( | |
| obs_dim=12, | |
| action_dim=3, | |
| latent_dim=24, | |
| ) | |
| optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) | |
| obs_t = torch.randn(32, 12) | |
| action_t = torch.randn(32, 3) | |
| obs_t1 = torch.randn(32, 12) | |
| pred_obs_t1, _ = model(obs_t, action_t) | |
| loss = nn.functional.mse_loss(pred_obs_t1, obs_t1) | |
| optimizer.zero_grad() | |
| loss.backward() | |
| optimizer.step() | |
| print("training loss:", float(loss)) | |