{"cells": [{"cell_type": "markdown", "id": "636e51e3", "metadata": {"papermill": {"duration": 0.003219, "end_time": "2025-04-03T20:56:52.409834", "exception": false, "start_time": "2025-04-03T20:56:52.406615", "status": "completed"}, "tags": []}, "source": ["\n", "# How to train a Deep Q Network\n", "\n", "* **Author:** Lightning.ai\n", "* **License:** CC BY-SA\n", "* **Generated:** 2025-04-03T20:56:45.942071\n", "\n", "Main takeaways:\n", "\n", "1. RL has the same flow as previous models we have seen, with a few additions\n", "2. Handle unsupervised learning by using an IterableDataset where the dataset itself is constantly updated during training\n", "3. Each training step carries has the agent taking an action in the environment and storing the experience in the IterableDataset\n", "\n", "\n", "---\n", "Open in [![Open In Colab](data:image/png;base64,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){height=\"20px\" width=\"117px\"}](https://colab.research.google.com/github/PytorchLightning/lightning-tutorials/blob/publication/.notebooks/lightning_examples/reinforce-learning-DQN.ipynb)\n", "\n", "Give us a \u2b50 [on Github](https://www.github.com/Lightning-AI/lightning/)\n", "| Check out [the documentation](https://lightning.ai/docs/)\n", "| Join us [on Discord](https://discord.com/invite/tfXFetEZxv)"]}, {"cell_type": "markdown", "id": "dbd8f0c4", "metadata": {"papermill": {"duration": 0.002193, "end_time": "2025-04-03T20:56:52.414457", "exception": false, "start_time": "2025-04-03T20:56:52.412264", "status": "completed"}, "tags": []}, "source": ["## Setup\n", "This notebook requires some packages besides pytorch-lightning."]}, {"cell_type": "code", "execution_count": 1, "id": "524907c8", "metadata": {"colab": {}, "colab_type": "code", "execution": {"iopub.execute_input": "2025-04-03T20:56:52.421115Z", "iopub.status.busy": "2025-04-03T20:56:52.420090Z", "iopub.status.idle": "2025-04-03T20:56:53.613832Z", "shell.execute_reply": "2025-04-03T20:56:53.612362Z"}, "id": "LfrJLKPFyhsK", "lines_to_next_cell": 0, "papermill": {"duration": 1.199272, "end_time": "2025-04-03T20:56:53.616049", "exception": false, "start_time": "2025-04-03T20:56:52.416777", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable.It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.\u001b[0m\u001b[33m\r\n", "\u001b[0m"]}, {"name": "stdout", "output_type": "stream", "text": ["\r\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m25.0.1\u001b[0m\r\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython -m pip install --upgrade pip\u001b[0m\r\n"]}], "source": ["! pip install --quiet \"matplotlib\" \"numpy <2.0\" \"numpy <3.0\" \"pandas\" \"gym <0.24\" \"pygame\" \"torch>=1.8.1, <2.7\" \"torch ==2.1.*\" \"pytorch-lightning >=2.0,<2.6\" \"torchvision ==0.16.*\" \"seaborn\" \"torchmetrics>=1.0, <1.8\""]}, {"cell_type": "code", "execution_count": 2, "id": "5cb2e377", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:53.623508Z", "iopub.status.busy": "2025-04-03T20:56:53.622995Z", "iopub.status.idle": "2025-04-03T20:56:56.688851Z", "shell.execute_reply": "2025-04-03T20:56:56.687594Z"}, "papermill": {"duration": 3.072217, "end_time": "2025-04-03T20:56:56.691347", "exception": false, "start_time": "2025-04-03T20:56:53.619130", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["/tmp/ipykernel_691/94481177.py:10: DeprecationWarning: Importing display from IPython.core.display is deprecated since IPython 7.14, please import from IPython display\n", " from IPython.core.display import display\n"]}], "source": ["import os\n", "from collections import OrderedDict, deque, namedtuple\n", "from typing import Iterator, List, Tuple\n", "\n", "import gym\n", "import numpy as np\n", "import pandas as pd\n", "import seaborn as sn\n", "import torch\n", "from IPython.core.display import display\n", "from pytorch_lightning import LightningModule, Trainer\n", "from pytorch_lightning.loggers import CSVLogger\n", "from torch import Tensor, nn\n", "from torch.optim import Adam, Optimizer\n", "from torch.utils.data import DataLoader\n", "from torch.utils.data.dataset import IterableDataset\n", "\n", "PATH_DATASETS = os.environ.get(\"PATH_DATASETS\", \".\")"]}, {"cell_type": "code", "execution_count": 3, "id": "cfca6d08", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:56.703664Z", "iopub.status.busy": "2025-04-03T20:56:56.703320Z", "iopub.status.idle": "2025-04-03T20:56:56.708746Z", "shell.execute_reply": "2025-04-03T20:56:56.707918Z"}, "papermill": {"duration": 0.013678, "end_time": "2025-04-03T20:56:56.710685", "exception": false, "start_time": "2025-04-03T20:56:56.697007", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class DQN(nn.Module):\n", " def __init__(self, obs_size: int, n_actions: int, hidden_size: int = 128):\n", " \"\"\"Simple MLP network.\n", "\n", " Args:\n", " obs_size: observation/state size of the environment\n", " n_actions: number of discrete actions available in the environment\n", " hidden_size: size of hidden layers\n", "\n", " \"\"\"\n", " super().__init__()\n", " self.net = nn.Sequential(\n", " nn.Linear(obs_size, hidden_size),\n", " nn.ReLU(),\n", " nn.Linear(hidden_size, n_actions),\n", " )\n", "\n", " def forward(self, x):\n", " return self.net(x.float())"]}, {"cell_type": "markdown", "id": "f090e220", "metadata": {"papermill": {"duration": 0.005196, "end_time": "2025-04-03T20:56:56.721152", "exception": false, "start_time": "2025-04-03T20:56:56.715956", "status": "completed"}, "tags": []}, "source": ["### Memory"]}, {"cell_type": "code", "execution_count": 4, "id": "be2418d3", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:56.732885Z", "iopub.status.busy": "2025-04-03T20:56:56.732707Z", "iopub.status.idle": "2025-04-03T20:56:56.736672Z", "shell.execute_reply": "2025-04-03T20:56:56.735812Z"}, "papermill": {"duration": 0.012112, "end_time": "2025-04-03T20:56:56.738605", "exception": false, "start_time": "2025-04-03T20:56:56.726493", "status": "completed"}, "tags": []}, "outputs": [], "source": ["\n", "# Named tuple for storing experience steps gathered in training\n", "Experience = namedtuple(\n", " \"Experience\",\n", " field_names=[\"state\", \"action\", \"reward\", \"done\", \"new_state\"],\n", ")"]}, {"cell_type": "code", "execution_count": 5, "id": "3014214f", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:56.750285Z", "iopub.status.busy": "2025-04-03T20:56:56.750100Z", "iopub.status.idle": "2025-04-03T20:56:56.755893Z", "shell.execute_reply": "2025-04-03T20:56:56.755080Z"}, "papermill": {"duration": 0.013985, "end_time": "2025-04-03T20:56:56.757962", "exception": false, "start_time": "2025-04-03T20:56:56.743977", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class ReplayBuffer:\n", " \"\"\"Replay Buffer for storing past experiences allowing the agent to learn from them.\n", "\n", " Args:\n", " capacity: size of the buffer\n", "\n", " \"\"\"\n", "\n", " def __init__(self, capacity: int) -> None:\n", " self.buffer = deque(maxlen=capacity)\n", "\n", " def __len__(self) -> None:\n", " return len(self.buffer)\n", "\n", " def append(self, experience: Experience) -> None:\n", " \"\"\"Add experience to the buffer.\n", "\n", " Args:\n", " experience: tuple (state, action, reward, done, new_state)\n", "\n", " \"\"\"\n", " self.buffer.append(experience)\n", "\n", " def sample(self, batch_size: int) -> Tuple:\n", " indices = np.random.choice(len(self.buffer), batch_size, replace=False)\n", " states, actions, rewards, dones, next_states = zip(*(self.buffer[idx] for idx in indices))\n", "\n", " return (\n", " np.array(states),\n", " np.array(actions),\n", " np.array(rewards, dtype=np.float32),\n", " np.array(dones, dtype=bool),\n", " np.array(next_states),\n", " )"]}, {"cell_type": "code", "execution_count": 6, "id": "ede3d32f", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:56.769741Z", "iopub.status.busy": "2025-04-03T20:56:56.769570Z", "iopub.status.idle": "2025-04-03T20:56:56.774513Z", "shell.execute_reply": "2025-04-03T20:56:56.773659Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.013058, "end_time": "2025-04-03T20:56:56.776402", "exception": false, "start_time": "2025-04-03T20:56:56.763344", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class RLDataset(IterableDataset):\n", " \"\"\"Iterable Dataset containing the ExperienceBuffer which will be updated with new experiences during training.\n", "\n", " Args:\n", " buffer: replay buffer\n", " sample_size: number of experiences to sample at a time\n", "\n", " \"\"\"\n", "\n", " def __init__(self, buffer: ReplayBuffer, sample_size: int = 200) -> None:\n", " self.buffer = buffer\n", " self.sample_size = sample_size\n", "\n", " def __iter__(self) -> Iterator[Tuple]:\n", " states, actions, rewards, dones, new_states = self.buffer.sample(self.sample_size)\n", " for i in range(len(dones)):\n", " yield states[i], actions[i], rewards[i], dones[i], new_states[i]"]}, {"cell_type": "markdown", "id": "1cf9079f", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.005379, "end_time": "2025-04-03T20:56:56.788563", "exception": false, "start_time": "2025-04-03T20:56:56.783184", "status": "completed"}, "tags": []}, "source": ["### Agent"]}, {"cell_type": "code", "execution_count": 7, "id": "18e9ceb8", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:56.798798Z", "iopub.status.busy": "2025-04-03T20:56:56.798619Z", "iopub.status.idle": "2025-04-03T20:56:56.807393Z", "shell.execute_reply": "2025-04-03T20:56:56.806464Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.014878, "end_time": "2025-04-03T20:56:56.808877", "exception": false, "start_time": "2025-04-03T20:56:56.793999", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class Agent:\n", " def __init__(self, env: gym.Env, replay_buffer: ReplayBuffer) -> None:\n", " \"\"\"Base Agent class handling the interaction with the environment.\n", "\n", " Args:\n", " env: training environment\n", " replay_buffer: replay buffer storing experiences\n", "\n", " \"\"\"\n", " self.env = env\n", " self.replay_buffer = replay_buffer\n", " self.reset()\n", " self.state = self.env.reset()\n", "\n", " def reset(self) -> None:\n", " \"\"\"Resents the environment and updates the state.\"\"\"\n", " self.state = self.env.reset()\n", "\n", " def get_action(self, net: nn.Module, epsilon: float, device: str) -> int:\n", " \"\"\"Using the given network, decide what action to carry out using an epsilon-greedy policy.\n", "\n", " Args:\n", " net: DQN network\n", " epsilon: value to determine likelihood of taking a random action\n", " device: current device\n", "\n", " Returns:\n", " action\n", "\n", " \"\"\"\n", " if np.random.random() < epsilon:\n", " action = self.env.action_space.sample()\n", " else:\n", " state = torch.tensor([self.state])\n", "\n", " if device not in [\"cpu\"]:\n", " state = state.cuda(device)\n", "\n", " q_values = net(state)\n", " _, action = torch.max(q_values, dim=1)\n", " action = int(action.item())\n", "\n", " return action\n", "\n", " @torch.no_grad()\n", " def play_step(\n", " self,\n", " net: nn.Module,\n", " epsilon: float = 0.0,\n", " device: str = \"cpu\",\n", " ) -> Tuple[float, bool]:\n", " \"\"\"Carries out a single interaction step between the agent and the environment.\n", "\n", " Args:\n", " net: DQN network\n", " epsilon: value to determine likelihood of taking a random action\n", " device: current device\n", "\n", " Returns:\n", " reward, done\n", "\n", " \"\"\"\n", " action = self.get_action(net, epsilon, device)\n", "\n", " # do step in the environment\n", " # So, in the deprecated version of gym, the env.step() has 4 values unpacked which is\n", " # obs, reward, done, info = env.step(action)\n", " # In the latest version of gym, the step() function returns back an additional variable which is truncated.\n", " # obs, reward, terminated, truncated, info = env.step(action)\n", " new_state, reward, done, _ = self.env.step(action)\n", "\n", " exp = Experience(self.state, action, reward, done, new_state)\n", "\n", " self.replay_buffer.append(exp)\n", "\n", " self.state = new_state\n", " if done:\n", " self.reset()\n", " return reward, done"]}, {"cell_type": "markdown", "id": "02cee7cd", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.003465, "end_time": "2025-04-03T20:56:56.815922", "exception": false, "start_time": "2025-04-03T20:56:56.812457", "status": "completed"}, "tags": []}, "source": ["### DQN Lightning Module"]}, {"cell_type": "code", "execution_count": 8, "id": "d86c159b", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:56.823740Z", "iopub.status.busy": "2025-04-03T20:56:56.823561Z", "iopub.status.idle": "2025-04-03T20:56:56.837412Z", "shell.execute_reply": "2025-04-03T20:56:56.836469Z"}, "papermill": {"duration": 0.019402, "end_time": "2025-04-03T20:56:56.838748", "exception": false, "start_time": "2025-04-03T20:56:56.819346", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class DQNLightning(LightningModule):\n", " def __init__(\n", " self,\n", " batch_size: int = 16,\n", " lr: float = 1e-2,\n", " env: str = \"CartPole-v0\",\n", " gamma: float = 0.99,\n", " sync_rate: int = 10,\n", " replay_size: int = 1000,\n", " warm_start_size: int = 1000,\n", " eps_last_frame: int = 1000,\n", " eps_start: float = 1.0,\n", " eps_end: float = 0.01,\n", " episode_length: int = 200,\n", " warm_start_steps: int = 1000,\n", " ) -> None:\n", " \"\"\"Basic DQN Model.\n", "\n", " Args:\n", " batch_size: size of the batches\")\n", " lr: learning rate\n", " env: gym environment tag\n", " gamma: discount factor\n", " sync_rate: how many frames do we update the target network\n", " replay_size: capacity of the replay buffer\n", " warm_start_size: how many samples do we use to fill our buffer at the start of training\n", " eps_last_frame: what frame should epsilon stop decaying\n", " eps_start: starting value of epsilon\n", " eps_end: final value of epsilon\n", " episode_length: max length of an episode\n", " warm_start_steps: max episode reward in the environment\n", "\n", " \"\"\"\n", " super().__init__()\n", " self.save_hyperparameters()\n", "\n", " self.env = gym.make(self.hparams.env)\n", " obs_size = self.env.observation_space.shape[0]\n", " n_actions = self.env.action_space.n\n", "\n", " self.net = DQN(obs_size, n_actions)\n", " self.target_net = DQN(obs_size, n_actions)\n", "\n", " self.buffer = ReplayBuffer(self.hparams.replay_size)\n", " self.agent = Agent(self.env, self.buffer)\n", " self.total_reward = 0\n", " self.episode_reward = 0\n", " self.populate(self.hparams.warm_start_steps)\n", "\n", " def populate(self, steps: int = 1000) -> None:\n", " \"\"\"Carries out several random steps through the environment to initially fill up the replay buffer with\n", " experiences.\n", "\n", " Args:\n", " steps: number of random steps to populate the buffer with\n", "\n", " \"\"\"\n", " for _ in range(steps):\n", " self.agent.play_step(self.net, epsilon=1.0)\n", "\n", " def forward(self, x: Tensor) -> Tensor:\n", " \"\"\"Passes in a state x through the network and gets the q_values of each action as an output.\n", "\n", " Args:\n", " x: environment state\n", "\n", " Returns:\n", " q values\n", "\n", " \"\"\"\n", " output = self.net(x)\n", " return output\n", "\n", " def dqn_mse_loss(self, batch: Tuple[Tensor, Tensor]) -> Tensor:\n", " \"\"\"Calculates the mse loss using a mini batch from the replay buffer.\n", "\n", " Args:\n", " batch: current mini batch of replay data\n", "\n", " Returns:\n", " loss\n", "\n", " \"\"\"\n", " states, actions, rewards, dones, next_states = batch\n", "\n", " state_action_values = self.net(states).gather(1, actions.long().unsqueeze(-1)).squeeze(-1)\n", "\n", " with torch.no_grad():\n", " next_state_values = self.target_net(next_states).max(1)[0]\n", " next_state_values[dones] = 0.0\n", " next_state_values = next_state_values.detach()\n", "\n", " expected_state_action_values = next_state_values * self.hparams.gamma + rewards\n", "\n", " return nn.MSELoss()(state_action_values, expected_state_action_values)\n", "\n", " def get_epsilon(self, start: int, end: int, frames: int) -> float:\n", " if self.global_step > frames:\n", " return end\n", " return start - (self.global_step / frames) * (start - end)\n", "\n", " def training_step(self, batch: Tuple[Tensor, Tensor], nb_batch) -> OrderedDict:\n", " \"\"\"Carries out a single step through the environment to update the replay buffer. Then calculates loss based on\n", " the minibatch received.\n", "\n", " Args:\n", " batch: current mini batch of replay data\n", " nb_batch: batch number\n", "\n", " Returns:\n", " Training loss and log metrics\n", "\n", " \"\"\"\n", " device = self.get_device(batch)\n", " epsilon = self.get_epsilon(self.hparams.eps_start, self.hparams.eps_end, self.hparams.eps_last_frame)\n", " self.log(\"epsilon\", epsilon)\n", "\n", " # step through environment with agent\n", " reward, done = self.agent.play_step(self.net, epsilon, device)\n", " self.episode_reward += reward\n", " self.log(\"episode reward\", self.episode_reward)\n", "\n", " # calculates training loss\n", " loss = self.dqn_mse_loss(batch)\n", "\n", " if done:\n", " self.total_reward = self.episode_reward\n", " self.episode_reward = 0\n", "\n", " # Soft update of target network\n", " if self.global_step % self.hparams.sync_rate == 0:\n", " self.target_net.load_state_dict(self.net.state_dict())\n", "\n", " self.log_dict(\n", " {\n", " \"reward\": reward,\n", " \"train_loss\": loss,\n", " }\n", " )\n", " self.log(\"total_reward\", self.total_reward, prog_bar=True)\n", " self.log(\"steps\", self.global_step, logger=False, prog_bar=True)\n", "\n", " return loss\n", "\n", " def configure_optimizers(self) -> List[Optimizer]:\n", " \"\"\"Initialize Adam optimizer.\"\"\"\n", " optimizer = Adam(self.net.parameters(), lr=self.hparams.lr)\n", " return optimizer\n", "\n", " def __dataloader(self) -> DataLoader:\n", " \"\"\"Initialize the Replay Buffer dataset used for retrieving experiences.\"\"\"\n", " dataset = RLDataset(self.buffer, self.hparams.episode_length)\n", " dataloader = DataLoader(\n", " dataset=dataset,\n", " batch_size=self.hparams.batch_size,\n", " )\n", " return dataloader\n", "\n", " def train_dataloader(self) -> DataLoader:\n", " \"\"\"Get train loader.\"\"\"\n", " return self.__dataloader()\n", "\n", " def get_device(self, batch) -> str:\n", " \"\"\"Retrieve device currently being used by minibatch.\"\"\"\n", " return batch[0].device.index if self.on_gpu else \"cpu\""]}, {"cell_type": "markdown", "id": "d5c381bd", "metadata": {"papermill": {"duration": 0.003454, "end_time": "2025-04-03T20:56:56.845705", "exception": false, "start_time": "2025-04-03T20:56:56.842251", "status": "completed"}, "tags": []}, "source": ["### Trainer"]}, {"cell_type": "code", "execution_count": 9, "id": "f555ca49", "metadata": {"execution": {"iopub.execute_input": "2025-04-03T20:56:56.853662Z", "iopub.status.busy": "2025-04-03T20:56:56.853486Z", "iopub.status.idle": "2025-04-03T20:57:10.926026Z", "shell.execute_reply": "2025-04-03T20:57:10.925162Z"}, "papermill": {"duration": 14.079211, "end_time": "2025-04-03T20:57:10.928450", "exception": false, "start_time": "2025-04-03T20:56:56.849239", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["/usr/local/lib/python3.10/dist-packages/gym/envs/registration.py:505: UserWarning: \u001b[33mWARN: The environment CartPole-v0 is out of date. You should consider upgrading to version `v1` with the environment ID `CartPole-v1`.\u001b[0m\n", " logger.warn(\n", "/usr/local/lib/python3.10/dist-packages/pygame/pkgdata.py:25: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html\n", " from pkg_resources import resource_stream, resource_exists\n"]}, {"name": "stderr", "output_type": "stream", "text": ["GPU available: True (cuda), used: True\n"]}, {"name": "stderr", "output_type": "stream", "text": ["TPU available: False, using: 0 TPU cores\n"]}, {"name": "stderr", "output_type": "stream", "text": ["HPU available: False, using: 0 HPUs\n"]}, {"name": "stderr", "output_type": "stream", "text": ["You are using a CUDA device ('NVIDIA GeForce RTX 3090') that has Tensor Cores. To properly utilize them, you should set `torch.set_float32_matmul_precision('medium' | 'high')` which will trade-off precision for performance. For more details, read https://pytorch.org/docs/stable/generated/torch.set_float32_matmul_precision.html#torch.set_float32_matmul_precision\n"]}, {"name": "stderr", "output_type": "stream", "text": ["LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1]\n"]}, {"name": "stderr", "output_type": "stream", "text": ["\n", " | Name | Type | Params | Mode \n", "--------------------------------------------\n", "0 | net | DQN | 898 | train\n", "1 | target_net | DQN | 898 | train\n", "--------------------------------------------\n", "1.8 K Trainable params\n", "0 Non-trainable params\n", "1.8 K Total params\n", "0.007 Total estimated model params size (MB)\n", "10 Modules in train mode\n", "0 Modules in eval mode\n"]}, {"name": "stderr", "output_type": "stream", "text": ["/usr/local/lib/python3.10/dist-packages/pytorch_lightning/trainer/connectors/data_connector.py:424: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=63` in the `DataLoader` to improve performance.\n", "/usr/local/lib/python3.10/dist-packages/torch/utils/data/_utils/collate.py:175: DeprecationWarning: In future, it will be an error for 'np.bool_' scalars to be interpreted as an index\n", " return torch.as_tensor(batch)\n"]}, {"data": {"application/vnd.jupyter.widget-view+json": {"model_id": "57c3adb365fb4547a97b0ef3312d023e", "version_major": 2, "version_minor": 0}, "text/plain": ["Training: | | 0/? [00:00\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
episode rewardepsilonrewardtotal_rewardtrain_loss
epoch
35.00.951491.035.02.484817
76.00.901991.014.014.151343
113.00.852491.012.01.501582
1515.00.802991.029.012.476444
191.00.753491.015.066.397606
\n", ""], "text/plain": [" episode reward epsilon reward total_reward train_loss\n", "epoch \n", "3 5.0 0.95149 1.0 35.0 2.484817\n", "7 6.0 0.90199 1.0 14.0 14.151343\n", "11 3.0 0.85249 1.0 12.0 1.501582\n", "15 15.0 0.80299 1.0 29.0 12.476444\n", "19 1.0 0.75349 1.0 15.0 66.397606"]}, "metadata": {}, "output_type": "display_data"}, {"data": {"text/plain": [""]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "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115LcXFxF0V8es899xySJPHAAw94HzsX4s/Pz+fGG28kJCQEi8VCSkoKO3fu9D6vqipPPfUUUVFRWCwWJk2axLFjx7ow4mYej4cnn3ySpKQkLBYLPXr04JlnnqHlep3uFv/GjRu58soriY6ORpIkPv/881bPdybeiooKZs6cib+/P4GBgdx2223U1dV1efwul4tHHnmElJQUfHx8iI6O5qabbqKgoKDbxH+mczjVXXfdhSRJvPzyy60e7+pzEITu7LxOxD7++GPmzp3L008/za5du0hNTWXKlCmUlJR0dWhtbNiwgTlz5rB161ZWrVqFy+Vi8uTJ1NfXe4958MEH+fLLL1m6dCkbNmygoKCAa665pgujbt+OHTv45z//yaBBg1o93t3jr6ysZOzYsRgMBr7++msOHTrEokWLCAoK8h7zwgsvsHjxYt544w22bduGj48PU6ZMoaGhoQsj1zz//PMsWbKEV199lcOHD/P888/zwgsv8Morr3iP6W7x19fXk5qaymuvvdbu852Jd+bMmRw8eJBVq1bx1VdfsXHjRu68884uj99ms7Fr1y6efPJJdu3axWeffUZGRgZXXXVVq+O6Mn448z1osnz5crZu3Up0dHSb57r6HAShW1PPYyNGjFDnzJnj/X+Px6NGR0erCxcu7MKoOqekpEQF1A0bNqiqqqpVVVWqwWBQly5d6j3m8OHDKqBu2bKlq8Jso7a2Vu3Vq5e6atUqdfz48er999+vquq5Ef8jjzyijhs3rsPnFUVRIyMj1RdffNH7WFVVlWoymdQPP/zwlwjxtK644gr11ltvbfXYNddco86cOVNV1e4fP6AuX77c+/+diffQoUMqoO7YscN7zNdff61KkqTm5+f/YrGratv427N9+3YVULOzs1VV7V7xq2rH55CXl6fGxMSoBw4cUBMSEtSXXnrJ+1x3OwdB6G7O2x4xp9NJeno6kyZN8j4myzKTJk1iy5YtXRhZ51RXVwMQHBwMQHp6Oi6Xq9X59O3bl/j4+G51PnPmzOGKK65oFSecG/H/97//JS0tjd/97neEh4czZMgQ/u///s/7/IkTJygqKmp1DgEBAYwcObJbnMOYMWNYs2YNR48eBWDv3r189913XHbZZUD3j/9UnYl3y5YtBAYGkpaW5j1m0qRJyLLMtm3bfvGYz6S6uhpJkggMDATOjfgVRWHW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", "text/plain": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["\n", "metrics = pd.read_csv(f\"{trainer.logger.log_dir}/metrics.csv\")\n", "del metrics[\"step\"]\n", "metrics.set_index(\"epoch\", inplace=True)\n", "display(metrics.dropna(axis=1, how=\"all\").head())\n", "sn.relplot(data=metrics, kind=\"line\")"]}, {"cell_type": "markdown", "id": "db6ffb1a", "metadata": {"papermill": {"duration": 0.00927, "end_time": "2025-04-03T20:57:11.285406", "exception": false, "start_time": "2025-04-03T20:57:11.276136", "status": "completed"}, "tags": []}, "source": ["## Congratulations - Time to Join the Community!\n", "\n", "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the Lightning\n", "movement, you can do so in the following ways!\n", "\n", "### Star [Lightning](https://github.com/Lightning-AI/lightning) on GitHub\n", "The easiest way to help our community is just by starring the GitHub repos! This helps raise awareness of the cool\n", "tools we're building.\n", "\n", "### Join our [Discord](https://discord.com/invite/tfXFetEZxv)!\n", "The best way to keep up to date on the latest advancements is to join our community! Make sure to introduce yourself\n", "and share your interests in `#general` channel\n", "\n", "\n", "### Contributions !\n", "The best way to contribute to our community is to become a code contributor! At any time you can go to\n", "[Lightning](https://github.com/Lightning-AI/lightning) or [Bolt](https://github.com/Lightning-AI/lightning-bolts)\n", "GitHub Issues page and filter for \"good first issue\".\n", "\n", "* [Lightning good first issue](https://github.com/Lightning-AI/lightning/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n", "* [Bolt good first issue](https://github.com/Lightning-AI/lightning-bolts/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n", "* You can also contribute your own notebooks with useful examples !\n", "\n", "### Great thanks from the entire Pytorch Lightning Team for your interest !\n", "\n", "[![Pytorch Lightning](data:image/png;base64,NDA0OiBOb3QgRm91bmQ=){height=\"60px\" width=\"240px\"}](https://pytorchlightning.ai)"]}, {"cell_type": "raw", "metadata": {"raw_mimetype": "text/restructuredtext"}, "source": [".. customcarditem::\n", " :header: How to train a Deep Q Network\n", " :card_description: Main takeaways: 1. RL has the same flow as previous models we have seen, with a few additions 2. Handle unsupervised learning by using an IterableDataset where the dataset...\n", " :tags: RL,GPU/TPU,Lightning-Examples"]}], "metadata": {"jupytext": {"cell_metadata_filter": "colab,id,colab_type,-all", "formats": "ipynb,py:percent", "main_language": "python"}, "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.12"}, "papermill": {"default_parameters": {}, "duration": 22.206167, "end_time": "2025-04-03T20:57:13.633661", "environment_variables": {}, "exception": null, "input_path": "lightning_examples/reinforce-learning-DQN/dqn.ipynb", "output_path": ".notebooks/lightning_examples/reinforce-learning-DQN.ipynb", "parameters": {}, "start_time": "2025-04-03T20:56:51.427494", "version": "2.6.0"}, "widgets": {"application/vnd.jupyter.widget-state+json": {"state": {"05c10a038d9f4522a9de307efcadf4a1": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_40309ffb3cbb4899ab10794c60631137", "max": 1.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_860cf5ee186e4506b9abe46f2342b839", "tabbable": null, "tooltip": null, "value": 1.0}}, "09de168e36c74c67a7c52354840ad7a6": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_f8ad9ef19b51468ca2d9ac22372fb7fa", "placeholder": "\u200b", "style": "IPY_MODEL_9609ab1b4dd5467a8ba580bd5729f353", "tabbable": null, "tooltip": null, "value": "Epoch\u2007149:\u2007"}}, "2c06cbf206d24bd18cb983d723b07c72": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HTMLView", "description": "", "description_allow_html": false, "layout": "IPY_MODEL_3358fe4863d14029bf06c39d4aadb736", "placeholder": "\u200b", "style": "IPY_MODEL_cbc2b173d8004a61bceb1351bf0da53e", "tabbable": null, "tooltip": null, "value": "\u200713/?\u2007[00:00<00:00,\u2007149.83it/s,\u2007v_num=0,\u2007total_reward=154.0,\u2007steps=1949.0]"}}, "3358fe4863d14029bf06c39d4aadb736": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "3c38391b162a437dac2ce33a83e4d1ad": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": "inline-flex", "flex": null, "flex_flow": "row wrap", "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": "100%"}}, "40309ffb3cbb4899ab10794c60631137": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": "2", "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "57c3adb365fb4547a97b0ef3312d023e": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_09de168e36c74c67a7c52354840ad7a6", "IPY_MODEL_05c10a038d9f4522a9de307efcadf4a1", "IPY_MODEL_2c06cbf206d24bd18cb983d723b07c72"], "layout": "IPY_MODEL_3c38391b162a437dac2ce33a83e4d1ad", "tabbable": null, "tooltip": null}}, "860cf5ee186e4506b9abe46f2342b839": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "9609ab1b4dd5467a8ba580bd5729f353": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "cbc2b173d8004a61bceb1351bf0da53e": {"model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "HTMLStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "StyleView", "background": null, "description_width": "", "font_size": null, "text_color": null}}, "f8ad9ef19b51468ca2d9ac22372fb7fa": {"model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}}, "version_major": 2, "version_minor": 0}}}, "nbformat": 4, "nbformat_minor": 5}