{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Actions as vector, and RL agent training" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is recommended to have a look at the [0_basic_functionalities](0_basic_functionalities.ipynb), [1_Observation_Agents](1_Observation_Agents.ipynb) and [2_Action_GridManipulation](2_Action_GridManipulation.ipynb) notebooks before getting into this one." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Objectives**\n", "\n", "In this notebook we will expose :\n", "* how to use the \"converters\": some specific action_space that allows to manipulate a specific action representation\n", "* how to train a (stupid) Agent using reinforcement learning.\n", "* how to inspect (rapidly) the action taken by the Agent\n", "\n", "**NB** for this tutorial we train an Agent inspired from this blog post: [deep-reinforcement-learning-tutorial-with-open-ai-gym](https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368). Many other different reinforcement learning tutorial exist. The code showed in this notebook has no pretention except to demonstrate how to use Grid2Op functionality to train a Deep Reinforcement learning Agent and inspect its behaviour. There are absolutely nothing implied about the performance, training strategy, type of Agent, meta parameters etc. All of them are purely \"random\".\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os\n", "import sys\n", "import grid2op" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Impossible to automatically add a menu / table of content to this notebook.\n", "You can download \"jyquickhelper\" package with: \n", "\"pip install jyquickhelper\"\n" ] } ], "source": [ "res = None\n", "try:\n", " from jyquickhelper import add_notebook_menu\n", " res = add_notebook_menu()\n", "except ModuleNotFoundError:\n", " print(\"Impossible to automatically add a menu / table of content to this notebook.\\nYou can download \\\"jyquickhelper\\\" package with: \\n\\\"pip install jyquickhelper\\\"\")\n", "res" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## I) Manipulating action representation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Grid2op package has been built with an \"object oriented\" perspective: almost everything is encapsulated in a dedicated `class`. This allows for more customization of the plateform.\n", "\n", "The downside of this approach is that machine learning method, and especially deep learning, often prefers to deal with vectors rather than with `complex` objects. Indeed, as we covered in the previous tutorials on the platform, building our own actions can be tedious and can sometime require knowledge of the powergrid.\n", "\n", "On the contrary, in most of standard Reinforcement Learning environment, actions have an higher representation. For example in pacman, there are 4 different types of actions: turn left, turn right, go up or do down. This allows for easy sampling (you need to achieve a uniform sampling you simply need to sample a number between 0 and 3 included) and an easy representation: each action is a different component of a vector of dimension 4 [because there are 4 actions]. \n", "\n", "On the other hand this representation is not \"human friendly\". It is quite convenient in the case of pacman because the action space is rather small making it possible to remember which action corresponds to which component, but in the case of the grid2op package, there are hundreds, sometimes thousands of actions, making it impossible to remember which component corresponds to which actions. We suppose we don't really care about this fact here, as tutorials on Reinforcement Learning with discrete action space often assume that actions are labelled with integer (such as in pacman for example).\n", "\n", "Howerever, to allow the training of RL agent more easily, we allows to make some \"[Converters](https://grid2op.readthedocs.io/en/latest/converters.html)\" whose roles are to allow an agent to deal with a custom representation of the action space. The class [AgentWithConverter](https://grid2op.readthedocs.io/en/latest/agent.html#grid2op.Agent.AgentWithConverter) is perfect for such usage." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/benjamin/Documents/grid2op_test/getting_started/grid2op/MakeEnv.py:668: UserWarning:\n", "\n", "Your are using only 2 chronics for this environment. More can be download by running, from a command line:\n", "python -m grid2op.download --name \"case14_redisp\" --path_save PATH\\WHERE\\YOU\\WANT\\TO\\DOWNLOAD\\DATA\n", "\n" ] } ], "source": [ "# import the usefull class\n", "import numpy as np\n", "\n", "from grid2op import make\n", "from grid2op.Agent import RandomAgent \n", "max_iter = 100 # to make computation much faster we will only consider 50 time steps instead of 287\n", "\n", "env = make(name_env=\"case14_redisp\")\n", "env.seed(0) # this is to ensure the same action are taken by the \"RandomAgent\".\n", "my_agent = RandomAgent(env.action_space)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And that's it. This agent will be able to perform any action, but instead of going through the description of the actions from a powersystem point of view (ie setting what is connected to what, what is disconnected etc.) it will simply choose an integer with the method `my_act` this integer will then be converter back to a proper valid action.\n", "\n", "Here we have an example on the action representation as seen by the Agent:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "172\n", "47\n", "117\n" ] } ], "source": [ "for el in range(3):\n", " print(my_agent.my_act(None, None))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And below you can see the \"`act`\" functions behaves as expected:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This action will:\n", "\t - NOT change anything to the injections\n", "\t - NOT perform any redispatching action\n", "\t - NOT force any line status\n", "\t - NOT switch any line status\n", "\t - NOT switch anything in the topology\n", "\t - Set the bus of the following element:\n", "\t \t - assign bus 2 to line (origin) 12 [on substation 5]\n", "\t \t - assign bus 2 to line (origin) 13 [on substation 5]\n", "\t \t - assign bus 1 to line (origin) 14 [on substation 5]\n", "\t \t - assign bus 2 to line (extremity) 17 [on substation 5]\n", "\t \t - assign bus 1 to generator 2 [on substation 5]\n", "\t \t - assign bus 1 to load 5 [on substation 5]\n", "This action will:\n", "\t - NOT change anything to the injections\n", "\t - NOT perform any redispatching action\n", "\t - NOT force any line status\n", "\t - NOT switch any line status\n", "\t - Change the bus of the following element:\n", "\t \t - switch bus of line (origin) 3 [on substation 8]\n", "\t \t - switch bus of line (extremity) 16 [on substation 8]\n", "\t \t - switch bus of line (extremity) 19 [on substation 8]\n", "\t - NOT force any particular bus configuration\n", "This action will:\n", "\t - NOT change anything to the injections\n", "\t - NOT perform any redispatching action\n", "\t - NOT force any line status\n", "\t - NOT switch any line status\n", "\t - Change the bus of the following element:\n", "\t \t - switch bus of generator 1 [on substation 2]\n", "\t \t - switch bus of load 1 [on substation 2]\n", "\t - NOT force any particular bus configuration\n" ] } ], "source": [ "for el in range(3):\n", " print(my_agent.act(None, None))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**NB** lots of these actions are equivalent to the \"do nothing\" action at some point. For example, when trying to reconnect a powerline that is already connected will do nothing. Same for the topology. If everything is already connected to bus 1, then the action to connect things to bus 1 on the same substation will not affect the powergrid." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## II) Training an Agent" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For this tutorial, we will expose to built a Q-learning Agent. Most of the code (except the neural network architecture) are inspired from this blog post: [https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368](https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368).\n", "\n", "**Requirements** This notebook require to have `keras` installed on your machine.\n", "\n", "As always in these notebook, we will use the `case14_fromfile` Environment. No proper care has been taken to set the thermal limits on this grid. It's unlikely that the agent can learn anything in this context." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### II.A) Defining some \"helpers\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The type of Agent were are using require a bit of set up, independantly of Grid2Op. We will reuse the code showed in \n", "[https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368](https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368) and in [Reinforcement-Learning-Tutorial](https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial) from Abhinav Sagar code under a *MIT license* found here: [MIT License](https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial/blob/master/LICENSE).\n", "\n", "This first section is here to define these classes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But first let's import the necessary dependencies" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "#tf2.0 friendly\n", "import numpy as np\n", "import random\n", "import warnings\n", "with warnings.catch_warnings():\n", " warnings.filterwarnings(\"ignore\", category=FutureWarning)\n", " import tensorflow.keras\n", " import tensorflow.keras.backend as K\n", " from tensorflow.keras.models import load_model, Sequential, Model\n", " from tensorflow.keras.optimizers import Adam\n", " from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense, subtract, add\n", " from tensorflow.keras.layers import Input, Lambda, Concatenate" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### a) Replay buffer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " First we define a \"replay buffer\" necessary to train the Agent." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# Credit Abhinav Sagar: \n", "# https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial\n", "# Code under MIT license, available at:\n", "# https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial/blob/master/LICENSE\n", "from collections import deque\n", "\n", "class ReplayBuffer:\n", " \"\"\"Constructs a buffer object that stores the past moves\n", " and samples a set of subsamples\"\"\"\n", "\n", " def __init__(self, buffer_size):\n", " self.buffer_size = buffer_size\n", " self.count = 0\n", " self.buffer = deque()\n", "\n", " def add(self, s, a, r, d, s2):\n", " \"\"\"Add an experience to the buffer\"\"\"\n", " # S represents current state, a is action,\n", " # r is reward, d is whether it is the end, \n", " # and s2 is next state\n", " experience = (s, a, r, d, s2)\n", " if self.count < self.buffer_size:\n", " self.buffer.append(experience)\n", " self.count += 1\n", " else: \n", " self.buffer.popleft()\n", " self.buffer.append(experience)\n", "\n", " def size(self):\n", " return self.count\n", "\n", " def sample(self, batch_size):\n", " \"\"\"Samples a total of elements equal to batch_size from buffer\n", " if buffer contains enough elements. Otherwise return all elements\"\"\"\n", "\n", " batch = []\n", "\n", " if self.count < batch_size:\n", " batch = random.sample(self.buffer, self.count)\n", " else:\n", " batch = random.sample(self.buffer, batch_size)\n", "\n", " # Maps each experience in batch in batches of states, actions, rewards\n", " # and new states\n", " s_batch, a_batch, r_batch, d_batch, s2_batch = list(map(np.array, list(zip(*batch))))\n", "\n", " return s_batch, a_batch, r_batch, d_batch, s2_batch\n", "\n", " def clear(self):\n", " self.buffer.clear()\n", " self.count = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### b) Meta parameters of the methods" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we re-use the default parameters, note that these can be optimized. Nothing has been changed for this example.\n", "\n", "For more information about them, please refer to the blog post of Abhinav Sagar [available here](https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368)." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "DECAY_RATE = 0.9\n", "BUFFER_SIZE = 40000\n", "MINIBATCH_SIZE = 64\n", "TOT_FRAME = 3000000\n", "EPSILON_DECAY = 10000\n", "MIN_OBSERVATION = 42 #5000\n", "FINAL_EPSILON = 1/300 # have on average 1 random action per scenario of approx 287 time steps\n", "INITIAL_EPSILON = 0.1\n", "TAU = 0.01\n", "ALPHA = 1\n", "# Number of frames to \"throw\" into network\n", "NUM_FRAMES = 1 ## this has been changed compared to the original implementation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### II.B) Adapatation of the inputs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the original code, the models were used to play an Atari game and the inputs were images. For our system, the inputs are \"Observation\" converted as vector.\n", "\n", "For a more detailed description of the code used, please check:\n", "* [https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368](https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368)\n", "* and [Reinforcement-Learning-Tutorial](https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial)\n", "\n", "\n", "This is why we adapted the original code from Abhinav Sagar:\n", "* We replaced convolutional layers with fully connected (dense) layers\n", "* We made sure not to look at all the observations, but rather at only some part of it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### a) extracting relevant information of observation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we extract relevant information about the dimension of the observation space, and the action space." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "OBSERVATION_SIZE = env.observation_space.size()\n", "NUM_ACTIONS = my_agent.action_space.n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A few comments here.\n", "\n", "First, we don't change anything to the observation space. This means that the vector the agent will receive is really big, not scaled and with lots of informations that are not really usefull." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### b) Code the neural networks" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The code of the neural networks, used to solve this problem is modified very slightly to adapt. The biggest changes come from removing the convolutional layers, as well as adapting the input and output size.\n", "\n", "For each of the method below, we specify what have been adapted/modified in comparison with the original blog post by Abhinav." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We want to emphasize here that these models are used through the \"`predict_movement`\" method. This method outputs an integer: the action id that maximizes the expected reward at the current tim step in an episode of the game during the training process. It's perfectly suited to use a representation of actions with integer rather than with complete descriptions of what the agent is doing." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### II.C) Making the code of the Agent and train it" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the \"reference\" article [https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368](https://towardsdatascience.com/deep-reinforcement-learning-tutorial-with-open-ai-gym-c0de4471f368), the author Abhinav Sagar made a dedicated environment based on SpaceInvader in the gym repository. We proceed here on a similar way, but with a the grid2op environment." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### a) Adapated code" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# Credit Abhinav Sagar: \n", "# https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial\n", "# Code under MIT license, available at:\n", "# https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial/blob/master/LICENSE\n", "\n", "class DeepQ(object):\n", " \"\"\"Constructs the desired deep q learning network\"\"\"\n", " def __init__(self, action_size, lr=1e-5, observation_size=OBSERVATION_SIZE):\n", " # It is not modified from Abhinav Sagar's code, except for adding the possibility to change the learning rate\n", " # in parameter is also present the size of the action space\n", " # (it used to be a global variable in the original code)\n", " self.action_size = action_size\n", " self.observation_size = observation_size\n", " self.model = None\n", " self.target_model = None\n", " self.lr_ = lr\n", " self.qvalue_evolution = []\n", " self.construct_q_network()\n", " \n", " def construct_q_network(self):\n", " # replacement of the Convolution layers by Dense layers, and change the size of the input space and output space\n", " \n", " # Uses the network architecture found in DeepMind paper\n", " self.model = Sequential()\n", " input_layer = Input(shape = (self.observation_size*NUM_FRAMES,))\n", " layer1 = Dense(self.observation_size*NUM_FRAMES)(input_layer)\n", " layer1 = Activation('relu')(layer1)\n", " layer2 = Dense(self.observation_size)(layer1)\n", " layer2 = Activation('relu')(layer2)\n", " layer3 = Dense(self.observation_size)(layer2)\n", " layer3 = Activation('relu')(layer3)\n", " layer4 = Dense(2*NUM_ACTIONS)(layer3)\n", " layer4 = Activation('relu')(layer4)\n", " output = Dense(NUM_ACTIONS)(layer4)\n", " \n", " self.model = Model(inputs=[input_layer], outputs=[output])\n", " self.model.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " self.target_model = Model(inputs=[input_layer], outputs=[output])\n", " self.target_model.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " self.target_model.set_weights(self.model.get_weights())\n", " \n", " def predict_movement(self, data, epsilon):\n", " \"\"\"Predict movement of game controler where is epsilon\n", " probability randomly move.\"\"\"\n", " # nothing has changed from the original implementation\n", " rand_val = np.random.random()\n", " q_actions = self.model.predict(data.reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " \n", " if rand_val < epsilon:\n", " opt_policy = np.random.randint(0, NUM_ACTIONS)\n", " else:\n", " opt_policy = np.argmax(np.abs(q_actions))\n", " \n", " self.qvalue_evolution.append(q_actions[0,opt_policy])\n", "\n", " return opt_policy, q_actions[0, opt_policy]\n", "\n", " def train(self, s_batch, a_batch, r_batch, d_batch, s2_batch, observation_num):\n", " \"\"\"Trains network to fit given parameters\"\"\"\n", " # nothing has changed from the original implementation, except for changing the input dimension 'reshape'\n", " batch_size = s_batch.shape[0]\n", " targets = np.zeros((batch_size, NUM_ACTIONS))\n", "\n", " for i in range(batch_size):\n", " targets[i] = self.model.predict(s_batch[i].reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " fut_action = self.target_model.predict(s2_batch[i].reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " targets[i, a_batch[i]] = r_batch[i]\n", " if d_batch[i] == False:\n", " targets[i, a_batch[i]] += DECAY_RATE * np.max(fut_action)\n", " loss = self.model.train_on_batch(s_batch, targets)\n", " # Print the loss every 100 iterations.\n", " if observation_num % 100 == 0:\n", " print(\"We had a loss equal to \", loss)\n", "\n", " def save_network(self, path):\n", " # Saves model at specified path as h5 file\n", " # nothing has changed\n", " self.model.save(path)\n", " print(\"Successfully saved network.\")\n", "\n", " def load_network(self, path):\n", " # nothing has changed\n", " self.model = load_model(path)\n", " print(\"Succesfully loaded network.\")\n", "\n", " def target_train(self):\n", " # nothing has changed from the original implementation\n", " model_weights = self.model.get_weights()\n", " target_model_weights = self.target_model.get_weights()\n", " for i in range(len(model_weights)):\n", " target_model_weights[i] = TAU * model_weights[i] + (1 - TAU) * target_model_weights[i]\n", " self.target_model.set_weights(target_model_weights)\n", " \n", "class DuelQ(object):\n", " \"\"\"Constructs the desired deep q learning network\"\"\"\n", " def __init__(self, action_size, lr=0.00001, observation_size=OBSERVATION_SIZE):\n", " # It is not modified from Abhinav Sagar's code, except for adding the possibility to change the learning rate\n", " # in parameter is also present the size of the action space\n", " # (it used to be a global variable in the original code)\n", " self.action_size = action_size\n", " self.observation_size = observation_size\n", " self.lr_ = lr\n", " self.model = None\n", " self.qvalue_evolution = []\n", " self.construct_q_network()\n", "\n", " def construct_q_network(self):\n", " # Uses the network architecture found in DeepMind paper\n", " # The inputs and outputs size have changed, as well as replacing the convolution by dense layers.\n", " self.model = Sequential()\n", " \n", " input_layer = Input(shape = (self.observation_size*NUM_FRAMES,))\n", " lay1 = Dense(self.observation_size*NUM_FRAMES)(input_layer)\n", " lay1 = Activation('relu')(lay1)\n", " \n", " lay2 = Dense(self.observation_size)(lay1)\n", " lay2 = Activation('relu')(lay2)\n", " \n", " lay3 = Dense(2*NUM_ACTIONS)(lay2)\n", " lay3 = Activation('relu')(lay3)\n", " \n", " fc1 = Dense(NUM_ACTIONS)(lay3)\n", " advantage = Dense(NUM_ACTIONS)(fc1)\n", " fc2 = Dense(NUM_ACTIONS)(lay3)\n", " value = Dense(1)(fc2)\n", " \n", " meaner = Lambda(lambda x: K.mean(x, axis=1) )\n", " mn_ = meaner(advantage) \n", " tmp = subtract([advantage, mn_]) # keras doesn't like this part...\n", " policy = add([tmp, value])\n", "\n", " self.model = Model(inputs=[input_layer], outputs=[policy])\n", " self.model.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", "\n", " self.target_model = Model(inputs=[input_layer], outputs=[policy])\n", " self.target_model.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " print(\"Successfully constructed networks.\")\n", " \n", " def predict_movement(self, data, epsilon):\n", " \"\"\"Predict movement of game controler where is epsilon\n", " probability randomly move.\"\"\"\n", " # only changes lie in adapting the input shape\n", " q_actions = self.model.predict(data.reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " opt_policy = np.argmax(q_actions)\n", " rand_val = np.random.random()\n", " if rand_val < epsilon:\n", " opt_policy = np.random.randint(0, NUM_ACTIONS)\n", " \n", " self.qvalue_evolution.append(q_actions[0,opt_policy])\n", "\n", " return opt_policy, q_actions[0, opt_policy]\n", "\n", " def train(self, s_batch, a_batch, r_batch, d_batch, s2_batch, observation_num):\n", " \"\"\"Trains network to fit given parameters\"\"\"\n", " # nothing has changed except adapting the input shapes\n", " batch_size = s_batch.shape[0]\n", " targets = np.zeros((batch_size, NUM_ACTIONS))\n", "\n", " for i in range(batch_size):\n", " targets[i] = self.model.predict(s_batch[i].reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " fut_action = self.target_model.predict(s2_batch[i].reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " targets[i, a_batch[i]] = r_batch[i]\n", " if d_batch[i] == False:\n", " targets[i, a_batch[i]] += DECAY_RATE * np.max(fut_action)\n", "\n", " loss = self.model.train_on_batch(s_batch, targets)\n", "\n", " # Print the loss every 100 iterations.\n", " if observation_num % 100 == 0:\n", " print(\"We had a loss equal to \", loss)\n", "\n", " def save_network(self, path):\n", " # Saves model at specified path as h5 file\n", " # nothing has changed\n", " self.model.save(path)\n", " print(\"Successfully saved network.\")\n", "\n", " def load_network(self, path):\n", " # nothing has changed\n", " self.model.load_weights(path)\n", " self.target_model.load_weights(path)\n", " print(\"Succesfully loaded network.\")\n", "\n", " def target_train(self):\n", " # nothing has changed\n", " model_weights = self.model.get_weights()\n", " self.target_model.set_weights(model_weights)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another custom made version of the Q-Learning algorithm" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "class RealQ(object):\n", " \"\"\"Constructs the desired deep q learning network\"\"\"\n", " def __init__(self, action_size, lr=1e-5, observation_size=OBSERVATION_SIZE, mean_reg=False):\n", "\n", " self.action_size = action_size\n", " self.observation_size = observation_size\n", " self.model = None\n", " self.target_model = None\n", " self.lr_ = lr\n", " self.mean_reg = mean_reg\n", " \n", " self.qvalue_evolution=[]\n", "\n", " self.construct_q_network()\n", " \n", " def construct_q_network(self):\n", "\n", " self.model = Sequential()\n", " \n", " input_states = Input(shape = (self.observation_size,))\n", " input_action = Input(shape = (NUM_ACTIONS,))\n", " input_layer = Concatenate()([input_states, input_action])\n", " \n", " lay1 = Dense(self.observation_size)(input_layer)\n", " lay1 = Activation('relu')(lay1)\n", " \n", " lay2 = Dense(self.observation_size)(lay1)\n", " lay2 = Activation('relu')(lay2)\n", " \n", " lay3 = Dense(2*NUM_ACTIONS)(lay2)\n", " lay3 = Activation('relu')(lay3)\n", " \n", " fc1 = Dense(NUM_ACTIONS)(lay3)\n", " advantage = Dense(1, activation = 'linear')(fc1)\n", " \n", " if self.mean_reg==True:\n", " advantage = Lambda(lambda x : x - K.mean(x))(advantage)\n", " \n", " self.model = Model(inputs=[input_states, input_action], outputs=[advantage])\n", " self.model.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " \n", " self.model_copy = Model(inputs=[input_states, input_action], outputs=[advantage])\n", " self.model_copy.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " self.model_copy.set_weights(self.model.get_weights())\n", " \n", " def predict_movement(self, states, epsilon):\n", " \"\"\"Predict movement of game controler where is epsilon\n", " probability randomly move.\"\"\"\n", " # nothing has changed from the original implementation\n", " rand_val = np.random.random()\n", " q_actions = self.model.predict([np.tile(states.reshape(1, self.observation_size),(NUM_ACTIONS,1)), np.eye(NUM_ACTIONS)]).reshape(1,-1)\n", " if rand_val < epsilon:\n", " opt_policy = np.random.randint(0, NUM_ACTIONS)\n", " else:\n", " opt_policy = np.argmax(np.abs(q_actions))\n", " \n", " self.qvalue_evolution.append(q_actions[0,opt_policy])\n", " \n", " return opt_policy, q_actions[0,opt_policy]\n", "\n", " def train(self, s_batch, a_batch, r_batch, d_batch, s2_batch, observation_num):\n", " \"\"\"Trains network to fit given parameters\"\"\"\n", " # nothing has changed from the original implementation, except for changing the input dimension 'reshape'\n", " batch_size = s_batch.shape[0]\n", " targets = np.zeros(batch_size)\n", " last_action=np.zeros((batch_size, NUM_ACTIONS))\n", " for i in range(batch_size):\n", " last_action[i,a_batch[i]] = 1\n", " q_pre = self.model.predict([s_batch[i].reshape(1, self.observation_size), last_action[i].reshape(1,-1)], batch_size=1).reshape(1,-1)\n", " q_fut = self.model_copy.predict([np.tile(s2_batch[i].reshape(1, self.observation_size),(NUM_ACTIONS,1)), np.eye(NUM_ACTIONS)]).reshape(1,-1)\n", " fut_action = np.max(q_fut)\n", " if d_batch[i] == False:\n", " targets[i] = ALPHA * (r_batch[i] + DECAY_RATE * fut_action - q_pre)\n", " else:\n", " targets[i] = ALPHA * (r_batch[i] - q_pre)\n", " loss = self.model.train_on_batch([s_batch, last_action], targets)\n", " # Print the loss every 100 iterations.\n", " if observation_num % 100 == 0:\n", " print(\"We had a loss equal to \", loss)\n", "\n", " def save_network(self, path):\n", " # Saves model at specified path as h5 file\n", " # nothing has changed\n", " self.model.save(path)\n", " print(\"Successfully saved network.\")\n", "\n", " def load_network(self, path):\n", " # nothing has changed\n", " self.model = load_model(path)\n", " print(\"Succesfully loaded network.\")\n", "\n", " def target_train(self):\n", " # nothing has changed from the original implementation\n", " model_weights = self.model.get_weights() \n", " target_model_weights = self.model_copy.get_weights()\n", " for i in range(len(model_weights)):\n", " target_model_weights[i] = TAU * model_weights[i] + (1 - TAU) * target_model_weights[i]\n", " self.model_copy.set_weights(model_weights)\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A version of SAC algorithm as described in https://spinningup.openai.com/en/latest/algorithms/sac.html" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "class SAC(object):\n", " \"\"\"Constructs the desired deep q learning network\"\"\"\n", " def __init__(self, action_size, lr=1e-5, observation_size=OBSERVATION_SIZE):\n", "\n", " self.action_size = action_size\n", " self.observation_size = observation_size\n", " self.model = None\n", " self.target_model = None\n", " self.lr_ = lr\n", " self.average_reward = 0\n", " self.life_spent = 1\n", " self.qvalue_evolution = []\n", " self.Is_nan = False\n", "\n", " self.construct_q_network()\n", " \n", " def build_q_NN(self):\n", " model = Sequential()\n", " \n", " input_states = Input(shape = (self.observation_size,))\n", " input_action = Input(shape = (NUM_ACTIONS,))\n", " input_layer = Concatenate()([input_states, input_action])\n", " \n", " lay1 = Dense(self.observation_size)(input_layer)\n", " lay1 = Activation('relu')(lay1)\n", " \n", " lay2 = Dense(self.observation_size)(lay1)\n", " lay2 = Activation('relu')(lay2)\n", " \n", " lay3 = Dense(2*NUM_ACTIONS)(lay2)\n", " lay3 = Activation('relu')(lay3)\n", " \n", " advantage = Dense(1, activation = 'linear')(lay3)\n", " \n", " model = Model(inputs=[input_states, input_action], outputs=[advantage])\n", " model.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " \n", " return model\n", " \n", " def construct_q_network(self):\n", " #construct double Q networks\n", " self.model_Q = self.build_q_NN()\n", " self.model_Q2 = self.build_q_NN()\n", "\n", " \n", " #state value function approximation\n", " self.model_value = Sequential()\n", " \n", " input_states = Input(shape = (self.observation_size,))\n", " \n", " lay1 = Dense(self.observation_size)(input_states)\n", " lay1 = Activation('relu')(lay1)\n", " \n", " lay3 = Dense(2*NUM_ACTIONS)(lay1)\n", " lay3 = Activation('relu')(lay3)\n", " \n", " advantage = Dense(NUM_ACTIONS, activation = 'relu')(lay3)\n", " state_value = Dense(1, activation = 'linear')(advantage)\n", " \n", " self.model_value = Model(inputs=[input_states], outputs=[state_value])\n", " self.model_value.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " \n", " self.model_value_target = Sequential()\n", " \n", " input_states = Input(shape = (self.observation_size,))\n", " \n", " lay1 = Dense(self.observation_size)(input_states)\n", " lay1 = Activation('relu')(lay1)\n", " \n", " lay3 = Dense(2*NUM_ACTIONS)(lay1)\n", " lay3 = Activation('relu')(lay3)\n", " \n", " advantage = Dense(NUM_ACTIONS, activation = 'relu')(lay3)\n", " state_value = Dense(1, activation = 'linear')(advantage)\n", " \n", " self.model_value_target = Model(inputs=[input_states], outputs=[state_value])\n", " self.model_value_target.compile(loss='mse', optimizer=Adam(lr=self.lr_))\n", " self.model_value_target.set_weights(self.model_value.get_weights())\n", " #policy function approximation\n", " \n", " self.model_policy = Sequential()\n", " input_states = Input(shape = (self.observation_size,))\n", " lay1 = Dense(self.observation_size)(input_states)\n", " lay1 = Activation('relu')(lay1)\n", " \n", " lay2 = Dense(self.observation_size)(lay1)\n", " lay2 = Activation('relu')(lay2)\n", " \n", " lay3 = Dense(2*NUM_ACTIONS)(lay2)\n", " lay3 = Activation('relu')(lay3)\n", " \n", " soft_proba = Dense(NUM_ACTIONS, activation=\"softmax\", kernel_initializer='uniform')(lay3)\n", " \n", " self.model_policy = Model(inputs=[input_states], outputs=[soft_proba])\n", " self.model_policy.compile(loss='categorical_crossentropy', optimizer=Adam(lr=self.lr_))\n", " \n", " print(\"Successfully constructed networks.\")\n", " \n", " def predict_movement(self, states, epsilon):\n", " \"\"\"Predict movement of game controler where is epsilon\n", " probability randomly move.\"\"\"\n", " # nothing has changed from the original implementation\n", " p_actions = self.model_policy.predict(states.reshape(1, self.observation_size)).ravel()\n", " rand_val = np.random.random()\n", " \n", " if rand_val < epsilon / 10:\n", " opt_policy = np.random.randint(0, NUM_ACTIONS)\n", " else:\n", " #opt_policy = np.random.choice(np.arange(NUM_ACTIONS, dtype=int), size=1, p = p_actions)\n", " opt_policy = np.argmax(p_actions)\n", " \n", " return np.int(opt_policy), p_actions[opt_policy]\n", "\n", " def train(self, s_batch, a_batch, r_batch, d_batch, s2_batch, observation_num):\n", " \"\"\"Trains networks to fit given parameters\"\"\"\n", "\n", " # nothing has changed from the original implementation, except for changing the input dimension 'reshape'\n", " batch_size = s_batch.shape[0]\n", " target = np.zeros((batch_size, 1))\n", " new_proba = np.zeros((batch_size, NUM_ACTIONS))\n", " last_action=np.zeros((batch_size, NUM_ACTIONS))\n", " \n", " #training of the action state value networks\n", " last_action=np.zeros((batch_size, NUM_ACTIONS))\n", "\n", " for i in range(batch_size):\n", " last_action[i,a_batch[i]] = 1\n", "\n", " v_t = self.model_value_target.predict(s_batch[i].reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " \n", " self.qvalue_evolution.append(v_t[0])\n", " fut_action = self.model_value_target.predict(s2_batch[i].reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", "\n", " target[i,0] = r_batch[i] + (1 - d_batch[i]) * DECAY_RATE * fut_action \n", "\n", " \n", " loss = self.model_Q.train_on_batch([s_batch, last_action], target)\n", " loss_2 = self.model_Q2.train_on_batch([s_batch, last_action], target) \n", " \n", " #training of the policy\n", " \n", " for i in range(batch_size):\n", " self.life_spent += 1\n", " temp = 1 / np.log(self.life_spent) / 2\n", " new_values = self.model_Q.predict([np.tile(s_batch[i].reshape(1, self.observation_size),(NUM_ACTIONS,1)),\n", " np.eye(NUM_ACTIONS)]).reshape(1,-1)\n", " new_values -= np.amax(new_values, axis=-1)\n", " new_proba[i] = np.exp(new_values / temp) / np.sum(np.exp(new_values / temp), axis=-1)\n", " \n", " loss_policy = self.model_policy.train_on_batch(s_batch, new_proba)\n", " \n", " #training of the value_function\n", " value_target = np.zeros(batch_size)\n", " for i in range(batch_size):\n", " target_pi = self.model_policy.predict(s_batch[i].reshape(1, self.observation_size*NUM_FRAMES), batch_size = 1)\n", " action_v1 = self.model_Q.predict([np.tile(s_batch[i].reshape(1, self.observation_size),(NUM_ACTIONS,1)),\n", " np.eye(NUM_ACTIONS)]).reshape(1,-1)\n", " action_v2 = self.model_Q2.predict([np.tile(s_batch[i].reshape(1, self.observation_size),(NUM_ACTIONS,1)),\n", " np.eye(NUM_ACTIONS)]).reshape(1,-1)\n", " value_target[i] = np.fmin(action_v1[0,a_batch[i]], action_v2[0,a_batch[i]]) - np.sum(target_pi * np.log(target_pi + 1e-6))\n", " \n", " loss_value = self.model_value.train_on_batch(s_batch, value_target.reshape(-1,1))\n", " \n", " self.Is_nan = np.isnan(loss) + np.isnan(loss_2) + np.isnan(loss_policy) + np.isnan(loss_value)\n", " # Print the loss every 100 iterations.\n", " if observation_num % 100 == 0:\n", " print(\"We had a loss equal to \", loss, loss_2, loss_policy, loss_value)\n", "\n", " def save_network(self, path):\n", " # Saves model at specified path as h5 file\n", " # nothing has changed\n", " self.model_policy.save(\"policy_\"+path)\n", " self.model_value_target.save(\"value_\"+path)\n", " print(\"Successfully saved network.\")\n", "\n", " def load_network(self, path):\n", " # nothing has changed\n", " self.model_policy = load_model(\"policy_\"+path)\n", " elf.model_value_target = load_model(\"value_\"+path)\n", " print(\"Succesfully loaded network.\")\n", "\n", " def target_train(self):\n", " # nothing has changed from the original implementation\n", " model_weights = self.model_value.get_weights() \n", " target_model_weights = self.model_value_target.get_weights()\n", " for i in range(len(model_weights)):\n", " target_model_weights[i] = TAU * model_weights[i] + (1 - TAU) * target_model_weights[i]\n", " self.model_value_target.set_weights(model_weights)\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We first show how the agent code looks like without the \"utilities\" to train it. As we can see, defining this agent is pretty simple. The only real method that need to be adapted it \"`my_act`\" that is a method of 2 lines of code." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# Credit Abhinav Sagar: \n", "# https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial\n", "# Code under MIT license, available at:\n", "# https://github.com/abhinavsagar/Reinforcement-Learning-Tutorial/blob/master/LICENSE\n", "\n", "from grid2op.Parameters import Parameters\n", "from grid2op.Agent import AgentWithConverter\n", "from grid2op.Converter import IdToAct\n", "import pdb\n", "\n", "\n", "class DeepQAgent(AgentWithConverter):\n", " # first change: An Agent must derived from grid2op.Agent (in this case MLAgent, because we manipulate vector instead\n", " # of classes)\n", " \n", " def convert_obs(self, observation):\n", " return observation.to_vect()\n", " \n", " def my_act(self, transformed_observation, reward, done=False):\n", " if self.deep_q is None:\n", " self.init_deep_q(transformed_observation)\n", " predict_movement_int, *_ = self.deep_q.predict_movement(transformed_observation, epsilon=0.0)\n", " # print(\"predict_movement_int: {}\".format(predict_movement_int))\n", " return predict_movement_int\n", " \n", " def init_deep_q(self, transformed_observation):\n", " if self.deep_q is None:\n", " # the first time an observation is observed, I set up the neural network with the proper dimensions.\n", " if self.mode == \"DQN\":\n", " cls = DeepQ\n", " elif self.mode == \"DDQN\":\n", " cls = DuelQ\n", " elif self.mode == \"RealQ\":\n", " cls = RealQ\n", " elif self.mode == \"SAC\":\n", " cls = SAC\n", " else:\n", " raise RuntimeError(\"Unknown neural network named \\\"{}\\\"\".format(self.mode))\n", " self.deep_q = cls(self.action_space.size(), observation_size=transformed_observation.shape[0], lr=self.lr)\n", " \n", " def __init__(self, action_space, mode=\"DDQN\", lr=1e-5):\n", " # this function has been adapted.\n", " \n", " # to built a AgentWithConverter, we need an action_space. \n", " # No problem, we add it in the constructor.\n", " AgentWithConverter.__init__(self, action_space, action_space_converter=IdToAct)\n", " \n", " # and now back to the origin implementation\n", " self.replay_buffer = ReplayBuffer(BUFFER_SIZE)\n", " \n", " # compare to original implementation, i don't know the observation space size. \n", " # Because it depends on the component of the observation we want to look at. So these neural network will\n", " # be initialized the first time an observation is observe.\n", " self.deep_q = None\n", " self.mode = mode\n", " self.lr=lr\n", " \n", " def load_network(self, path):\n", " # not modified compare to original implementation\n", " self.deep_q.load_network(path)\n", " \n", " def convert_process_buffer(self):\n", " \"\"\"Converts the list of NUM_FRAMES images in the process buffer\n", " into one training sample\"\"\"\n", " # here i simply concatenate the action in case of multiple action in the \"buffer\"\n", " # this function existed in the original implementation, bus has been adapted.\n", " return np.concatenate(self.process_buffer)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now we will also define some utility class (as defined in the blog post) to make the training easier." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "from grid2op.Reward import L2RPNReward\n", "from grid2op.Reward import RedispReward\n", "\n", "class L2RPNReward_LoadWise(L2RPNReward):\n", " \"\"\"\n", " Update the L2RPN reward to take into account the fact that a change in the loads sum shall not be allocated as reward for the agent.\n", " \n", " \"\"\"\n", " def __init__(self):\n", " super().__init__()\n", " \n", " def initialize(self, env):\n", " super().initialize(env)\n", " self.reward_min = - 10 * env.backend.n_line\n", " self.previous_loads = self.reward_max * np.ones(env.backend.n_line)\n", " \n", " def __call__(self, action, env, has_error, is_done, is_illegal, is_ambiguous):\n", " if not is_done and not has_error:\n", " line_cap = self._L2RPNReward__get_lines_capacity_usage(env)\n", " \n", " new_loads, _, _ = env.backend.loads_info()\n", " new_flows = np.abs(env.backend.get_line_flow())\n", " loads_variation = (np.sum(new_loads) - np.sum(self.previous_loads)) / np.sum(self.previous_loads)\n", " \n", " res = np.sum(line_cap + loads_variation)\n", " else:\n", " # no more data to consider, no powerflow has been run, reward is what it is\n", " res = self.reward_min\n", " return res\n", " \n", "class L2RPNReward_LoadWise_ActionWise(L2RPNReward):\n", " \"\"\"\n", " Update the L2RPN reward to take into account the fact that a change in the loads sum shall not be allocated as reward for the agent.\n", " \n", " \"\"\"\n", " def __init__(self):\n", " super().__init__()\n", " \n", " def initialize(self, env):\n", " super().initialize(env)\n", " self.reward_min = - 10 * env.backend.n_line\n", " self.previous_loads = self.reward_max * np.ones(env.backend.n_line)\n", " self.last_action = env.helper_action_env({})\n", " \n", " def __call__(self, action, env, has_error, is_done, is_illegal, is_ambiguous):\n", " if not is_done and not has_error:\n", " line_cap = self._L2RPNReward__get_lines_capacity_usage(env)\n", " \n", " new_loads, _, _ = env.backend.loads_info()\n", " new_flows = np.abs(env.backend.get_line_flow())\n", " loads_variation = (np.sum(new_loads) - np.sum(self.previous_loads)) / np.sum(self.previous_loads)\n", " \n", " res = np.sum(line_cap + loads_variation)\n", " else:\n", " # no more data to consider, no powerflow has been run, reward is what it is\n", " res = self.reward_min\n", " \n", " res -= (action != env.helper_action_env({})) * (action == self.last_action) * env.backend.n_line / 2\n", " \n", " self.last_action = action\n", " \n", " return res\n", " \n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "class TrainAgent(object):\n", " def __init__(self, agent, reward_fun=RedispReward, env=None):\n", " self.agent = agent\n", " self.reward_fun = reward_fun\n", " self.env = env\n", " \n", " def _build_valid_env(self):\n", " # now we are creating a valid Environment\n", " # it's mandatory because no environment are created when the agent is \n", " # an Agent should not get direct access to the environment, but can interact with it only by:\n", " # * receiving reward\n", " # * receiving observation\n", " # * sending action\n", " \n", " close_env = False\n", " \n", " if self.env is None:\n", " self.env = grid2op.make(action_class=type(self.agent.action_space({})),\n", " reward_class=self.reward_fun)\n", " close_env = True\n", " \n", " # I make sure the action space of the user and the environment are the same.\n", " if not isinstance(self.agent.init_action_space, type(self.env.action_space)):\n", " raise RuntimeError(\"Imposssible to build an agent with 2 different action space\")\n", " if not isinstance(self.env.action_space, type(self.agent.init_action_space)):\n", " raise RuntimeError(\"Imposssible to build an agent with 2 different action space\")\n", " \n", " # A buffer that keeps the last `NUM_FRAMES` images\n", " self.agent.replay_buffer.clear()\n", " self.agent.process_buffer = []\n", " \n", " # make sure the environment is reset\n", " obs = self.env.reset()\n", " self.agent.process_buffer.append(self.agent.convert_obs(obs))\n", " do_nothing = self.env.action_space()\n", " for _ in range(NUM_FRAMES-1):\n", " # Initialize buffer with the first frames\n", " s1, r1, _, _ = self.env.step(do_nothing)\n", " self.agent.process_buffer.append(self.agent.convert_obs(s1)) \n", " return close_env\n", " \n", " def train(self, num_frames, env=None):\n", " # this function existed in the original implementation, but has been slightly adapted.\n", " \n", " # first we create an environment or make sure the given environment is valid\n", " close_env = self._build_valid_env()\n", " \n", " # bellow that, only slight modification has been made. They are highlighted\n", " observation_num = 0\n", " curr_state = self.agent.convert_process_buffer()\n", " epsilon = INITIAL_EPSILON\n", " alive_frame = 0\n", " total_reward = 0\n", "\n", " while observation_num < num_frames:\n", " if observation_num % 1000 == 999:\n", " print((\"Executing loop %d\" %observation_num))\n", "\n", " # Slowly decay the learning rate\n", " if epsilon > FINAL_EPSILON:\n", " epsilon -= (INITIAL_EPSILON-FINAL_EPSILON)/EPSILON_DECAY\n", "\n", " initial_state = self.agent.convert_process_buffer()\n", " self.agent.process_buffer = []\n", "\n", " # it's a bit less convenient that using the SpaceInvader environment.\n", " # first we need to initiliaze the neural network\n", " self.agent.init_deep_q(curr_state)\n", " # then we need to predict the next move\n", " predict_movement_int, predict_q_value = self.agent.deep_q.predict_movement(curr_state, epsilon)\n", " # and then we convert it to a valid action\n", " act = self.agent.convert_act(predict_movement_int)\n", " \n", " reward, done = 0, False\n", " for i in range(NUM_FRAMES):\n", " temp_observation_obj, temp_reward, temp_done, _ = self.env.step(act)\n", " # here it has been adapted too. The observation get from the environment is\n", " # first converted to vector\n", " \n", " # below this line no changed have been made to the original implementation.\n", " reward += temp_reward\n", " self.agent.process_buffer.append(self.agent.convert_obs(temp_observation_obj))\n", " done = done | temp_done\n", "\n", " if done:\n", " print(\"Lived with maximum time \", alive_frame)\n", " print(\"Earned a total of reward equal to \", total_reward)\n", " # reset the environment\n", " self.env.reset()\n", " \n", " alive_frame = 0\n", " total_reward = 0\n", "\n", " new_state = self.agent.convert_process_buffer()\n", " self.agent.replay_buffer.add(initial_state, predict_movement_int, reward, done, new_state)\n", " total_reward += reward\n", " if self.agent.replay_buffer.size() > MIN_OBSERVATION:\n", " s_batch, a_batch, r_batch, d_batch, s2_batch = self.agent.replay_buffer.sample(MINIBATCH_SIZE)\n", " self.agent.deep_q.train(s_batch, a_batch, r_batch, d_batch, s2_batch, observation_num)\n", " self.agent.deep_q.target_train()\n", "\n", " # Save the network every 1000 iterations after 50000 iterations\n", " if observation_num > 50000 and observation_num % 1000 == 0 and self.agent.deep_q.Is_nan == 0:\n", " print(\"Saving Network\")\n", " self.agent.deep_q.save_network(\"saved_agent_\"+self.agent.mode+\".h5\")\n", "\n", " alive_frame += 1\n", " observation_num += 1\n", " \n", " if close_env:\n", " print(\"closing env\")\n", " self.env.close()\n", " \n", " def calculate_mean(self, num_episode = 100, env=None):\n", " # this method has been only slightly adapted from the original implementation\n", " \n", " # Note that it is NOT the recommended method to evaluate an Agent. Please use \"Grid2Op.Runner\" instead\n", " \n", " # first we create an environment or make sure the given environment is valid\n", " close_env = self._build_valid_env()\n", " \n", " reward_list = []\n", " print(\"Printing scores of each trial\")\n", " for i in range(num_episode):\n", " done = False\n", " tot_award = 0\n", " self.env.reset()\n", " while not done:\n", " state = self.convert_process_buffer()\n", " \n", " # same adapation as in \"train\" function. \n", " predict_movement_int = self.agent.deep_q.predict_movement(state, 0.0)[0]\n", " predict_movement = self.agent.convert_act(predict_movement_int)\n", " \n", " # same adapation as in the \"train\" funciton\n", " observation_obj, reward, done, _ = self.env.step(predict_movement)\n", " observation_vect_full = observation_obj.to_vect()\n", " \n", " tot_award += reward\n", " self.process_buffer.append(observation)\n", " self.process_buffer = self.process_buffer[1:]\n", " print(tot_award)\n", " reward_list.append(tot_award)\n", " \n", " if close_env:\n", " self.env.close()\n", " return np.mean(reward_list), np.std(reward_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### b) Training the model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can define the model (agent), and then train it.\n", "\n", "This is done exactly the same way as in the Abhinav Sagar implementation.\n", "\n", "**NB** The code bellow can take a few minutes to run. It's training a Deep Reinforcement Learning Agent afterall. It this takes too long on your machine, you can always decrease the \"nb_frame\", and set it to 1000 for example. In this case, the Agent will probably not be really good.\n", "\n", "**NB** For a real Agent, it would take much longer to train." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/benjamin/Documents/grid2op_test/getting_started/grid2op/MakeEnv.py:668: UserWarning:\n", "\n", "Your are using only 2 chronics for this environment. More can be download by running, from a command line:\n", "python -m grid2op.download --name \"case14_redisp\" --path_save PATH\\WHERE\\YOU\\WANT\\TO\\DOWNLOAD\\DATA\n", "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Successfully constructed networks.\n", "Lived with maximum time 87\n", "Earned a total of reward equal to 99318.90852576918\n", "Lived with maximum time 8\n", "Earned a total of reward equal to 7582.116955233524\n", "Successfully saved network.\n" ] } ], "source": [ "nb_frame = 100\n", "\n", "env = make(name_env=\"case14_redisp\")\n", "my_agent = DeepQAgent(env.action_space, mode=\"DDQN\")\n", "trainer = TrainAgent(agent=my_agent, env=env, reward_fun=RedispReward)\n", "trainer.train(nb_frame)\n", "trainer.agent.deep_q.save_network(\"saved_agent_\"+trainer.agent.mode+\".h5\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# To see whether the agent learnt something during training: lets plot the learning curve" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0.0, 100.0)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "plt.figure(figsize=(30,20))\n", "plt.plot(my_agent.deep_q.qvalue_evolution)\n", "plt.axhline(y=0, linewidth=3, color='red')\n", "plt.xlim(0, len(my_agent.deep_q.qvalue_evolution))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The learning curve shown above is really poor. It's because the agent has not been trained for a long time (and because it uses a very poor input data). If you train this agent for approximately 10-12 hours, using only the relative flow (`obs.rho` see the last section of this notebook for an example) you will get the following:\n", "\n", "![](img/trained_agent.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## III) Evaluating the Agent" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now, time to test this trained agent.\n", "\n", "To do that, we have multiple choices.\n", "\n", "Either we recode the \"DeepQAgent\" class to load the stored weights (that have been saved during trainig) when it is initialized (not covered in this notebook), or we can also directly specify the \"instance\" of the Agent to use in the Grid2Op Runner.\n", "\n", "To do that, it's fairly simple. First, you need to specify that you won't use the \"*agentClass*\" argument, by setting it to ``None``, and secondly you simply provide the agent to use in the *agentInstance* argument.\n", "\n", "**NB** If you don't do that, the Runner will be created (the constructor will raise an exception). And if you choose to use the \"*agentClass*\" argument, your agent will be reloaded from scratch. So **if it doesn't load the weights** it will behave as a non trained agent, unlikely to perform well on the task." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### III.A) Evaluate the Agent" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have \"successfully\" trained our Agent, we will evaluating it. As opposed to the trainining, the evaluation is done classically using a standard Runner.\n", "\n", "Note that the Runner will use a \"scoring function\" that might be different from the \"reward function\" used during training. In our case, it's not. We use the `L2RPNReward` in both cases.\n", "\n", "In the code bellow, we commented on what can be different and what must be identical for training and evaluation of model." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "from grid2op.Runner import Runner\n", "from grid2op.Chronics import GridStateFromFileWithForecasts, Multifolder\n", "scoring_function = L2RPNReward\n", "\n", "dict_params = env.get_params_for_runner()\n", "dict_params[\"gridStateclass_kwargs\"][\"max_iter\"] = max_iter\n", "# make a runner from an intialized environment\n", "runner = Runner(**dict_params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Run the Agent and save the results. As opposed to the multiple times we exposed the \"runner.run\" call, we never really dive into the \"path_save\" argument. This path allows you to save lots of information about your Agent behaviour. Please All the informations present are shown on the documentation [here](https://grid2op.readthedocs.io/en/latest/runner.html)." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The results for the trained agent are:\n", "\tFor chronics located at 0\n", "\t\t - cumulative reward: 121368.512117\n", "\t\t - number of time steps completed: 100 / 100\n" ] } ], "source": [ "import shutil\n", "path_save=\"trained_agent_log\"\n", "\n", "# delete the previous stored results\n", "if os.path.exists(path_save):\n", " shutil.rmtree(path_save)\n", "\n", "# run the episode\n", "res = runner.run(nb_episode=1, path_save=path_save)\n", "print(\"The results for the trained agent are:\")\n", "for _, chron_name, cum_reward, nb_time_step, max_ts in res:\n", " msg_tmp = \"\\tFor chronics located at {}\\n\".format(chron_name)\n", " msg_tmp += \"\\t\\t - cumulative reward: {:.6f}\\n\".format(cum_reward)\n", " msg_tmp += \"\\t\\t - number of time steps completed: {:.0f} / {:.0f}\".format(nb_time_step, max_ts)\n", " print(msg_tmp)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### III.B) Inspect the Agent " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Please refer to the official document for more information about the content of the directory where the data are saved. Note that the saving of the information is triggered by the \"path_save\" argument sent to the \"runner.run\" function.\n", "\n", "Some information that will be present in this repository are:\n", "If enabled, the :class:`Runner` will save the information in a structured way. For each episode there will be a folder\n", "with:\n", "\n", " - \"episode_meta.json\" that represents some meta information about:\n", "\n", " - \"backend_type\": the name of the `grid2op.Backend` class used\n", " - \"chronics_max_timestep\": the **maximum** number of timestep for the chronics used\n", " - \"chronics_path\": the path where the temporal data (chronics) are located\n", " - \"env_type\": the name of the `grid2op.Environment` class used.\n", " - \"grid_path\": the path where the powergrid has been loaded from\n", "\n", " - \"episode_times.json\": gives some information about the total time spend in multiple part of the runner, mainly the\n", " `grid2op.Agent` (and especially its method `grid2op.Agent.act`) and amount of time spent in the\n", " `grid2op.Environment`\n", "\n", " - \"_parameters.json\": is a representation as json of a the `grid2op.Parameters` used for this episode\n", " - \"rewards.npy\" is a numpy 1d array giving the rewards at each time step. We adopted the convention that the stored\n", " reward at index `i` is the one observed by the agent at time `i` and **NOT** the reward sent by the\n", " `grid2op.Environment` after the action has been implemented.\n", " - \"exec_times.npy\" is a numpy 1d array giving the execution time of each time step of the episode\n", " - \"actions.npy\" gives the actions that has been taken by the `grid2op.Agent`. At row `i` of \"actions.npy\" is a\n", " vectorized representation of the action performed by the agent at timestep `i` *ie.* **after** having observed\n", " the observation present at row `i` of \"observation.npy\" and the reward showed in row `i` of \"rewards.npy\".\n", " - \"disc_lines.npy\" gives which lines have been disconnected during the simulation of the cascading failure at each\n", " time step. The same convention as for \"rewards.npy\" has been adopted. This means that the powerlines are\n", " disconnected when the `grid2op.Agent` takes the `grid2op.Action` at time step `i`.\n", " - \"observations.npy\" is a numpy 2d array reprensenting the `grid2op.Observation` at the disposal of the\n", " `grid2op.Agent` when he took his action.\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can first look at the repository were the data are stored:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['dict_env_modification_space.json',\n", " 'dict_action_space.json',\n", " 'dict_observation_space.json',\n", " '0']" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import os\n", "os.listdir(path_save)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we can see, there is only one folder there. It's named \"1\" because, in the original data, this came from the folder named \"1\" (the original data are located at \"/home/donnotben/.local/lib/python3.6/site-packages/grid2op/data/test_multi_chronics/\")\n", "\n", "If there were multiple episode, each episode would have it's own folder, with a name as resemblant as possible to the origin name of the data. This is done to ease the studying of the results.\n", "\n", "Now let's see what is inside this folder:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['rewards.npy',\n", " 'episode_meta.json',\n", " 'disc_lines_cascading_failure.npy',\n", " 'agent_exec_times.npy',\n", " 'actions.npy',\n", " 'episode_times.json',\n", " 'observations.npy',\n", " '_parameters.json',\n", " 'other_rewards.json',\n", " 'env_modifications.npy']" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "os.listdir(os.path.join(path_save,\"0\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can for example load the \"actions\" performed by the Agent, and have a look at them.\n", "\n", "To do that we will load the action array (represented as vector) and use the action_space to convert it back into valid action class." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "all_actions = np.load(os.path.join(\"trained_agent_log\", \"0\", \"actions.npy\"))\n", "li_actions = []\n", "for i in range(all_actions.shape[0]):\n", " try:\n", " tmp = runner.env.action_space.from_vect(all_actions[i,:])\n", " li_actions.append(tmp)\n", " except:\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This allows us to have a deeper look at the action, and their effect. Note that here, we used action that can only **set** the line status, so looking at their effect is pretty straightforward.\n", "\n", "Also, note that as oppose to \"change\", if a powerline is already connected, trying to **set** it as connected has absolutely no impact." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "line_disc = 0\n", "line_reco = 0\n", "for act in li_actions:\n", " dict_ = act.as_dict()\n", " if \"set_line_status\" in dict_:\n", " line_reco += dict_[\"set_line_status\"][\"nb_connected\"]\n", " line_disc += dict_[\"set_line_status\"][\"nb_disconnected\"]\n", "line_reco" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As wa can see for our event, the agent always try to reconnect a powerline. As all lines are alway reconnected, this Agent does basically nothing." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also do the same kind of post analysis for the observation, even though here, as the observations come from files, it's probably not particularly intersting." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all_observations = np.load(os.path.join(\"trained_agent_log\", \"0\", \"observations.npy\"))\n", "li_observations = []\n", "nb_real_disc = 0\n", "for i in range(all_observations.shape[0]):\n", " try:\n", " tmp = runner.env.observation_space.from_vect(all_observations[i,:])\n", " li_observations.append(tmp)\n", " nb_real_disc += (np.sum(tmp.line_status) - tmp.line_status.shape[0])\n", " except:\n", " break\n", "nb_real_disc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can also look at the type of action the agent did:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of different actions played: 1\n" ] } ], "source": [ "actions_count = {}\n", "for act in li_actions:\n", " act_as_vect = tuple(act.to_vect())\n", " if not act_as_vect in actions_count:\n", " actions_count[act_as_vect] = 0\n", " actions_count[act_as_vect] += 1\n", "print(\"Number of different actions played: {}\".format(len(actions_count)))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This action will:\n", "\t - NOT change anything to the injections\n", "\t - NOT perform any redispatching action\n", "\t - NOT force any line status\n", "\t - NOT switch any line status\n", "\t - NOT switch anything in the topology\n", "\t - NOT force any particular bus configuration\n" ] } ], "source": [ "print(runner.env.action_space.from_vect(np.array(list(actions_count.keys())[0])))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The agent only did one action (note that this number can really vary on the number of training step and the . This is not really good, the agent didn't learn anything." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## IV) Improve your Agent " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As we saw, the agent we develop was not really interesting. To improve it, we could think about:\n", "\n", "- a better encoding of the observation. For now everything is fed to the neural network, without any normalization of any kind. This is a real problem for learning algorithm.\n", "- a better neural network architecture (as said, we didn't pay any attention to it in our model)\n", "- train it for a longer time\n", "- adapt the learning rate and all the meta parameters of the learning algorithm.\n", "- etc.\n", "\n", "In this notebook, we will focus on changing the observation representation, by only feeding the agent only some informations.\n", "\n", "To do so, the only modification we need to do is to modify the way the observation are converted. So the \"*convert_obs*\" method, and that is it. Nothing else need to be changed. Here for example we could think of only using the flow ratio (*i.e.,* the current flows divided by the thermal limits) as part of the observation (named rho) instead of feeding the whole observation." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "class DeepQAgent_Improved(DeepQAgent):\n", " def __init__(self, action_space, mode=\"DDQN\"):\n", " DeepQAgent.__init__(self, action_space, mode=mode)\n", " \n", " def convert_obs(self, observation):\n", " return observation.rho" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we can reuse exactly the same code to train it :-)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Successfully constructed networks.\n", "Lived with maximum time 56\n", "Earned a total of reward equal to 3232.3359374684956\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "my_agent = DeepQAgent_Improved(env.action_space, mode=\"DDQN\")\n", "trainer = TrainAgent(agent=my_agent, env=env)\n", "trainer.train(nb_frame)\n", "\n", "plt.figure(figsize=(30,20))\n", "plt.plot(my_agent.deep_q.qvalue_evolution)\n", "plt.axhline(y=0, linewidth=3, color='red')\n", "_ = plt.xlim(0, len(my_agent.deep_q.qvalue_evolution))" ] } ], "metadata": { "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.6.10" } }, "nbformat": 4, "nbformat_minor": 2 }