{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "tmj6YpybPggi" }, "source": [ "## Configuration for Colab" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "pjqeHnaKPggj", "outputId": "84d8f310-5220-491e-fba2-1ac5ff202b5c" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Collecting gymnasium==1.0.0\n", " Downloading gymnasium-1.0.0-py3-none-any.whl.metadata (9.5 kB)\n", "Requirement already satisfied: numpy>=1.21.0 in /usr/local/lib/python3.10/dist-packages (from gymnasium==1.0.0) (1.26.4)\n", "Requirement already satisfied: cloudpickle>=1.2.0 in /usr/local/lib/python3.10/dist-packages (from gymnasium==1.0.0) (3.1.0)\n", "Requirement already satisfied: typing-extensions>=4.3.0 in /usr/local/lib/python3.10/dist-packages (from gymnasium==1.0.0) (4.12.2)\n", "Collecting farama-notifications>=0.0.1 (from gymnasium==1.0.0)\n", " Downloading Farama_Notifications-0.0.4-py3-none-any.whl.metadata (558 bytes)\n", "Downloading gymnasium-1.0.0-py3-none-any.whl (958 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m958.1/958.1 kB\u001b[0m \u001b[31m25.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hDownloading Farama_Notifications-0.0.4-py3-none-any.whl (2.5 kB)\n", "Installing collected packages: farama-notifications, gymnasium\n", "Successfully installed farama-notifications-0.0.4 gymnasium-1.0.0\n" ] } ], "source": [ "import sys\n", "\n", "IN_COLAB = \"google.colab\" in sys.modules\n", "\n", "if IN_COLAB:\n", " !pip install gymnasium==1.0.0" ] }, { "cell_type": "markdown", "metadata": { "id": "DIGopM6lPggk" }, "source": [ "# 04. TD3\n", "\n", "[Fujimoto, Scott, Herke van Hoof, and David Meger. \"Addressing function approximation error in actor-critic methods.\" arXiv preprint arXiv:1802.09477 2018.](https://arxiv.org/pdf/1802.09477.pdf)\n", "\n", "In value-based reinforcement learning methods, function approximation errors are known to lead to overestimated value estimates and suboptimal policies. However, similar issues with actor-critic methods in continuous control domains have been largely left untouched (See paper for detailed description). To solve this problem, this paper proposes *a clipped Double Q-learning*. In addtion, this paper contains a number of components that address variance reduction.\n", "\n", "The author's modifications are applied to actor-critic method for continuous control, Deep Deterministic Policy Gradient algorithm ([DDPG](https://arxiv.org/pdf/1509.02971.pdf)), to form the *Twin Delayed Deep Deterministic policy gradient algorithm (TD3)*.\n", "\n", "### DDPG\n", "For learning in high-dimentional and continous action spaces, the authors of DDPG combine the actor-critic approach with insights from the success of DQN. Deep DPG(DDPG) is based on the deterministic policy gradient(DPG) algorithm ([Silver et al., 2014](http://proceedings.mlr.press/v32/silver14.pdf)). Please see *03.DDPG.ipynb* for detailed description of DDPG.\n", "\n", "### Double Q-learning\n", "In Double DQN ([Van Hasselt et al., 2016](https://arxiv.org/pdf/1509.06461.pdf)), the authors propose using the target network as one of the value estimates, and obtain a policy by greedy maximization of the current value network rather than the target network. In an actor-critic setting, an analogous update uses the current policy rather than the target policy in the learning target. However, with the slow-changing policy in actor-critic, the current and target networks were too similar to make an independent estimation, and offered little improvement. Instead, the original Double Q-learning formulation can be used, with a pair of actors $(\\pi_{\\phi_1}, \\pi_{\\phi_2})$ and critics $(Q_{\\theta_1}, Q_{\\theta_2})$, where $\\pi_{\\phi_1}$ is optimized with respect to $Q_{\\theta_1}$ and $\\pi_{\\phi_2}$ with respect to $Q_{\\theta_2}$:\n", "\n", "$$\n", "y_1 = r + \\gamma Q_{\\theta'_2} (s' , \\pi_{\\phi_1}(s')) \\\\\n", "y_2 = r + \\gamma Q_{\\theta'_1} (s' , \\pi_{\\phi_2}(s'))\n", "$$\n", "\n", "### A clipped Double Q-learning\n", "The critics are not entirely independent, due to the use of the opposite critic in the learning targets, as well as the same replay buffer. As a result, for some states we will have $Q_{\\theta'_2}(s, \\pi_{\\phi_1}) > Q_{\\theta'_1}(s, \\pi_{\\phi_1})$. This is problematic because $Q_{\\theta'_1}(s, \\pi_{\\phi_1})$ will generally overestimate the true value, and in certain areas of the state space the overestimation will be further exaggerated. To address this problem, the authors propose to take the minimum between the two estimates:\n", "\n", "$$\n", "y_1 = r + \\gamma \\underset{i=1,2}{\\min} Q_{\\theta'_i} (s' , \\pi_{\\phi_1}(s'))\n", "$$\n", "\n", "### Delayed Policy Updates\n", "If policy updates on high-error states cause different behavior, then the policy network should be updated at a lower frequency than the value network, to first minimize error before introducing a policy update. The authors propose delaying policy updates until the value error is as small as possible.\n", "\n", "### Target Policy Smoothing Regularization\n", "When updating the critic, a learning target using a deterministic policy is highly susceptible to in accuracies induced by function approximation error, increasing the variance of the target. This induced variance can be reduced through regularization. The authors propose that fitting the value of a small area around the target action\n", "\n", "$$\n", "y = r + E_\\epsilon [Q_{\\theta'}(s', \\pi_{\\phi '}(s') + \\epsilon],\n", "$$\n", "\n", "would have the benefit of smoothing the value estimate by bootstrapping off of similar state-action value estimates. In practice, this makes below:\n", "\n", "$$\n", "y = r + \\gamma Q_{\\theta '}(s', \\pi_{\\phi '}(s') + \\epsilon), \\\\\n", "\\epsilon \\sim \\text{clip} (\\mathcal(N)(0, \\sigma), -c, c),\n", "$$\n", "\n", "where the added noise is clipped to keep the target close tothe original action." ] }, { "cell_type": "markdown", "metadata": { "id": "dO5NkLRePggl" }, "source": [ "## import module" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "f4DQHLwlPggl" }, "outputs": [], "source": [ "import copy\n", "import os\n", "import random\n", "from typing import Dict, List, Tuple\n", "\n", "import gymnasium as gym\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "import torch.optim as optim\n", "from IPython.display import clear_output" ] }, { "cell_type": "markdown", "metadata": { "id": "XAXt8mj-Pggl" }, "source": [ "## Replay buffer\n", "Typically, people implement replay buffers with one of the following three data structures:\n", "\n", "- collections.deque\n", "- list\n", "- numpy.ndarray\n", "\n", "**deque** is very easy to handle once you initialize its maximum length (e.g. deque(maxlen=buffer_size)). However, the indexing operation of deque gets terribly slow as it grows up because it is [internally doubly linked list](https://wiki.python.org/moin/TimeComplexity#collections.deque). On the other hands, **list** is an array, so it is relatively faster than deque when you sample batches at every step. Its amortized cost of Get item is [O(1)](https://wiki.python.org/moin/TimeComplexity#list).\n", "\n", "Last but not least, let's see **numpy.ndarray**. numpy.ndarray is even faster than list due to the fact that it is [a homogeneous array of fixed-size items](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html#numpy.ndarray), so you can get the benefits of [locality of reference](https://en.wikipedia.org/wiki/Locality_of_reference), . Whereas list is an array of pointers to objects, even when all of them are of the same type.\n", "\n", "Here, we are going to implement a replay buffer using numpy.ndarray.\n", "\n", "Reference:\n", "- [OpenAI spinning-up](https://github.com/openai/spinningup/blob/master/spinup/algos/sac/sac.py#L10)\n", "- [rainbow-is-all-you-need](https://render.githubusercontent.com/view/ipynb?commit=032d11277cf2436853478a69ca5a4aba03202598&enc_url=68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f437572742d5061726b2f7261696e626f772d69732d616c6c2d796f752d6e6565642f303332643131323737636632343336383533343738613639636135613461626130333230323539382f30312e64716e2e6970796e62&nwo=Curt-Park%2Frainbow-is-all-you-need&path=01.dqn.ipynb&repository_id=191133946&repository_type=Repository#Replay-buffer)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "Ly-vgoJ0Pggl" }, "outputs": [], "source": [ "class ReplayBuffer:\n", " \"\"\"A simple numpy replay buffer.\"\"\"\n", "\n", " def __init__(self, obs_dim: int, act_dim: int, size: int, batch_size: int = 32):\n", " \"\"\"Initializate.\"\"\"\n", " self.obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n", " self.next_obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n", " self.acts_buf = np.zeros([size, act_dim], dtype=np.float32)\n", " self.rews_buf = np.zeros([size], dtype=np.float32)\n", " self.done_buf = np.zeros([size], dtype=np.float32)\n", " self.max_size, self.batch_size = size, batch_size\n", " self.ptr, self.size = 0, 0\n", "\n", " def store(\n", " self,\n", " obs: np.ndarray,\n", " act: np.ndarray,\n", " rew: float,\n", " next_obs: np.ndarray,\n", " done: bool,\n", " ):\n", " \"\"\"Store the transition in buffer.\"\"\"\n", " self.obs_buf[self.ptr] = obs\n", " self.next_obs_buf[self.ptr] = next_obs\n", " self.acts_buf[self.ptr] = act\n", " self.rews_buf[self.ptr] = rew\n", " self.done_buf[self.ptr] = done\n", " self.ptr = (self.ptr + 1) % self.max_size\n", " self.size = min(self.size + 1, self.max_size)\n", "\n", " def sample_batch(self) -> Dict[str, np.ndarray]:\n", " \"\"\"Randomly sample a batch of experiences from memory.\"\"\"\n", " idxs = np.random.choice(self.size, size=self.batch_size, replace=False)\n", " return dict(\n", " obs=self.obs_buf[idxs],\n", " next_obs=self.next_obs_buf[idxs],\n", " acts=self.acts_buf[idxs],\n", " rews=self.rews_buf[idxs],\n", " done=self.done_buf[idxs],\n", " )\n", "\n", " def __len__(self) -> int:\n", " return self.size" ] }, { "cell_type": "markdown", "metadata": { "id": "GlEggFvFPggl" }, "source": [ "## Gaussian Noise\n", "Because the DDPG and the TD3 policy is deterministic, it's not enough to explore a wide variety of actions. In order to facilitate more exploration. TD3 adds Gaussian noise to each action, while DDPG uses Ornstein-Uhlenbeck noise. The TD3 paper states Ornstein-Uhlenbeck noise offered no performance benefits." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "bUT5eWg6Pggl" }, "outputs": [], "source": [ "class GaussianNoise:\n", " \"\"\"Gaussian Noise.\n", " Taken from https://github.com/vitchyr/rlkit\n", " \"\"\"\n", "\n", " def __init__(\n", " self,\n", " action_dim: int,\n", " min_sigma: float = 1.0,\n", " max_sigma: float = 1.0,\n", " decay_period: int = 1000000,\n", " ):\n", " \"\"\"Initialize.\"\"\"\n", " self.action_dim = action_dim\n", " self.max_sigma = max_sigma\n", " self.min_sigma = min_sigma\n", " self.decay_period = decay_period\n", "\n", " def sample(self, t: int = 0) -> float:\n", " \"\"\"Get an action with gaussian noise.\"\"\"\n", " sigma = self.max_sigma - (self.max_sigma - self.min_sigma) * min(1.0, t / self.decay_period)\n", " return np.random.normal(0, sigma, size=self.action_dim)" ] }, { "cell_type": "markdown", "metadata": { "id": "nEXGUpYPPggm" }, "source": [ "## Network\n", "We are going to use two separated networks for actor and critic. The actor network has three fully connected layers and three non-linearity functions, *ReLU* for hidden layers and *tanh* for the output layer. On the other hand, the critic network has three fully connected layers, but it used two activation functions for hidden layers *ReLU*. Plus, its input sizes of critic network are sum of state sizes and action sizes. One thing to note is that we initialize the final layer's weights and biases so that they are *uniformly distributed.*" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "U0oDM0VLPggm" }, "outputs": [], "source": [ "class Actor(nn.Module):\n", " def __init__(self, in_dim: int, out_dim: int, init_w: float = 3e-3):\n", " \"\"\"Initialize.\"\"\"\n", " super(Actor, self).__init__()\n", "\n", " self.hidden1 = nn.Linear(in_dim, 128)\n", " self.hidden2 = nn.Linear(128, 128)\n", " self.out = nn.Linear(128, out_dim)\n", "\n", " self.out.weight.data.uniform_(-init_w, init_w)\n", " self.out.bias.data.uniform_(-init_w, init_w)\n", "\n", " def forward(self, state: torch.Tensor) -> torch.Tensor:\n", " \"\"\"Forward method implementation.\"\"\"\n", " x = F.relu(self.hidden1(state))\n", " x = F.relu(self.hidden2(x))\n", " action = self.out(x).tanh()\n", "\n", " return action\n", "\n", "\n", "class Critic(nn.Module):\n", " def __init__(self, in_dim: int, init_w: float = 3e-3):\n", " \"\"\"Initialize.\"\"\"\n", " super(Critic, self).__init__()\n", "\n", " self.hidden1 = nn.Linear(in_dim, 128)\n", " self.hidden2 = nn.Linear(128, 128)\n", " self.out = nn.Linear(128, 1)\n", "\n", " self.out.weight.data.uniform_(-init_w, init_w)\n", " self.out.bias.data.uniform_(-init_w, init_w)\n", "\n", " def forward(self, state: torch.Tensor, action: torch.Tensor) -> torch.Tensor:\n", " \"\"\"Forward method implementation.\"\"\"\n", " x = torch.cat((state, action), dim=-1)\n", " x = F.relu(self.hidden1(x))\n", " x = F.relu(self.hidden2(x))\n", " value = self.out(x)\n", "\n", " return value" ] }, { "cell_type": "markdown", "metadata": { "id": "M8jQ75q_Pggm" }, "source": [ "## TD3Agent\n", "Here is a summary of TD3Agent class.\n", "\n", "| Method | Note |\n", "|--- |--- |\n", "|select_action | select an action from the input state. |\n", "|step | take an action and return the response of the env. |\n", "|update_model | update the model by gradient descent. |\n", "|train | train the agent during num_frames. |\n", "|test | test the agent (1 episode). |\n", "|\\_target_soft_update| soft update from the local model to the target model.|\n", "|\\_plot | plot the training progresses. |" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "id": "q-87beELPggm" }, "outputs": [], "source": [ "class TD3Agent:\n", " \"\"\"TD3Agent interacting with environment.\n", "\n", " Attribute:\n", " env (gym.Env): openAI Gym environment\n", " actor1 (nn.Module): target actor model to select actions\n", " actor2 (nn.Module): target actor model to select actions\n", " actor_target1 (nn.Module): actor model to predict next actions\n", " actor_target2 (nn.Module): actor model to predict next actions\n", " actor_optimizer (Optimizer): optimizer for training actor\n", " critic1 (nn.Module): critic model to predict state values\n", " critic2 (nn.Module): critic model to predict state values\n", " critic_target1 (nn.Module): target critic model to predict state values\n", " critic_target2 (nn.Module): target critic model to predict state values\n", " critic_optimizer (Optimizer): optimizer for training critic\n", " memory (ReplayBuffer): replay memory to store transitions\n", " batch_size (int): batch size for sampling\n", " gamma (float): discount factor\n", " tau (float): parameter for soft target update\n", " initial_random_steps (int): initial random action steps\n", " exploration_noise (GaussianNoise): gaussian noise for policy\n", " target_policy_noise (GaussianNoise): gaussian noise for target policy\n", " target_policy_noise_clip (float): clip target gaussian noise\n", " device (torch.device): cpu / gpu\n", " transition (list): temporory storage for the recent transition\n", " policy_update_freq (int): update actor every time critic updates this times\n", " total_step (int): total step numbers\n", " is_test (bool): flag to show the current mode (train / test)\n", " seed (int): random seed\n", " \"\"\"\n", "\n", " def __init__(\n", " self,\n", " env: gym.Env,\n", " memory_size: int,\n", " batch_size: int,\n", " gamma: float = 0.99,\n", " tau: float = 5e-3,\n", " exploration_noise: float = 0.1,\n", " target_policy_noise: float = 0.2,\n", " target_policy_noise_clip: float = 0.5,\n", " initial_random_steps: int = int(1e4),\n", " policy_update_freq: int = 2,\n", " seed: int = 777,\n", " ):\n", " \"\"\"Initialize.\"\"\"\n", " obs_dim = env.observation_space.shape[0]\n", " action_dim = env.action_space.shape[0]\n", "\n", " self.env = env\n", " self.memory = ReplayBuffer(obs_dim, action_dim, memory_size, batch_size)\n", " self.batch_size = batch_size\n", " self.gamma = gamma\n", " self.tau = tau\n", " self.initial_random_steps = initial_random_steps\n", " self.policy_update_freq = policy_update_freq\n", " self.seed = seed\n", "\n", " # device: cpu / gpu\n", " self.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", " print(self.device)\n", "\n", " # noise\n", " self.exploration_noise = GaussianNoise(action_dim, exploration_noise, exploration_noise)\n", " self.target_policy_noise = GaussianNoise(\n", " action_dim, target_policy_noise, target_policy_noise\n", " )\n", " self.target_policy_noise_clip = target_policy_noise_clip\n", "\n", " # networks\n", " self.actor = Actor(obs_dim, action_dim).to(self.device)\n", " self.actor_target = Actor(obs_dim, action_dim).to(self.device)\n", " self.actor_target.load_state_dict(self.actor.state_dict())\n", "\n", " self.critic1 = Critic(obs_dim + action_dim).to(self.device)\n", " self.critic_target1 = Critic(obs_dim + action_dim).to(self.device)\n", " self.critic_target1.load_state_dict(self.critic1.state_dict())\n", "\n", " self.critic2 = Critic(obs_dim + action_dim).to(self.device)\n", " self.critic_target2 = Critic(obs_dim + action_dim).to(self.device)\n", " self.critic_target2.load_state_dict(self.critic2.state_dict())\n", "\n", " # concat critic parameters to use one optim\n", " critic_parameters = list(self.critic1.parameters()) + list(self.critic2.parameters())\n", "\n", " # optimizer\n", " self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=3e-4)\n", " self.critic_optimizer = optim.Adam(critic_parameters, lr=1e-3)\n", "\n", " # transition to store in memory\n", " self.transition = list()\n", "\n", " # total steps count\n", " self.total_step = 0\n", "\n", " # update step for actor\n", " self.update_step = 0\n", "\n", " # mode: train / test\n", " self.is_test = False\n", "\n", " def select_action(self, state: np.ndarray) -> np.ndarray:\n", " \"\"\"Select an action from the input state.\"\"\"\n", " # if initial random action should be conducted\n", " if self.total_step < self.initial_random_steps and not self.is_test:\n", " selected_action = self.env.action_space.sample()\n", " else:\n", " selected_action = (\n", " self.actor(torch.FloatTensor(state).to(self.device))[0].detach().cpu().numpy()\n", " )\n", "\n", " # add noise for exploration during training\n", " if not self.is_test:\n", " noise = self.exploration_noise.sample()\n", " selected_action = np.clip(selected_action + noise, -1.0, 1.0)\n", "\n", " self.transition = [state, selected_action]\n", "\n", " return selected_action\n", "\n", " def step(self, action: np.ndarray) -> Tuple[np.ndarray, np.float64, bool]:\n", " \"\"\"Take an action and return the response of the env.\"\"\"\n", " next_state, reward, terminated, truncated, _ = self.env.step(action)\n", " done = terminated or truncated\n", "\n", " if not self.is_test:\n", " self.transition += [reward, next_state, done]\n", " self.memory.store(*self.transition)\n", "\n", " return next_state, reward, done\n", "\n", " def update_model(self) -> torch.Tensor:\n", " \"\"\"Update the model by gradient descent.\"\"\"\n", " device = self.device # for shortening the following lines\n", "\n", " samples = self.memory.sample_batch()\n", " states = torch.FloatTensor(samples[\"obs\"]).to(device)\n", " next_states = torch.FloatTensor(samples[\"next_obs\"]).to(device)\n", " actions = torch.FloatTensor(samples[\"acts\"]).to(device)\n", " rewards = torch.FloatTensor(samples[\"rews\"].reshape(-1, 1)).to(device)\n", " dones = torch.FloatTensor(samples[\"done\"].reshape(-1, 1)).to(device)\n", " masks = 1 - dones\n", "\n", " # get actions with noise\n", " noise = torch.FloatTensor(self.target_policy_noise.sample()).to(device)\n", " clipped_noise = torch.clamp(\n", " noise, -self.target_policy_noise_clip, self.target_policy_noise_clip\n", " )\n", "\n", " next_actions = (self.actor_target(next_states) + clipped_noise).clamp(-1.0, 1.0)\n", "\n", " # min (Q_1', Q_2')\n", " next_values1 = self.critic_target1(next_states, next_actions)\n", " next_values2 = self.critic_target2(next_states, next_actions)\n", " next_values = torch.min(next_values1, next_values2)\n", "\n", " # G_t = r + gamma * v(s_{t+1}) if state != Terminal\n", " # = r otherwise\n", " curr_returns = rewards + self.gamma * next_values * masks\n", " curr_returns = curr_returns.detach()\n", "\n", " # critic loss\n", " values1 = self.critic1(states, actions)\n", " values2 = self.critic2(states, actions)\n", " critic1_loss = F.mse_loss(values1, curr_returns)\n", " critic2_loss = F.mse_loss(values2, curr_returns)\n", "\n", " # train critic\n", " critic_loss = critic1_loss + critic2_loss\n", " self.critic_optimizer.zero_grad()\n", " critic_loss.backward()\n", " self.critic_optimizer.step()\n", "\n", " if self.total_step % self.policy_update_freq == 0:\n", " # train actor\n", " actor_loss = -self.critic1(states, self.actor(states)).mean()\n", "\n", " self.actor_optimizer.zero_grad()\n", " actor_loss.backward()\n", " self.actor_optimizer.step()\n", "\n", " # target update\n", " self._target_soft_update()\n", " else:\n", " actor_loss = torch.zeros(())\n", "\n", " return actor_loss.data, critic_loss.data\n", "\n", " def train(self, num_frames: int, plotting_interval: int = 200):\n", " \"\"\"Train the agent.\"\"\"\n", " self.is_test = False\n", "\n", " state, _ = self.env.reset(seed=self.seed)\n", " actor_losses = []\n", " critic_losses = []\n", " scores = []\n", " score = 0\n", "\n", " for self.total_step in range(1, num_frames + 1):\n", " action = self.select_action(state)\n", " next_state, reward, done = self.step(action)\n", "\n", " state = next_state\n", " score += reward\n", "\n", " # if episode ends\n", " if done:\n", " state, _ = self.env.reset(seed=self.seed)\n", " scores.append(score)\n", " score = 0\n", "\n", " # if training is ready\n", " if len(self.memory) >= self.batch_size and self.total_step > self.initial_random_steps:\n", " actor_loss, critic_loss = self.update_model()\n", " actor_losses.append(actor_loss.cpu().numpy())\n", " critic_losses.append(critic_loss.cpu().numpy())\n", "\n", " # plotting\n", " if self.total_step % plotting_interval == 0:\n", " self._plot(self.total_step, scores, actor_losses, critic_losses)\n", "\n", " self.env.close()\n", "\n", " def test(self, video_folder: str):\n", " \"\"\"Test the agent.\"\"\"\n", " self.is_test = True\n", "\n", " tmp_env = self.env\n", " self.env = gym.wrappers.RecordVideo(self.env, video_folder=video_folder)\n", "\n", " state, _ = self.env.reset(seed=self.seed)\n", " done = False\n", " score = 0\n", "\n", " while not done:\n", " action = self.select_action(state)\n", " next_state, reward, done = self.step(action)\n", "\n", " state = next_state\n", " score += reward\n", "\n", " print(\"score: \", score)\n", " self.env.close()\n", "\n", " self.env = tmp_env\n", "\n", " def _target_soft_update(self):\n", " \"\"\"Soft-update: target = tau*local + (1-tau)*target.\"\"\"\n", " tau = self.tau\n", " for t_param, l_param in zip(self.actor_target.parameters(), self.actor.parameters()):\n", " t_param.data.copy_(tau * l_param.data + (1.0 - tau) * t_param.data)\n", "\n", " for t_param, l_param in zip(self.critic_target1.parameters(), self.critic1.parameters()):\n", " t_param.data.copy_(tau * l_param.data + (1.0 - tau) * t_param.data)\n", "\n", " for t_param, l_param in zip(self.critic_target2.parameters(), self.critic2.parameters()):\n", " t_param.data.copy_(tau * l_param.data + (1.0 - tau) * t_param.data)\n", "\n", " def _plot(\n", " self,\n", " frame_idx: int,\n", " scores: List[float],\n", " actor_losses: List[float],\n", " critic_losses: List[float],\n", " ):\n", " \"\"\"Plot the training progresses.\"\"\"\n", " clear_output(True)\n", " plt.figure(figsize=(30, 5))\n", " plt.subplot(131)\n", " plt.title(\"frame %s. score: %s\" % (frame_idx, np.mean(scores[-10:])))\n", " plt.plot(scores)\n", " plt.subplot(132)\n", " plt.title(\"actor_loss\")\n", " plt.plot(actor_losses)\n", " plt.subplot(133)\n", " plt.title(\"critic_loss\")\n", " plt.plot(critic_losses)\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": { "id": "zSZfdaLLPggn" }, "source": [ "## Environment\n", "*ActionNormalizer* is an action wrapper class to normalize the action values ranged in (-1. 1). Thanks to this class, we can make the agent simply select action values within the zero centered range (-1, 1)." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "id": "pihKfCMnPggn" }, "outputs": [], "source": [ "class ActionNormalizer(gym.ActionWrapper):\n", " \"\"\"Rescale and relocate the actions.\"\"\"\n", "\n", " def action(self, action: np.ndarray) -> np.ndarray:\n", " \"\"\"Change the range (-1, 1) to (low, high).\"\"\"\n", " low = self.action_space.low\n", " high = self.action_space.high\n", "\n", " scale_factor = (high - low) / 2\n", " reloc_factor = high - scale_factor\n", "\n", " action = action * scale_factor + reloc_factor\n", " action = np.clip(action, low, high)\n", "\n", " return action\n", "\n", " def reverse_action(self, action: np.ndarray) -> np.ndarray:\n", " \"\"\"Change the range (low, high) to (-1, 1).\"\"\"\n", " low = self.action_space.low\n", " high = self.action_space.high\n", "\n", " scale_factor = (high - low) / 2\n", " reloc_factor = high - scale_factor\n", "\n", " action = (action - reloc_factor) / scale_factor\n", " action = np.clip(action, -1.0, 1.0)\n", "\n", " return action" ] }, { "cell_type": "markdown", "metadata": { "id": "SVXyz01CPggn" }, "source": [ "You can see [the code](https://github.com/Farama-Foundation/Gymnasium/blob/main/gymnasium/envs/classic_control/pendulum.py) and [configurations](https://github.com/Farama-Foundation/Gymnasium/blob/e73245912087d47b538dcdb45fa9a9d185b805c5/gymnasium/envs/__init__.py#L41) of Pendulum-v1 from Gymnasyim repository." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "id": "8Dgiu4DqPggn" }, "outputs": [], "source": [ "# environment\n", "env = gym.make(\"Pendulum-v1\", render_mode=\"rgb_array\")\n", "env = ActionNormalizer(env)" ] }, { "cell_type": "markdown", "metadata": { "id": "jp8ncVgqPggn" }, "source": [ "## Set random seed" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "id": "_AodxUQEPggn" }, "outputs": [], "source": [ "def seed_torch(seed):\n", " torch.manual_seed(seed)\n", " if torch.backends.cudnn.enabled:\n", " torch.backends.cudnn.benchmark = False\n", " torch.backends.cudnn.deterministic = True\n", "\n", "\n", "seed = 777\n", "random.seed(seed)\n", "np.random.seed(seed)\n", "seed_torch(seed)" ] }, { "cell_type": "markdown", "metadata": { "id": "WUmq-sFDPggo" }, "source": [ "## Initialize" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "6C2phgU0Pggo", "outputId": "b9f1d839-69a2-49e8-b0fb-fa844a6d288b" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "cuda\n" ] } ], "source": [ "# parameters\n", "num_frames = 50000\n", "memory_size = 100000\n", "batch_size = 128\n", "initial_random_steps = 10000\n", "\n", "agent = TD3Agent(env, memory_size, batch_size, initial_random_steps=initial_random_steps, seed=seed)" ] }, { "cell_type": "markdown", "metadata": { "id": "swxwhrCVPggo" }, "source": [ "## Train" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "scrolled": true, "colab": { "base_uri": "https://localhost:8080/", "height": 318 }, "id": "FHLPS9MAPggo", "outputId": "feb214c7-cae6-4b97-d5fb-6f7747caf2d9" }, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "iVBORw0KGgoAAAANSUhEUgAACWEAAAHDCAYAAABP6Ep3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd3hU1dbH8d9k0hMInYC0iAVULCAqqBRFAbHwKiBWVBSvYkG9XsWuqKiIig1sF9ALiqggUg0dpPfeCRBIISG9TTvvH5MZMqTXScL38zzzMLPPPvusSSYhZ2adtUyGYRgCAAAAAAAAAAAAAAAAAJSJj7cDAAAAAAAAAAAAAAAAAICajCQsAAAAAAAAAAAAAAAAACgHkrAAAAAAAAAAAAAAAAAAoBxIwgIAAAAAAAAAAAAAAACAciAJCwAAAAAAAAAAAAAAAADKgSQsAAAAAAAAAAAAAAAAACgHkrAAAAAAAAAAAAAAAAAAoBxIwgIAAAAAAAAAAAAAAACAciAJCwAAAAAAAAAAAAAAAADKgSQsoJpZv369unbtqpCQEJlMJm3ZssXbIQEAAAAAgEIsXbpUJpNJS5cu9XYoAAAAAGqQSZMmyWQyKSoqqti5lXXeERUVJZPJpEmTJlXougBwtiIJC6hGrFarBg4cqFOnTunTTz/VTz/9pNatW3s7rArx0EMPyWQy5bu1a9cu31yHw6GPPvpIERERCgwM1KWXXqqff/65wHV3796tPn36KDQ0VA0aNNADDzygkydPVsmaKNr48eM1cOBAtWrVSiaTSQ899FCB8xYtWqRHHnlEF1xwgYKDg3Xuuefq0UcfVUxMTL65PXr0KPB11KdPn1LHt3LlSvf+CQkJ+bb/8ssv6tixowIDA9W4cWMNHTo03zzXCVJhtylTpuRbd9q0aerSpYtCQkJUr149de3aVYsXL3Zvz8rK0tChQ3XJJZcoLCxMoaGhuuyyyzRu3DhZrdZ86yUnJ2vYsGFq3LixQkJC1LNnT23atKnA5zxr1iz3c2rVqpXefPNN2Wy2fPM2btyoW2+9VeHh4QoNDdWll16qzz//XHa73T0nMTFRY8aMUbdu3dS4cWPVq1dP11xzjaZNm1b4Fz3Xe++9J5PJpEsuuaTA7atWrdJ1112n4OBghYeH65lnnlF6errHnJ07d2rgwIE699xzFRwcrEaNGqlbt27666+/8q23bt06Pfnkk+rUqZP8/PxkMpmKjC8uLk6PP/64zjnnHAUGBqpNmzYaOnRosc8LAAAA3nHixAm99dZbXMQEAAAAoMb7+uuvSYgCgBrM19sBADjt4MGDOnLkiL777js9+uij3g6nwgUEBOj777/3GAsLC8s379VXX9UHH3ygxx57TJ07d9aff/6pe++9VyaTSYMHD3bPi46OVrdu3RQWFqb3339f6enp+vjjj7V9+3atW7dO/v7+lbomivbhhx8qLS1NV111VYEJVS4vvfSSTp06pYEDB+r888/XoUOH9OWXX2r27NnasmWLwsPDPea3aNFCo0eP9hhr3rx5qWJzOBx6+umnFRISooyMjHzbx48fryeffFI33nijPvnkE0VHR2vcuHHasGGD1q5dq8DAQElSt27d9NNPP+Xb/9NPP9XWrVt14403eoy/9dZbeueddzRgwAA99NBDslqt2rFjh44fP+6ek5WVpZ07d+qWW25RmzZt5OPjo1WrVum5557T2rVrNXXqVI/n0a9fP23dulUvvviiGjVqpK+//lo9evTQxo0bdf7557vnzps3T/3791ePHj30xRdfaPv27Xr33XcVHx+v8ePHu+dt3LhRXbt21fnnn6+XXnpJwcHBmjdvnp599lkdPHhQ48aNkyStXr1ar776qm655Ra99tpr8vX11e+//67Bgwdr165devvttwv82kdHR+v9999XSEhIgdu3bNmiG2+8Ue3bt3d/7T/++GPt379f8+bNc887cuSI0tLSNGTIEDVv3lyZmZn6/fffdfvtt+ubb77RsGHD3HPnzp2r77//XpdeeqnOPfdc7du3r8BjS9KxY8d07bXXSpL+9a9/6ZxzztGJEye0bt26QvcBAACAd504cUJvv/222rRpo8svv9zb4QAAAABAiTzwwAMaPHiwAgIC3GNff/21GjVqlO/C9m7duikrK4vPqQCgujMAVBvLli0zJBnTp08vdm56enoVRFRxhgwZYoSEhBQ7Lzo62vDz8zOGDx/uHnM4HMb1119vtGjRwrDZbO7xJ554wggKCjKOHDniHouMjDQkGd98802lrlmTOBwOIzMzs8qPGxUVZTgcDsMwDCMkJMQYMmRIgfOWLVtm2O32fGOSjFdffdVjvHv37sbFF19c7tjGjx9vNGzY0Hj22WcNScbJkyfd23Jycox69eoZ3bp1c8dvGIbx119/GZKMzz//vMi1MzMzjTp16hg33XSTx/jq1asNk8lkfPLJJ2WK+amnnjIkGTExMe6xadOm5fudER8fb9SrV8+45557PPa/6KKLjMsuu8ywWq3usVdffdUwmUzG7t273WOPPfaY4e/vbyQmJnrs361bN6Nu3brux4cOHTKioqI85jgcDuOGG24wAgICCv0ddffddxs33HBDod/Lvn37Gs2aNTNSUlLcY999950hyViwYEGBa7rYbDbjsssuMy688EKP8djYWPfPwPDhw42i/vzp27evERERYSQkJBR5LAAAAFQf69evNyQZEydOrNB1S3revWTJEkOSsWTJkgo9PgAAAIDaqahzjYsvvtjo3r17lcVy+PDhSjmfAoCzFe0IgWrioYceUvfu3SVJAwcOlMlkUo8ePdzbQkNDdfDgQd1yyy2qU6eO7rvvPknSihUr3C3fAgIC1LJlSz333HPKysrKt35oaKiOHj2qW2+9VaGhoTrnnHP01VdfSZK2b9+uG264QSEhIWrdurVHtR2X5ORkjRgxQi1btlRAQIDOO+88ffjhh3I4HCV+nna7XampqYVu//PPP2W1WvXkk0+6x0wmk5544glFR0dr9erV7vHff/9dt956q1q1auUe69Wrly644AL9+uuvlbpmaWzYsEG9e/dWo0aNFBQUpIiICD3yyCMecxwOh8aNG6cOHTq429/16dNHGzZscM+x2WwaNWqU2rZtq4CAALVp00avvPKKcnJyPNZq06aNbr31Vi1YsEBXXnmlgoKC9M0330gq+fcwJiZGe/bsKbD9XUm1bt262LZvkvPqDR8fn3xjDRo00O7duwvcx2az5WtPV1KnTp3Sa6+9pnfeeUf16tXLt33Hjh1KTk7W3Xff7RG/6+fml19+KXL9v/76S2lpae6fUZfPPvtM4eHhevbZZ2UYRqnjb9OmjSTn99Dlt99+U9OmTXXnnXe6xxo3bqxBgwbpzz//dL82du3apV27dmnYsGHy9T1dBPPJJ5+UYRj67bff3GOpqakKDAzM97Vp1qyZgoKC3I8jIiLytUs1mUzq37+/cnJydOjQoXzPYfny5frtt9/02WefFfgcU1NTFRkZqfvvv19169Z1jz/44IMKDQ0t9mfQbDarZcuWHl8jSWratKlH7IXZs2eP5s2bpxdffFENGzZUdnZ2uX4GAAAAULgjR47oySef1IUXXqigoCA1bNhQAwcOVFRUVL65ycnJeu6559SmTRsFBASoRYsWevDBB5WQkKClS5eqc+fOkqSHH37Y3Ro8b/uO6dOnq1OnTgoKClKjRo10//33e1SjlYo+7y6rkhw3NjZWDz/8sFq0aKGAgAA1a9ZMd9xxh8fXoSTnlAAAAAC85/jx4xo6dKiaN2+ugIAARURE6IknnpDFYtGkSZNkMpm0bNkyPfnkk2rSpIlatGghSe5trr//27Rpo507d2rZsmXucxvXZ4VLly6VyWTS0qVLPY69du1a3XLLLapfv75CQkJ06aWXujtalMfixYt1/fXXKyQkRPXq1dMdd9yR7zObtLQ0jRgxwn2u1qRJE910003atGmTe87+/ft11113KTw8XIGBgWrRooUGDx6slJSUcscIANUR7QiBauLxxx/XOeeco/fff1/PPPOMOnfurKZNm7q322w29e7dW9ddd50+/vhjBQcHS3K+qZuZmaknnnhCDRs21Lp16/TFF18oOjpa06dP9ziG3W5X37591a1bN3300UeaMmWKnnrqKYWEhOjVV1/VfffdpzvvvFMTJkzQgw8+qC5duigiIkKSlJmZqe7du+v48eN6/PHH1apVK61atUojR45UTExMoUkVeWVmZqpu3brKzMxU/fr1dc899+jDDz9UaGioe87mzZsVEhKi9u3be+x71VVXubdfd911On78uOLj43XllVfmO85VV12luXPnVuqaJRUfH6+bb75ZjRs31ssvv6x69eopKipKf/zxh8e8oUOHatKkSerbt68effRR2Ww2rVixQmvWrHHH8+ijj2ry5MkaMGCAXnjhBa1du1ajR4/W7t27NWPGDI/19u7dq3vuuUePP/64HnvsMV144YWl+h6OHDlSkydP1uHDh93JP1UpPT1d6enpatSoUb5t+/btU0hIiCwWi5o2barHHntMb7zxhvz8/Eq09uuvv67w8HA9/vjjGjVqVL7trsSlgpJ2goKCtHnzZjkcjnyJYy5TpkxRUFCQR2KUJC1atEhdu3bV559/rnfffVeJiYkKDw/Xq6++qqeeeirfOhaLRampqcrKytKGDRv08ccfq3Xr1jrvvPPcczZv3qyOHTvmi+Wqq67St99+q3379qlDhw7avHmzJOV7bTdv3lwtWrRwb5ekHj16aNq0aXr88cf1/PPPu9sR/vHHHxozZkyBzzmv2NhYScr3vbPb7Xr66af16KOPqkOHDgXuu337dtlstnxx+vv76/LLL/eI0yUjI0NZWVlKSUnRrFmzNG/ePN19993FxlmQhQsXSnImbd14441avHixzGazbrrpJo0fP94rPwsAAAC11fr167Vq1SoNHjxYLVq0UFRUlMaPH68ePXpo165d7nPe9PR0XX/99dq9e7ceeeQRdezYUQkJCZo1a5aio6PVvn17vfPOO3rjjTc0bNgwXX/99ZKkrl27SnJ+qPHwww+rc+fOGj16tOLi4jRu3Dj9888/2rx5s8fFB4Wdd5dFSY971113aefOnXr66afVpk0bxcfHKzIyUkePHnU/Lsk5JQAAAADvOHHihK666iolJydr2LBhateunY4fP67ffvtNmZmZ7nlPPvmkGjdurDfeeEMZGRkFrvXZZ5/p6aefVmhoqF599VVJ8vis8EyRkZG69dZb1axZMz377LMKDw/X7t27NXv2bD377LNlfk4LFy5U3759de655+qtt95SVlaWvvjiC1177bXatGmT+73yf/3rX/rtt9/01FNP6aKLLlJiYqJWrlyp3bt3q2PHjrJYLOrdu7dycnL09NNPKzw8XMePH9fs2bOVnJyssLCwMscIANWWt0txATjN1cLgzHaEQ4YMMSQZL7/8cr59CmozN3r0aMNkMnm01HOt8f7777vHkpKSjKCgIMNkMhm//PKLe3zPnj2GJOPNN990j40aNcoICQkx9u3b53Gsl19+2TCbzcbRo0eLfG4vv/yy8dJLLxnTpk0zfv75Z3c81157rUd7tH79+hnnnntuvv0zMjI8vgaudhM//vhjvrkvvviiIcnIzs6utDVLasaMGYYkY/369YXOWbx4sSHJeOaZZ/Jtc7XD27JliyHJePTRRz22//vf/zYkGYsXL3aPtW7d2pBkzJ8/32Nuab6Hru/P4cOHS/xci1JUO8KCjBo1ypBkLFq0yGP8kUceMd566y3j999/N3788Ufj9ttvNyQZgwYNKtG6W7duNcxms7ut3ZtvvpmvHeHJkycNk8lkDB061GNf18+FpEJb1SUmJhr+/v754jl16pQhyWjYsKERGhpqjBkzxpg2bZrRp08fQ5IxYcKEfGv9/PPP7uNJMq688kpj27ZtHnNCQkKMRx55JN++c+bM8XgNjBkzxpBU4M9p586djWuuucb92GazGU899ZTh5+fnPrbZbDbGjx9f4HM+8/k3adLEuP766/Nt+/LLL42wsDAjPj7eMIyCW0tOnz7dkGQsX7483/4DBw40wsPD840//vjj7jh9fHyMAQMGGKdOnSo0xqLaET7zzDPu71OfPn2MadOmGWPGjDFCQ0ONtm3bGhkZGUU+fwAAAJRcQeeyq1evzndO9sYbbxiSjD/++CPffNf5UmHtCC0Wi9GkSRPjkksuMbKystzjs2fPNiQZb7zxhnusqPPu4pzZjrCkx01KSjIkGWPGjCl07ZKcUwIAAADwngcffNDw8fEp8G92h8NhTJw40ZBkXHfddYbNZvPY7tqW97OYwtoRnnneYbPZjIiICKN169ZGUlJSvuOWVEHtCC+//HKjSZMmRmJionts69atho+Pj/Hggw+6x8LCwozhw4cXuvbmzZsL/NwTAGoz2hECNcgTTzyRbyxvtZ6MjAwlJCSoa9euMgyjwKoxjz76qPt+vXr1dOGFFyokJESDBg1yj1944YWqV6+eRzux6dOn6/rrr1f9+vWVkJDgvvXq1Ut2u13Lly8vMvbRo0frgw8+0KBBgzR48GBNmjRJ7733nv755x+PVmhZWVkKCAjIt39gYKB7e95/Szq3otcsKdfVzbNnzy60rdnvv/8uk8mkN998M982Vzs8VxWu559/3mP7Cy+8IEmaM2eOx3hERIR69+7tMVaa7+GkSZNkGIZXKv8sX75cb7/9tgYNGqQbbrjBY9sPP/ygN998U3feeaceeOAB/fnnn3rsscf066+/as2aNcWu/cwzz6hv3766+eabC53TqFEjDRo0SJMnT9bYsWN16NAhrVixQnfffbe72lZhr4PffvtNFoslX9sSV+vBxMREff/99/r3v/+tQYMGac6cObrooov07rvv5lurZ8+eioyM1PTp0/Wvf/1Lfn5++a6OqajXdt7nYzab1bZtW/Xu3VuTJ0/WtGnTdNttt+npp5/WzJkzC3zekrOl5n333afk5GR98cUXHtsSExP1xhtv6PXXX1fjxo0LXaM0cbqMGDFCkZGRmjx5svr27Su73S6LxVLoMYri+j6Fh4drzpw5GjRokP7973/ru+++08GDBwts0woAAICyyXsua7ValZiYqPPOO0/16tXzaF3x+++/67LLLtP//d//5VujuPbnGzZsUHx8vJ588kn338iS1K9fP7Vr1y7feZRU8Hl3aZX0uEFBQfL399fSpUuVlJRU4FolOacEAAAA4B0Oh0MzZ87UbbfdVmCXlbznLI899pjMZnOFHXvz5s06fPiwRowY4VHh98zjllZMTIy2bNmihx56SA0aNHCPX3rppbrppps8usbUq1dPa9eu1YkTJwpcy1XpasGCBR5VwQCgNiMJC6ghfH193T2i8zp69Kj7D6HQ0FA1btxY3bt3l6R8/ZQDAwPzJUCEhYWpRYsW+f4gCwsL83gTeP/+/Zo/f74aN27scevVq5ckZ9u90nruuefk4+PjbgEmOd+EdrWDyys7O9u9Pe+/JZ1b0WuWVPfu3XXXXXfp7bffVqNGjXTHHXdo4sSJHsc4ePCgmjdv7vHH7JmOHDkiHx8fj1Z0kjNZpF69ejpy5IjHuKuNZF6V8T08efKkYmNj3TdXEktZ7dmzR//3f/+nSy65RN9//32J9nElouV9HRVk2rRpWrVqlcaOHVvsmt98841uueUW/fvf/1bbtm3VrVs3dejQQbfddpskebTQzGvKlClq0KCB+vbt6zHuet34+flpwIAB7nEfHx/dfffdio6O1tGjRz32adq0qXr16qUBAwZo/PjxuvXWW3XTTTe52/251q2I13be1/UHH3ygDz/8UD///LMefPBBDRo0SDNmzNB1112n4cOHy2azFfjcn376ac2fP1/ff/+9LrvsMo9tr732mho0aKCnn366wH3zPp+SxunSrl079erVSw8++KBmz56t9PR03XbbbTIMo8hjFXX8QYMGebR4HDhwoHx9fbVq1apSrwkAAICCZWVl6Y033lDLli0VEBCgRo0aqXHjxkpOTvY4lz148KAuueSSMh3DdZ504YUX5tvWrl27fOdRhZ13V9ZxAwIC9OGHH2revHlq2rSpunXrpo8++sjjb/6SnFMCAAAA8I6TJ08qNTW1ROcsBX1uUx4HDx6UpDKfLxWmqPOZ9u3bKyEhwX3B+EcffaQdO3aoZcuWuuqqq/TWW295FHiIiIjQ888/r++//16NGjVS79699dVXX+X7/BIAahOSsIAaIiAgwCMpQJLsdrtuuukmzZkzRy+99JJmzpypyMhITZo0SZIzAz+vwjLsCxvPm8TgcDh00003KTIyssDbXXfdVernFBQUpIYNG+rUqVPusWbNmik2NjZfAkVMTIwkqXnz5u55ecfPnNugQQN3NZ3KWLOkTCaTfvvtN61evVpPPfWUjh8/rkceeUSdOnUqU8JSSa9eKChZpTK+h507d1azZs3ct48//rjUa7gcO3ZMN998s8LCwjR37lzVqVOnRPu1bNlSkjxeRwV58cUXNXDgQPn7+ysqKkpRUVFKTk52HzvvlRphYWH6888/deTIES1btkxRUVH66aefFBMTo8aNG+e7qkRyJkSuWLFCAwcOdFfMcmnQoIECAwPVsGHDfD9vTZo0kaRCr3x3GTBggNLT0/Xnn3+6x5o1a1bo61Uq+WvbNU+Svv76a91www35Es1uv/12nThxQlFRUfnWePvtt/X111/rgw8+0AMPPOCxbf/+/fr222/1zDPPuPePiopSdna2rFaroqKi3N+70sRZmAEDBmj9+vXat29fsXPP5Fq/adOmHuNms1kNGzYs9nsEAACAknv66af13nvvadCgQfr111/1999/KzIyUg0bNsx3LltVCjrvrmwjRozQvn37NHr0aAUGBur1119X+/bt3ZWtK/qcEgAAAIB3lPYi/5pg0KBBOnTokL744gs1b95cY8aM0cUXX6x58+a554wdO1bbtm3TK6+8oqysLD3zzDO6+OKLFR0d7cXIAaDykIQF1GDbt2/Xvn37NHbsWL300ku644471KtXrxIlKpRW27ZtlZ6erl69ehV4a9WqVanXTEtLU0JCgkd1rssvv1yZmZnavXu3x9y1a9e6t0vSOeeco8aNG2vDhg351l23bp17XmWtWVrXXHON3nvvPW3YsEFTpkzRzp079csvv0hyfm1PnDhRZBJR69at5XA4tH//fo/xuLg4JScnq3Xr1sXGUBnfwylTpngkcj344IOlXkNytqu7+eablZOTowULFriTcUrCdVVFUW3uJGei1dSpUxUREeG+jRs3TpLUsWNH3XLLLfn2adWqlbp166bWrVsrOTlZGzdudFcOO9PPP/8swzDytSKUnBWvLr/8cp08eTJfqzxX8ldx8bta8eW9QuTyyy/Xpk2b8n1ItXbtWgUHB+uCCy5wz5OU77V94sQJRUdHe7y24+LiZLfb8x3f1frkzEpYX331ld566y2NGDFCL730Ur79jh8/LofDoWeeecbja7927Vrt27dPEREReueddyQ5r9jx9fXNF6fFYtGWLVtK9DNY0NeppDp16uSO+czjn/m7CgAAAOXz22+/aciQIRo7dqwGDBigm266Sdddd537QgmXtm3baseOHUWuVdjFKq7zpL179+bbtnfv3hKdR5VFaY/btm1bvfDCC/r777+1Y8cOWSyWfBV8izqnBAAAAOAdjRs3Vt26dYs9ZymNkl6M37ZtW0mq0GNLRZ/P7NmzR40aNVJISIh7rFmzZnryySc1c+ZMHT58WA0bNtR7773nsV+HDh302muvafny5VqxYoWOHz+uCRMmVGjcAFBdkIQF1GCuijp5KzwZhuFOLKlIgwYN0urVq7VgwYJ825KTkwttUSY524ilpaXlGx81apQMw1CfPn3cY3fccYf8/Pz09ddfu8cMw9CECRN0zjnnqGvXru7xu+66S7Nnz9axY8fcY4sWLdK+ffs0cODASl3TarVqz549BVbsySspKSlfBS5XIomrfcRdd90lwzD09ttv59vfta8rQeizzz7z2P7JJ59Ikvr161dkHFLpvocxMTHas2ePO/GmMNdee61HIte5555bbBxnysjI0C233KLjx49r7ty5Ov/88wucl5qamq/lhmEYevfddyVJvXv3do9nZmZqz549SkhIcI/NmDEj3+3uu++WJP3444/69NNPi4xz5MiRstlseu655wrcPnXqVLVq1UrXXXddgdvvvvtu2e12TZ482T2WnZ2tKVOm6KKLLnInTyYkJBTYSs/VnjFvX/kBAwYoLi5Of/zxh3ssISFB06dP12233eau3HbxxRerXbt2+vbbbz0SrMaPHy+TyeTRIvGCCy5QZGSkEhMT3WN2u12//vqr6tSp4z6xk5wtHp955hndd9997tfimS655JICv/YXX3yxWrVqpRkzZmjo0KGSnBXIevXqpf/9738evzN++uknpaene/wMFtQ+02q16scff1RQUJAuuuiiAuMpSo8ePdSkSRNNmTLF3dJRkiZNmuSuPAgAAICKYTab8/3d+8UXX+S7IOCuu+7S1q1bNWPGjHxruPZ3fQBwZgLXlVdeqSZNmmjChAke5xLz5s3T7t27S3QeVRYlPW5mZqbH352S84OUOnXquPcryTklAAAAAO/w8fFR//799ddffxV4gX9B7/UXJyQkJN+5TUE6duyoiIgIffbZZ/nml+W4Ls2aNdPll1+uyZMne6y7Y8cO/f333+7Pq+x2e76LoZs0aaLmzZu7z1VSU1PzfX7YoUMH+fj4cD4DoNby9XYAAMquXbt2atu2rf7973/r+PHjqlu3rn7//fdKaZn14osvatasWbr11lv10EMPqVOnTsrIyND27dv122+/KSoqSo0aNSpw39jYWF1xxRW655571K5dO0nSggULNHfuXPXp00d33HGHe26LFi00YsQIjRkzRlarVZ07d9bMmTO1YsUKTZkyxaOV2yuvvKLp06erZ8+eevbZZ5Wenq4xY8aoQ4cOevjhhyt1zePHj6t9+/YaMmSIu/1jQSZPnqyvv/5a//d//6e2bdsqLS1N3333nerWrev+Q7Vnz5564IEH9Pnnn2v//v3q06ePHA6HVqxYoZ49e+qpp57SZZddpiFDhujbb79VcnKyunfvrnXr1mny5Mnq37+/evbsWaHfw5EjR2ry5Mk6fPiw2rRpU+zaBfnrr7+0detWSc7kmG3btrkTpm6//XZdeumlkqT77rtP69at0yOPPKLdu3d7VCwLDQ1V//79JUmbNm3SPffco3vuuUfnnXeesrKyNGPGDP3zzz8aNmyYOnbs6N5v3bp16tmzp95880299dZbkuReJ68tW7ZIkvr27evx+v3ggw+0Y8cOXX311fL19dXMmTP1999/691331Xnzp3zrbNjxw5t27ZNL7/8cqFXqTz++OP6/vvvNXz4cO3bt0+tWrXSTz/9pCNHjuivv/5yz/vf//6nCRMmqH///jr33HOVlpamBQsWKDIyUrfddptuuOEG99wBAwbommuu0cMPP6xdu3apUaNG+vrrr2W32/Ml9Y0ZM0a33367br75Zg0ePFg7duzQl19+qUcffVTt27d3z3v55Zd1//336+qrr9awYcMUFBSkn3/+WRs3btS7777rbrW4bt06Pfjgg2rYsKFuvPFGTZkyxeN4Xbt21bnnnqtGjRoV+LV3JRSeue29995T165d1b17dw0bNkzR0dEaO3asbr75Zo+Ezccff1ypqanq1q2bzjnnHMXGxmrKlCnas2ePxo4d69FO8ciRI/rpp58kna4G5nottm7d2t1CMSAgQGPGjNGQIUPUrVs3PfDAAzp69KjGjRun66+/XnfeeWeB31sAAACU3q233qqffvpJYWFhuuiii7R69WotXLhQDRs29Jj34osv6rffftPAgQPdbfhOnTqlWbNmacKECbrsssvUtm1b1atXTxMmTFCdOnUUEhKiq6++WhEREfrwww/18MMPq3v37rrnnnsUFxencePGqU2bNoVeYFFefn5+JTruvn37dOONN2rQoEG66KKL5OvrqxkzZiguLk6DBw+WVLJzSgAAAADe8/777+vvv/92v6fdvn17xcTEaPr06Vq5cmWp1+vUqZPGjx+vd999V+edd56aNGni8bmAi4+Pj8aPH6/bbrtNl19+uR5++GE1a9ZMe/bs0c6dOwu8IL+kxowZo759+6pLly4aOnSosrKy9MUXXygsLMz9mUtaWppatGihAQMG6LLLLlNoaKgWLlyo9evXuyv7Ll68WE899ZQGDhyoCy64QDabTT/99JPMZrPuuuuuMscHANWaAaDaWLJkiSHJmD59usf4kCFDjJCQkAL32bVrl9GrVy8jNDTUaNSokfHYY48ZW7duNSQZEydOLHaN7t27GxdffHG+8datWxv9+vXzGEtLSzNGjhxpnHfeeYa/v7/RqFEjo2vXrsbHH39sWCyWQp9XUlKScf/99xvnnXeeERwcbAQEBBgXX3yx8f777xe4n91uN95//32jdevWhr+/v3HxxRcb//vf/wpce8eOHcbNN99sBAcHG/Xq1TPuu+8+IzY2ttLXPHz4sCHJGDJkSKHP2zAMY9OmTcY999xjtGrVyggICDCaNGli3HrrrcaGDRs85tlsNmPMmDFGu3btDH9/f6Nx48ZG3759jY0bN7rnWK1W4+233zYiIiIMPz8/o2XLlsbIkSON7Oxsj7UK+t65lPR7OGTIEEOScfjw4SKfX1FcaxR0y/vabN26daHzWrdu7Z536NAhY+DAgUabNm2MwMBAIzg42OjUqZMxYcIEw+FweBzb9bP05ptvFhnjm2++aUgyTp486TE+e/Zs46qrrjLq1KljBAcHG9dcc43x66+/FrrOyy+/bEgytm3bVuTx4uLijCFDhhgNGjQwAgICjKuvvtqYP3++x5z169cbAwcOdL9mQkJCjI4dOxqffPKJYbVa86156tQpY+jQoUbDhg2N4OBgo3v37sb69esLPP6MGTOMyy+/3AgICDBatGhhvPbaawX+DM6fP9/o3r270ahRI8Pf39/o0KGDMWHCBI85EydOLPT7dub3uCCF/e4xDMNYsWKF0bVrVyMwMNBo3LixMXz4cCM1NdVjzs8//2z06tXLaNq0qeHr62vUr1/f6NWrl/Hnn3/m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476fmpqqm2++Wb169dKECRO0fft2PfLII6pXr56GDRsmSVq1apXuuecejR49WrfeequmTp2q/v37a9OmTbrkkkuq/PkAZxOr3fmma95KWJKUY3W42xJSCQsAAACoPCZx5SRQ2z06eUOB4+VNgzIKWOHRH53HurRFmG5s31SS9P7cPZKkF6dv0+pDiZKcFcHqh/iXMwIAQGWbP3++x+NJkyapSZMm2rhxo7p166aUlBT98MMPmjp1qm644QZJ0sSJE9W+fXutWbNG11xzjf7++2/t2rVLCxcuVNOmTXX55Zdr1KhReumll/TWW2/J399fEyZMUEREhMaOHStJat++vVauXKlPP/1UvXv3rvLnDQAAAHiL17Mj6tSpo/DwcPctJCTEvW3KlCmyWCz673//q4svvliDBw/WM888o08++cQ9Z9y4cerTp49efPFFtW/fXqNGjVLHjh315ZdfeuPpAGcVu8OZaOXnY5Kv2UdmH+cHQDm20+0IqYQFAAAAAEDZ7YlNK3B8X1y6+35pEzKLm794T7y2Hkv2GCuqDVxxhbHotAEA1UNKSookqUGDBpKkjRs3ymq1qlevXu457dq1U6tWrbR69WpJ0urVq9WhQwc1bdrUPad3795KTU3Vzp073XPyruGa41oDAAAAOFt4PTvigw8+UMOGDXXFFVdozJgxHn3EV69erW7dusnf//SVdb1799bevXuVlJTknlPaP+5zcnKUmprqcQNQelaHqxKW81eJK+EqPed0CxQqYQEAAACVh8QG4Oy1O+b0+1lF/S5IPqNtaUlMWXtUd3z1j1KzT5/fF1Q5y2XZvpN5YvFM8Vq0O06/bYwu8nif/L1Xw6dukqOIRC8AQPk4HA6NGDFC1157rbuLSGxsrPz9/VWvXj2PuU2bNlVsbKx7Tt4ELNd217ai5qSmpiorK6vAePicBgAAALWRV7MjnnnmGf3yyy9asmSJHn/8cb3//vv6z3/+495enj/uXdsLMnr0aIWFhblvLVu2rKinBJxV7LntCH3NzrdXXQlXqdmnkykDfM1VHxgAAAAAAJAkPTllU4HjeatXLdkTX+CcpIySJXAVdgxJGlpIO8W8Pl98QHO2xWh91KkSHa8wyZkWxaVml2sNAKithg8frh07duiXX37xdiiS+JwGAAAAtVOFJ2G9/PLLziveirjt2bNHkvT888+rR48e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\n" }, "metadata": {} } ], "source": [ "agent.train(num_frames)" ] }, { "cell_type": "markdown", "metadata": { "id": "U6bFhE6VPggo" }, "source": [ "## Test\n", "Run the trained agent (1 episode)." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "8WO81xN6Pggo", "outputId": "13807e2a-ea5a-43da-dfbb-ebbd85f99f7f" }, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "/usr/local/lib/python3.10/dist-packages/gymnasium/wrappers/rendering.py:283: UserWarning: \u001b[33mWARN: Overwriting existing videos at /content/videos/td3 folder (try specifying a different `video_folder` for the `RecordVideo` wrapper if this is not desired)\u001b[0m\n", " logger.warn(\n" ] }, { "output_type": "stream", "name": "stdout", "text": [ "score: -125.55866347145377\n" ] } ], "source": [ "# test\n", "video_folder = \"videos/td3\"\n", "agent.test(video_folder=video_folder)" ] }, { "cell_type": "markdown", "metadata": { "id": "ViEG3OoAPggo" }, "source": [ "## Render" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 279 }, "id": "FnPuWnuqPggo", "outputId": "68dac121-d28c-4b92-9413-7a0e7f5126b8" }, "outputs": [ { "output_type": "display_data", "data": { "text/plain": [ "" ], "text/html": [ "\n", " \n", " " ] }, "metadata": {} }, { "output_type": "stream", "name": "stdout", "text": [ "Played: videos/td3/rl-video-episode-0.mp4\n" ] } ], "source": [ "import base64\n", "import glob\n", "import io\n", "import os\n", "\n", "from IPython.display import HTML, display\n", "\n", "\n", "def ipython_show_video(path: str) -> None:\n", " \"\"\"Show a video at `path` within IPython Notebook.\"\"\"\n", " if not os.path.isfile(path):\n", " raise NameError(\"Cannot access: {}\".format(path))\n", "\n", " video = io.open(path, \"r+b\").read()\n", " encoded = base64.b64encode(video)\n", "\n", " display(\n", " HTML(\n", " data=\"\"\"\n", " \n", " \"\"\".format(\n", " encoded.decode(\"ascii\")\n", " )\n", " )\n", " )\n", "\n", "\n", "def show_latest_video(video_folder: str) -> str:\n", " \"\"\"Show the most recently recorded video from video folder.\"\"\"\n", " list_of_files = glob.glob(os.path.join(video_folder, \"*.mp4\"))\n", " latest_file = max(list_of_files, key=os.path.getctime)\n", " ipython_show_video(latest_file)\n", " return latest_file\n", "\n", "\n", "latest_file = show_latest_video(video_folder=video_folder)\n", "print(\"Played:\", latest_file)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "9CPeCapxPggo" }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.13" }, "colab": { "provenance": [], "gpuType": "T4" }, "accelerator": "GPU" }, "nbformat": 4, "nbformat_minor": 0 }