Last active
June 19, 2025 16:55
-
-
Save DiegoHernanSalazar/ac50e5d49638193782332b98a507656a to your computer and use it in GitHub Desktop.
Stanford Online/ DeepLearning.AI. Unsupervised Learning, Recommenders Systems and Reinforcement Learning: Reinforcement Learning, Deep Q-Learning - Lunar Lander
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Deep Q-Learning - Lunar Lander\n", | |
| "\n", | |
| "In this assignment, you will train an agent to land a lunar lander safely on a landing pad on the surface of the moon.\n", | |
| "\n", | |
| "\n", | |
| "# Outline\n", | |
| "- [ 1 - Import Packages <img align=\"Right\" src=\"./images/lunar_lander.gif\" width = 60% >](#1)\n", | |
| "- [ 2 - Hyperparameters](#2)\n", | |
| "- [ 3 - The Lunar Lander Environment](#3)\n", | |
| " - [ 3.1 Action Space](#3.1)\n", | |
| " - [ 3.2 Observation Space](#3.2)\n", | |
| " - [ 3.3 Rewards](#3.3)\n", | |
| " - [ 3.4 Episode Termination](#3.4)\n", | |
| "- [ 4 - Load the Environment](#4)\n", | |
| "- [ 5 - Interacting with the Gym Environment](#5)\n", | |
| " - [ 5.1 Exploring the Environment's Dynamics](#5.1)\n", | |
| "- [ 6 - Deep Q-Learning](#6)\n", | |
| " - [ 6.1 Target Network](#6.1)\n", | |
| " - [ Exercise 1](#ex01)\n", | |
| " - [ 6.2 Experience Replay](#6.2)\n", | |
| "- [ 7 - Deep Q-Learning Algorithm with Experience Replay](#7)\n", | |
| " - [ Exercise 2](#ex02)\n", | |
| "- [ 8 - Update the Network Weights](#8)\n", | |
| "- [ 9 - Train the Agent](#9)\n", | |
| "- [ 10 - See the Trained Agent In Action](#10)\n", | |
| "- [ 11 - Congratulations!](#11)\n", | |
| "- [ 12 - References](#12)\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "_**NOTE:** To prevent errors from the autograder, you are not allowed to edit or delete non-graded cells in this lab. Please also refrain from adding any new cells. \n", | |
| "**Once you have passed this assignment** and want to experiment with any of the non-graded code, you may follow the instructions at the bottom of this notebook._" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"1\"></a>\n", | |
| "## 1 - Import Packages\n", | |
| "\n", | |
| "We'll make use of the following packages:\n", | |
| "- `numpy` is a package for scientific computing in python.\n", | |
| "- `deque` will be our data structure for our memory buffer.\n", | |
| "- `namedtuple` will be used to store the experience tuples.\n", | |
| "- The `gym` toolkit is a collection of environments that can be used to test reinforcement learning algorithms. We should note that in this notebook we are using `gym` version `0.24.0`.\n", | |
| "- `PIL.Image` and `pyvirtualdisplay` are needed to render the Lunar Lander environment.\n", | |
| "- We will use several modules from the `tensorflow.keras` framework for building deep learning models.\n", | |
| "- `utils` is a module that contains helper functions for this assignment. You do not need to modify the code in this file.\n", | |
| "\n", | |
| "Run the cell below to import all the necessary packages." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": { | |
| "deletable": false, | |
| "id": "KYbOPKRtfQOr" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "import time # Use the time module to check the execution time, measuring time taken for\n", | |
| " # a code segmentby recording start and end times\n", | |
| "\n", | |
| "# Data structure 'deque' for memory buffer and store the experience tuples 'namedtuple'\n", | |
| "from collections import deque, namedtuple\n", | |
| "\n", | |
| "# Collection of environments used to test reinforcement learning algorithms\n", | |
| "import gym\n", | |
| "\n", | |
| "# Managing scientific computing with numpy arrays\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "# Import and handle images with PIL library to render Lunar lander\n", | |
| "import PIL.Image\n", | |
| "\n", | |
| "# Get tensorflow framework for building deep learning models\n", | |
| "import tensorflow as tf\n", | |
| "\n", | |
| "# Contains 'helper' functions\n", | |
| "import utils\n", | |
| "\n", | |
| "from pyvirtualdisplay import Display # Needed to render the Lunar Lander environment\n", | |
| "from tensorflow.keras import Sequential # Create a deep learning NN 'Sequential()' model\n", | |
| "from tensorflow.keras.layers import Dense, Input # Create 'Dense()' layers and 'Input()' features of NN\n", | |
| "from tensorflow.keras.losses import MSE # Get 'Mean Squared Error (MSE)' as loss / error function\n", | |
| "from tensorflow.keras.optimizers import Adam # Get 'Adam()' optimizer as GD updating algorithm" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Set up a virtual display to render the Lunar Lander environment.\n", | |
| "# in a non-graphical environment, such as a server.\n", | |
| "# 'visible=0' indicates that the display is not visible\n", | |
| "# 'size=(840, 480)' defines the resolution of the virtual display\n", | |
| "# '.start()' function starts the virtual display\n", | |
| "Display(visible=0, size=(840, 480)).start();\n", | |
| "\n", | |
| "# Set the random seed for TensorFlow, getting the same results every time we run this cell\n", | |
| "tf.random.set_seed(utils.SEED)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"2\"></a>\n", | |
| "## 2 - Hyperparameters\n", | |
| "\n", | |
| "Run the cell below to set the hyperparameters." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "metadata": { | |
| "deletable": false, | |
| "editable": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "MEMORY_SIZE = 100_000 # size of memory buffer\n", | |
| "GAMMA = 0.995 # discount factor\n", | |
| "ALPHA = 1e-3 # learning rate \n", | |
| "NUM_STEPS_FOR_UPDATE = 4 # perform a learning update every C time steps" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"3\"></a>\n", | |
| "## 3 - The Lunar Lander Environment\n", | |
| "\n", | |
| "In this notebook we will be using [OpenAI's Gym Library](https://www.gymlibrary.dev/). The Gym library provides a wide variety of environments for reinforcement learning. To put it simply, an environment represents a problem or task to be solved. In this notebook, we will try to solve the Lunar Lander environment using reinforcement learning.\n", | |
| "\n", | |
| "The goal of the Lunar Lander environment is to land the lunar lander safely on the landing pad on the surface of the moon. The landing pad is designated by two flag poles and its center is at coordinates `(0,0)` but the lander is also allowed to land outside of the landing pad. The lander starts at the top center of the environment with a random initial force applied to its center of mass and has infinite fuel. The environment is considered solved if you get `200` points. \n", | |
| "\n", | |
| "<br>\n", | |
| "<br>\n", | |
| "<figure>\n", | |
| " <img src = \"images/lunar_lander.gif\" width = 40%>\n", | |
| " <figcaption style = \"text-align: center; font-style: italic\">Fig 1. Lunar Lander Environment.</figcaption>\n", | |
| "</figure>\n", | |
| "\n", | |
| "\n", | |
| "\n", | |
| "<a name=\"3.1\"></a>\n", | |
| "### 3.1 Action Space\n", | |
| "\n", | |
| "The agent has four discrete actions available:\n", | |
| "\n", | |
| "* Do nothing.\n", | |
| "* Fire right engine.\n", | |
| "* Fire main engine.\n", | |
| "* Fire left engine.\n", | |
| "\n", | |
| "Each action has a corresponding numerical value:\n", | |
| "\n", | |
| "```python\n", | |
| "Do nothing = 0\n", | |
| "Fire right engine = 1\n", | |
| "Fire main engine = 2\n", | |
| "Fire left engine = 3\n", | |
| "```\n", | |
| "\n", | |
| "<a name=\"3.2\"></a>\n", | |
| "### 3.2 Observation Space\n", | |
| "\n", | |
| "The agent's observation space consists of a state vector with 8 variables:\n", | |
| "\n", | |
| "* Its $(x,y)$ coordinates. The landing pad is always at coordinates $(0,0)$.\n", | |
| "* Its linear velocities $(\\dot x,\\dot y)$.\n", | |
| "* Its angle $\\theta$.\n", | |
| "* Its angular velocity $\\dot \\theta$.\n", | |
| "* Two booleans, $l$ and $r$, that represent whether each leg is in contact with the ground or not.\n", | |
| "\n", | |
| "<a name=\"3.3\"></a>\n", | |
| "### 3.3 Rewards\n", | |
| "\n", | |
| "After every step, a reward is granted. The total reward of an episode is the sum of the rewards for all the steps within that episode.\n", | |
| "\n", | |
| "For each step, the reward:\n", | |
| "- is increased/decreased the closer/further the lander is to the landing pad.\n", | |
| "- is increased/decreased the slower/faster the lander is moving.\n", | |
| "- is decreased the more the lander is tilted (angle not horizontal).\n", | |
| "- is increased by 10 points for each leg that is in contact with the ground.\n", | |
| "- is decreased by 0.03 points each frame a side engine is firing.\n", | |
| "- is decreased by 0.3 points each frame the main engine is firing.\n", | |
| "\n", | |
| "The episode receives an additional reward of -100 or +100 points for crashing or landing safely respectively.\n", | |
| "\n", | |
| "<a name=\"3.4\"></a>\n", | |
| "### 3.4 Episode Termination\n", | |
| "\n", | |
| "An episode ends (i.e the environment enters a terminal state) if:\n", | |
| "\n", | |
| "* The lunar lander crashes (i.e if the body of the lunar lander comes in contact with the surface of the moon).\n", | |
| "\n", | |
| "* The absolute value of the lander's $x$-coordinate is greater than 1 (i.e. it goes beyond the left or right border)\n", | |
| "\n", | |
| "You can check out the [Open AI Gym documentation](https://www.gymlibrary.dev/environments/box2d/lunar_lander/) for a full description of the environment. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"4\"></a>\n", | |
| "## 4 - Load the Environment\n", | |
| "\n", | |
| "We start by loading the `LunarLander-v2` environment from the `gym` library by using the `.make()` method. `LunarLander-v2` is the latest version of the Lunar Lander environment and you can read about its version history in the [Open AI Gym documentation](https://www.gymlibrary.dev/environments/box2d/lunar_lander/#version-history)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "metadata": { | |
| "deletable": false, | |
| "id": "ILVMYKewfR0n" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Load 'LunarLander-v2' environment from 'gym' library\n", | |
| "# using the '.make()' method\n", | |
| "env = gym.make('LunarLander-v2')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Once we load the environment we use the `.reset()` method to reset the environment to the initial state. The lander starts at the top center of the environment and we can render the first frame of the environment by using the `.render()` method." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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Ur7tttuef/75uKsg6fo5RLM5oKOXqT5nKv96G+xZmXKUoJfyU089dffdd8ddBeWk9yGaqQEdoyz0OeP511uKT5wm5aW8evXquXPnxl0F5SrFhygRk38DkbITp/EH4aRJk/L5/NixY+MuBBiEI0eOtA/M4cOH4y729OTfmUnHidOYg3DBggXLli2Ltwag1BKbmvKvWMr6rEycQfjggw8+/PDDMRYAJFAEqSn/SmrJkiVBEOzZsyfuQgYqtiBsamryKgSGaFCpKf+i9NZbbwVBsGbNmrgLOb0YgrCqqiqfz1922WXR7xqAKLW0tDQ0NLz88stxF9KfqIPwmmuuef/99yPeKQAxOnToUBAEQRAcP3487lr6MCzKndXV1UlBgKy54IILHnnkka6urueee+7yyy+Pu5yeontH+Oyzz955552R7Q6AZFqxYkUQBO+8807chXwroiBct27dtddeG82+AEi+rVu3BkHwxhtvdHR0xFtJyYNw8uTJ+Xz+nHPOKfWOACg7R48ebWhoCIIgxgsvlDYIb7rppjfffLOkuwAgBV588cUgCD744IPod13CIKyvr3/ooYdK9/gApMzq1asbGho++uijHTt2RLbTUgXhW2+9deONN5bowQFIsV27dgVB8Nxzz3V3d0ewu+IHYXV1dT6fv/jii4v+yABkx8mTJ4MgaGhoaG1tLemOihyEc+bMKYsL6gBQLpqamoIgKN0y9GIG4V133fX0008X8QEBoGD9+vVBEKxdu7bobxCLFoSNjY233357sR4NAHpra2srLLco4seHxQnC9evXX3311UV5KAA4rWeeeSYIgqJ8uXSoQTh16tR8Pj9y5MihlwIAg7J8+fKGhobDhw8PZQHikIKwtrb29ddfH8ojAMAQbdmyJQiCZcuWndnlac48CB955JEHHnjgjH8dAIroyJEjheUWg7146RkGYXNz8w033HBmvwsApbN06dIgCGpqagb4By4GHYTjxo3L5/MTJ04cfG0AEJGVK1cGQbBz586PP/64/3sOLgjnzZu3atWqIRQGANHZvn17Q0PDCy+8cPz48R+7zyD+Qv0999wjBQEoI1OmTHn22Wfb29sfffTR8ePH33LLLb3vM9B3hEuXLr311luLWh4AROrVV19taGgYNWrUD68GOqAgbGlpmTlzZskKA4DorFu3LgiCTZs27dmzJ3faIJw+fXo+nx8+fHgktQFARD7//PMgCIIg6C8IFy1a9Morr0RWEwBE70e/LPP4449LQQBSr+93hCtWrLjuuusiLgUAotczCMePH5/P5y+66KJYqgGAiP3ZqdH58+cfOHBACgKQHd8H4X333TfAy7IBQGp8e2r0pZde6nO9PQCkW0Uul9uyZcuVV14ZdyUAEIOKMAzjrgEAYjOIi24DQPoIQgAyTRACkGmCEIBME4QAZJogBCDTBCEAmSYIAcg0QQhApglCADJNEAKQaYIQgEwThABkmiAEINMEIQCZJggByDRBCECmCUIAMk0QApBpghCATBOEAGSaIAQg0wQhAJkmCAHINEEIQKYJQgAyTRACkGmCEIBME4QAZJogBCDTBCEAmSYIAcg0QQhApglCADJNEAKQaYIQgEwThABkmiAEINMEIQCZJggByDRBCECmCUIAMk0QApBpghCATBOEAGSaIAQg0wQhAJkmCAHINEEIQKYJQgAyTRACkGmCEIBME4QAZJogBCDTBCEAmSYIAcg0QQhApglCADJNEAKQaYIQgEwThABkmiAEINP+H4bqlqkM8g9eAAAAAElFTkSuQmCC\n", | |
| "text/plain": [ | |
| "<PIL.Image.Image image mode=RGB size=600x400 at 0x7EB475A9E650>" | |
| ] | |
| }, | |
| "execution_count": 5, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "# 'env.reset()' the environment to the initial state (Top center of environment)\n", | |
| "env.reset()\n", | |
| "\n", | |
| "# 'env.render()' the first frame of the environment from RGB array, and display as pillow Image\n", | |
| "PIL.Image.fromarray(env.render(mode='rgb_array'))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "In order to build our neural network later on we need to know the size of the state vector and the number of valid actions. We can get this information from our environment by using the `.observation_space.shape` and `action_space.n` methods, respectively." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "metadata": { | |
| "deletable": false, | |
| "id": "x3fdqdG4CUu2" | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "State s shape (1D vector): (8,)\n", | |
| "Number of actions (scalar): 4\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# To know the SIZE of the [state s] vector -> (8 elements,_) \n", | |
| "state_size = env.observation_space.shape\n", | |
| "\n", | |
| "# To know the NUMBER of valid actions a -> (4) scalar\n", | |
| "num_actions = env.action_space.n\n", | |
| "\n", | |
| "print('State s shape (1D vector):', state_size)\n", | |
| "print('Number of actions (scalar):', num_actions)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"5\"></a>\n", | |
| "## 5 - Interacting with the Gym Environment\n", | |
| "\n", | |
| "The Gym library implements the standard “agent-environment loop” formalism:\n", | |
| "\n", | |
| "<br>\n", | |
| "<center>\n", | |
| "<video src = \"./videos/rl_formalism.m4v\" width=\"840\" height=\"480\" controls autoplay loop poster=\"./images/rl_formalism.png\"> </video>\n", | |
| "<figcaption style = \"text-align:center; font-style:italic\">Fig 2. Agent-environment Loop Formalism.</figcaption>\n", | |
| "</center>\n", | |
| "<br>\n", | |
| "\n", | |
| "In the standard “agent-environment loop” formalism, an agent interacts with the environment in discrete time steps $t=0,1,2,...$. At each time step $t$, the agent uses a policy $\\pi$ to select an action $A_t$ based on its observation of the environment's state $S_t$. The agent receives a numerical reward $R_t$ and on the next time step, moves to a new state $S_{t+1}$.\n", | |
| "\n", | |
| "<a name=\"5.1\"></a>\n", | |
| "### 5.1 Exploring the Environment's Dynamics\n", | |
| "\n", | |
| "In Open AI's Gym environments, we use the `.step()` method to run a single time step of the environment's dynamics. In the version of `gym` that we are using the `.step()` method accepts an action and returns four values:\n", | |
| "\n", | |
| "* `observation` (**object**): an environment-specific object representing your observation of the environment. In the Lunar Lander environment this corresponds to a numpy array containing the positions and velocities of the lander as described in section [3.2 Observation Space](#3.2).\n", | |
| "\n", | |
| "\n", | |
| "* `reward` (**float**): amount of reward returned as a result of taking the given action. In the Lunar Lander environment this corresponds to a float of type `numpy.float64` as described in section [3.3 Rewards](#3.3).\n", | |
| "\n", | |
| "\n", | |
| "* `done` (**boolean**): When done is `True`, it indicates the episode has terminated and it’s time to reset the environment. \n", | |
| "\n", | |
| "\n", | |
| "* `info` (**dictionary**): diagnostic information useful for debugging. We won't be using this variable in this notebook but it is shown here for completeness.\n", | |
| "\n", | |
| "To begin an episode, we need to reset the environment to an initial state. We do this by using the `.reset()` method. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[x, y, x’, y’, theta, theta’, l, r] =\n", | |
| " [ 0.00191936 1.4223009 0.19439952 0.5058145 -0.00221732 -0.04403437\n", | |
| " 0. 0. ]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# 'env.reset()' the environment and get into initial state (Top center of environment)\n", | |
| "# to begin a new episode, each time.\n", | |
| "# current_state = [x, y, x’, y’, theta, theta’, l, r]\n", | |
| "current_state = env.reset()\n", | |
| "\n", | |
| "print('[x, y, x’, y’, theta, theta’, l, r] =\\n',current_state)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Once the environment is reset, the agent can start taking actions in the environment by using the `.step()` method. Note that the agent can only take one action per time step. \n", | |
| "\n", | |
| "In the cell below you can select different actions and see how the returned values change depending on the action taken. Remember that in this environment the agent has four discrete actions available and we specify them in code by using their corresponding numerical value:\n", | |
| "\n", | |
| "```python\n", | |
| "Do nothing = 0\n", | |
| "Fire right engine = 1\n", | |
| "Fire main engine = 2\n", | |
| "Fire left engine = 3\n", | |
| "```" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<style type=\"text/css\" >\n", | |
| " #T_28da7a48_4c97_11f0_9fc6_0242ac120042 th {\n", | |
| " border: 1px solid grey;\n", | |
| " text-align: center;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042 tbody td {\n", | |
| " border: 1px solid grey;\n", | |
| " text-align: center;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col0 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col1 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col2 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col3 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col4 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col5 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col6 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col7 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col8 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col9 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col10 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col11 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col0 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col1 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col2 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col3 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col4 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col5 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col6 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col7 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col8 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col9 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col10 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col11 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col1 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col2 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col3 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col4 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col5 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col6 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col7 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col8 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col9 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col10 {\n", | |
| " background-color : grey;\n", | |
| " } #T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col11 {\n", | |
| " background-color : grey;\n", | |
| " }</style><table id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042\" ><thead> <tr> <th class=\"blank level0\" ></th> <th class=\"col_heading level0 col0\" ></th> <th class=\"col_heading level0 col1\" colspan=8>State Vector</th> <th class=\"col_heading level0 col9\" colspan=3>Derived from the State Vector (the closer to zero, the better)</th> </tr> <tr> <th class=\"blank level1\" ></th> <th class=\"col_heading level1 col0\" ></th> <th class=\"col_heading level1 col1\" colspan=2>Coordinate</th> <th class=\"col_heading level1 col3\" colspan=2>Velocity</th> <th class=\"col_heading level1 col5\" colspan=2>Tilting</th> <th class=\"col_heading level1 col7\" colspan=2>Ground contact</th> <th class=\"col_heading level1 col9\" >Distance from landing pad</th> <th class=\"col_heading level1 col10\" >Velocity</th> <th class=\"col_heading level1 col11\" >Tilting Angle (absolute value)</th> </tr> <tr> <th class=\"blank level2\" ></th> <th class=\"col_heading level2 col0\" ></th> <th class=\"col_heading level2 col1\" >X (Horizontal)</th> <th class=\"col_heading level2 col2\" >Y (Vertical)</th> <th class=\"col_heading level2 col3\" >X (Horizontal)</th> <th class=\"col_heading level2 col4\" >Y (Vertical)</th> <th class=\"col_heading level2 col5\" >Angle</th> <th class=\"col_heading level2 col6\" >Angular Velocity</th> <th class=\"col_heading level2 col7\" >Left Leg?</th> <th class=\"col_heading level2 col8\" >Right Leg?</th> <th class=\"col_heading level2 col9\" ></th> <th class=\"col_heading level2 col10\" ></th> <th class=\"col_heading level2 col11\" ></th> </tr></thead><tbody>\n", | |
| " <tr>\n", | |
| " <th id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042level0_row0\" class=\"row_heading level0 row0\" >Current State</th>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col0\" class=\"data row0 col0\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col1\" class=\"data row0 col1\" >0.001919</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col2\" class=\"data row0 col2\" >1.422301</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col3\" class=\"data row0 col3\" >0.194400</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col4\" class=\"data row0 col4\" >0.505814</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col5\" class=\"data row0 col5\" >-0.002217</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col6\" class=\"data row0 col6\" >-0.044034</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col7\" class=\"data row0 col7\" >False</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col8\" class=\"data row0 col8\" >False</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col9\" class=\"data row0 col9\" >1.422302</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col10\" class=\"data row0 col10\" >0.541885</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row0_col11\" class=\"data row0 col11\" >0.002217</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042level0_row1\" class=\"row_heading level0 row1\" >Action</th>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col0\" class=\"data row1 col0\" >Do nothing</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col1\" class=\"data row1 col1\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col2\" class=\"data row1 col2\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col3\" class=\"data row1 col3\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col4\" class=\"data row1 col4\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col5\" class=\"data row1 col5\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col6\" class=\"data row1 col6\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col7\" class=\"data row1 col7\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col8\" class=\"data row1 col8\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col9\" class=\"data row1 col9\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col10\" class=\"data row1 col10\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row1_col11\" class=\"data row1 col11\" ></td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042level0_row2\" class=\"row_heading level0 row2\" >Next State</th>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col0\" class=\"data row2 col0\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col1\" class=\"data row2 col1\" >0.003839</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col2\" class=\"data row2 col2\" >1.433103</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col3\" class=\"data row2 col3\" >0.194137</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col4\" class=\"data row2 col4\" >0.480094</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col5\" class=\"data row2 col5\" >-0.004393</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col6\" class=\"data row2 col6\" >-0.043519</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col7\" class=\"data row2 col7\" >False</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col8\" class=\"data row2 col8\" >False</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col9\" class=\"data row2 col9\" >1.433108</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col10\" class=\"data row2 col10\" >0.517860</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row2_col11\" class=\"data row2 col11\" >0.004393</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042level0_row3\" class=\"row_heading level0 row3\" >Reward</th>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col0\" class=\"data row3 col0\" >1.104326</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col1\" class=\"data row3 col1\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col2\" class=\"data row3 col2\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col3\" class=\"data row3 col3\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col4\" class=\"data row3 col4\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col5\" class=\"data row3 col5\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col6\" class=\"data row3 col6\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col7\" class=\"data row3 col7\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col8\" class=\"data row3 col8\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col9\" class=\"data row3 col9\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col10\" class=\"data row3 col10\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row3_col11\" class=\"data row3 col11\" ></td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042level0_row4\" class=\"row_heading level0 row4\" >Episode Terminated</th>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col0\" class=\"data row4 col0\" >False</td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col1\" class=\"data row4 col1\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col2\" class=\"data row4 col2\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col3\" class=\"data row4 col3\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col4\" class=\"data row4 col4\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col5\" class=\"data row4 col5\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col6\" class=\"data row4 col6\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col7\" class=\"data row4 col7\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col8\" class=\"data row4 col8\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col9\" class=\"data row4 col9\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col10\" class=\"data row4 col10\" ></td>\n", | |
| " <td id=\"T_28da7a48_4c97_11f0_9fc6_0242ac120042row4_col11\" class=\"data row4 col11\" ></td>\n", | |
| " </tr>\n", | |
| " </tbody></table>" | |
| ], | |
| "text/plain": [ | |
| "<pandas.io.formats.style.Styler at 0x7eb3d592d210>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "# Select an action -> Do nothing = 0\n", | |
| "action = 0\n", | |
| "\n", | |
| "# Run a single time '.step()' of the environment's dynamics, with the given action a.\n", | |
| "next_state, reward, done, _ = env.step(action)\n", | |
| "\n", | |
| "# Display table with values.\n", | |
| "utils.display_table(current_state, action, next_state, reward, done)\n", | |
| "\n", | |
| "# Replace / Overwrite the previous `current_state` s with the New state s', after the action a is taken.\n", | |
| "current_state = next_state" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "In practice, when we train the agent we use a loop to allow the agent to take many consecutive actions during an episode." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"6\"></a>\n", | |
| "## 6 - Deep Q-Learning\n", | |
| "\n", | |
| "In cases where both the state and action space are discrete we can estimate the action-value function iteratively by using the Bellman equation:\n", | |
| "\n", | |
| "$$\n", | |
| "Q_{i+1}(s,a) = R + \\gamma \\max_{a'}Q_i(s',a')\n", | |
| "$$\n", | |
| "\n", | |
| "This iterative method converges to the optimal action-value function $Q^*(s,a)$ as $i\\to\\infty$. This means that the agent just needs to gradually explore the state-action space and keep updating the estimate of $Q(s,a)$ until it converges to the optimal action-value function $Q^*(s,a)$. However, in cases where the state space is continuous it becomes practically impossible to explore the entire state-action space. Consequently, this also makes it practically impossible to gradually estimate $Q(s,a)$ until it converges to $Q^*(s,a)$.\n", | |
| "\n", | |
| "In the Deep $Q$-Learning, we solve this problem by using a neural network to estimate the action-value function $Q(s,a)\\approx Q^*(s,a)$. We call this neural network a $Q$-Network and it can be trained by adjusting its weights at each iteration to minimize the mean-squared error in the Bellman equation.\n", | |
| "\n", | |
| "Unfortunately, using neural networks in reinforcement learning to estimate action-value functions has proven to be highly unstable. Luckily, there's a couple of techniques that can be employed to avoid instabilities. These techniques consist of using a ***Target Network*** and ***Experience Replay***. We will explore these two techniques in the following sections." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"6.1\"></a>\n", | |
| "### 6.1 Target Network\n", | |
| "\n", | |
| "We can train the $Q$-Network by adjusting it's weights at each iteration to minimize the mean-squared error in the Bellman equation, where the target values are given by:\n", | |
| "\n", | |
| "$$\n", | |
| "y = R + \\gamma \\max_{a'}Q(s',a';w)\n", | |
| "$$\n", | |
| "\n", | |
| "where $w$ are the weights of the $Q$-Network. This means that we are adjusting the weights $w$ at each iteration to minimize the following error:\n", | |
| "\n", | |
| "$$\n", | |
| "\\overbrace{\\underbrace{R + \\gamma \\max_{a'}Q(s',a'; w)}_{\\rm {y~target}} - Q(s,a;w)}^{\\rm {Error}}\n", | |
| "$$\n", | |
| "\n", | |
| "Notice that this forms a problem because the $y$ target is changing on every iteration. Having a constantly moving target can lead to oscillations and instabilities. To avoid this, we can create\n", | |
| "a separate neural network for generating the $y$ targets. We call this separate neural network the **target $\\hat Q$-Network** and it will have the same architecture as the original $Q$-Network. By using the target $\\hat Q$-Network, the above error becomes:\n", | |
| "\n", | |
| "$$\n", | |
| "\\overbrace{\\underbrace{R + \\gamma \\max_{a'}\\hat{Q}(s',a'; w^-)}_{\\rm {y~target}} - Q(s,a;w)}^{\\rm {Error}}\n", | |
| "$$\n", | |
| "\n", | |
| "where $w^-$ and $w$ are the weights of the target $\\hat Q$-Network and $Q$-Network, respectively.\n", | |
| "\n", | |
| "In practice, we will use the following algorithm: every $C$ time steps we will use the $\\hat Q$-Network to generate the $y$ targets and update the weights of the target $\\hat Q$-Network using the weights of the $Q$-Network. We will update the weights $w^-$ of the the target $\\hat Q$-Network using a **soft update**. This means that we will update the weights $w^-$ using the following rule:\n", | |
| " \n", | |
| "$$\n", | |
| "w^-\\leftarrow \\tau w + (1 - \\tau) w^-\n", | |
| "$$\n", | |
| "\n", | |
| "where $\\tau\\ll 1$. By using the soft update, we are ensuring that the target values, $y$, change slowly, which greatly improves the stability of our learning algorithm." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"ex01\"></a>\n", | |
| "### Exercise 1\n", | |
| "\n", | |
| "In this exercise you will create the $Q$ and target $\\hat Q$ networks and set the optimizer. Remember that the Deep $Q$-Network (DQN) is a neural network that approximates the action-value function $Q(s,a)\\approx Q^*(s,a)$. It does this by learning how to map states to $Q$ values.\n", | |
| "\n", | |
| "To solve the Lunar Lander environment, we are going to employ a DQN with the following architecture:\n", | |
| "\n", | |
| "* An `Input` layer that takes `state_size` 'state_size' of s vector = (8 elements/cols, _) as input.\n", | |
| "\n", | |
| "* A `Dense` layer as HL1 with `64` units / NEURONS and a `ReLU` activation function.\n", | |
| "\n", | |
| "* A `Dense` layer as HL2 with `64` units / NEURONS and a `ReLU` activation function.\n", | |
| "\n", | |
| "* A `Dense` layer as OL with `num_actions` = 4 units / NEURONS / outputs and a `linear` activation function. This will be the output layer (OL) of our Network.\n", | |
| "\n", | |
| "\n", | |
| "In the cell below you should create the $Q$-Network and the target $\\hat Q$-Network using the model architecture described above. Remember that BOTH the $Q$-Network and the target $\\hat Q$-Network HAVE the SAME ARCHITECTURE.\n", | |
| "\n", | |
| "Lastly, you should set `Adam` as the OPTIMIZER (GD) with a learning rate (α) equal to `ALPHA`. Recall that `ALPHA = 0.001` was defined in the [Hyperparameters](#2) section. We should note that for this exercise you should use the already imported packages:\n", | |
| "```python\n", | |
| "from tensorflow.keras.layers import Dense, Input\n", | |
| "from tensorflow.keras.optimizers import Adam\n", | |
| "```" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 9, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# EXERCISE 1\n", | |
| "# UNQ_C1\n", | |
| "# GRADED CELL\n", | |
| "\n", | |
| "# Create the Q-Network NN model\n", | |
| "q_network = Sequential([\n", | |
| " \n", | |
| " ### START CODE HERE ###\n", | |
| " \n", | |
| " Input(shape = state_size), # Input layer -> state_size s = (8,_) 1D vector\n", | |
| " # s = [x,y,x',y',theta,theta',r,l]\n", | |
| " Dense(units=64, activation='relu'), # HL1 -> 64 Units / Neurons with 'ReLU' activation function \n", | |
| " # g(z) = 0 (z < 0) and g(z) = z (z >= 0) \n", | |
| " Dense(units=64, activation='relu'), # HL2 -> 64 Units / Neurons with 'ReLU' activation function \n", | |
| " # g(z) = 0 (z < 0) and g(z) = z (z >= 0)\n", | |
| " Dense(units=num_actions, activation='linear'), # OL -> num_actions a = 4 Units / Neurons with 'linear' \n", | |
| " # g(z) = z activation function\n", | |
| " ### END CODE HERE ### \n", | |
| " ])\n", | |
| "\n", | |
| "# Create the target Q^-Network NN model (The SAME architecture as the previous NN model)\n", | |
| "target_q_network = Sequential([\n", | |
| " \n", | |
| " ### START CODE HERE ### \n", | |
| " \n", | |
| " Input(shape = state_size), # Input layer -> state_size s = (8,_) 1D vector\n", | |
| " # s = [x,y,x',y',theta,theta',r,l]\n", | |
| " Dense(units=64, activation='relu'), # HL1 -> 64 Units / Neurons with 'ReLU' activation function \n", | |
| " # g(z) = 0 (z < 0) and g(z) = z (z >= 0) \n", | |
| " Dense(units=64, activation='relu'), # HL2 -> 64 Units / Neurons with 'ReLU' activation function \n", | |
| " # g(z) = 0 (z < 0) and g(z) = z (z >= 0)\n", | |
| " Dense(units=num_actions, activation='linear'), # OL -> num_actions a = 4 Units / Neurons with 'linear' \n", | |
| " # g(z) = z activation function\n", | |
| " ### END CODE HERE ###\n", | |
| " ])\n", | |
| "\n", | |
| "# Create OPTIMIZER (GD) = Adam(alpha = 0.001) function\n", | |
| "### START CODE HERE ###\n", | |
| "\n", | |
| "optimizer = Adam(learning_rate = ALPHA) # 𝑤− = alpha 𝑤 + (1−alpha)𝑤−\n", | |
| "\n", | |
| "### END CODE HERE ###" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 10, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "\u001b[92mAll tests passed!\n", | |
| "\u001b[92mAll tests passed!\n", | |
| "\u001b[92mAll tests passed!\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Import ALL (*) modules from ‘public_tests’ for UNIT TEST\n", | |
| "from public_tests import *\n", | |
| "\n", | |
| "# TEST Q NN model\n", | |
| "test_network(q_network)\n", | |
| "\n", | |
| "# TEST target Q^ NN model\n", | |
| "test_network(target_q_network)\n", | |
| "\n", | |
| "# TEST 'Adam()' OPTIMIZER (GD)\n", | |
| "test_optimizer(optimizer, ALPHA) " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<details>\n", | |
| " <summary><font size=\"3\" color=\"darkgreen\"><b>Click for hints</b></font></summary>\n", | |
| " \n", | |
| "```python\n", | |
| "# Create the Q-Network\n", | |
| "q_network = Sequential([\n", | |
| " Input(shape=state_size), \n", | |
| " Dense(units=64, activation='relu'), \n", | |
| " Dense(units=64, activation='relu'), \n", | |
| " Dense(units=num_actions, activation='linear'),\n", | |
| " ])\n", | |
| "\n", | |
| "# Create the target Q^-Network\n", | |
| "target_q_network = Sequential([\n", | |
| " Input(shape=state_size), \n", | |
| " Dense(units=64, activation='relu'), \n", | |
| " Dense(units=64, activation='relu'), \n", | |
| " Dense(units=num_actions, activation='linear'), \n", | |
| " ])\n", | |
| "\n", | |
| "optimizer = Adam(learning_rate=ALPHA) \n", | |
| "``` " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"6.2\"></a>\n", | |
| "### 6.2 Experience Replay\n", | |
| "\n", | |
| "When an agent interacts with the environment, the states, actions, and rewards the agent experiences are sequential by nature. If the agent tries to learn from these consecutive experiences it can run into problems due to the strong correlations between them. To avoid this, we employ a technique known as **Experience Replay** to generate uncorrelated experiences for training our agent. Experience replay consists of storing the agent's experiences (i.e the states, actions, and rewards the agent receives) in a memory buffer and then sampling a random mini-batch of experiences from the buffer to do the learning. The experience tuples $(S_t, A_t, R_t, S_{t+1})$ will be added to the memory buffer at each time step as the agent interacts with the environment.\n", | |
| "\n", | |
| "For convenience, we will STORE each experience with 'namedtuple()' function." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 11, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Store each experience / tuple with 'namedtuple()' function\n", | |
| "experience = namedtuple(\"Experience\", field_names=[\"state\", \"action\", \"reward\", \"next_state\", \"done\"])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "By using experience replay we avoid problematic correlations, oscillations and instabilities. In addition, experience replay also allows the agent to potentially use the same experience in multiple weight updates, which increases data efficiency." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"7\"></a>\n", | |
| "## 7 - Deep Q-Learning Algorithm with Experience Replay\n", | |
| "\n", | |
| "Now that we know all the techniques that we are going to use, we can put them together to arrive at the Deep Q-Learning Algorithm With Experience Replay.\n", | |
| "<br>\n", | |
| "<br>\n", | |
| "<figure>\n", | |
| " <img src = \"images/deep_q_algorithm.png\" width = 90% style = \"border: thin silver solid; padding: 0px\">\n", | |
| " <figcaption style = \"text-align: center; font-style: italic\">Fig 3. Deep Q-Learning with Experience Replay.</figcaption>\n", | |
| "</figure>" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"ex02\"></a>\n", | |
| "### Exercise 2\n", | |
| "\n", | |
| "In this exercise you will implement line ***12*** of the algorithm outlined in *Fig 3* above and you will also compute the loss between the $y$ targets and the $Q(s,a)$ values. In the cell below, complete the `compute_loss` function by setting the $y$ targets equal to:\n", | |
| "\n", | |
| "$$\n", | |
| "\\begin{equation}\n", | |
| " y_j =\n", | |
| " \\begin{cases}\n", | |
| " R_j & \\text{if episode terminates at step } j+1\\\\\n", | |
| " R_j + \\gamma \\max_{a'}\\hat{Q}(s_{j+1},a') & \\text{otherwise}\\\\\n", | |
| " \\end{cases} \n", | |
| "\\end{equation}\n", | |
| "$$\n", | |
| "\n", | |
| "Here are a couple of things to note:\n", | |
| "\n", | |
| "* The `compute_loss` function takes in a mini-batch of experience tuples. This mini-batch of experience tuples is unpacked to extract the `states s`, `actions a`, `rewards R(s)`, `next_states s'`, and `done_vals ('True' when episode ends or 'False' otherwise)`. You should keep in mind that these variables are *TensorFlow Tensors* whose size will depend on the mini-batch SIZE. For example, if the mini-batch SIZE is `(64, )` then both `rewards R(s)` and `done_vals 'True' or 'False'` will be TensorFlow Tensors with `(64, )` elements.\n", | |
| "\n", | |
| "\n", | |
| "* Using `if/else` statements to set the $y$ targets will not work when the variables are tensors with many elements. However, notice that you can use the `done_vals` to implement the above in a single line of code. To do this, recall that the `done` variable is a Boolean variable that takes the value `True` when an episode terminates at step $j+1$ and it is `False` otherwise. Taking into account that a Boolean value of `True` has the numerical value of `1` and a Boolean value of `False` has the numerical value of `0`, you can use the factor `(1 - done_vals)` to implement the above in a single line of code. Here's a hint: notice that `(1 - done_vals) = 0` when `done_vals = True = 1` and a value of `(1 - done_vals) = 1` when `done_vals = False = 0`. \n", | |
| "\n", | |
| "Lastly, compute the `loss = MSE(y_pred, y_true)` by calculating the Mean-Squared Error (`MSE`) between the `y_targets` and the `q_values`. To calculate the mean-squared error you should use the already imported package `MSE()`:\n", | |
| "```python\n", | |
| "from tensorflow.keras.losses import MSE\n", | |
| "```" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 12, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# EXERCISE 2\n", | |
| "# UNQ_C2\n", | |
| "# GRADED FUNCTION: calculate_loss\n", | |
| "\n", | |
| "def compute_loss(experiences, gamma, q_network, target_q_network):\n", | |
| " \"\"\" \n", | |
| " Calculates the loss.\n", | |
| " \n", | |
| " Args:\n", | |
| " experiences: (tuple) tuple of [\"state\", \"action\", \"reward\", \"next_state\", \"done\"] namedtuples\n", | |
| " gamma: (float) The discount factor.\n", | |
| " q_network: (tf.keras.Sequential) Keras model for predicting the q_values\n", | |
| " target_q_network: (tf.keras.Sequential) Keras model for predicting the targets\n", | |
| " \n", | |
| " Returns:\n", | |
| " loss: (TensorFlow Tensor(shape=(0,), dtype=int32)) the Mean-Squared Error between\n", | |
| " the y targets and the Q(s,a) values.\n", | |
| " \"\"\"\n", | |
| "\n", | |
| " # Unpack the mini-batch of 'experiences' tuples -> ( [[s]*64],[[a]*64],[[R]*64],[[s']*64],[[done]*64] )\n", | |
| " # Each tuple variable has tensors with 64 elements\n", | |
| " states, actions, rewards, next_states, done_vals = experiences\n", | |
| " \n", | |
| " # Compute max Q^(s,a) along last axis(-1) -> ALL col / elements -> rows -> [Qnothing, Qleft, Qmain, Qright]\n", | |
| " max_qsa = tf.reduce_max(target_q_network(next_states), axis=-1)\n", | |
| " \n", | |
| " ### START CODE HERE ###\n", | |
| " \n", | |
| " # Set y = R if episode terminates -> done_vals = True = 1 \n", | |
| " # -> R + γ max Q^(s,a)[1-done] = R + γ max Q^(s,a)[1-1] = R + 0\n", | |
| " \n", | |
| " # otherwise set y = R + γ max Q^(s,a) -> done_vals = False = 0\n", | |
| " # -> R + γ max Q^(s,a)[1-done] = R + γ max Q^(s,a)[1-0] = R + γ max Q^(s,a)\n", | |
| " \n", | |
| " # (64,) * 4mini-batches \n", | |
| " y_targets = rewards + ( gamma * max_qsa * (1 - done_vals) )\n", | |
| " # (64,) * 4mini-batches (64,) * 4mini-batches\n", | |
| " \n", | |
| " print('y_targets mini-batch:',y_targets.shape)\n", | |
| " \n", | |
| " ### END CODE HERE ###\n", | |
| " \n", | |
| " # Get the original 'q_values' (64, 4)\n", | |
| " q_values = q_network(states)\n", | |
| " print('q_values original size:', q_values.shape)\n", | |
| " \n", | |
| " # And reshape 'q_values' (64, 4) -> (64, ) * 4 mini-batches \n", | |
| " # to match 'y_targets' (64, ) * 4-mini-batches\n", | |
| " # col0 col1 col2 col3\n", | |
| " # Q = [row0 [Q_action0, Q_action1, Q_action2, Q_action3],\n", | |
| " # row1 [Q_action0, Q_action1, Q_action2, Q_action3],\n", | |
| " # ...\n", | |
| " # row63[Q_action0, Q_action1, Q_action2, Q_action3] ]\n", | |
| " \n", | |
| " # select Q position = [[row 0, col_action a],\n", | |
| " # [row 1, col_action a],\n", | |
| " # ...\n", | |
| " # [row 63,col_action a]]\n", | |
| " \n", | |
| " # col_action a = 0 -> Do nothing\n", | |
| " # col_action a = 1 -> Left\n", | |
| " # col_action a = 2 -> Main\n", | |
| " # col_action a = 3 -> Right\n", | |
| " \n", | |
| " # Select row indices\n", | |
| " row_indices = tf.range(q_values.shape[0])\n", | |
| " \n", | |
| " # Select col_action indices\n", | |
| " col_indices = tf.cast(actions, tf.int32)\n", | |
| " \n", | |
| " # Pile coordinates [row_indices, col_indices] as COLUMNS (axis = 1)\n", | |
| " row_col_indices = tf.stack([row_indices, col_indices], axis=1)\n", | |
| " \n", | |
| " # Select 64 Q values at [row, col_action] positions/indices\n", | |
| " q_values = tf.gather_nd(q_values, row_col_indices)\n", | |
| " \n", | |
| " ## Example of [row, col_action] stack -> \n", | |
| " ## print(tf.stack([tf.range(3), tf.cast([0.0, 0.1, 0.2], tf.int32)], axis=1))\n", | |
| " print('q_values mini - batch:',q_values.shape)\n", | |
| " \n", | |
| " ### START CODE HERE ###\n", | |
| " \n", | |
| " # Compute the loss = MSE = [1 / m_examples] SUM i=1 -> m ( y^(i) - y(i) )^2 \n", | |
| " # -> [1 / m] SUM i=1 -> m ( y_targets(i) - q_values(i) )^2\n", | |
| " # y_pred y_true\n", | |
| " loss = MSE(y_targets, q_values) \n", | |
| " \n", | |
| " print ('loss / MSE:', loss, '\\n')\n", | |
| " ### END CODE HERE ### \n", | |
| " \n", | |
| " return loss" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 13, | |
| "metadata": { | |
| "deletable": false, | |
| "editable": false | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "y_targets mini-batch: (64,)\n", | |
| "q_values original size: (64, 4)\n", | |
| "q_values mini - batch: (64,)\n", | |
| "loss / MSE: tf.Tensor(0.6991737, shape=(), dtype=float32) \n", | |
| "\n", | |
| "y_targets mini-batch: (64,)\n", | |
| "q_values original size: (64, 4)\n", | |
| "q_values mini - batch: (64,)\n", | |
| "loss / MSE: tf.Tensor(0.34327018, shape=(), dtype=float32) \n", | |
| "\n", | |
| "y_targets mini-batch: (64,)\n", | |
| "q_values original size: (64, 4)\n", | |
| "q_values mini - batch: (64,)\n", | |
| "loss / MSE: tf.Tensor(0.0, shape=(), dtype=float32) \n", | |
| "\n", | |
| "y_targets mini-batch: (64,)\n", | |
| "q_values original size: (64, 4)\n", | |
| "q_values mini - batch: (64,)\n", | |
| "loss / MSE: tf.Tensor(1.0, shape=(), dtype=float32) \n", | |
| "\n", | |
| "\u001b[92mAll tests passed!\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# UNIT TEST \n", | |
| "test_compute_loss(compute_loss)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<details>\n", | |
| " <summary><font size=\"3\" color=\"darkgreen\"><b>Click for hints</b></font></summary>\n", | |
| " \n", | |
| "```python\n", | |
| "def compute_loss(experiences, gamma, q_network, target_q_network):\n", | |
| " \"\"\" \n", | |
| " Calculates the loss.\n", | |
| " \n", | |
| " Args:\n", | |
| " experiences: (tuple) tuple of [\"state\", \"action\", \"reward\", \"next_state\", \"done\"] namedtuples\n", | |
| " gamma: (float) The discount factor.\n", | |
| " q_network: (tf.keras.Sequential) Keras model for predicting the q_values\n", | |
| " target_q_network: (tf.keras.Sequential) Keras model for predicting the targets\n", | |
| " \n", | |
| " Returns:\n", | |
| " loss: (TensorFlow Tensor(shape=(0,), dtype=int32)) the Mean-Squared Error between\n", | |
| " the y targets and the Q(s,a) values.\n", | |
| " \"\"\"\n", | |
| "\n", | |
| " \n", | |
| " # Unpack the mini-batch of experience tuples\n", | |
| " states, actions, rewards, next_states, done_vals = experiences\n", | |
| " \n", | |
| " # Compute max Q^(s,a)\n", | |
| " max_qsa = tf.reduce_max(target_q_network(next_states), axis=-1)\n", | |
| " \n", | |
| " # Set y = R if episode terminates, otherwise set y = R + γ max Q^(s,a).\n", | |
| " y_targets = rewards + (gamma * max_qsa * (1 - done_vals))\n", | |
| " \n", | |
| " # Get the q_values\n", | |
| " q_values = q_network(states)\n", | |
| " q_values = tf.gather_nd(q_values, tf.stack([tf.range(q_values.shape[0]),\n", | |
| " tf.cast(actions, tf.int32)], axis=1))\n", | |
| " \n", | |
| " # Calculate the loss\n", | |
| " loss = MSE(y_targets, q_values)\n", | |
| " \n", | |
| " return loss\n", | |
| "\n", | |
| "``` \n", | |
| " " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"8\"></a>\n", | |
| "## 8 - Update the Network Weights\n", | |
| "\n", | |
| "We will use the `agent_learn` function below to implement lines ***12 -14*** of the algorithm outlined in [Fig 3](#7). The `agent_learn` function will UPDATE the weights W, B of the $Q$ and target $\\hat Q$ networks using a CUSTOM TRAINING LOOP. Because we are using a CUSTOM TRAINING LOOP we need to retrieve the Gradients via a `tf.GradientTape` instance, and then call `optimizer.apply_gradients()` to update the weights of our $Q$-Network, performing `AUTOMATIC DIFFERENTIATION of input tensor variables`. Note that we are also using the `@tf.function` decorator to INCREASE PERFORMANCE. Without this decorator our training will take TWICE as LONG. If you would like to know more about how to increase performance with `@tf.function` take a look at the [TensorFlow documentation](https://www.tensorflow.org/guide/function).\n", | |
| "\n", | |
| "The last line of this function updates the weights of the target $\\hat Q$-Network using a [soft update](#6.1). If you want to know how this is implemented in code we encourage you to take a look at the `utils.update_target_network` function in the `utils` module." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 14, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# '@tf.function' decorator INCREASES PERFORMANCE. \n", | |
| "# Without this decorator our training will take TWICE as LONG.\n", | |
| "@tf.function\n", | |
| "\n", | |
| "def agent_learn(experiences, gamma):\n", | |
| " \"\"\"\n", | |
| " Updates the weights of the Q networks.\n", | |
| " \n", | |
| " Args:\n", | |
| " experiences: (tuple) tuple of [\"state\", \"action\", \"reward\", \"next_state\", \"done\"] namedtuples\n", | |
| " gamma: (float) The discount factor.\n", | |
| " \n", | |
| " \"\"\"\n", | |
| " # Use TensorFlow’s GradientTape\n", | |
| " # to record the operations used to compute the cost / loss\n", | |
| " # Record steps needed to compute COST J, enabling auto-differentiation (Line 12)\n", | |
| " with tf.GradientTape() as tape:\n", | |
| " \n", | |
| " # Compute the COST / loss function J, with 'compute_loss()' function (Line 12)\n", | |
| " loss = compute_loss(experiences, gamma, q_network, target_q_network)\n", | |
| "\n", | |
| " # Get the Gradients/Derivatives of the loss/COST J with respect to the weights W -> dJ / dW and B -> dJ / dB (Line 13)\n", | |
| " gradients = tape.gradient(loss, q_network.trainable_variables)\n", | |
| " \n", | |
| " # UPDATE the NEW weights W' <- W and B' <- B of the q_network, \n", | |
| " # using previous computed Gradients -> dJ / dW and B -> dJ / dB\n", | |
| " # gradients = [dJ/dW, dJ/dB] q_network.trainable_variables = parameters = [ [[W]](8,64), [[B]](64,) ] -> \n", | |
| " # zip(grads,parameters) = [ ( [[dJ/dW]](8,64), [[W]](8,64) ), ( [[dJ/dB]](64,), [[B]](64,) ) ]. \n", | |
| " # Combines each computed gradient/derivative in 'gradients' with its 'parameter' in a tuple (_,_), \n", | |
| " # and put ALL tuples in a list [(_,_), (_,_)], to get ready, to be UPDATED and MINIMIZED each tuple at a time, \n", | |
| " # via GD, by the picked 'optimizer'. \n", | |
| " # Run one (1) step / update of gradient descent (GD) by UPDATING / MINIMIZING\n", | |
| " # the value of the TF variables / changeable parameters W,B to also MINIMIZE the COST function J. (Line 13)\n", | |
| " optimizer.apply_gradients(zip(gradients, q_network.trainable_variables))\n", | |
| "\n", | |
| " # UPDATE the weights W' <- W and B' <- B of target q_network (Line 14)\n", | |
| " utils.update_target_network(q_network, target_q_network)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"9\"></a>\n", | |
| "## 9 - Train the Agent\n", | |
| "\n", | |
| "We are now ready to train our agent to solve the Lunar Lander environment. In the cell below we will implement the algorithm in [Fig 3](#7) line by line (please note that we have included the same algorithm below for easy reference. This will prevent you from scrolling up and down the notebook):\n", | |
| "\n", | |
| "* **Line 1**: We initialize the `memory_buffer` with a capacity of $N =$ `MEMORY_SIZE`. Notice that we are using a `deque` as the data structure for our `memory_buffer`.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 2**: We skip this line since we already initialized the `q_network` in [Exercise 1](#ex01).\n", | |
| "\n", | |
| "\n", | |
| "* **Line 3**: We initialize the `target_q_network` by setting its weights to be equal to those of the `q_network`.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 4**: We start the outer loop. Notice that we have set $M =$ `num_episodes = 2000 iterations / episodes`. This number is reasonable because the agent should be able to solve the Lunar Lander environment in less than `2000 iterations / episodes` using this notebook's default parameters.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 5**: We use the `.reset()` method to reset the environment to the initial state (Top Center of the environment) and get the `initial state s = (s, a, R(s), s’, done)`.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 6**: We start the inner loop. Notice that we have set $T =$ `max_num_timesteps = 1000 max time steps t, each episode / iteration i`. This means that the episode will AUTOMATICALLY TERMINATE if the episode hasn't terminated after `1000` time steps t.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 7**: The agent observes the current `state s` and chooses an `action a` using an p = (1 - $\\epsilon$-greedy) policy. Our agent starts out using a value of $\\epsilon =$ `epsilon = 1` which yields an p = (1 - $\\epsilon$-greedy) policy that is equivalent to the equiprobable random policy. This means that at the beginning of our TRAINING, `𝜖 = epsilon = 1`, so `p = (1 - 𝜖-greedy) = 0`(0% of time, we’ll choose to MAXIMIZE the obtained Q(s, a) value, so we’ll pick 100% of time -> ‘Exploration’) so the agent is going to choose SMALL Q(s, a) values at the state s, so the agent is just going to take RANDOM actions a regardless of the observed `state s`. As TRAINING progresses, we will DECREASE the value of $\\epsilon$ SLOWLY towards a `minimum` value using a given $\\epsilon$-decay rate. We want this minimum value to be CLOSE to zero '0' because a value of $\\epsilon = 0$ will yield an p = (1 - $\\epsilon$-greedy) = 1 policy that is equivalent to the greedy policy. This means that towards the END of TRAINING, the agent will lean towards selecting 100% of the times, the `action a` that it believes (based on its past experiences) will MAXIMIZE $Q(s,a)$ at `state s`. We will set the MINIMUM $\\epsilon$ =`0.01` and (not exactly 0), p = (1 - $\\epsilon$-greedy) = 0.99 (99% of time we will PICK to MAXIMIZE the obtained Q(s, a) value, and 1% of time we will PICK to KEEP a LITTLE BIT of ’Exploration’ during TRAINING. If you want to know how this is implemented in code we encourage you to take a look at the `utils.get_action()` function in the `utils` module.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 8**: We use the `env.step()` method to take the given `action a` in the environment and get the `reward R(s)` and the `next_state s'`. \n", | |
| "\n", | |
| "\n", | |
| "* **Line 9**: We store the `experience(state, action, reward, next_state, done)` tuple in our `memory_buffer`. Notice that we also store the `done (True / False)` variable so that we can keep track of when an episode terminates (`done = True`). This allowed us to set the $y$ targets in [Exercise 2](#ex02).\n", | |
| "\n", | |
| "\n", | |
| "* **Line 10**: We check if the conditions are met to perform a `learning update`. We do this by using our custom `utils.check_update_conditions()` function. This function checks if $C =$ `NUM_STEPS_FOR_UPDATE = 4` time steps t have occurred and if our `memory_buffer` list [ ] has enough ‘experience’ tuples `[ experience1, experience2, ... , experience64, ... ] = [ (s,a,R,s',done)1, (s,a,R,s',done)2, ... , (s,a,R,s',done)64, ... ]` to FILL a `mini-batch`. For example, if the mini-batch size is `64`, then our `memory_buffer` should have `MORE THAN 64 'experience' tuples to be SAMPLED RANDOMLY`, in order to pass the latter condition. If the conditions are met, then the `utils.check_update_conditions()` function will return a BOOLEAN value of `True`, otherwise it will return a BOOLEAN value of `False`.\n", | |
| "\n", | |
| "\n", | |
| "* **Lines 11 - 14**: If the `update = True` then we perform a learning UPDATE. The learning UPDATE consists of `SAMPLING a RANDOM mini-batch of 'experience' tuples` from our `memory_buffer = [ experience1, experience2, ... , experience64, ... ] = [ (s,a,R,s',done)1, (s,a,R,s',done)2, ... , (s,a,R,s',done)64, ... ]` (Line 11), setting the **$y$ targets = Q^(s, a)** (Line 12), performing **Gradient Descent -> 'Adam' optimizer** (Line 13), and **UPDATING the weights W,B** (Line 14) of the Q-network and target Q^-network. We will use the `agent_learn()` function we defined in the previous [Section 8](#8) to perform the latter 3.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 15**: At the `end of each time step t iteration (t = 0, 1, ... ,999) of the inner loop`, we'll **OVERWRITE / UPDATE or SET** the **NEW** `next_state s'` as our **actual** `state s` so that the inner loop can **START AGAIN** at next iteration, from this `NEW state s = s'`. We also **ADD** the previous `‘total_points’ counter of ‘rewards’` with a `NEW ‘reward’`. In addition, we **check if the episode has reached a terminal state** (i.e we check if `done = True`). `If a terminal state HAS BEEN REACHED, then we 'break' out of the inner loop`.\n", | |
| "\n", | |
| "\n", | |
| "* **Line 16**: At the **end** of `each iteration (i = 0, 1, 2, ... , 1999) of the outer loop`, we `append ‘total_points’ counter of 'rewards’ (updated value), at 'total_point_history' list [ ]`, then `select the LAST num_p_av = 100 UPDATED 'reward’ points, at 'total_point_history' list [ ]`, and `get the ‘mean’ of these 100 points`. Finally `UPDATE the value of $\\epsilon$, returning the 'MAX' value between 'E_MIN = 0.01' and a ‘DECREASED epsilon’ value (E_DECAY * ϵ epsilon) = (0.995 * ϵ epsilon)`, and check if the 'environment' has been solved. We consider that the `'environment' has been SOLVED if the agent AT LEAST receives an average reward ‘av_latest_points’ ≥ 200 points in the last `100` episodes / i-th iterations`. If the `'environment' HAS NOT BEEN solved we continue the outer loop and` **start** `a NEW episode / i-th iteration`.\n", | |
| "\n", | |
| "Finally, we wanted to note that we have **included some extra variables to keep track** of the `total number of points (AVG rewards) the agent received in each episode/i-th iter`. This will help us **determine if the agent has SOLVED** the 'environment' and it will also allow us to `see how our agent performed during training`. We also use the `‘time.time()’` module to measure `HOW LONG` the training code/cell takes **(Execution_time = end - start)**. \n", | |
| "\n", | |
| "<br>\n", | |
| "<br>\n", | |
| "<figure>\n", | |
| " <img src = \"images/deep_q_algorithm.png\" width = 90% style = \"border: thin silver solid; padding: 0px\">\n", | |
| " <figcaption style = \"text-align: center; font-style: italic\">Fig 4. Deep Q-Learning with Experience Replay.</figcaption>\n", | |
| "</figure>\n", | |
| "<br>\n", | |
| "\n", | |
| "**Note:** With this notebook's default parameters, the following cell takes between 10 to 15 minutes to run. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 15, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "y_targets mini-batch: (64,)\n", | |
| "q_values original size: (64, 4)\n", | |
| "q_values mini - batch: (64,)\n", | |
| "loss / MSE: Tensor(\"Mean:0\", shape=(), dtype=float32) \n", | |
| "\n", | |
| "y_targets mini-batch: (64,)\n", | |
| "q_values original size: (64, 4)\n", | |
| "q_values mini - batch: (64,)\n", | |
| "loss / MSE: Tensor(\"Mean:0\", shape=(), dtype=float32) \n", | |
| "\n", | |
| "Episode 100 | Total point AVG 'reward' of the last 100 iters/episodes: -150.85\n", | |
| "Episode 200 | Total point AVG 'reward' of the last 100 iters/episodes: -106.11\n", | |
| "Episode 300 | Total point AVG 'reward' of the last 100 iters/episodes: -77.256\n", | |
| "Episode 400 | Total point AVG 'reward' of the last 100 iters/episodes: -25.01\n", | |
| "Episode 500 | Total point AVG 'reward' of the last 100 iters/episodes: 159.91\n", | |
| "Episode 534 | Total point AVG 'reward' of the last 100 iters/episodes: 201.37\n", | |
| "\n", | |
| "Environment solved in 534 episodes!\n", | |
| "\n", | |
| "Total Runtime: 734.99 s (12.25 min)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Check the execution time, measuring time taken for\n", | |
| "# a code segment by recording 'start' and 'end' times\n", | |
| "# execution time = end time - start time\n", | |
| "start = time.time()\n", | |
| "\n", | |
| "# i-th iterations / episodes i=[0,1,2,...,1999] at outer loop of Lunar lander environment (line 3)\n", | |
| "num_episodes = 2000\n", | |
| "\n", | |
| "# Max Time steps t=[0,1,2,...,999] transcurred at inner loop, each episode/iteration i. (Line 6)\n", | |
| "max_num_timesteps = 1000\n", | |
| "\n", | |
| "# Initialize empty [] list to store Total updated rewards (1000 step times t), per iteration i\n", | |
| "total_point_history = []\n", | |
| "\n", | |
| "num_p_av = 100 # number of the LAST total points to use for averaging -> '100'\n", | |
| "epsilon = 1.0 # initial ε epsilon value for ε-greedy policy\n", | |
| "\n", | |
| "# Create a memory buffer D with capacity N = MEMORY_SIZE = 100_000. Generally represents an integer number,\n", | |
| "# in our case N = 100,000. \"_\" is used just for legibility of Large numbers in Python\n", | |
| "# 'Deque' is a list-like data structure -> [], that allows elements to be added and removed\n", | |
| "# from both ends /extremos/ efficiently. (Line 1)\n", | |
| "memory_buffer = deque(maxlen=MEMORY_SIZE)\n", | |
| "\n", | |
| "# Exercise 1 (Line 2)\n", | |
| "\n", | |
| "# Set the target network weights equal to the Q-Network weights (line 3)\n", | |
| "target_q_network.set_weights(q_network.get_weights())\n", | |
| "\n", | |
| "# Start outer loop with M = 2000 Iters / episodes, to solve Lunar Lander environment\n", | |
| "# during these episodes/iters, using notebook's default parameters\n", | |
| "# i = 0, 1, 2, ... , 1999 iters / episodes. (Line 4)\n", | |
| "for i in range(num_episodes):\n", | |
| " \n", | |
| " # Reset the environment to the initial state (Top center of the environment)\n", | |
| " # and get the initial state vector s = [x, y, x’, y’, theta, theta’, l, r] (Line 5)\n", | |
| " state = env.reset()\n", | |
| " \n", | |
| " # Initialize total 'rewards' counter as '0'\n", | |
| " total_points = 0\n", | |
| " \n", | |
| " # Start inner loop which, after T = 1000 time steps t transcurred, each iteration i,\n", | |
| " # and episode i-th hasn't terminated, it will automatically terminate.\n", | |
| " # t = 0, 1, 2, ... , 999 time steps t, per iteration/episode i. (Line 6)\n", | |
| " for t in range(max_num_timesteps):\n", | |
| " \n", | |
| " # From the current state s, choose an action a using an p = (1 - ε-greedy) policy\n", | |
| " # Inits ε=0.99 -> p=(1 - ε-greedy) = 0.01 (Just 1% of times PICK MAXIMIZE Q(s, a) -> 'Exploration')\n", | |
| " # so we take 'RANDOM actions a' primarily. Then DECREASES epsilon ε until:\n", | |
| " # Ends ε=0.01 -> p=(1 - ε-greedy) = 0.99 (Most 99% of times PICK MAXIMIZE Q(s, a) -> 'Exploitation')\n", | |
| " # so we PICK 'NOT to take RANDOM actions a' primarily. (Line 7)\n", | |
| " \n", | |
| " # state s vector needs to be the 'right shape' to be the input for the 'q_network'\n", | |
| " # 1D state = [x, y, x’, y’, theta, theta’, l, r] shape (8, ) ->\n", | |
| " # Add a NEW dimension at 'axis = 0' (rows) position, so 'np.expand_dims(state, axis=0)' ->\n", | |
| " # 2D state s = [ [x, y, x’, y’, theta, theta’, l, r] ] shape (1, 8) (Line 7)\n", | |
| " state_qn = np.expand_dims(state, axis=0)\n", | |
| " \n", | |
| " # Input 2D state s = [ [x, y, x’, y’, theta, theta’, l, r] ] shape (1, 8) to NN 'q-network' model\n", | |
| " # 'q_values' output Tensor with shape (1 row, 4 Q-values):\n", | |
| " # [ [ 1 vector/row, each with 4 Q-values related to 4 possible actions a=[0=nothing, 1=left, 2=main, 3=right] ] ] \n", | |
| " # Q(s,a) = [ [Q2, Q2, Q3, Q4] ] 2D tensor vector (Line 7)\n", | |
| " q_values = q_network(state_qn)\n", | |
| " \n", | |
| " # From the current state s, Get an action a using the p = (1 - ε-greedy) policy with p[0-1] (+)\n", | |
| " ## if random.random() > epsilon: # When float random number[0-1) - epsilon[0-1] > 0.0 (+)\n", | |
| " ## return np.argmax(q_values.numpy()[0]) # return the action (index of q_values) [0-3] where Q-value is MAXIMUM\n", | |
| " ## else:\n", | |
| " ## return random.choice(np.arange(4)) # Otherwise when float random number[0-1) - epsilon[0-1] < 0.0 (-)\n", | |
| " ## # return a random action [0-3]\n", | |
| " # action is an integer between [0-3] -> action=0=nothing, action=1=left, action=2=main, action=3=right\n", | |
| " \n", | |
| " # From Q(s,a) = [ [Q2, Q2, Q3, Q4] ] 2D tensor vector CONVERT TO -> 1D numpy vector [Q2, Q2, Q3, Q4] -> \n", | |
| " # select MAX[Q2, Q2, Q3, Q4] -> so return the index of MAX Q(s,a) scalar = action[0-3] (Line 7)\n", | |
| " action = utils.get_action(q_values, epsilon)\n", | |
| " \n", | |
| " # Take (1) step in environment, to perform previous 'action' A, and receive a 'reward' R(S), in the next state S'\n", | |
| " # done = True -> if episode finished because it reached a terminal state\n", | |
| " # done = False -> if episode didn't finished or NOT reached a terminal state yet. (Line 8)\n", | |
| " next_state, reward, done, _ = env.step(action)\n", | |
| " \n", | |
| " # state = env.reset() -> s = [x, y, x’, y’, theta, theta’, l, r]\n", | |
| " # action = utils.get_action(q_values, epsilon) -> action[0-3]: 0=nothing, 1=left, 2=main, 3=right\n", | |
| " # next_state, reward, done, _ = env.step(action)\n", | |
| " # Store 'experience' tuple = (state,action,reward,state',done) in the 'memory_buffer' list [].\n", | |
| " # We store the 'done' variable (True/False) as well for convenience.\n", | |
| " \n", | |
| " # environment (obj) creates a new tuple -> environment(s,a,R,s',done)\n", | |
| " # memory_buffer = [ experience1, experience2, ... , experience64, ... ]\n", | |
| " # memory_buffer = [ (s,a,R,s',done)1, (s,a,R,s',done)2, ... , (s,a,R,s',done)64, ... ]\n", | |
| " # If mini-batch has 64 tuples/examples/rows, our 'memory_buffer'\n", | |
| " # should have more than 64 'experience' tuples in order to pass the latter condition (Line 9)\n", | |
| " memory_buffer.append(experience(state, action, reward, next_state, done))\n", | |
| " \n", | |
| " # ONLY UPDATE the Neural Network, when every C=NUM_STEPS_FOR_UPDATE=4 time steps t have occurred,\n", | |
| " # and when 'memory_buffer' has MORE THAN 64 tuples to be SAMPLED RANDOMLY, \n", | |
| " # because MINIBATCH_SIZE = 64 tuples/examples/rows,\n", | |
| " ## if (t + 1) % num_steps_upd == 0 and len(memory_buffer) > MINIBATCH_SIZE:\n", | |
| " ## return True\n", | |
| " ## else:\n", | |
| " ## return False\n", | |
| " # memory_buffer = [ experience1, experience2, ... , experience64, ... ]\n", | |
| " # memory_buffer = [ (s,a,R,s',done)1, (s,a,R,s',done)2, ... , (s,a,R,s',done)64, ... ]\n", | |
| " # Then update = 'True', otherwise update = 'False' (Line 10)\n", | |
| " update = utils.check_update_conditions(t, NUM_STEPS_FOR_UPDATE, memory_buffer)\n", | |
| " \n", | |
| " # When update = 'True'\n", | |
| " if update:\n", | |
| " \n", | |
| " # SAMPLE RANDOM mini-batch of 'experience' tuples (S,A,R,S',done) from D\n", | |
| " # memory_buffer = [ experience1, experience2, ... , experience64, ... ]\n", | |
| " # memory_buffer = [ (s,a,R,s',done)1, (s,a,R,s',done)2, ... , (s,a,R,s',done)64, ... ] \n", | |
| " ## experiences = random.sample(memory_buffer, k=MINIBATCH_SIZE) # Select k=64 elements randomly from\n", | |
| " ## # 'memory_buffer' list -> [()1,()2,()3,...,()64]\n", | |
| " ## states = tf.convert_to_tensor(np.array([e.state for e in experiences if e is not None]), dtype=tf.float32)\n", | |
| " ## actions = tf.convert_to_tensor(np.array([e.action for e in experiences if e is not None]), dtype=tf.float32)\n", | |
| " ## rewards = tf.convert_to_tensor(np.array([e.reward for e in experiences if e is not None]), dtype=tf.float32)\n", | |
| " ## next_states = tf.convert_to_tensor(np.array([e.next_state for e in experiences if e is not None]), \n", | |
| " ## dtype=tf.float32)\n", | |
| " ##done_vals = tf.convert_to_tensor(np.array([e.done for e in experiences if e is not None]).astype(np.uint8),\n", | |
| " ## dtype=tf.float32)\n", | |
| " ## return (states, actions, rewards, next_states, done_vals) # Each tuple's variable has tensors \n", | |
| " ## # with 64 elements \n", | |
| " # ( [[s]*64],[[a]*64],[[R]*64],[[s']*64],[[done]*64] ) (Line 11)\n", | |
| " experiences = utils.get_experiences(memory_buffer)\n", | |
| " \n", | |
| " # Set the y targets = Q^(s, a), perform a Gradient Descent step -> 'Adam' optimizer,\n", | |
| " # and UPDATE the Q-network and target Q^-network weights W,B. \n", | |
| " # experiences = ( [[s]*64],[[a]*64],[[R]*64],[[s']*64],[[done]*64] )\n", | |
| " # GAMMA = 0.995 Discount Factor (Lines 12, 13, 14)\n", | |
| " agent_learn(experiences, GAMMA)\n", | |
| " \n", | |
| " # At the end of each inner loop / time step t iteration (t = 0, 1, 2, ..., 999), \n", | |
| " # OVERWRITE/UPDATE/SET the NEW next_state s' as our actual state s -> s = s',\n", | |
| " # using an independent copy of s’, to keep state s' UNMODIFIED. (Line 15)\n", | |
| " state = next_state.copy()\n", | |
| " \n", | |
| " # ADD to the previous accumulated SUM ‘total_points’ counter of ‘rewards’ at time step t, a NEW ‘reward’ -> \n", | |
| " # total_points = total_points (counter init as 0) + reward (line 15)\n", | |
| " total_points += reward\n", | |
| " \n", | |
| " # done = True -> if episode finished because it reached a terminal state\n", | |
| " # done = False -> if episode didn't finished or NOT reached a terminal state yet.\n", | |
| " # next_state, reward, done, _ = env.step(action)\n", | |
| " # If a 'terminal state' HAS BEEN REACHED (done = 'True'), then we 'BREAK' out the inner loop (Line 15)\n", | |
| " if done:\n", | |
| " break\n", | |
| " \n", | |
| " # At the end of each i-th outer loop iteration (i = 0, 1, 2, ..., 1999),\n", | |
| " # append ‘total_points’ counter of rewards (updated value), at 'total_point_history' list [] \n", | |
| " # after finishing 1000 time steps t (each iteration i). (Line 16)\n", | |
| " total_point_history.append(total_points)\n", | |
| " \n", | |
| " # At the end of outer loop, 'total_point_history[-100:]' selects the LAST num_p_av = 100 i-th \n", | |
| " # updated reward points, at 'total_point_history' list []. Then, get the 'mean' of these 100 points\n", | |
| " # each of them, obtained during 1000 times steps t, during inner loop iterations. (line 16)\n", | |
| " av_latest_points = np.mean(total_point_history[-num_p_av:])\n", | |
| " \n", | |
| " # UPDATE the ε epsilon value, gradually DECREASING the value of ε epsilon towards a MIN value E_MIN = 0.01 \n", | |
| " # using a given ε-decay rate E_DECAY = 0.995. \n", | |
| " # 'utils.get_new_eps(epsilon)' function, returns the 'MAX' value between 'E_MIN = 0.01' and a 'DECREASED epsilon' \n", | |
| " # return max(E_MIN, E_DECAY * epsilon) -> return max(0.01, 0.995 * epsilon). (Line 16)\n", | |
| " epsilon = utils.get_new_eps(epsilon)\n", | |
| " \n", | |
| " # Print just the 1st iter/Episode (i=0 -> i+1=1), print AVG reward of LAST [100] iters/episodes: [x.xx], end=\"\" \n", | |
| " # because module (%) of i+1=1 is != 0, so it is NOT printed at if statement below\n", | |
| " # i+1=1 |_100\n", | |
| " # 1 0\n", | |
| " # print(\"something\", end=\"\") end=\"\" secures the next print continuing on the same line. \n", | |
| " # print(f\"\\rEpisode...) \\r character returns the cursor at the begining of the line, \n", | |
| " # so it OVERWRITES the line, updating information on the same line instead of printing a new one each time (Line 16)\n", | |
| " print(f\"\\rEpisode {i+1} | Total point AVG 'reward' of the last {num_p_av} iters/episodes: {av_latest_points:.2f}\", end=\"\")\n", | |
| " \n", | |
| " # Print every 100 iters/episodes i+1=[100,200,300, ... ,2000] (Line 16) \n", | |
| " if (i+1) % num_p_av == 0:\n", | |
| " \n", | |
| " # Every 100 iters/episodes i+1=[100,200,300, ... ,2000] print AVG reward of LAST [100] iters/episodes: [x.xx] \n", | |
| " # print(f\"\\rEpisode...) \\r character OVERWRITES the line, updating information on the same line (Line 16) \n", | |
| " print(f\"\\rEpisode {i+1} | Total point AVG 'reward' of the last {num_p_av} iters/episodes: {av_latest_points:.2f}\")\n", | |
| "\n", | |
| " # UNTIL we consider that the 'environment' has been SOLVED after some iters/episodes {i+1}, if we get AT LEAST an\n", | |
| " # AVG reward of ‘av_latest_points’>= 200 points, in the LAST 100 episodes/i-th iters, \n", | |
| " # then 'BREAK' out the outer loop (Line 16)\n", | |
| " if av_latest_points >= 200.0:\n", | |
| " \n", | |
| " # If ‘av_latest_points’ >= 200 then print \"Environment SOLVED! after i+1 episodes/iters\" (Line 16)\n", | |
| " print(f\"\\n\\nEnvironment solved in {i+1} episodes!\")\n", | |
| " \n", | |
| " # SAVE the Q-Network -> 'q_network' model as ‘.h5’ tensorflow file, saving architecture, \n", | |
| " # learned weights and learning info, becoming a portable and reusable NN model (Line 16)\n", | |
| " q_network.save('lunar_lander_model.h5')\n", | |
| " \n", | |
| " # And 'BREAK' the outer loop, so STOP computing AVG reward, because ‘av_latest_points’>= 200 points (Line 16)\n", | |
| " break\n", | |
| " \n", | |
| "# Check the execution time, measuring time taken for a code segment by recording 'start' and 'end' times, so \n", | |
| "# this cell of code has a total run or execution_time = (end_time - start_time) seconds \n", | |
| "tot_time = time.time() - start\n", | |
| "\n", | |
| "# Print total execution_time: x.xx seconds (x.xx mins)\n", | |
| "# 1 min -> 60 seconds then tot_time (seconds) / 60 = tot_time (mins)\n", | |
| "print(f\"\\nTotal Runtime: {tot_time:.2f} s ({(tot_time/60):.2f} min)\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "We can plot the `'total point history’ list [ ]` along with the `'moving average’ or episodes/iterations i` **to see how our agent improved during TRAINING**. If you want to know about the `different plotting options available` in the `utils.plot_history()` function we encourage you to take a look at the `utils` module." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 16, | |
| "metadata": { | |
| "deletable": false, | |
| "id": "E_EUXxurfe8m", | |
| "scrolled": false | |
| }, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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6c4771T37t0VHByssLAw3X333Xr11Vd18eJFW/t/7tw5vfTSSxo4cKA6duyokJAQxcXFadasWTp27JitPq50+PBhPfvss0pMTLTq6tmzp5KTk/WnP/1JlZWVze4TgIcYAPAzkqzXtfj888+tfmbNmmUWL15s2rVrV6f/K1/jx483Fy5caLKuESNGNLh+xYoVpn379o32X/sKCQlp9Dtyc3NNp06d3G7fu3dv869//cvtvu/fv9/07du30T4iIiLMzp07zYgRI2yN9UsvveR27CSZmJgY89VXX7ntB4B3uIzhLGgA/uXKe+Jdy19hGzdu1MiRIyVJ48aN07p16yRJDz/8sIYPH662bdtq+/btWrRokc6dOydJmjx5sj744AO3dY0YMUIbN26ss664uFj9+vXT2bNnJUnjx49XcnKywsPDVVNTo7KyMu3atUvr1q3TqVOndPLkyXr9r1q1SikpKaqurpYkDR8+XKmpqerRo4f+85//aMmSJdq9e7ckqUOHDtq2bZv69etXr58TJ04oLi5ORUVFkqS+ffsqIyNDMTExqqio0EcffaTPPvtMkZGR6tSpk/Lz8yU1Pta//OUvNX/+fOt709LSlJiYqJCQEH3zzTfKzc3Vhg0bJEk9evRQfn6+evbs2WBfALzEu3kUAJpPrTBDKMl06NDBbNmypV67/fv3m/DwcKvdBx984LauhmYI582bZ63//e9/32hNNTU15m9/+1u95adPnzahoaFWH1lZWfXaXLp0yTz22GNWm8GDBzf4HZmZmVabMWPGmHPnztVrM3/+/HozfA3Jzc211t91112mtLS0wXZ//vOfrXZTpkxpdP8BeAeBEIDfuTqo2Hn99a9/rdfP1YHwzTffbPQ7V69ebbW744473NbVUCB8/PHHrfUVFRXN3ucFCxZY299///2NtquqqjLx8fFW23Xr1tVZX1ZWZoKDg40k07VrV3P8+PFG+0pNTW0yEMbFxRlJplu3bm77MsaYhx9+2EgybdtdKtojAAAGjklEQVS2NYcPH3bbFoBncVEJAEjq3LmzHn300UbXjx07Vrfeeqsk6R//+Ie++eabZvV/ww03WO/37t3b7Po++ugj6/3TTz/daLu2bdvqqaeeanA7SVqxYoV1cccjjzyiLl26NNrXzJkz3da0a9cu/fvf/5YkZWRkuO1Lkh566CFJUnV1tdav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\n", | |
| "text/plain": [ | |
| "<Figure size 720x504 with 1 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "# Plot the total point history list of updated rewards [] VS episodes/iterations i []\n", | |
| "# UNTIL enviroment is Solved! when latest reward >= 200, (201.37) \n", | |
| "# after i+1 = 534 episodes/iterations.\n", | |
| "utils.plot_history(total_point_history)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "id": "c_xwgaX5MnYt" | |
| }, | |
| "source": [ | |
| "<a name=\"10\"></a>\n", | |
| "## 10 - See the Trained Agent In Action\n", | |
| "\n", | |
| "Now that we have trained our agent, we can see it in action. We will use the `utils.create_video` function to create a video of our agent interacting with the environment using the trained $Q$-Network. The `utils.create_video` function uses the `imageio` library to create the video. This library produces some warnings that can be distracting, so, to suppress these warnings we run the code below." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 17, | |
| "metadata": { | |
| "deletable": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Suppress warnings usually produced by 'imageio' library\n", | |
| "import logging\n", | |
| "logging.getLogger().setLevel(logging.ERROR)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "In the cell below we `create a video of our agent interacting with the Lunar Lander environment 'env'` using the trained `q_network`. The video is saved to the `videos` folder with the given `filename`. We use the `utils.embed_mp4()` function to **embed the video in the Jupyter Notebook so that we can see it here directly without having to download it**.\n", | |
| "\n", | |
| "We should note that `since the lunar lander starts with a random initial force applied to its center of mass, every time you run the cell below you will see a different video`. If the **agent was trained properly**, it should be able to `land the lunar lander in the landing pad every time`, **regardless of the initial force** applied to its center of mass." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 18, | |
| "metadata": { | |
| "deletable": false, | |
| "id": "3Ttb_zLeJKiG" | |
| }, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "\n", | |
| " <video width=\"840\" height=\"480\" controls>\n", | |
| " <source src=\"data:video/mp4;base64,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AAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACAAAAAACAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAgAAAAAAgAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAABgAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAgAABAAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEAAAIAAAAAAQAACgAAAAABAAAEAAAAAAEAAAAAAAAAAQAAAgAAAAABAAAKAAAAAAEAAAQAAAAAAQAAAAAAAAABAAACAAAAAAEAAAoAAAAAAQAABAAAAAABAAAAAAAAAAEA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\" type=\"video/mp4\">\n", | |
| " Your browser does not support the video tag.\n", | |
| " </video>" | |
| ], | |
| "text/plain": [ | |
| "<IPython.core.display.HTML object>" | |
| ] | |
| }, | |
| "execution_count": 18, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "# Save the video at 'videos' folder at 'filename' path.\n", | |
| "filename = \"./videos/lunar_lander.mp4\"\n", | |
| "\n", | |
| "# Create a video of our agent interacting with the Lunar Lander environment 'env' using the trained q_network.\n", | |
| "utils.create_video(filename, env, q_network)\n", | |
| "\n", | |
| "# Use 'utils.embed_mp4()' function to embed the video in the Jupyter Notebook, \n", | |
| "# so that we can see it here directly without having to download it\n", | |
| "utils.embed_mp4(filename)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"11\"></a>\n", | |
| "## 11 - Congratulations!\n", | |
| "\n", | |
| "You have successfully used Deep Q-Learning with Experience Replay to train an agent to land a lunar lander safely on a landing pad on the surface of the moon. Congratulations!" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<a name=\"12\"></a>\n", | |
| "## 12 - References\n", | |
| "\n", | |
| "If you would like to learn more about Deep Q-Learning, we recommend you check out the following papers.\n", | |
| "\n", | |
| "\n", | |
| "* Mnih, V., Kavukcuoglu, K., Silver, D. et al. Human-level control through deep reinforcement learning. Nature 518, 529–533 (2015).\n", | |
| "\n", | |
| "\n", | |
| "* Lillicrap, T. P., Hunt, J. J., Pritzel, A., et al. Continuous Control with Deep Reinforcement Learning. ICLR (2016).\n", | |
| "\n", | |
| "\n", | |
| "* Mnih, V., Kavukcuoglu, K., Silver, D. et al. Playing Atari with Deep Reinforcement Learning. arXiv e-prints. arXiv:1312.5602 (2013)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "<details>\n", | |
| " <summary><font size=\"2\" color=\"darkgreen\"><b>Please click here if you want to experiment with any of the non-graded code.</b></font></summary>\n", | |
| " <p><i><b>Important Note: Please only do this when you've already passed the assignment to avoid problems with the autograder.</b></i>\n", | |
| " <ol>\n", | |
| " <li> On the notebook’s menu, click “View” > “Cell Toolbar” > “Edit Metadata”</li>\n", | |
| " <li> Hit the “Edit Metadata” button next to the code cell which you want to lock/unlock</li>\n", | |
| " <li> Set the attribute value for “editable” to:\n", | |
| " <ul>\n", | |
| " <li> “true” if you want to unlock it </li>\n", | |
| " <li> “false” if you want to lock it </li>\n", | |
| " </ul>\n", | |
| " </li>\n", | |
| " <li> On the notebook’s menu, click “View” > “Cell Toolbar” > “None” </li>\n", | |
| " </ol>\n", | |
| " <p> Here's a short demo of how to do the steps above: \n", | |
| " <br>\n", | |
| " <img src=\"https://lh3.google.com/u/0/d/14Xy_Mb17CZVgzVAgq7NCjMVBvSae3xO1\" align=\"center\" alt=\"unlock_cells.gif\">\n", | |
| "</details>" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "accelerator": "GPU", | |
| "colab": { | |
| "collapsed_sections": [], | |
| "name": "TensorFlow - Lunar Lander.ipynb", | |
| "provenance": [] | |
| }, | |
| "kernelspec": { | |
| "display_name": "Python 3", | |
| "language": "python", | |
| "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.7.6" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 1 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment