{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Configurations for Colab" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import sys\n", "IN_COLAB = \"google.colab\" in sys.modules\n", "\n", "if IN_COLAB:\n", " !apt install python-opengl\n", " !apt install ffmpeg\n", " !apt install xvfb\n", " !pip install PyVirtualDisplay==3.0\n", " !pip install gymnasium==0.28.1\n", " from pyvirtualdisplay import Display\n", " \n", " # Start virtual display\n", " dis = Display(visible=0, size=(400, 400))\n", " dis.start()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 05. Noisy Networks for Exploration\n", "\n", "[M. Fortunato et al., \"Noisy Networks for Exploration.\" arXiv preprint arXiv:1706.10295, 2017.](https://arxiv.org/pdf/1706.10295.pdf)\n", "\n", "\n", "NoisyNet is an exploration method that learns perturbations of the network weights to drive exploration. The key insight is that a single change to the weight vector can induce a consistent, and potentially very complex, state-dependent change in policy over multiple time steps.\n", "\n", "Firstly, let's take a look into a linear layer of a neural network with $p$ inputs and $q$ outputs, represented by\n", "\n", "$$\n", "y = wx + b,\n", "$$\n", "\n", "where $x \\in \\mathbb{R}^p$ is the layer input, $w \\in \\mathbb{R}^{q \\times p}$, and $b \\in \\mathbb{R}$ the bias.\n", "\n", "The corresponding noisy linear layer is defined as:\n", "\n", "$$\n", "y = (\\mu^w + \\sigma^w \\odot \\epsilon^w) x + \\mu^b + \\sigma^b \\odot \\epsilon^b,\n", "$$\n", "\n", "where $\\mu^w + \\sigma^w \\odot \\epsilon^w$ and $\\mu^b + \\sigma^b \\odot \\epsilon^b$ replace $w$ and $b$ in the first linear layer equation. The parameters $\\mu^w \\in \\mathbb{R}^{q \\times p}, \\mu^b \\in \\mathbb{R}^q, \\sigma^w \\in \\mathbb{R}^{q \\times p}$ and $\\sigma^b \\in \\mathbb{R}^q$ are learnable, whereas $\\epsilon^w \\in \\mathbb{R}^{q \\times p}$ and $\\epsilon^b \\in \\mathbb{R}^q$ are noise random variables which can be generated by one of the following two ways:\n", "\n", "1. **Independent Gaussian noise**: the noise applied to each weight and bias is independent, where each random noise entry is drawn from a unit Gaussian distribution. This means that for each noisy linear layer, there are $pq + q$ noise variables (for $p$ inputs to the layer and $q$ outputs).\n", "2. **Factorised Gaussian noise:** This is a more computationally efficient way. It produces 2 random Gaussian noise vectors ($p, q$) and makes $pq + q$ noise entries by outer product as follows:\n", "\n", "$$\n", "\\begin{align}\n", "\\epsilon_{i,j}^w &= f(\\epsilon_i) f(\\epsilon_j),\\\\\n", "\\epsilon_{j}^b &= f(\\epsilon_i),\\\\\n", "\\text{where } f(x) &= sgn(x) \\sqrt{|x|}.\n", "\\end{align}\n", "$$\n", "\n", "In all experiements of the paper, the authors used Factorised Gaussian noise, so we will go for it as well." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/jinwoo.park/miniforge3/envs/rainbow-is-all-you-need/lib/python3.8/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "import math\n", "import os\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": {}, "source": [ "## Replay buffer\n", "\n", "Please see *01.dqn.ipynb* for detailed description." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "class ReplayBuffer:\n", " \"\"\"A simple numpy replay buffer.\"\"\"\n", "\n", " def __init__(self, obs_dim: int, size: int, batch_size: int = 32):\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], 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", " 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", " idxs = np.random.choice(self.size, size=self.batch_size, replace=False)\n", " return dict(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", " def __len__(self) -> int:\n", " return self.size" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Noisy Layer\n", "\n", "**References:**\n", "- https://github.com/higgsfield/RL-Adventure/blob/master/5.noisy%20dqn.ipynb\n", "- https://github.com/Kaixhin/Rainbow/blob/master/model.py" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "class NoisyLinear(nn.Module):\n", " \"\"\"Noisy linear module for NoisyNet.\n", " \n", " Attributes:\n", " in_features (int): input size of linear module\n", " out_features (int): output size of linear module\n", " std_init (float): initial std value\n", " weight_mu (nn.Parameter): mean value weight parameter\n", " weight_sigma (nn.Parameter): std value weight parameter\n", " bias_mu (nn.Parameter): mean value bias parameter\n", " bias_sigma (nn.Parameter): std value bias parameter\n", " \n", " \"\"\"\n", "\n", " def __init__(self, in_features: int, out_features: int, std_init: float = 0.5):\n", " \"\"\"Initialization.\"\"\"\n", " super(NoisyLinear, self).__init__()\n", " \n", " self.in_features = in_features\n", " self.out_features = out_features\n", " self.std_init = std_init\n", "\n", " self.weight_mu = nn.Parameter(torch.Tensor(out_features, in_features))\n", " self.weight_sigma = nn.Parameter(\n", " torch.Tensor(out_features, in_features)\n", " )\n", " self.register_buffer(\n", " \"weight_epsilon\", torch.Tensor(out_features, in_features)\n", " )\n", "\n", " self.bias_mu = nn.Parameter(torch.Tensor(out_features))\n", " self.bias_sigma = nn.Parameter(torch.Tensor(out_features))\n", " self.register_buffer(\"bias_epsilon\", torch.Tensor(out_features))\n", "\n", " self.reset_parameters()\n", " self.reset_noise()\n", "\n", " def reset_parameters(self):\n", " \"\"\"Reset trainable network parameters (factorized gaussian noise).\"\"\"\n", " mu_range = 1 / math.sqrt(self.in_features)\n", " self.weight_mu.data.uniform_(-mu_range, mu_range)\n", " self.weight_sigma.data.fill_(\n", " self.std_init / math.sqrt(self.in_features)\n", " )\n", " self.bias_mu.data.uniform_(-mu_range, mu_range)\n", " self.bias_sigma.data.fill_(\n", " self.std_init / math.sqrt(self.out_features)\n", " )\n", "\n", " def reset_noise(self):\n", " \"\"\"Make new noise.\"\"\"\n", " epsilon_in = self.scale_noise(self.in_features)\n", " epsilon_out = self.scale_noise(self.out_features)\n", "\n", " # outer product\n", " self.weight_epsilon.copy_(epsilon_out.ger(epsilon_in))\n", " self.bias_epsilon.copy_(epsilon_out)\n", "\n", " def forward(self, x: torch.Tensor) -> torch.Tensor:\n", " \"\"\"Forward method implementation.\n", " \n", " We don't use separate statements on train / eval mode.\n", " It doesn't show remarkable difference of performance.\n", " \"\"\"\n", " return F.linear(\n", " x,\n", " self.weight_mu + self.weight_sigma * self.weight_epsilon,\n", " self.bias_mu + self.bias_sigma * self.bias_epsilon,\n", " )\n", " \n", " @staticmethod\n", " def scale_noise(size: int) -> torch.Tensor:\n", " \"\"\"Set scale to make noise (factorized gaussian noise).\"\"\"\n", " x = torch.randn(size)\n", "\n", " return x.sign().mul(x.abs().sqrt())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Noisy Network\n", "\n", "We use NoisyLinear for the last two FC layers, and there is a method to reset noise at every step.\n", "These are the only differences from the example of *01.dqn.ipynb*." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "class Network(nn.Module):\n", " def __init__(self, in_dim: int, out_dim: int):\n", " \"\"\"Initialization.\"\"\"\n", " super(Network, self).__init__()\n", "\n", " self.feature = nn.Linear(in_dim, 128)\n", " self.noisy_layer1 = NoisyLinear(128, 128)\n", " self.noisy_layer2 = NoisyLinear(128, out_dim)\n", "\n", " def forward(self, x: torch.Tensor) -> torch.Tensor:\n", " \"\"\"Forward method implementation.\"\"\"\n", " feature = F.relu(self.feature(x))\n", " hidden = F.relu(self.noisy_layer1(feature))\n", " out = self.noisy_layer2(hidden)\n", " \n", " return out\n", " \n", " def reset_noise(self):\n", " \"\"\"Reset all noisy layers.\"\"\"\n", " self.noisy_layer1.reset_noise()\n", " self.noisy_layer2.reset_noise()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## DQN + NoisyNet Agent (w/o DuelingNet)\n", "\n", "Here is a summary of DQNAgent 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", "|compute_dqn_loss | return dqn loss. |\n", "|update_model | update the model by gradient descent. |\n", "|target_hard_update| hard update from the local model to the target model.|\n", "|train | train the agent during num_frames. |\n", "|test | test the agent (1 episode). |\n", "|plot | plot the training progresses. |\n", "\n", "In the paper, NoisyNet is used as a component of the Dueling Network Architecture, which includes Double-DQN and Prioritized Experience Replay. However, we don't implement them to simplify the tutorial. One thing to note is that NoisyNet is an alternertive to $\\epsilon$-greedy method, so all $\\epsilon$ related lines are removed. Please check all comments with *NoisyNet*." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "class DQNAgent:\n", " \"\"\"DQN Agent interacting with environment.\n", " \n", " Attribute:\n", " env (gym.Env): openAI Gym environment\n", " memory (ReplayBuffer): replay memory to store transitions\n", " batch_size (int): batch size for sampling\n", " target_update (int): period for target model's hard update\n", " gamma (float): discount factor\n", " dqn (Network): model to train and select actions\n", " dqn_target (Network): target model to update\n", " optimizer (torch.optim): optimizer for training dqn\n", " transition (list): transition information including\n", " state, action, reward, next_state, done\n", " \"\"\"\n", "\n", " def __init__(\n", " self, \n", " env: gym.Env,\n", " memory_size: int,\n", " batch_size: int,\n", " target_update: int,\n", " seed: int,\n", " gamma: float = 0.99,\n", " ):\n", " \"\"\"Initialization.\n", " \n", " Args:\n", " env (gym.Env): openAI Gym environment\n", " memory_size (int): length of memory\n", " batch_size (int): batch size for sampling\n", " target_update (int): period for target model's hard update\n", " gamma (float): discount factor\n", " \"\"\"\n", " # NoisyNet: All attributes related to epsilon are removed\n", " obs_dim = env.observation_space.shape[0]\n", " action_dim = env.action_space.n\n", " \n", " self.env = env\n", " self.memory = ReplayBuffer(obs_dim, memory_size, batch_size)\n", " self.batch_size = batch_size\n", " self.target_update = target_update\n", " self.seed = seed\n", " self.gamma = gamma\n", " \n", " # device: cpu / gpu\n", " self.device = torch.device(\n", " \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", " )\n", " print(self.device)\n", "\n", " # networks: dqn, dqn_target\n", " self.dqn = Network(obs_dim, action_dim).to(self.device)\n", " self.dqn_target = Network(obs_dim, action_dim).to(self.device)\n", " self.dqn_target.load_state_dict(self.dqn.state_dict())\n", " self.dqn_target.eval()\n", " \n", " # optimizer\n", " self.optimizer = optim.Adam(self.dqn.parameters())\n", "\n", " # transition to store in memory\n", " self.transition = list()\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", " # NoisyNet: no epsilon greedy action selection\n", " selected_action = self.dqn(\n", " torch.FloatTensor(state).to(self.device)\n", " ).argmax()\n", " selected_action = selected_action.detach().cpu().numpy()\n", " \n", " if not self.is_test:\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", " samples = self.memory.sample_batch()\n", "\n", " loss = self._compute_dqn_loss(samples)\n", "\n", " self.optimizer.zero_grad()\n", " loss.backward()\n", " self.optimizer.step()\n", " \n", " # NoisyNet: reset noise\n", " self.dqn.reset_noise()\n", " self.dqn_target.reset_noise()\n", "\n", " return loss.item()\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", " update_cnt = 0\n", " losses = []\n", " scores = []\n", " score = 0\n", "\n", " for frame_idx 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", " # NoisyNet: removed decrease of epsilon\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:\n", " loss = self.update_model()\n", " losses.append(loss)\n", " update_cnt += 1\n", " \n", " # if hard update is needed\n", " if update_cnt % self.target_update == 0:\n", " self._target_hard_update()\n", "\n", " # plotting\n", " if frame_idx % plotting_interval == 0:\n", " self._plot(frame_idx, scores, losses)\n", " \n", " self.env.close()\n", " \n", " def test(self, video_folder: str) -> None:\n", " \"\"\"Test the agent.\"\"\"\n", " self.is_test = True\n", " \n", " # for recording a video\n", " naive_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", " # reset\n", " self.env = naive_env\n", "\n", " def _compute_dqn_loss(self, samples: Dict[str, np.ndarray]) -> torch.Tensor:\n", " \"\"\"Return dqn loss.\"\"\"\n", " device = self.device # for shortening the following lines\n", " state = torch.FloatTensor(samples[\"obs\"]).to(device)\n", " next_state = torch.FloatTensor(samples[\"next_obs\"]).to(device)\n", " action = torch.LongTensor(samples[\"acts\"].reshape(-1, 1)).to(device)\n", " reward = torch.FloatTensor(samples[\"rews\"].reshape(-1, 1)).to(device)\n", " done = torch.FloatTensor(samples[\"done\"].reshape(-1, 1)).to(device)\n", " \n", " # G_t = r + gamma * v(s_{t+1}) if state != Terminal\n", " # = r otherwise\n", " curr_q_value = self.dqn(state).gather(1, action)\n", " next_q_value = self.dqn_target(next_state).max(\n", " dim=1, keepdim=True\n", " )[0].detach()\n", " mask = 1 - done\n", " target = (reward + self.gamma * next_q_value * mask).to(self.device)\n", "\n", " # calculate dqn loss\n", " loss = F.smooth_l1_loss(curr_q_value, target)\n", "\n", " return loss\n", "\n", " def _target_hard_update(self):\n", " \"\"\"Hard update: target <- local.\"\"\"\n", " self.dqn_target.load_state_dict(self.dqn.state_dict())\n", " \n", " def _plot(\n", " self, \n", " frame_idx: int, \n", " scores: List[float], \n", " losses: List[float], \n", " ):\n", " \"\"\"Plot the training progresses.\"\"\"\n", " clear_output(True)\n", " plt.figure(figsize=(20, 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('loss')\n", " plt.plot(losses)\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Environment\n", "\n", "You can see the [code](https://github.com/Farama-Foundation/Gymnasium/blob/main/gymnasium/envs/classic_control/cartpole.py) and [configurations](https://github.com/Farama-Foundation/Gymnasium/blob/main/gymnasium/envs/classic_control/cartpole.py#L91) of CartPole-v1 from Farama Gymnasium's repository." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# environment\n", "env = gym.make(\"CartPole-v1\", max_episode_steps=200, render_mode=\"rgb_array\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Set random seed" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "seed = 777\n", "\n", "def seed_torch(seed):\n", " torch.manual_seed(seed)\n", " if torch.backends.cudnn.enabled:\n", " torch.cuda.manual_seed(seed)\n", " torch.backends.cudnn.benchmark = False\n", " torch.backends.cudnn.deterministic = True\n", "\n", "np.random.seed(seed)\n", "seed_torch(seed)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Initialize" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cpu\n" ] } ], "source": [ "# parameters\n", "num_frames = 10000\n", "memory_size = 1000\n", "batch_size = 256\n", "target_update = 150\n", "\n", "# train\n", "agent = DQNAgent(env, memory_size, batch_size, target_update, seed)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Train" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "agent.train(num_frames)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Test\n", "\n", "Run the trained agent (1 episode)." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Moviepy - Building video /Users/jinwoo.park/Repositories/rainbow-is-all-you-need/videos/noisy_net/rl-video-episode-0.mp4.\n", "Moviepy - Writing video /Users/jinwoo.park/Repositories/rainbow-is-all-you-need/videos/noisy_net/rl-video-episode-0.mp4\n", "\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ " " ] }, { "name": "stdout", "output_type": "stream", "text": [ "Moviepy - Done !\n", "Moviepy - video ready /Users/jinwoo.park/Repositories/rainbow-is-all-you-need/videos/noisy_net/rl-video-episode-0.mp4\n", "score: 200.0\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\r" ] } ], "source": [ "video_folder=\"videos/noisy_net\"\n", "agent.test(video_folder=video_folder)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Render" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Played: videos/noisy_net/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(HTML(\n", " data=\"\"\"\n", " \n", " \"\"\".format(encoded.decode(\"ascii\"))\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)" ] } ], "metadata": { "kernelspec": { "display_name": "rainbow-is-all-you-need", "language": "python", "name": "rainbow-is-all-you-need" }, "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.8.12" } }, "nbformat": 4, "nbformat_minor": 4 }