From 2ecc9df3438bfc84bbf16c36cd734af4c7a3e033 Mon Sep 17 00:00:00 2001 From: Dmitri Soshnikov Date: Thu, 19 May 2022 15:21:24 +0300 Subject: [PATCH] Add section or DeepRL --- README.md | 2 +- .../6-Other/21-GeneticAlgorithms/README.md | 2 + .../6-Other/22-DeepRL/CartPole-RL-TF.ipynb | 567 ++++++++++++++++++ lessons/6-Other/22-DeepRL/README.md | 104 +++- .../22-DeepRL/images/cartpole-balance.gif | Bin 0 -> 391958 bytes .../22-DeepRL/images/cartpole-nobalance.gif | Bin 0 -> 43717 bytes lessons/6-Other/22-DeepRL/images/cartpole.png | Bin 0 -> 926 bytes .../6-Other/22-DeepRL/lab/MointainCar.ipynb | 98 +++ lessons/6-Other/22-DeepRL/lab/README.md | 22 + .../22-DeepRL/lab/images/mountaincar.png | Bin 0 -> 8161 bytes lessons/6-Other/22-DeepRL/notebook.ipynb | 520 ++++++++++++++++ lessons/6-Other/22-DeepRL/tmp.ipynb | 300 +++++++++ lessons/X-Extras/X1-MultiModal/README.md | 6 +- 13 files changed, 1616 insertions(+), 5 deletions(-) create mode 100644 lessons/6-Other/22-DeepRL/CartPole-RL-TF.ipynb create mode 100644 lessons/6-Other/22-DeepRL/images/cartpole-balance.gif create mode 100644 lessons/6-Other/22-DeepRL/images/cartpole-nobalance.gif create mode 100644 lessons/6-Other/22-DeepRL/images/cartpole.png create mode 100644 lessons/6-Other/22-DeepRL/lab/MointainCar.ipynb create mode 100644 lessons/6-Other/22-DeepRL/lab/README.md create mode 100644 lessons/6-Other/22-DeepRL/lab/images/mountaincar.png create mode 100644 lessons/6-Other/22-DeepRL/notebook.ipynb create mode 100644 lessons/6-Other/22-DeepRL/tmp.ipynb diff --git a/README.md b/README.md index e8b21431..f10e688b 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ For a gentle introduction to *AI in the Cloud* topics you may consider taking th 20Large Language Models, Prompt Programming and Few-Shot TasksTextPyTorchTensorFlow VIOther AI Techniques 21Genetic AlgorithmsTextNotebook -22Deep Reinforcement LearningTextPyTorchTensorFlow +22Deep Reinforcement LearningTextTensorFlowLab 23Multi-Agent SystemsText VIIAI Ethics 24AI Ethics and Responsible AIText diff --git a/lessons/6-Other/21-GeneticAlgorithms/README.md b/lessons/6-Other/21-GeneticAlgorithms/README.md index dbbbcea7..f4ded546 100644 --- a/lessons/6-Other/21-GeneticAlgorithms/README.md +++ b/lessons/6-Other/21-GeneticAlgorithms/README.md @@ -4,6 +4,8 @@ **Genetic Algorithms** (GA) are based on **evolutionary approach** to AI, in which methods of evolution of population is used to obtain an optimal solution for a given problem. They were proposed in 1975 by [John Henry Holland](https://en.wikipedia.org/wiki/John_Henry_Holland). +> **Watch** [this great video](https://www.youtube.com/watch?v=qv6UVOQ0F44) talking about how computer can learn to play Super Mario using neural networks trained by genetic algorithms. We will learn more about computer learning to play games like that [at the next section](../22-DeepRL/README.md). + Genetic Algorithms are based on the following ideas: * Valid solutions to the problem can be represented as **genes** diff --git a/lessons/6-Other/22-DeepRL/CartPole-RL-TF.ipynb b/lessons/6-Other/22-DeepRL/CartPole-RL-TF.ipynb new file mode 100644 index 00000000..5afa5a35 --- /dev/null +++ b/lessons/6-Other/22-DeepRL/CartPole-RL-TF.ipynb @@ -0,0 +1,567 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Training RL to do Cartpole Balancing\n", + "\n", + "This notebooks is part of [AI for Beginners Curriculum](http://aka.ms/ai-beginners). It has been inspired by [this blog post](https://medium.com/swlh/policy-gradient-reinforcement-learning-with-keras-57ca6ed32555), [official TensorFlow documentation](https://www.tensorflow.org/tutorials/reinforcement_learning/actor_critic) and [this Keras RL example](https://keras.io/examples/rl/actor_critic_cartpole/).\n", + "\n", + "In this example, we will use RL to train a model to balance a pole on a cart that can move left and right on horizontal scale. We will use [OpenAI Gym](https://www.gymlibrary.ml/) environment to simulate the pole.\n", + "\n", + "> **Note**: You can run this lesson's code locally (eg. from Visual Studio Code), in which case the simulation will open in a new window. When running the code online, you may need to make some tweaks to the code, as described [here](https://towardsdatascience.com/rendering-openai-gym-envs-on-binder-and-google-colab-536f99391cc7).\n", + "\n", + "We will start by making sure Gym is installed:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: gym in c:\\winapp\\miniconda3\\envs\\py38\\lib\\site-packages (0.23.1)\n", + "Collecting pygame\n", + " Downloading pygame-2.1.2-cp38-cp38-win_amd64.whl (8.4 MB)\n", + "Requirement already satisfied: importlib-metadata>=4.10.0 in c:\\winapp\\miniconda3\\envs\\py38\\lib\\site-packages (from gym) (4.11.3)\n", + "Requirement already satisfied: cloudpickle>=1.2.0 in c:\\winapp\\miniconda3\\envs\\py38\\lib\\site-packages (from gym) (2.0.0)\n", + "Requirement already satisfied: gym-notices>=0.0.4 in c:\\winapp\\miniconda3\\envs\\py38\\lib\\site-packages (from gym) (0.0.6)\n", + "Requirement already satisfied: numpy>=1.18.0 in c:\\winapp\\miniconda3\\envs\\py38\\lib\\site-packages (from gym) (1.22.3)\n", + "Requirement already satisfied: zipp>=0.5 in c:\\winapp\\miniconda3\\envs\\py38\\lib\\site-packages (from importlib-metadata>=4.10.0->gym) (3.6.0)\n", + "Installing collected packages: pygame\n", + "Successfully installed pygame-2.1.2\n" + ] + } + ], + "source": [ + "import sys\n", + "!{sys.executable} -m pip install gym pygame" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's create the CartPole environment and see how to operate on it. An environment has the following properties:\n", + "\n", + "* **Action space** is the set of possible actions that we can perform at each step of the simulation\n", + "* **Observation space** is the space of observations that we can make" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Action space: Discrete(2)\n", + "Observation space: Box([-4.8000002e+00 -3.4028235e+38 -4.1887903e-01 -3.4028235e+38], [4.8000002e+00 3.4028235e+38 4.1887903e-01 3.4028235e+38], (4,), float32)\n" + ] + } + ], + "source": [ + "import gym\n", + "\n", + "env = gym.make(\"CartPole-v1\")\n", + "\n", + "print(f\"Action space: {env.action_space}\")\n", + "print(f\"Observation space: {env.observation_space}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's see how the simulation works. The following loop runs the simulation, until `env.step` does not return the termination flag `done`. We will randomly chose actions using `env.action_space.sample()`, which means the experiment will probably fail very fast (CartPole environment terminates when the speed of CartPole, its position or angle are outside certain limits).\n", + "\n", + "> Simulation will open in the new window. You can run the code several times and see how it behaves." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-0.04825775 -0.21918646 -0.00796685 0.27188525] -> 1.0\n", + "[-0.05264147 -0.4141938 -0.00252914 0.5620448 ] -> 1.0\n", + "[-0.06092535 -0.21903647 0.00871175 0.26856613] -> 1.0\n", + "[-0.06530608 -0.41428167 0.01408308 0.56398404] -> 1.0\n", + "[-0.07359171 -0.60959834 0.02536276 0.8610703 ] -> 1.0\n", + "[-0.08578368 -0.4148308 0.04258416 0.57646877] -> 1.0\n", + "[-0.09408029 -0.610523 0.05411354 0.88225687] -> 1.0\n", + "[-0.10629076 -0.4161761 0.07175867 0.6070649 ] -> 1.0\n", + "[-0.11461428 -0.22212696 0.08389997 0.33781925] -> 1.0\n", + "[-0.11905681 -0.0282929 0.09065636 0.07272854] -> 1.0\n", + "[-0.11962268 0.16542032 0.09211093 -0.19003159] -> 1.0\n", + "[-0.11631427 -0.03089041 0.08831029 0.13022853] -> 1.0\n", + "[-0.11693208 -0.22715913 0.09091487 0.44941387] -> 1.0\n", + "[-0.12147526 -0.42344147 0.09990314 0.76931363] -> 1.0\n", + "[-0.12994409 -0.61978614 0.11528942 1.0916848 ] -> 1.0\n", + "[-0.14233981 -0.81622297 0.13712311 1.4182041 ] -> 1.0\n", + "[-0.15866427 -1.01275 0.1654872 1.7504154 ] -> 1.0\n", + "[-0.17891927 -1.2093195 0.2004955 2.0896728 ] -> 1.0\n", + "[-0.20310566 -1.4058217 0.24228896 2.4370732 ] -> 1.0\n", + "Total reward: 19.0\n" + ] + } + ], + "source": [ + "env.reset()\n", + "\n", + "done = False\n", + "total_reward = 0\n", + "while not done:\n", + " env.render()\n", + " obs, rew, done, info = env.step(env.action_space.sample())\n", + " total_reward += rew\n", + " print(f\"{obs} -> {rew}\")\n", + "print(f\"Total reward: {total_reward}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Youn can notice that observations contain 4 numbers. They are:\n", + "- Position of cart\n", + "- Velocity of cart\n", + "- Angle of pole\n", + "- Rotation rate of pole\n", + "\n", + "`rew` is the reward we receive at each step. You can see that in CartPole environment you are rewarded 1 point for each simulation step, and the goal is to maximize total reward, i.e. the time CartPole is able to balance without falling.\n", + "\n", + "During reinforcement learning, our goal is to train a **policy** $\\pi$, that for each state $s$ will tell us which action $a$ to take, so essentially $a = \\pi(s)$.\n", + "\n", + "If you want probabilistic solution, you can think of policy as returning a set of probabilities for each action, i.e. $\\pi(a|s)$ would mean a probability that we should take action $a$ at state $s$.\n", + "\n", + "## Policy Gradient Method\n", + "\n", + "In simplest RL algorithm, called **Policy Gradient**, we will train a neural network to predict the next action." + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "from tensorflow import keras\n", + "import matplotlib.pyplot as plt\n", + "\n", + "num_inputs = 4\n", + "num_actions = 2\n", + "\n", + "model = keras.Sequential([\n", + " keras.layers.Dense(128, activation=\"relu\",input_shape=(num_inputs,)),\n", + " keras.layers.Dense(num_actions, activation=\"softmax\")\n", + "])\n", + "\n", + "model.compile(loss='categorical_crossentropy', optimizer=keras.optimizers.Adam(learning_rate=0.01))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will train the network by running many experiments, and updating our network after each run. Let's define a function that will run the experiment and return the results (so-called **trace**) - all states, actions (and their recommended probabilities), and rewards:" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [], + "source": [ + "def run_episode(max_steps_per_episode = 10000,render=False): \n", + " states, actions, probs, rewards = [],[],[],[]\n", + " state = env.reset()\n", + " for _ in range(max_steps_per_episode):\n", + " if render:\n", + " env.render()\n", + " action_probs = model(np.expand_dims(state,0))[0]\n", + " action = np.random.choice(num_actions, p=np.squeeze(action_probs))\n", + " nstate, reward, done, info = env.step(action)\n", + " if done:\n", + " break\n", + " states.append(state)\n", + " actions.append(action)\n", + " probs.append(action_probs)\n", + " rewards.append(reward)\n", + " state = nstate\n", + " return np.vstack(states), np.vstack(actions), np.vstack(probs), np.vstack(rewards)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can run one episode with untrained network and observe that total reward (AKA length of episode) is very low:" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total reward: 13.0\n" + ] + } + ], + "source": [ + "s,a,p,r = run_episode()\n", + "print(f\"Total reward: {np.sum(r)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One of the tricky aspects of policy gradient algorithm is to use **discounted rewards**. The idea is that we compute the vector of total rewards at each step of the game, and during this process we discount the early rewards using some coefficient $gamma$. We also normalize the resulting vector, because we will use it as weight to affect our training: " + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": {}, + "outputs": [], + "source": [ + "eps = 0.0001\n", + "\n", + "def discounted_rewards(rewards,gamma=0.99,normalize=True):\n", + " ret = []\n", + " s = 0\n", + " for r in rewards[::-1]:\n", + " s = r + gamma * s\n", + " ret.insert(0, s)\n", + " if normalize:\n", + " ret = (ret-np.mean(ret))/(np.std(ret)+eps)\n", + " return ret" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's do the actual training! We will run 300 episodes, and at each episode we will do the following:\n", + "\n", + "1. Run the experiment and collect the trace\n", + "1. Calculate the difference (`gradients`) between the actions taken, and by predicted probabilities. The less the difference is, the more we are sure that we have taken the right action.\n", + "1. Calculate discounted rewards and multiply gradients by discounted rewards - that will make sure that steps with higher rewards will make more effect on the final result than lower-rewarded ones\n", + "1. Expected target actions for our neural network would be partly taken from the predicted probabilities during the run, and partly from calculated gradients. We will use `alpha` parameter to determine to which extent gradients and rewards are taken into account - this is called *learning rate* of reinforcement algorithm.\n", + "1. Finally, we train our network on states and expected actions, and repeat the process " + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 -> 44.0\n", + "100 -> 105.0\n", + "200 -> 145.0\n", + "300 -> 70.0\n", + "400 -> 190.0\n", + "500 -> 298.0\n", + "600 -> 289.0\n", + "700 -> 499.0\n", + "800 -> 499.0\n", + "900 -> 499.0\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "alpha = 1e-4\n", + "\n", + "history = []\n", + "for epoch in range(300):\n", + " states, actions, probs, rewards = run_episode()\n", + " one_hot_actions = np.eye(2)[actions.T][0]\n", + " gradients = one_hot_actions-probs\n", + " dr = discounted_rewards(rewards)\n", + " gradients *= dr\n", + " target = alpha*np.vstack([gradients])+probs\n", + " model.train_on_batch(states,target)\n", + " history.append(np.sum(rewards))\n", + " if epoch%100==0:\n", + " print(f\"{epoch} -> {np.sum(rewards)}\")\n", + "\n", + "plt.plot(history)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's run the episode with rendering to see the result:" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [], + "source": [ + "_ = run_episode(render=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hopefully, you can see that pole can now balance pretty well!\n", + "\n", + "## Actor-Critic Model\n", + "\n", + "Actor-Critic model is the further development of policy gradients, in which we build a neural network to learn both the policy and estimated rewards. The network will have two outputs (or you can view it as two separate networks):\n", + "* **Actor** will recommend the action to take by giving us the state probability distribution, as in policy gradient model\n", + "* **Critic** would estimate what the reward would be from those actions. It returns total estimated rewards in the future at the given state.\n", + "\n", + "Let's define such a model: " + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [], + "source": [ + "num_inputs = 4\n", + "num_actions = 2\n", + "num_hidden = 128\n", + "\n", + "inputs = keras.layers.Input(shape=(num_inputs,))\n", + "common = keras.layers.Dense(num_hidden, activation=\"relu\")(inputs)\n", + "action = keras.layers.Dense(num_actions, activation=\"softmax\")(common)\n", + "critic = keras.layers.Dense(1)(common)\n", + "\n", + "model = keras.Model(inputs=inputs, outputs=[action, critic])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We would need to slightly modify our `run_episode` function to return also critic results:" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [], + "source": [ + "def run_episode(max_steps_per_episode = 10000,render=False): \n", + " states, actions, probs, rewards, critic = [],[],[],[],[]\n", + " state = env.reset()\n", + " for _ in range(max_steps_per_episode):\n", + " if render:\n", + " env.render()\n", + " action_probs, est_rew = model(np.expand_dims(state,0))\n", + " action = np.random.choice(num_actions, p=np.squeeze(action_probs[0]))\n", + " nstate, reward, done, info = env.step(action)\n", + " if done:\n", + " break\n", + " states.append(state)\n", + " actions.append(action)\n", + " probs.append(tf.math.log(action_probs[0,action]))\n", + " rewards.append(reward)\n", + " critic.append(est_rew[0,0])\n", + " state = nstate\n", + " return states, actions, probs, rewards, critic" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we will run the main training loop. We will use manual network training process by computing proper loss functions and updating network parameters:" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "running reward: 5.82 at episode 10\n", + "running reward: 9.43 at episode 20\n", + "running reward: 10.30 at episode 30\n", + "running reward: 10.28 at episode 40\n", + "running reward: 11.00 at episode 50\n", + "running reward: 13.01 at episode 60\n", + "running reward: 21.78 at episode 70\n", + "running reward: 40.54 at episode 80\n", + "running reward: 73.70 at episode 90\n", + "running reward: 100.19 at episode 100\n", + "running reward: 159.20 at episode 110\n", + "Solved at episode 114!\n" + ] + } + ], + "source": [ + "optimizer = keras.optimizers.Adam(learning_rate=0.01)\n", + "huber_loss = keras.losses.Huber()\n", + "episode_count = 0\n", + "running_reward = 0\n", + "\n", + "while True: # Run until solved\n", + " state = env.reset()\n", + " episode_reward = 0\n", + " with tf.GradientTape() as tape:\n", + " _,_,action_probs, rewards, critic_values = run_episode()\n", + " episode_reward = np.sum(rewards)\n", + " \n", + " # Update running reward to check condition for solving\n", + " running_reward = 0.05 * episode_reward + (1 - 0.05) * running_reward\n", + "\n", + " # Calculate discounted rewards that will be labels for our critic\n", + " dr = discounted_rewards(rewards)\n", + "\n", + " # Calculating loss values to update our network\n", + " actor_losses = []\n", + " critic_losses = []\n", + " for log_prob, value, rew in zip(action_probs, critic_values, dr):\n", + " # When we took the action with probability `log_prob`, we received discounted reward of `rew`,\n", + " # while critic predicted it to be `value` \n", + " # First we calculate actor loss, to make actor predict actions that lead to higher rewards\n", + " diff = rew - value\n", + " actor_losses.append(-log_prob * diff)\n", + "\n", + " # The critic loss is to minimize the difference between predicted reward `value` and actual\n", + " # discounted reward `rew`\n", + " critic_losses.append(\n", + " huber_loss(tf.expand_dims(value, 0), tf.expand_dims(rew, 0))\n", + " )\n", + "\n", + " # Backpropagation\n", + " loss_value = sum(actor_losses) + sum(critic_losses)\n", + " grads = tape.gradient(loss_value, model.trainable_variables)\n", + " optimizer.apply_gradients(zip(grads, model.trainable_variables))\n", + "\n", + " # Log details\n", + " episode_count += 1\n", + " if episode_count % 10 == 0:\n", + " template = \"running reward: {:.2f} at episode {}\"\n", + " print(template.format(running_reward, episode_count))\n", + "\n", + " if running_reward > 195: # Condition to consider the task solved\n", + " print(\"Solved at episode {}!\".format(episode_count))\n", + " break\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's run the episode and see how good our model is:" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [], + "source": [ + "_ = run_episode(render=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, let's close the environment." + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [], + "source": [ + "env.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Takeaway\n", + "\n", + "We have seen two RL algorithms in this demo: simple policy gradient, and more sophisticated actor-critic. You can see that those algorithms operate with abstract notions of state, action and reward - thus they can be applied to very different environments.\n", + "\n", + "Reinforcement learning allows us to learn the best strategy to solve the problem just by looking at the final reward. The fact that we do not need labelled datasets allows us to repeat simulations many times to optimize our models. However, there are still many challenges in RL, which you may learn if you decide to focus more on this interesting area of AI. " + ] + } + ], + "metadata": { + "interpreter": { + "hash": "16af2a8bbb083ea23e5e41c7f5787656b2ce26968575d8763f2c4b17f9cd711f" + }, + "kernelspec": { + "display_name": "Python 3.8.12 ('py38')", + "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.8.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lessons/6-Other/22-DeepRL/README.md b/lessons/6-Other/22-DeepRL/README.md index f6e0339a..15ecb6c8 100644 --- a/lessons/6-Other/22-DeepRL/README.md +++ b/lessons/6-Other/22-DeepRL/README.md @@ -1 +1,103 @@ -Placeholder \ No newline at end of file +# Deep Reinforcement Learning + +Reinforcement learning (RL) is seen as one of the basic machine learning paradigms, next to supervised learning and unsupervised learning. While in supervised learning we rely on the dataset with known outcomes, RL is based on **learning by doing**. For example, when we first see a computer game, we start playing, even not knowing the rules, and soon we are able to improve our skills just by the process of playing and adjusting our behavior. + +> **Learn more** about classical reinforcement learning in our [Machine Learning for Beginners Curriculum](https://github.com/microsoft/ML-For-Beginners/blob/main/8-Reinforcement/README.md). + +> **Watch** [this great video](https://www.youtube.com/watch?v=qv6UVOQ0F44) talking about how computer can learn to play Super Mario. + +To perform RL, we need: + +* An **environment** or **simulator** that sets the rules of the game. We should be able to run the experiments in the simulator and observe the results. +* Some **Reward function**, which indicates how successful our experiment was. In case of learning to play computer game, the reward would be our final score. + +Based on reward function, we should be able to adjust our behavior and improve our skills, so that next time we play better. The main difference between other types of machine learning and RL is that in RL we typically do not know whether we win or lose until we finish the game. Thus, we cannot say whether a certain move alone is good or not - we only receive a reward at the end of the game. + +During RL, we typically perform many experiments. During each experiment, we need to balance between following the optimal strategy that we have learnt so far (**exploitation**) and exploring new possible states (**exploration**). + +## OpenAI Gym + +A great tool for RL is [OpenAI Gym](https://gym.openai.com/) - a **simulation environment**, which can simulate ,many different environments - starting from Atari games, to the physics behind pole balancing. It is one of the most popular simulation environments for training reinforcement learning algorithms, and is maintained by [OpenAI](https://openai.com/). + +> **Note**: You can see all the environments available from OpenAI Gym [here](https://gym.openai.com/envs/#classic_control). + +## CartPole Balancing + +You have probably all seen modern devices such as *Segway* or *Gyroscooters*. They are able to automatically balance by adjusting their wheels in response to a signal from accelerometer or gyroscope. In this section, we will learn how to solve a similar problem - balancing a pole. It is similar to a situation when a circus actor need to balance a pole on his hand - only in 1D. + +A simplified version of balancing is known as a **CartPole** problem. In the cartpole world, we have a horizontal slider that can move left or right, and the goal is to balance a vertical pole on top of the slider. + +a cartpole + +To create and use this environment, we need a couple of lines of Python code: + +```python +import gym +env = gym.make("CartPole-v1") + +env.reset() +done = False +total_reward = 0 +while not done: + env.render() + action = env.action_space.sample() + observaton, reward, done, info = env.step(action) + total_reward += reward + +print(f"Total reward: {total_reward}") +``` + +Each environment can be accessed exactly in the same way: +* `env.reset` starts a new experiment +* `env.step` performs simulation step. It receives **action** from the **action space**, and returns **observation** (from the observation space), reward, and a termination flag. + +In the example above we perform random action at each step, that's why the experiment life is very short: + +![non-balancing cartpole](images/cartpole-nobalance.gif) + +The goal of RL algorithm is to train a model - so called **policy** π - which will return the action in response to a given state. We can also consider policy to be probabilistic, eg. for any state *s* and action *a* it will return the probability π(*a*|*s*) that we should take *a* in state *s*. + +## Policy Gradients Algorithm + +The most obvious way to model a policy is by creating a neural network that will take states as input, and return corresponding actions (or rather probabilities of all actions). In a sense, it would be similar to a normal classification task, with a major difference - we do not know in advance which actions should we take at each of the steps. + +The idea here is to estimate those probabilities. We build a vector of **cumulative rewards**, which shows our total reward at each step of the experiment. We also apply **reward discounting** by multiplying earlier rewards by some coefficient γ=0.99, in order to diminish the role of earlier rewards. Then, we reinforce those steps along the experiment path that yield larger rewards. + +> Learn more about Policy Gradient algorithm and see it in action in the [example notebook](CartPole-RL-TF.ipynb). + +## Actor-Critic Algorithm + +An improved version of Policy Gradients approach is called **Actor-Critic**. The main idea behind it is that the neural network would be trained to return two things: + +* Policy, which determines which action to take. This part is called **actor** +* Estimation of the total reward we can expect to get at this state - this part is called **critic**. + +In a sense, this architecture resembles [GAN](../../4-ComputerVision/10-GANs/README.md), where we have two networks the are trained against each other. In actor-critic model, actor proposes the action we need to take, and critic tries to be critical and estimate the result. However, our goal is to train those networks in unison. + +Because we know both real cumulative rewards and results returned by the critic during the experiment, it is relatively easy to build a loss function that will minimize the difference between them. That would give us **critic loss**. We can computer **actor loss** by using the same approach as in the policy gradient algorithm. + +After running one of those algorithms, we can expect our CartPole to behave like this: + +![a balancing cartpole](images/cartpole-balance.gif) + +## ✍️ Exercises: Policy Gradients and Actor-Critic RL + +Continue your learning in the following notebooks: + +* [RL in Tensorflow](CartPole-RL-TF.ipynb) + +## Other RL Tasks + +Reinforcement Learning nowadays is a fast growing field of research. Some of the interesting examples of reinforcement learning are: + +* Teaching computer to play **Atari Games**. The challenging part in this problem is that we do not have simple state represented as a vector, but rather a screenshot - and we need to use CNN to convert this screen image to a feature vector, or to extract reward information. Atari games are available in Gym. +* Teaching computer to play board games, such as Chess and Go. Recent state-of-the-art programs like **Alpha Zero** was trained from scratch by two agents playing against each other, and improving at each step. +* In industry, RL is used to create control systems from simulation. A service called [Bonsai](https://azure.microsoft.com/services/project-bonsai/) is specifically designed for that. + +## Assignment: [Train a Mountain Car](labs/README.md) + +Your goal during this assignment would be to train a different Gym environment - [Mountain Car](https://www.gymlibrary.ml/environments/classic_control/mountain_car/). + +## Conclusion + +We have now learned how to train agents to achieve good results just by providing them a reward function that defines the desired state of the game, and by giving them an opportunity to intelligently explore the search space. We have successfully tried two algorithms, and achieved good result in relatively short time. However, this is just the beginning of your journey into RL, and you should definitely consider taking a separate course is you want to dig deeper. \ No newline at end of file diff --git a/lessons/6-Other/22-DeepRL/images/cartpole-balance.gif b/lessons/6-Other/22-DeepRL/images/cartpole-balance.gif new file mode 100644 index 0000000000000000000000000000000000000000..52dbd2043f010d52a0238bf5bdb6e4d472663cfd GIT binary patch literal 391958 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

y^IDB&dUgf@^!fh+ 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 **Problem**: If Peter wants to escape from the wolf, he needs to be able to move faster than him. We will see how Peter can learn to skate, in particular, to keep balance, using Q-Learning.\n", + "\n", + "First, let's install the gym and import required libraries:" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Requirement already satisfied: gym in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (0.18.3)\n", + "Requirement already satisfied: Pillow<=8.2.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from gym) (7.0.0)\n", + "Requirement already satisfied: scipy in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from gym) (1.4.1)\n", + "Requirement already satisfied: numpy>=1.10.4 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from gym) (1.19.2)\n", + "Requirement already satisfied: cloudpickle<1.7.0,>=1.2.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from gym) (1.6.0)\n", + "Requirement already satisfied: pyglet<=1.5.15,>=1.4.0 in /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages (from gym) (1.5.15)\n", + "\u001b[33mWARNING: You are using pip version 20.2.3; however, version 21.1.2 is available.\n", + "You should consider upgrading via the '/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7 -m pip install --upgrade pip' command.\u001b[0m\n" + ] + } + ], + "source": [ + "import sys\n", + "!pip install gym \n", + "\n", + "import gym\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import random" + ] + }, + { + "source": [ + "## Create a cartpole environment" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "source": [ + "env = gym.make(\"CartPole-v1\")\n", + "print(env.action_space)\n", + "print(env.observation_space)\n", + "print(env.action_space.sample())" + ], + "cell_type": "code", + "metadata": {}, + "execution_count": 2, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Discrete(2)\nBox(-3.4028234663852886e+38, 3.4028234663852886e+38, (4,), float32)\n0\n" + ] + } + ] + }, + { + "source": [ + "To see how the environment works, let's run a short simulation for 100 steps." + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "source": [ + "env.reset()\n", + "\n", + "for i in range(100):\n", + " env.render()\n", + " env.step(env.action_space.sample())\n", + "env.close()" + ], + "cell_type": "code", + "metadata": {}, + "execution_count": 3, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/gym/logger.py:30: UserWarning: \u001b[33mWARN: You are calling 'step()' even though this environment has already returned done = True. You should always call 'reset()' once you receive 'done = True' -- any further steps are undefined behavior.\u001b[0m\n warnings.warn(colorize('%s: %s'%('WARN', msg % args), 'yellow'))\n" + ] + } + ] + }, + { + "source": [ + "During simulation, we need to get observations in order to decide how to act. In fact, `step` function returns us back current observations, reward function, and the `done` flag that indicates whether it makes sense to continue the simulation or not:" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "source": [ + "env.reset()\n", + "\n", + "done = False\n", + "while not done:\n", + " env.render()\n", + " obs, rew, done, info = env.step(env.action_space.sample())\n", + " print(f\"{obs} -> {rew}\")\n", + "env.close()" + ], + "cell_type": "code", + "metadata": {}, + "execution_count": 4, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[ 0.03044442 -0.19543914 -0.04496216 0.28125618] -> 1.0\n", + "[ 0.02653564 -0.38989186 -0.03933704 0.55942606] -> 1.0\n", + "[ 0.0187378 -0.19424049 -0.02814852 0.25461393] -> 1.0\n", + "[ 0.01485299 -0.38894946 -0.02305624 0.53828712] -> 1.0\n", + "[ 0.007074 -0.19351108 -0.0122905 0.23842953] -> 1.0\n", + "[ 0.00320378 0.00178427 -0.00752191 -0.05810469] -> 1.0\n", + "[ 0.00323946 0.19701326 -0.008684 -0.35315131] -> 1.0\n", + "[ 0.00717973 0.00201587 -0.01574703 -0.06321931] -> 1.0\n", + "[ 0.00722005 0.19736001 -0.01701141 -0.36082863] -> 1.0\n", + "[ 0.01116725 0.39271958 -0.02422798 -0.65882671] -> 1.0\n", + "[ 0.01902164 0.19794307 -0.03740452 -0.37387001] -> 1.0\n", + "[ 0.0229805 0.39357584 -0.04488192 -0.67810827] -> 1.0\n", + "[ 0.03085202 0.58929164 -0.05844408 -0.98457719] -> 1.0\n", + "[ 0.04263785 0.78514572 -0.07813563 -1.2950295 ] -> 1.0\n", + "[ 0.05834076 0.98116859 -0.10403622 -1.61111521] -> 1.0\n", + "[ 0.07796413 0.78741784 -0.13625852 -1.35259196] -> 1.0\n", + "[ 0.09371249 0.98396202 -0.16331036 -1.68461179] -> 1.0\n", + "[ 0.11339173 0.79106371 -0.1970026 -1.44691436] -> 1.0\n", + "[ 0.12921301 0.59883361 -0.22594088 -1.22169133] -> 1.0\n" + ] + } + ] + }, + { + "source": [ + "We can get min and max value of those numbers:" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[-4.8000002e+00 -3.4028235e+38 -4.1887903e-01 -3.4028235e+38]\n[4.8000002e+00 3.4028235e+38 4.1887903e-01 3.4028235e+38]\n" + ] + } + ], + "source": [ + "print(env.observation_space.low)\n", + "print(env.observation_space.high)" + ] + }, + { + "source": [ + "## State Discretization" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def discretize(x):\n", + " return tuple((x/np.array([0.25, 0.25, 0.01, 0.1])).astype(np.int))" + ] + }, + { + "source": [ + "Let's also explore other discretization method using bins:" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Sample bins for interval (-5,5) with 10 bins\n [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5.]\n" + ] + } + ], + "source": [ + "def create_bins(i,num):\n", + " return np.arange(num+1)*(i[1]-i[0])/num+i[0]\n", + "\n", + "print(\"Sample bins for interval (-5,5) with 10 bins\\n\",create_bins((-5,5),10))\n", + "\n", + "ints = [(-5,5),(-2,2),(-0.5,0.5),(-2,2)] # intervals of values for each parameter\n", + "nbins = [20,20,10,10] # number of bins for each parameter\n", + "bins = [create_bins(ints[i],nbins[i]) for i in range(4)]\n", + "\n", + "def discretize_bins(x):\n", + " return tuple(np.digitize(x[i],bins[i]) for i in range(4))" + ] + }, + { + "source": [ + "Let's now run a short simulation and observe those discrete environment values." + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "(0, 0, -1, -3)\n(0, 0, -2, 0)\n(0, 0, -2, -3)\n(0, 1, -3, -6)\n(0, 2, -4, -9)\n(0, 3, -6, -12)\n(0, 2, -8, -9)\n(0, 3, -10, -13)\n(0, 4, -13, -16)\n(0, 4, -16, -19)\n(0, 4, -20, -17)\n(0, 4, -24, -20)\n" + ] + } + ], + "source": [ + "env.reset()\n", + "\n", + "done = False\n", + "while not done:\n", + " #env.render()\n", + " obs, rew, done, info = env.step(env.action_space.sample())\n", + " #print(discretize_bins(obs))\n", + " print(discretize(obs))\n", + "env.close()" + ] + }, + { + "source": [ + "## Q-Table Structure" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "Q = {}\n", + "actions = (0,1)\n", + "\n", + "def qvalues(state):\n", + " return [Q.get((state,a),0) for a in actions]" + ] + }, + { + "source": [ + "## Let's Start Q-Learning!" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# hyperparameters\n", + "alpha = 0.3\n", + "gamma = 0.9\n", + "epsilon = 0.90" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "0: 108.0, alpha=0.3, epsilon=0.9\n" + ] + } + ], + "source": [ + "def probs(v,eps=1e-4):\n", + " v = v-v.min()+eps\n", + " v = v/v.sum()\n", + " return v\n", + "\n", + "Qmax = 0\n", + "cum_rewards = []\n", + "rewards = []\n", + "for epoch in range(100000):\n", + " obs = env.reset()\n", + " done = False\n", + " cum_reward=0\n", + " # == do the simulation ==\n", + " while not done:\n", + " s = discretize(obs)\n", + " if random.random() Qmax:\n", + " Qmax = np.average(cum_rewards)\n", + " Qbest = Q\n", + " cum_rewards=[]" + ] + }, + { + "source": [ + "## Plotting Training Progress" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[]" + ] + }, + "metadata": {}, + "execution_count": 20 + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ], + "source": [ + "plt.plot(rewards)" + ] + }, + { + "source": [ + "From this graph, it is not possible to tell anything, because due to the nature of stochastic training process the length of training sessions varies greatly. To make more sense of this graph, we can calculate **running average** over series of experiments, let's say 100. This can be done conveniently using `np.convolve`:" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[]" + ] + }, + "metadata": {}, + "execution_count": 22 + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXsAAAD4CAYAAAANbUbJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nO2dd3gVZfbHvycdAiGUAKEZelGqkY4gICDo4rr6U3dVVKxrWdeKde2ylnXX1bWiYu8FpYmAKCol9AABAgQIBAglQALp7++PO3Mzd+70O7fk3vN5njyZeeedmXfu3HvmzHlPISEEGIZhmOgmLtwDYBiGYYIPC3uGYZgYgIU9wzBMDMDCnmEYJgZgYc8wDBMDJIR7AADQokULkZWVFe5hMAzD1CtWrVp1SAiRYaVvRAj7rKws5OTkhHsYDMMw9Qoi2mW1L5txGIZhYgAW9gzDMDEAC3uGYZgYgIU9wzBMDMDCnmEYJgZgYc8wDBMDsLBnGIaJAUyFPRGlENEKIlpHRBuJ6DGp/V0i2klEa6W/flI7EdFLRJRPROuJaECwL4JhwoUQAp/n7EFldW24h8IwhlgJqqoAMFoIUUpEiQCWEtFcads9QogvVP3PA9BV+hsE4FXpP8NEHXNz9+OeL9aj4HAZ7hnfI9zDYRhdTDV74aFUWk2U/owqnkwG8J603zIA6USUGfhQGSbyOHaqCgBw6ERlmEfCMMZYstkTUTwRrQVwEMACIcRyadNTkqnmRSJKltraAtij2L1QalMf8wYiyiGinOLi4gAugWHCB4V7AAxjEUvCXghRI4ToB6AdgIFEdAaA+wH0AHAWgGYA7pO6a33//d4EhBBvCCGyhRDZGRmW8vgwDMMwDrHljSOEKAHwE4AJQogiyVRTAeAdAAOlboUA2it2awdgnwtjZRiGYRxixRsng4jSpeUGAMYCyJPt8EREAC4EkCvtMgvAVZJXzmAAx4QQRUEZPcOEmVrpnVUYTmPFBt+v34dVu46GexiMDlY0+0wAi4loPYCV8NjsvwfwIRFtALABQAsAT0r95wDYASAfwJsA/ur6qBkmQnjn150AgFnr+OX11o/W4E+v/hbuYTA6mLpeCiHWA+iv0T5ap78AcEvgQ2OYyGfbQY+jWnmVr599eVUNVhYcwYiuPB/FRAYcQcswQeDRWRtx5YwVyNt/PNxDYRgALOyZKOPD5bvw2co95h2DjKzxnyivDtk5K6pr8I9vc1FVw9G8jD8s7Jmo4sGvc3Hvl+tt7fPBsl3YeajM1XHIE5Wh9MO/94v1mPn7Lpz97OIQnpWpL7CwZ2KSkpOVKD5RASEEHvomFxe+8mtAx5twemvNdgqhtP9l2yEAQNGxchwqrbC0z9wNRciaNtsbCcxELyzsmZhkwBMLcNZTP3pdJwMVdh2aN9Rs31tSHtBx7XCkrC5lw/8WbzfsW3yiAmUV1XhtiaffzkNluPWj1fh4xe6gjpEJHyzsmZjE6x8vAvOPv3poFgCgVVqK5vZtB04EdHynmD28znrqR5z/36UorfDMKdQKge/XF+H+rzb49T1cWoGsabOxcPMBS+cuq3A2T3Gqsiak8w3Xv5cTUw83FvZMTBNoKJRsptETrtW14Qm2+s6C3//OQ2XYXuyZqyg1mEjeVOTxKHrn1wJL5z79H/ORf9D+Q67nI/PQ9cG55h1dYsGmA5oPt2Bj1cTmNizsmZimNkDN/rf8wwCAlxZu09xeFaY895U2NeSftribjHDjPnsup1v2h+cNKNQs33EY2U/+iHm5oU8qwMKeiXpeXrQNd362VnNbgLIeW0zMNG5r9vtKTiFr2mx8u3avq8dtmZbsXe720FzNCetgpoQ4WRk6F1XA13zn5C3EKTmSl9a6wmMhO6cMC3sm6nn+h634arW5cHzw6w2ue6XY1bDNeG7+FgDA3z7Rfng5JbNJ3ZxDZXUt1u4p8a6T5ED6a/5h3dw3gc591ITY3KU83dh//YwCl11v9ZAfag0S40NyPiUs7JmoJGvabNz3hbm/vdKM8+Hy3brmGKe4bcZJSdT/yd43wXmlrMR4a6JAby5ALazJps9pqOc21Oa7/cdD4zU1e73HfPP1GnffzKzAwp6JWj7N8Y2k3V5c6tdHrZAGatZR47YMS06o0wgHPf0j8vYfR8GhMmRNm42PVuxyfNz4OGvCOU5HiKuFtcXDeQl11K/64ZSU4FwU7iguxUPfbECthZtdcPgkAGD/sdC55MqwsGdihjEvLPFrU/88F2856Oo50xsmunq8FMXr/4HjFXjz550Y9fxPAIA9R045Pq6eEAeA2RvqJhP1uqmFNdmMHS456dx8tufISaxTmJ2soH6ot0hN1u5ogZs+WIUPlu3GVhPbf/GJCnTKSAUAnKqqcXw+p7CwZ2Ia9eu8kfWhsroWk176Bb/mH7J8/GqXNdZklQYaqDeRTFqKdgLcE+VVPr7oeh9PpcpcdeSkvZq8pQ598wFgxLOLMdlmBLRbnxsAlFV4BHd1jf4xtx44gbOe+hE7ikMzN6AFC3sm5thz5KR3Wf2bH9lNPyXxvpJT2LjvuC3f7CqX7TjJicER9o00hP2O4lJMfTfHp03vYaiM3gX0Hx56lIdY01V/biWnnBeM31vieaP6YlWhbp/cvaH3vlHDwp6JOUYoEoXd+tFqn21G5gdZPOxWPCzMqDHQ9pyg9uLQe5b8aUA7W8fVemaMfmEJVhQc8WnTM/esUZlRGibZE/bqCeK1e0rwyLe5ul4+xSc8Ub2L8qxF9cpU1dTio+W7/Wz26jcTJ5yq1H9gac0XhRoW9kxMIycPk3n7151+Oej3HDmJDQ79oqtq3fbG8RX2esLQonONl2cll04zCo9qzwscV7ms2nXFVNv8L3zlV7z3+y6/ojAysqZ8rerNw4zXl2zHA19vwOc5vlp4WoPA51aM5me27GdhzzARx6SXlvqsj3h2MS54ealO7zpOf2SenznCyI7rBPVEpJ4Zx6p3jczPW61F0Cona5WotdpaIXD9eznIUb0Z6KGnWS/bcdjS/laRbeay6UXG7n06dqoKX632fWAcLtM3BVVUh35CVg0LeybieG5+HuZv3B+047dpop20TMZKgI+W5lpWWYN3fyvwaat2WbP/RFWYRe/wahu6kkADoLR4YcFWn/XiExVYsOkArn/PXPP+bt0+fLNW23//pI5ppOCw/0RnTa3Aw9/k+szJKDl4vBxfSf7tB1R+9XbnPvo+9gPu/GwdNu6re+NTH1NJhc7DbF/JqaDcDy1Y2DMRxyuLt+PG91f5tdfUCld+GOkNkxztpzy3nvfI9Ll5PutVLmv2TVTmBr0UBvM36tuyQyFb5DQSRy24VN728RpsLtLOpaPnovjYd5v82tbsPor3l+3C3z/Vji6+Q9HevplvSuqaWoH8g6XImjYby228TWzcWzfuHq0b6/ar0LiO938vwNDpi3Drx2ssny8QWNgz9YbOD8zBzR+sNu9owiYdwWIHPWHfv0O6z7rbrpcNk6xN0KrZUHgMD3/jmfB0w4PnyhnLMeCJBbrbW0spnxPsRlepsOOPLkft1kjX98rifOQfrLOV/7a9TojLkawyNULgmTmbAQCv/7xD9xzPzN2MborMnD9trYvLGNalhe5+WuUpP1qxR3MswcJU2BNRChGtIKJ1RLSRiB6T2jsS0XIi2kZEnxJRktSeLK3nS9uzgnsJTCwxL0DzTiBeF0rBeqqyRtNdsEtGI591ZWRpba0wfNW3NgZfQW1Vbl/y+m94f9kulFZUY6mNOAE9ftl2CEfKKnVt0bLg7dgiNaDznLKRIE1+rtTWCuwrOYXn5m/BJa/9ptlXbbOvqRVYmOcR3Ivy9APrXl+ywyff0dDOdQLeaJ5kh0buncY23VMDxYpmXwFgtBCiL4B+ACYQ0WAA/wTwohCiK4CjAKZK/acCOCqE6ALgRakfw0QE3wSQk0QpaEe/sASXvv67Rh/fdeXE3yuL8zHo6YW6NmUr2H1Y1dQKHC+v8nq1LNx8EFe/s9Lx+dVco3Msed7DKDLXCqcqrV+vLGxrhMDlby7z7C89kI+ZmJOcJmLLaFwXeWv3EFbSK7iJqbAXHuR3oUTpTwAYDeALqX0mgAul5cnSOqTtY8huViQmavlpy0EUn3CneMPGfcfw8iJ7ics+DKAykVogrCs85memUNvQlRO0SySPl0CSbvnbwI0FxqSXfkGfR3/wrt+hY892itI0okR+MDr55Zcoom+bNUqyLBTlB0tNLbBLykEjP59HPm9chN2p4FW+WdUKgRlLd+K5+Xn6OyjI0ckgGiws2eyJKJ6I1gI4CGABgO0ASoQQ8jtWIYC20nJbAHsAQNp+DEBzjWPeQEQ5RJRTXOxu4QQmMhFC4Op3VuKyN/w1Yidc8N+leP6HrYZ91JpwUYn1/DGnKmt8smC+9ctOvz5+9m/VqnKCVv5xV+j4jjvBzIyTF6aiIAelB7qT9ABK09fD3+Si0wNzLAljWdgfVXgiyZ+PWe6d71R28xcXbLVUhvGmDxSOBAJ44vtNeMWk/m+4sCTshRA1Qoh+ANoBGAigp1Y36b/Ws9zvTgkh3hBCZAshsjMy9EPUmehB/r1q2S9lRktJvewczwi1Nn7QxltFz0fm4V8Kl8IvV/uHw6vH0CzV19NHy/UykND8Sb0zHe/rFupJ5x83+QvFuZI/vlk+fy3ziVbZPjmD6c9bi5E1bbbmseT9lG9OAsJSKoZftvkqnP9ZuA1TZ3rcRn/NP4SsabNNJ9vdzLcTDGx54wghSgD8BGAwgHQikmcY2gGQHWULAbQHAGl7EwDWIiuYqMb7am/Qx+hBoIeRO6bd4KJAGdTJ9yVWK1gnkPS2Qzr7vSSHnNtUroLXafjSWw1SeusXf8+XCf/+xa/tsCTI//dTvu6xrnp7hV9bVY2wlD5Zzw8eAP7y1nIAwAfLjFNIq1NLRBpWvHEyiChdWm4AYCyAzQAWA7hY6jYFwLfS8ixpHdL2RSJUUQNMRFNnx3VXAMvfLq2vmVNty2nZP2WQDaBdlGOrSSlDNXn7j+OdXz0mJPXRwvHDmptr7hE1tIvnoWRUkWnBpgN4Zq41+7b8nXFiWtebV1BiZR5pywHjlAdHDQLZjLhueEdH+9nFiu9PJoCZRBQPz8PhMyHE90S0CcAnRPQkgDUAZkj9ZwB4n4jy4dHoLwvCuJl6iMvBpF4Kj57CjkOl2FfirzEfL3eWJ/3Vn5zZXZXeGYDH5FFRXYN4xQPOivBRImu61wzr6Gekj1Q9qpmUH753uya6faxE18pU1wg8Omujo7eitTZz3euR1sBYXOq9zew+bOx91ad9uuF2tzAV9kKI9QD6a7TvgMd+r24vB3CJK6NjogorZhw91HZXZaTq6Bd+QnWtwMCsZv47OpSFTic2m6uKYFTXCnR/aB7OPK2pt00vmZgVIkGzt4a7I3t/2S5NW74V1u62J+yzmjf0VpRSYpbBVK94ydnPGXsCZSu+G8GEI2iZkBHIBNYuxY/vVGUNXltSp3nLppKaCNRyZW1Pr1C3HY6drLKl2RYdc/5QCRR54nXFTnfs2E4FPQD8bjOZml49XrM6uQePOxtjqBzTWdgzISOQGBKl//oJHdOMlmdHuMW/m7VVNxYdw3u/+04SGj3fLvivvepNbmImGJduCzyKN1jojd0sqZ3Te223hKNTWNgzIcOJfVkIgQWbDvjYQ4+d0hb2WrbZUCv7ZRXVPuMwE3p6ZE2b7edi+MrifNw6uovlYwSiDQfKGoXppEDDw+qKGctDORxbqEs/ymjlt1GiDnjL23/c0kR/qBzGQpucgYlpnMi9GUt34snZmzFU4XJ47os/W95/9e7QRine9fk6n3Ut3+zz+xj7yiv91pVFU37NP+xXNtHtZ9nbV2fbLgiixU6FgB/1/E946fL+OHSiAteGyPMkGHyrk4ZZDy0XUk1Y2DPRhmyzlwXUF6sKMbxLC7Q2yC//5GxPJkK7Hiwyf/0w8CyZgaBVg9aozi3g67depkoE5nISTT9G92gVlOPeLvnmbztYig6q9MKRhtIcGIr8NWzGYaIOWdjLybnu/nxdRL/Ou4GWZm9nolrd1T/rpfvCKJjeIR+v2I1/zrPmW+8WRoF1fTVcQ5XC/sUfjdNx6GHnIREqMw4Le8YV9L7cQghvoJGydJ1snlDmG49GtD4WI+28TJUnXy3MQ6FpntFW3ze+PmKU0fLu8d392pR1g79Y5Z8iwwr/WWg9QV+o8kSysGcCZs6GInR6YI5m6t73ft+FSS8txW/5h/Dh8rqMk3IIuhJ19Gm0onYRnbOhCFnTZuO6mSv9hItSTt00srPfHMRelc9+kt1K4xo8MLEnLh/YPuDjuMnoHi2Dclx1MRjA15/eaaUxW8Le0Rnsw8KeCZj7vlwPAPhcQwvK2++pCrXzcJmpa5q60He0otbW5XmFHzcfRO5e3wee0uX0tSXbsXiLb8Ku3YoH7PIHxmDj4+NxaXZggjopIQ4jutpPTtiiUbJ5J4cESyAmJ/gLe6UHlds1hLXQ8y5zGxb2TMDILmk/aFSRypVqdC7bcSTkbpCRipFZQZ2Qy+wzi1MYfFulpSAxPk63Lm2wCaY1wqkLqxmZGs4BynkRvYLnbtKicfAekkpY2DOuoZViYIOkqS42KPWmh7KIRTRhJOzV+ffNkqZZqVyVZrH8nbKEoLqwuRXcKkqjRbA07OYabyNK000gZSz1yGru643EZhwmIjlUWoGsabPx3bp9OF5ehSe/3+Td1qJRku5+aSkJttMl9Htcv6B1faZWCNTUCgx5ZqFfmcRyVU1X2fU0EBIs2vHH9apzuxwaAamUlVRVh+5txWmJQquo8+4EWrrRKizsGVtskbT36XPz8MycPLy1tK56U28DL47z+7aJWjPOZzcOsdW/tLwaldW1KDpW7p3vkLFSaMMuWsLkvDNa+7UpTUiRVkk0GLni9dIvh8JOr4Rz4zARyQGpCtDeklPe/N1yHdbzemfins/XadaF/WHj/rDZkoON3QIpLy3K934Wai2y3IWShWkpviYYLcVeK9mX+s2rbXqDgMcSyXRt1UizPdiafbhgYc/oIoTw8xzZXHTcuyxPmsn/5+Xux+erCjXrwhYcPomhnVtonqf/4z/gjk/WaG6rDxxxULSi1yPzAfhPPBpVTDJiYu86TT1O9fDR0uzj4wjjT/eNllULuQYabolGhLgoWMDozTEEazJYD9bsmbDT+9EfcI6qJux36+oKM/+oKshcWmGcKEqtccocPVmFb2zmHXGbu8d1c7yvmxPJLR16ZijNLuoHtJawv/Ss9pg6vJNPmzrRl16qXz3s9jdjapDz6Dx/SV/N9mCbG9VzW2yzZ8JGaUU1sqbNRmlFtd9k0sET+vnU1bnLlfbnsT1bRrQZZ4jOW4cVurdu7No4lmwtNu+kgZHASIj33fbjnWdjcKfmGNixGWZMyfa2b1NFMyfpZH/Uw+lbiR7BNKe0SkvGsC6ee948Vd+xIBh8fP1g/H1snXLB3jhM2DjjH/N1tyl/fyO66gvI8qoa9Hh4nnd9cKfmPtkcI4U2kp91IIXJu7RshC9vHurWkByhHL16cjVBdW2dM+ps1crUCEoTHQAkxYfXLuM0VYEVFtw50rusNnsFkxFdW6Brq8b429iu3jZOl8BEPOkNPRqRlqDUCg5atsN9jwqnvHbFAKx8cKz3XSM+gB9cw6QEDOgQmjqiehjJq8Nllbhy8GnedaVwaZWmn3HULH97sLGS5O2/l/tVTLWE0qQYaHyAnYLh708d5F1u38wzAc6aPVNvsPK6LSBw48hOpv1CxYiuGchonOy1z8bZ+CXcf14Pv7Zwuyoanb/kZBUenNTT9jG3mAR0BZvINfoBtymKyDx0fi9Hx/j8xqF47YoBIXuzYGHP4EhZJY7rlPpzyk9b/CNmX9Dw0gkWPTPTDLfLNm55HsHOJNmNIzujkyLaNBIwG32lg0T46RpRtI0tRuO6QSA1i43o0lLb5RKw7hlz1zj/bJl2ad0kBRPOMC5k4yamwp6I2hPRYiLaTEQbiehvUvujRLSXiNZKfxMV+9xPRPlEtIWIxgfzApjAGfDEAvR59Afb+2nlapf52ydrfdZnLN2JvSXuFsD+6e5RutvMfrPqH7WVH/n401uhhzQZG2la51drjMvfNUryCOnbbJQ1/EPfNn5tTtIoOMXK/OzI7vYTtv2osNeridbAP8CaZl8N4C4hRE8AgwHcQkTye8uLQoh+0t8cAJC2XQbgdAATAPyPiOw57DJhxWjiVcncXP/EZ3ocOO5+3pQsA+3a6oSrnOjKimb/+pXZmHfH2dYGF2TsCt24OELB9Em2NNLxp3t895VvMWYxBdcN74ibRna2NTYtRvdoaclmn5aSiB1Pe/VM3DyqMz5Q2MXVPOTAnBUtmAp7IUSREGK1tHwCwGYAbQ12mQzgEyFEhRBiJ4B8AAPdGCzjLsdOVaGi2j88f3An37woe46c9EbORhp6KRrMZL0s2+VJSLtm02BUiLLD97cNd/2Y6jmVoV1a4Pf7R/t4rsjLKYnaouOh83uhUbI13U7P5XFsz1Z4++qz0L6ptfKFSpv39+v3GZp/AvG6knnnmrP82sxKTQLASw4nk93Cls2eiLIA9AcgV564lYjWE9HbRCTXMmsLYI9it0IYPxyYMNH3sR9w0f9+865nTZuNmb8V+PUb8exiDHp6YQhHZh09bwyt6M9hXeoeYuq6n+GeYLVLexfruA7q2AyAtsDKbNLAR0C2TW+AgumTsPyBsbqBaLLw7WpgGwf0I3RrpNw0vTVKBpqx58gpNG2o7zfvxl0epfE5vXlVXbyC3ptxqs2IZLexLOyJqBGALwHcIYQ4DuBVAJ0B9ANQBOAFuavG7n6PWiK6gYhyiCinuNhZIAnjnG2Sp8XGfb6+1f+YtTEcw3FMok7gT8Mk/4nEBIXLjSy/5PS/ekLg+hHBjeIMBKMso3aQg67s5P9q0iARt47u6tP2x/4enU42iZlNsOoVs1Gn4bBD4+QEpFp8s3CKlmKgDEB79A+na+53tgXtP5hYEvZElAiPoP9QCPEVAAghDgghaoQQtQDeRJ2pphCAslROOwB+sfBCiDeEENlCiOyMjPB+CLFIcWnwco87wUwL1EPrrXxsz5Z4WMMdTlkFSv7BJkuZD/Vs9r3bafvPy/t/fpO9jJdu4pYlSb72QLM9pjf0zCPEe4W9cX+9eRzZlVcvvYYR8fFkrNkH8Q1umuSSm9E4GZec2c5nW9v0Bq6nk7CLFW8cAjADwGYhxL8U7UqfoT8CyJWWZwG4jIiSiagjgK4AVrg3ZMYNjL54Rn7z/YMUPETkzJ6qtc9bU87yKxABAGWVdUFC8l7HpZJwejKgfVPjzI+h9E5R888/9XHlOHKErdF9//624XjtigGGx5Ft8LIZx+zhcUZbbfdYWaN/aFJPPGLRh13O0NmuaQOkN0zE+X0yNR/EWt/fyf38vY6ccOPZnbDj6YlIS0nEMxf19tlmN/VEMLAygmEArgQwWuVm+SwRbSCi9QDOAfB3ABBCbATwGYBNAOYBuEUIEfzaXowtWjXWj5w0ErqntzH2X7fCoxf0woWqH1gcEZo5yFGSoVP3VEuDG9WtpWK7578c6aun2evVVd15qMyvrbVBNGowOPO0puadLBAvmbeMhP0ZbZtY9gk/Q/qO9G9vPL42TbQfpLXSOFKTE3CtxehUeXK5b7t0EBFe/vMAnJXVzKdPzkNj0UfjTe2JC8+wdA4ziMj7oFMXjFGnrAgHVrxxlgohSAjRR+lmKYS4UgjRW2r/gxCiSLHPU0KIzkKI7kKIucG9BMYJRknJ9IT920t3ouRk4MFXU4ZmITXZ16ZeUV3ryMPFzmv5PEWNXHm/RtI4GupMniXreJ3IKGMH/jKog+WxuIHepdsVK3KQUdMAE4LJz4pBnZpj+QNjfNIua6FV/xUAaix+D/oqJnDJGySnzZJ7Ruk+uPXMRaMc+PDrYbVaWDAJ/wiYoCGEwKK8A5rBT0a/Jz0l5PHvN+H79UXaG21ARLhYZdOsrK7VtPEqPWiCid5Dw8yMfbKi7qX15lGB+5e7gd1H5l3juuH9qQP9NGG7KD25jHLuyOgJdavZLpVxFrKicEqnQLiTNMLPumQmA/yTzIUDFvZRRnVNLW7/eA027TuOV5dsx7Xv5uAJRZ1YGSNPCbVbYjDo38H3Fb9FoyTU1Aq/4tjn9vQtsBEIsouhFnoPuETJU2WgjiBUCqxQa29W71Oyib04MT4OI7oGrsUeVgVcDeroeVC/8mdtW79aB5FNHVZ81gHf5HVyLd+vdSKJzfLPTOrtb6IKdDJX77rDBQv7KGPHoTLMWrcPE1/6Bc/O2wIAmPn7LszLLUKZorjI+sJjeocIC/FxhFoh8CeVxq/8kVqN7NXjuhH6idi0BOel2e3RvFEyCqZPwmc6XjdWA4jcpGD6JM+CjixSm8OSwmRCaJqahILpkzCpT6amSadG9dok55dXpmA2QvnduELK6qlnSjMzmb94aT+seHCM3z5P/7G34wC2SX1Cl/fGCizsowy97/RNH6zGtK82eNeX79RPNzw3N3BTjV2ICEJ4XrevHprl0y5z7bCO+G3aaEfHv/+8HprauSwYSeOXcG4v/bcK2QunV6Z54I+ebdpNOiiCrNQvbZP7u+NtYkYPgyIu3Vt5Jm1lU9fAjs1QXeM70LvGdcODE3viAo2cPEr+fWk/AHXzLYDHx/+tq7LxmI6Pu555RyYpIQ4tVU4L8XGEPw/q4JPzvz7Dwj7KMHrz3H2kruqU0WTo6t0luttG92ipuy0QjpRVorSiGodKK5CSWKctKzWyuDhCG40i2B9ep58LRaZVWophGmOtj23fMf3EbfKErpXJxFJFXninWSO1JpCV9/rZi/Xty+eFKLOiUVKyW0d3wZc3D8V9E3rgzauy8f7UgX5BU8kJ8bj+7E5+DgK3j/EN3jq/TybuHtcN94yvy/NDRBjbq5WuKa2Rg8/9pMkDor7Bwj7qMJD2CsFkZQJN+xDByQkjuzJ+u3afz+u9cmJN71Vcfv0HgDeuPFP3HHYn6YwmCmWBVGthMvGEwnw2pJP2hLPaD1vtpy3nAFIH68go507BDLIAAB5KSURBVGDUIwpVJoi2Gg9imfg48rqKnturFZIT4i1PxGarXEwT4uNw6+iufh5dRlg1ZXXKqJv0VR5f+WCRuXxgB812La4ZlmWpXzBhYR9lGP2wjygKYzv10Q5iWVAvyrwvPpq9wcWdJgVR6b1yt0pLMfxstCbjurbUN0skeAOH7H0getegFkbqdXm/sxSTzMojpSrSQ6ifx6EoaD2sS3NcMeg0844K1MJezx1YmWbgkxsG2x8crJcenHVrnX1emcvmNI0gvWcu6o1bzrGWMtrouxQqWNhHGUZf6T1H6swSTos5Oy2IbQel0FAKLiOZNfOagbh9TFdN+/hzF/fBkM7NbQs9I/kgexPp+efroTeERJN6r17ThuLzUNqse2TWCZN+qijRUCj2fxrQznbFJav+9ACw4oEx+PLmoX4ZWa1iteyk8jNVmpMCVXL0ooVDSejKzjAhwaq72M/bIjf5nFJoLMqrq3hl5GqY1SIVd56rnYUxo7EnmMaugmv0WT5zUW9cMyzLtjlMT76ZuW2SV9YLRRvhg6mD8P6yAiQn1D10/tC3DVo1Tsalbyzz9gsWk/pkYvb6Ikdup2qFw+j+tkxLQcsAIpSdpOJQfm5OzZf5T52HgsMnDatjhQrW7KOI4+VVun7GMq8t2Q4AeOfXghCMKHDi4wj92ns0VacR57JA1hImsneIli+6kYxMSYzXDL03Q8scAAAX9PH1QFGfW09YDe/aAq9fme3XrpzIDmbuffnYTu6NOuulUVR3oITClKVFQnxcRAh6gDX7qMJKacHpc/NcqSQUKpQTl04LM8sapNbut47u6peq13u+IAiIjhrVtQZ0SEc7VcK1MT1bIS0lAcclTx5ZMFo1JyhTAARzmkWeS3fyWQWrxqwWgeamkYeqVaqxvsCaPeMKcnpbtyk8esorrALNJWXFnKFMtbxi5+HATqg5Bv+27q3T/K6tSYNEzL59hHf913zPWL5b55ctXJMmivsRTJlaG4Bm73TeyAlOFYVogoV9PWb5jsPImjYbBRoZGENF89QkbHlyQtBCw1ftOqpYc/aDlQWs2e99zcPn+nhjHCo1rrdqh/sm9ECvzDS0VmR6bCNNJv+hbxvNB5GWgDqh8Nm3SqVBYfhAkeW1k3kBdVCV1UnUYBMsxSXcsBkngjlwvBylFdW64ePfrPVoeb9uP2RYfDuYpCTGIzkh3kcMd2jW0CeAyy2cygLZVm8mkNRZH7cXlzo7oQY3j+rsnR8474zWmHBGa0zuV1etM2+/f6IsrdE6sWuv31NiOd+MXWQvIidmEqXb6gMTe0SMbXvtI+PCPYSgwMI+gpHrvnpzoahIkn5oVdXB09zMGCj5fSsF6ZmnNdUV9p0znD+UQq33bZVKN7rNq1f4B35pmVq0nk25e+1nT3QaQGeFJy48A+2aNsCo7vYjq5U2+xvOjux5pLQGHlHZKk07TXJ9gIV9PaZK0ozCWWJQjvRUCiYj7w+tdAdK1JWfOrZIDdjobJQmwYhQBsLIV9gzMw3T5c/Upcfb6J7BSXEBeIq7PDjJWjUpNS0b1x/BeU73lvjX//WNuORmdmCbfT1mzgZPwrJXFm8P2xjkPDZKsbS5SF8jNpuUO3bKtziK0uUwmP7iWgQrD5AW8gNySKfm6Bugq6kavaId4SZbSkx3ncVqVOGEiHDRgHY+8Qz1DRb29Ri5apS6xJ8dPphqnkTMCsrJxC0G5g8zd7uemZ5Iw2uHeQRAIAU1ZN95py8GoawbKrwTnYpGDWFvZ/Lwrauy8anD9AKhxEnAE2MfFvZRQEJ8nKWEXDJZ02Z7l4cHmCNexurP1UzwPj7Zk6L2ppGd0LRhok+6Y7s4qWmrxKzoh1WsJOHScmFs1rBu/PIEq53Sh2N7tcIgh+kFooV7xnc3TL0cS7Cwr8dcdlZ7AJ6MiP/7KT9o51ELXPm8SqxaWJSavVYmQNkdr2VaCtY8Mg7dFT9Uu5GgRcfKAQB7j+qnKjYiOdH5K/tfR3X2ZuDsoBM1q6QulqDug1SmIHj9yjPx0fWDcPc4a1kWGQ+3nNMF8+44O9zDiAh4grYekxAvuxQCz/+wNWjnaZPu682hLNwtY2RP3/T4eCzZUoybP1ztEwGqFU2qDqEH6kxEdmNwZBfQds2MJ4X1cKLZt01vgN5tm+DeCT0AeEwpfdqbF7/wPgT1iogTMLSzO29hkUboQqtiGxb2UUKz1CQcKXMvCEhJlSr4peRkFR6c2NNH6zZS7BsmJXiTWCknaLX20cqEKAfb2I24TEmMk87jzCbsRNj/qqqkNdag2pUdIiXgyE2i74oiG9NvMxG1J6LFRLSZiDYS0d+k9mZEtICItkn/m0rtREQvEVE+Ea0nosiquhtFyHKxvKomaIIe0M59f/3ZnXzyjJt5yshavFwrFAC+X+9f/vBsjcLX8gSeXWEve3uo3TmtEsoJWjPClcgrmLSV8gEp6xcwwcOKZl8N4C4hxGoiagxgFREtAHA1gIVCiOlENA3ANAD3ATgPQFfpbxCAV6X/jENOVlajYZL/rZJF39Nz8oJ6/gwL/tC5e40LmDeTik8r2bTPP0BIyzPj6Yt64+VF+bYLrjx6wem4emgWWjusAevWBK0bRGNul0m9M9HsuiQM6Rzbk8ihwvTbLIQoEkKslpZPANgMoC2AyQBmSt1mArhQWp4M4D3hYRmAdCKqv5EILiGEcJxqttcj83WOGciIrJNoISpJq/jGvRO64zmD2qhWldXOGY3w4qX9bGvaSQlx6NbKuSdGUnz99amuDxARhnZpEfL4iVjF1q+HiLIA9AewHEArIUQR4HkgAJAjUNoC2KPYrVBqUx/rBiLKIaKc4uLILaThFh3vn4O7PlsX8HFeX7IdP0gTpBVVdQWRz8pyVmbQCu2aNsDFOrVPZZR1YGW6t2qMS7L9PXdkjjtI6gUA/7msH2ZM8c/h7jaJCaETQt55BZ6tZIKEZWFPRI0AfAngDiGEUYIO7fxN6gYh3hBCZAshsjMygpOkKdL4yqSwiBHHpACqZ+bm4Yb3V/kdzzc7pDWmDDGvGdqjdWPExZGhhg5om1+ClcJ2cr+2GNPTnYlP7eN7gtQymzjz4nECK7dMsLEk7IkoER5B/6EQ4iup+YBsnpH+y/XjCgEo1bl2AKwl4Y5S7AQ86fHb9kM+6+8v2+V7DgensFLPU37FNnvV1hL2ai8eM+6T3BXDzX8u64+C6ZMcT+w6Qf74QlnQg4ktrHjjEIAZADYLIf6l2DQLwBRpeQqAbxXtV0leOYMBHJPNPbHKzsOB55tX1/h8+JvcgI95pgXTz+Yi/5c4rYhE2TWwqSKcv1xhZtIiSxVs9OeB1qNDo41mqZ5JcHWa5Wcu6o2+7cz99BnGDCveOMMAXAlgAxGtldoeADAdwGdENBXAbgCXSNvmAJgIIB/ASQDXuDriesjyHUcCPsb+4+V+2n2gNE4211wzNTxZtLR42TVQqZdWmKRevnNcd9z+8RrveiS5Ooaai/q3hRACF/b3nd66fGAHXB7DD0HGPUyFvRBiKfTjH8Zo9BcAbglwXFGFVlSomoMnypHRKNlrLlHb4P+7cBsOnnA3lXGDJHNvk/SG/vllxvVq7dcmW3mUJqvKamPNvqzCd4JWy6MnVoiLI8PJbIYJlNhVpUKIme03d+8xDHxqIT7PKfS2qQtnuCXo7SYH03IXvW10F782cqDZK/OZF0yf5GeqYhjGPfjXFQIqdDTcrGmzkTVtNj5cvhsAsKKgztwTjBzkfx/bDRdKpfCmnWdtMnScRri/VoBPqvSWoJxkNRP2IzSiZRmGCQ6cGycEmAm9j1d4hH2ipNl+tnIPdh1xPqk7Y0o2ps7M8WufOqIjGibG465x3ZCabH7rVz98LtIteqQkxMd5I2QfkiaP9R5yMpzHnGFCBwt7FymvqsHGfcf9wvorqqzViJWLNt/75fqAxqH0QR/ZLQNLtnqC1uLIo5VbEfRA4Pngza5blvWRlJaAYaIV/pW5yKOzNuJPr/6GXZKr5Wc5e5B/sNRUw5UJhqL77jVneZfdqmlqFbO5CiLCfRN6YNatw0M0IoaJXVizd5FNkk96yckqnNYcuPeL9UhOiMP1Izp5++wrOaVbdNvNHCEfXz8YLdOSfY7ptPC2Xc48rSlW7TqKszqalxS8eVTnEIyIYRgW9i6yvtCT+fFwWYU3VUBFda2PZp9g4F7oZhpbrUyCdo7fVueBZIUGUoUnKy6noeaFS/oikc1GTAzCwj4IrCw4iiGd6hKDKSdodxSXoWXjFM2UwMEOlQ+VEUf2l49EYf8nk4RuDBOtsIoTBI6dqsI9X9RluFSmDZCXH9JId/DubwX4dOVuW+d6aFJPy31DVQDjkQtOx9ndMnweeAzDhBfW7IPAR8t9BbZSs1+ytRiz1u7TzQh535cbbJ1rytAsPDl7s6W+ZgUwWqelYP9xT5FurefCm1dlW8rJ37FFKt67dqClMTEMExpY2IcApQviO78WAACSXIoWVdcm/UPfNo6PpXwWaAn7c12qp8owTOhhM04AlFVU47n5eag0CZoqq/Qv0lHpkj1bra2/eGk/x8dSeu6E2k2TYZjgwsI+AK6bmYNXFm/HN2uNi5L8ss3dbJVGaEWlWk0wdk4PZQFx14bEMEwEwMI+AH7fcRgAsGZ3ScjPTQTT6lEyP/x9JF68tK9pv39ccDoW3TUSDZPiMS1CCokwDOMObLN3gd0B5LExY94dIzDh37/4tV8x6DTLKXE7tkhFxxaputu/u3U45m/cj8T4OHTKaIRNj09wPF6GYSIT1uxdoE2TBkGrt9o8VTv75Ucr7LloGtG7XRPcPb67a8djGCbyYGHvAkO7NMftn6wx7+gAoarV3q99OoDgFfNmGCY6YWHvAmUVNZi9PjhldlMSfatJrd0T+vkBhmHqPyzsXeDRWRuDduyGiealA7+8eUjQzs8wTHTAwl6DaV+uxyWv/Wa5f3UQTSpWSvWVW8yXzzBM7MLeOBp8snKP4facgiO4+LXfvetxBITThB6MEoYMw0QXpmojEb1NRAeJKFfR9igR7SWitdLfRMW2+4kon4i2ENH4YA08nCgFPRCe8nqt0uoEfLdWjUJ+foZh6hdWNPt3AbwM4D1V+4tCiOeVDUTUC8BlAE4H0AbAj0TUTQhhrVRThPPIt7nomZnm1x7kzMSa3DWuzlXSzaInDMNEJ6bCXgjxMxFlWTzeZACfCCEqAOwkonwAAwH8brxbZLLrcBlOa14XjPTe77s0+wXTZq9HUUl5yM/JMEz9JZAJ2luJaL1k5pErbLcFoDR4F0ptfhDRDUSUQ0Q5xcXFAQwjeIx87iesL4xMV8fOLfUjYhmGYdQ4FfavAugMoB+AIgAvSO1a9gRNtVcI8YYQIlsIkZ2RkaHVJSLYfeSkX1v/Duk+6/dOCH30aeHRUz7rvds24XquDMPo4kjYCyEOCCFqhBC1AN6Ex1QDeDR5ZcKWdgD2BTbEyEOd+OyLnEJHx9kcQA6aU5W+0yDf3TYc93HyMoZhdHAk7IkoU7H6RwCyp84sAJcRUTIRdQTQFcCKwIYYXuS87ifKq3T77DjkLBFag6S6gKl5d4zwLmc09njaZDVvqLuv3IdhGMYKphO0RPQxgFEAWhBRIYB/ABhFRP3gMdEUALgRAIQQG4noMwCbAFQDuKW+e+I8Oz8Pk/pk4vI3l7l63LvHdfNZ79G6zstn5YNjTfcf2rm5q+NhGCa6seKNc7lG8wyD/k8BeCqQQUUSuw6fRL/Hf0DJSX3N3gm3ju7q1/bhdYOQf7DUrz37tKbI2XUUo3u0xKK8gwCAZAtpFBiGYWQ4XYIF3Bb0rdNSNNuHdWmBKUOz/Npfv/JMNE9Nwp3n1r0NWK0+xTAMA3C6BC+HSyuwcd9xnN0t+J5BN43s5F3u2z4dI7q0MOzfvFEyVj18rk9bYhw/pxmGsQ4Le4m/vLUceftPIPcxdzI8/HjnSGQ2ScGO4jJc8PJSn23tm9VNvH57yzBHx09MYGHPMIx1WGJIbDlwAgDw1OzNrhyvY4tUpCYnoHe7Jt422bumVxv/lAt2SWFhzzCMDVizB5C3/7g3v82+klPGnS2ilRxt0V2jcOxUFZqmJjk+7tpHzsX+4+WWUh8zDMPIsLAH8MmKugwPp6qC5ykaF0cBCXoASG+YhPSGgR2DYZjYI+aF/UPfbMAHy+qKd6/YeSSMo2EYhgkOMW8LUAp6hmGYaCXmhT3DMEwsENPCvromsNqt7107EL/ce45f+9y/jdDozTAMEz5i2mb/yKyNAe2vF4ClVc2KYRgmnMS0Zj9nQ5HjfXu3rfOfb8kZKBmGiXBiWrMPpHbsjKuzvctL7jkHOw6VYtJLS/GPC3r59f3qr0NRXROGQrUMwzASMS3sA6Fl47pkZg2S4nF6myYomD5Js++ADk012xmGYUJFTJtxGIZhYoWYFvbCoR1nbM+WLo+EYRgmuMS0sHfCiK4t8MaV2eYdGYZhIoiYFvZ6ev3401vp7pPVPBVxGknOGIZhIpmYFvYnyqs12+dvPKC7zxCu/cowTD0k5oR9Ta3A/mPleOTbXL9tZlWqLj6zHSb2zgzW0BiGYYJGzLle/nNeHt74eYfmtkbJxkW8OygqTDEMw9QnTDV7InqbiA4SUa6irRkRLSCibdL/plI7EdFLRJRPROuJaEAwB2+XlQVHdAU9ACSZFATp3yHd7SExDMOEBCtmnHcBTFC1TQOwUAjRFcBCaR0AzgPQVfq7AcCr7gzTHS557XfD7ftKyr3Lc24fgXeuPguXD+zgbRtuUhicYRgmUjEV9kKInwGoK3pMBjBTWp4J4EJF+3vCwzIA6URUb4zcKwrqLrNXmzSc06MlhnWpm5AlYi8chmHqJ04naFsJIYoAQPovRxm1BbBH0a9QavODiG4gohwiyikuLnY4DPdY8cAYzfZmXAKQYZgowG1vHC3VV9OdXQjxhhAiWwiRnZFh7AUTCL9tP4SPlu9GZbVx7vqWaSma7a2baLczDMPUJ5wK+wOyeUb6f1BqLwTQXtGvHYB9zocXOH9+czke+HoDKi0UKpHTFr91VV2EbAanL2YYJgpwKuxnAZgiLU8B8K2i/SrJK2cwgGOyuSfcHCmt1N3WOSMVABAvRcY2Ta0z3TROSQzuwBiGYUKAFdfLjwH8DqA7ERUS0VQA0wGcS0TbAJwrrQPAHAA7AOQDeBPAX4MyagekJOlfavfWjQEAXVs2AgA0aeAv4FulsYbPMEz9xTSoSghxuc4mvxlN4UkjeUuggwoGRsVD+rbz+M8/ceEZmNyvLbpIQl9GL089wzBMfSGq0yUcKq3wLg+dvki33/UjOgEAUhLjMbwr+9IzDBN9RLWwv+Kt5Zb6cRZLhmGinagW9nn7T4R7CAzDMBFBVAt7K2x8bHy4h8AwDBN0olbYV1vwq7+wXxukJsdc4k+GYWKQqBX2XR6ca9qndzvOYskwTGwQtcLeCuVVNeEeAsMwTEiIaWE/4YzW4R4CwzBMSIhpYS/046wYhmGiipgS9lufPM9nPS2FJ2cZhokNokra1dQKfLJyN/4vu71Pe3JCHH6+9xwkJcThgYk90CApAWN6tNRNa8wwDBNtRJWw/2LVHjz4dS5KTlZ52+4/rwduHNnZu37D2Z21dmUYholqosqMU1rh8a5Zs7sEAHDjyE4+gp5hGCZWiSphXyUFUv24+QAAYN2eknAOh2EYJmKIKmE/fW6ez3r+wbIwjYRhGCayiCphr0aZ4phhGCaWiWphzzAMw3iIamGf89DYcA+BYRgmIohqYd+iEdeNZRiGAaJY2PeQiogzDMMwUSzs371mYLiHwDAMEzEEFEFLRAUATgCoAVAthMgmomYAPgWQBaAAwP8JIY4GNkxz5HTF7Zs1wPSL+qB1E06FwDAMI+OGZn+OEKKfECJbWp8GYKEQoiuAhdJ60Bn+z0UAgPQGSRjWpUUoTskwDFNvCIYZZzKAmdLyTAAXBuEcfhwqrQQAbNh7LBSnYxiGqVcEKuwFgB+IaBUR3SC1tRJCFAGA9L9lgOewxcTeXJCEYRhGTaBZL4cJIfYRUUsAC4goz3QPCenhcAMAdOjQIcBh1PHipf1cOxbDMEy0EJBmL4TYJ/0/COBrAAMBHCCiTACQ/h/U2fcNIUS2ECI7IyMjkGEAAAZ08BQPT06ID/hYDMMw0YZjYU9EqUTUWF4GMA5ALoBZAKZI3aYA+DbQQVqhY4tGaM3FSBiGYTQJxIzTCsDXRCQf5yMhxDwiWgngMyKaCmA3gEsCH6YxczYU4cvVhcE+DcMwTL3FsbAXQuwA0Fej/TCAMYEMyi5//XB1KE/HMAxT74jaCFqGYRimDhb2DMMwMUC9F/alFdXhHgLDMEzEU++F/Wcr94R7CAzDMBFPvRf2S7YWe5ffuirboCfDMEzsEmgEbdhp3igJAPDtLcPQt316mEfDMAwTmdRrzf5kZTW+Wr0XANC+WcMwj4ZhGCZyqdfC/pFvN3qXGyXX+5cUhmGYoFGvhf1pCm0+KaFeXwrDMExQqdfq8G1juiI1OQF7S06FeygMwzARTb0W9gBw7fCO4R4CwzBMxMO2D4ZhmBiAhT3DMEwMwMKeYRgmBmBhzzAMEwOwsGcYhokBWNgzDMPEACzsGYZhYgAW9gzDMDEACSHCPQYQUTGAXQ53bwHgkIvDqQ/wNccGfM2xQSDXfJoQIsNKx4gQ9oFARDlCiJhKZM/XHBvwNccGobpmNuMwDMPEACzsGYZhYoBoEPZvhHsAYYCvOTbga44NQnLN9d5mzzAMw5gTDZo9wzAMYwILe4ZhmBigXgt7IppARFuIKJ+IpoV7PHYgovZEtJiINhPRRiL6m9TejIgWENE26X9TqZ2I6CXpWtcT0QDFsaZI/bcR0RRF+5lEtEHa5yUiotBfqT9EFE9Ea4joe2m9IxEtl8b/KRElSe3J0nq+tD1LcYz7pfYtRDRe0R5x3wkiSieiL4goT7rfQ6L9PhPR36XvdS4RfUxEKdF2n4nobSI6SES5irag31e9c5gihKiXfwDiAWwH0AlAEoB1AHqFe1w2xp8JYIC03BjAVgC9ADwLYJrUPg3AP6XliQDmAiAAgwEsl9qbAdgh/W8qLTeVtq0AMETaZy6A88J93dK47gTwEYDvpfXPAFwmLb8G4GZp+a8AXpOWLwPwqbTcS7rfyQA6St+D+Ej9TgCYCeA6aTkJQHo032cAbQHsBNBAcX+vjrb7DOBsAAMA5Cragn5f9c5hOt5w/xAC+KCHAJivWL8fwP3hHlcA1/MtgHMBbAGQKbVlAtgiLb8O4HJF/y3S9ssBvK5of11qywSQp2j36RfG62wHYCGA0QC+l77IhwAkqO8rgPkAhkjLCVI/Ut9ruV8kficApEmCj1TtUXuf4RH2eyQBliDd5/HReJ8BZMFX2Af9vuqdw+yvPptx5C+UTKHUVu+QXlv7A1gOoJUQoggApP8tpW5612vUXqjRHm7+DeBeALXSenMAJUKIamldOU7vtUnbj0n97X4W4aQTgGIA70imq7eIKBVRfJ+FEHsBPA9gN4AieO7bKkT3fZYJxX3VO4ch9VnYa9kl650fKRE1AvAlgDuEEMeNumq0CQftYYOIzgdwUAixStms0VWYbKs31wyPpjoAwKtCiP4AyuB59daj3l+zZEOeDI/ppQ2AVADnaXSNpvtsRtivsT4L+0IA7RXr7QDsC9NYHEFEifAI+g+FEF9JzQeIKFPangngoNSud71G7e002sPJMAB/IKICAJ/AY8r5N4B0IkqQ+ijH6b02aXsTAEdg/7MIJ4UACoUQy6X1L+AR/tF8n8cC2CmEKBZCVAH4CsBQRPd9lgnFfdU7hyH1WdivBNBVmuFPgmdiZ1aYx2QZaWZ9BoDNQoh/KTbNAiDPyE+Bx5Yvt18lzeoPBnBMeoWbD2AcETWVNKpx8NgziwCcIKLB0rmuUhwrLAgh7hdCtBNCZMFzvxYJIf4CYDGAi6Vu6muWP4uLpf5Car9M8uLoCKArPJNZEfedEELsB7CHiLpLTWMAbEIU32d4zDeDiaihNCb5mqP2PisIxX3VO4cx4ZzIcWFyZCI8XizbATwY7vHYHPtweF7L1gNYK/1NhMdWuRDANul/M6k/AXhFutYNALIVx7oWQL70d42iPRtArrTPy1BNEob5+kehzhunEzw/4nwAnwNIltpTpPV8aXsnxf4PSte1BQrvk0j8TgDoByBHutffwON1EdX3GcBjAPKkcb0Pj0dNVN1nAB/DMydRBY8mPjUU91XvHGZ/nC6BYRgmBqjPZhyGYRjGIizsGYZhYgAW9gzDMDEAC3uGYZgYgIU9wzBMDMDCnmEYJgZgYc8wDBMD/D9pwksMstgtRgAAAABJRU5ErkJggg==\n" + }, + "metadata": { + "needs_background": "light" + } + } + ], + "source": [ + "def running_average(x,window):\n", + " return np.convolve(x,np.ones(window)/window,mode='valid')\n", + "\n", + "plt.plot(running_average(rewards,100))" + ] + }, + { + "source": [ + "## Varying Hyperparameters and Seeing the Result in Action\n", + "\n", + "Now it would be interesting to actually see how the trained model behaves. Let's run the simulation, and we will be following the same action selection strategy as during training: sampling according to the probability distribution in Q-Table: " + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "obs = env.reset()\n", + "done = False\n", + "while not done:\n", + " s = discretize(obs)\n", + " env.render()\n", + " v = probs(np.array(qvalues(s)))\n", + " a = random.choices(actions,weights=v)[0]\n", + " obs,_,done,_ = env.step(a)\n", + "env.close()" + ] + }, + { + "source": [ + "\n", + "## Saving result to an animated GIF\n", + "\n", + "If you want to impress your friends, you may want to send them the animated GIF picture of the balancing pole. To do this, we can invoke `env.render` to produce an image frame, and then save those to animated GIF using PIL library:" + ], + "cell_type": "markdown", + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "360\n" + ] + } + ], + "source": [ + "from PIL import Image\n", + "obs = env.reset()\n", + "done = False\n", + "i=0\n", + "ims = []\n", + "while not done:\n", + " s = discretize(obs)\n", + " img=env.render(mode='rgb_array')\n", + " ims.append(Image.fromarray(img))\n", + " v = probs(np.array([Qbest.get((s,a),0) for a in actions]))\n", + " a = random.choices(actions,weights=v)[0]\n", + " obs,_,done,_ = env.step(a)\n", + " i+=1\n", + "env.close()\n", + "ims[0].save('images/cartpole-balance.gif',save_all=True,append_images=ims[1::2],loop=0,duration=5)\n", + "print(i)" + ] + } + ] +} \ No newline at end of file diff --git a/lessons/6-Other/22-DeepRL/tmp.ipynb b/lessons/6-Other/22-DeepRL/tmp.ipynb new file mode 100644 index 00000000..ce101f32 --- /dev/null +++ b/lessons/6-Other/22-DeepRL/tmp.ipynb @@ -0,0 +1,300 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import tensorflow as tf\n", + "from tensorflow import keras\n", + "import matplotlib.pyplot as plt\n", + "import gym" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "env = gym.make(\"CartPole-v1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "<>:74: DeprecationWarning: invalid escape sequence \\g\n", + "<>:93: DeprecationWarning: invalid escape sequence \\d\n" + ] + } + ], + "source": [ + "class REINFORCE:\n", + " def __init__(self, env, path=None):\n", + " self.env=env #import env\n", + " self.state_shape=env.observation_space.shape # the state space\n", + " self.action_shape=env.action_space.n # the action space\n", + " self.gamma=0.99 # decay rate of past observations\n", + " self.alpha=1e-4 # learning rate in the policy gradient\n", + " self.learning_rate=0.01 # learning rate in deep learning\n", + " \n", + " if not path:\n", + " self.model=self._create_model() #build model\n", + " else:\n", + " self.model=self.load_model(path) #import model\n", + "\n", + " # record observations\n", + " self.states=[]\n", + " self.gradients=[] \n", + " self.rewards=[]\n", + " self.probs=[]\n", + " self.discounted_rewards=[]\n", + " self.total_rewards=[]\n", + "\n", + " def hot_encode_action(self, action):\n", + " '''encoding the actions into a binary list'''\n", + "\n", + " action_encoded=np.zeros(self.action_shape, np.float32)\n", + " action_encoded[action]=1\n", + "\n", + " return action_encoded\n", + " \n", + " def remember(self, state, action, action_prob, reward):\n", + " '''stores observations'''\n", + " encoded_action=self.hot_encode_action(action)\n", + " self.gradients.append(encoded_action-action_prob)\n", + " self.states.append(state)\n", + " self.rewards.append(reward)\n", + " self.probs.append(action_prob)\n", + "\n", + " def _create_model(self):\n", + " ''' builds the model using keras'''\n", + " model=keras.Sequential()\n", + "\n", + " # input shape is of observations\n", + " model.add(keras.layers.Dense(24, input_shape=self.state_shape, activation=\"relu\"))\n", + " # add a relu layer \n", + " model.add(keras.layers.Dense(12, activation=\"relu\"))\n", + "\n", + " # output shape is according to the number of action\n", + " # The softmax function outputs a probability distribution over the actions\n", + " model.add(keras.layers.Dense(self.action_shape, activation=\"softmax\")) \n", + " model.compile(loss=\"categorical_crossentropy\",\n", + " optimizer=keras.optimizers.Adam(lr=self.learning_rate))\n", + " \n", + " return model\n", + "\n", + " def get_action(self, state):\n", + " '''samples the next action based on the policy probabilty distribution \n", + " of the actions'''\n", + "\n", + " # transform state\n", + " state=state.reshape([1, state.shape[0]])\n", + " # get action probably\n", + " action_probability_distribution=self.model.predict(state).flatten()\n", + " # norm action probability distribution\n", + " action_probability_distribution/=np.sum(action_probability_distribution)\n", + " \n", + " # sample action\n", + " action=np.random.choice(self.action_shape,1,\n", + " p=action_probability_distribution)[0]\n", + "\n", + " return action, action_probability_distribution\n", + "\n", + " def get_discounted_rewards(self, rewards): \n", + " '''Use gamma to calculate the total reward discounting for rewards\n", + " Following - \\gamma ^ t * Gt'''\n", + " \n", + " discounted_rewards=[]\n", + " cumulative_total_return=0\n", + " # iterate the rewards backwards and and calc the total return \n", + " for reward in rewards[::-1]: \n", + " cumulative_total_return=(cumulative_total_return*self.gamma)+reward\n", + " discounted_rewards.insert(0, cumulative_total_return)\n", + "\n", + " # normalize discounted rewards\n", + " mean_rewards=np.mean(discounted_rewards)\n", + " std_rewards=np.std(discounted_rewards)\n", + " norm_discounted_rewards=(discounted_rewards-\n", + " mean_rewards)/(std_rewards+1e-7) # avoiding zero div\n", + " \n", + " return norm_discounted_rewards\n", + "\n", + " def update_policy(self):\n", + " '''Updates the policy network using the NN model.\n", + " This function is used after the MC sampling is done - following\n", + " \\delta \\theta = \\alpha * gradient + log pi'''\n", + " \n", + " # get X\n", + " states=np.vstack(self.states)\n", + "\n", + " # get Y\n", + " gradients=np.vstack(self.gradients)\n", + " rewards=np.vstack(self.rewards)\n", + " discounted_rewards=self.get_discounted_rewards(rewards)\n", + " gradients*=discounted_rewards\n", + " gradients=self.alpha*np.vstack([gradients])+self.probs\n", + "\n", + " history=self.model.train_on_batch(states, gradients)\n", + " \n", + " self.states, self.probs, self.gradients, self.rewards=[], [], [], []\n", + "\n", + " return history\n", + "\n", + " def train(self, episodes, rollout_n=1, render_n=50):\n", + " '''train the model\n", + " episodes - number of training iterations \n", + " rollout_n- number of episodes between policy update\n", + " render_n - number of episodes between env rendering ''' \n", + " \n", + " env=self.env\n", + " total_rewards=np.zeros(episodes)\n", + "\n", + " for episode in range(episodes):\n", + " # each episode is a new game env\n", + " state=env.reset()\n", + " done=False \n", + " episode_reward=0 #record episode reward\n", + " \n", + " while not done:\n", + " # play an action and record the game state & reward per episode\n", + " action, prob=self.get_action(state)\n", + " next_state, reward, done, _=env.step(action)\n", + " self.remember(state, action, prob, reward)\n", + " state=next_state\n", + " episode_reward+=reward\n", + "\n", + " #if episode%render_n==0: ## render env to visualize.\n", + " #env.render()\n", + " if done:\n", + " # update policy \n", + " if episode%rollout_n==0:\n", + " history=self.update_policy()\n", + "\n", + " total_rewards[episode]=episode_reward\n", + " if episode%10==0:\n", + " print(f\"{episode} -> {episode_reward}\")\n", + " \n", + " self.total_rewards=total_rewards" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\winapp\\Miniconda3\\envs\\py38\\lib\\site-packages\\keras\\optimizer_v2\\adam.py:105: UserWarning: The `lr` argument is deprecated, use `learning_rate` instead.\n", + " super(Adam, self).__init__(name, **kwargs)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 -> 39.0\n", + "10 -> 50.0\n", + "20 -> 18.0\n", + "30 -> 15.0\n", + "40 -> 16.0\n", + "50 -> 17.0\n", + "60 -> 20.0\n", + "70 -> 11.0\n", + "80 -> 20.0\n", + "90 -> 40.0\n", + "100 -> 36.0\n", + "110 -> 18.0\n", + "120 -> 79.0\n", + "130 -> 43.0\n", + "140 -> 41.0\n", + "150 -> 37.0\n", + "160 -> 95.0\n", + "170 -> 72.0\n", + "180 -> 138.0\n", + "190 -> 102.0\n" + ] + } + ], + "source": [ + "r = REINFORCE(env)\n", + "\n", + "r.train(200)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(r.total_rewards)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "16af2a8bbb083ea23e5e41c7f5787656b2ce26968575d8763f2c4b17f9cd711f" + }, + "kernelspec": { + "display_name": "Python 3.8.12 ('py38')", + "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.8.12" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/lessons/X-Extras/X1-MultiModal/README.md b/lessons/X-Extras/X1-MultiModal/README.md index 3b81a155..dc7a056a 100644 --- a/lessons/X-Extras/X1-MultiModal/README.md +++ b/lessons/X-Extras/X1-MultiModal/README.md @@ -50,9 +50,9 @@ To generate an image corresponding to a text prompt, we start with some random e A great library that implements VQGAN+CLIP is [Pixray](http://github.com/pixray/pixray) -![Picture produced by Pixray](images/a_closeup_watercolor_portrait_of_young_male_teacher_of_literature_with_a_book.png) | ![Picture produced by pixray](images/a_closeup_oil_portrait_of_young_female_teacher_of_computer_science_with_a_computer.png) -----|---- -Picture generated from prompt *a closeup watercolor portrait of young male teacher of literature with a book* | Picture generated from prompt *a closeup oil portrait of young female teacher of computer science with a computer* +![Picture produced by Pixray](images/a_closeup_watercolor_portrait_of_young_male_teacher_of_literature_with_a_book.png) | ![Picture produced by pixray](images/a_closeup_oil_portrait_of_young_female_teacher_of_computer_science_with_a_computer.png) | ![Picture produced by Pixray](a_closeup_oil_portrait_of_old_male_teacher_of_mathematics_in_front_of_blackboard.png) +----|----|---- +Picture generated from prompt *a closeup watercolor portrait of young male teacher of literature with a book* | Picture generated from prompt *a closeup oil portrait of young female teacher of computer science with a computer* | Picture generated from prompt *a closeup oil portrait of old male teacher of mathematics in front of blackboard* > Pictures from **Artificial Teachers** collection by [Dmitry Soshnikov](http://soshnikov.com)