├── DQN ├── cartpole_dqn.png └── cartpole_dqn.py ├── Mountain_Car ├── q_learning_mountain.png ├── q_learning_mountain_cart.py ├── sarsa_lambda.py ├── sarsa_lambda_mountain.png ├── sarsa_mountain.png └── sarsa_mountain_car.py ├── README.md ├── q-learning cart pole.ipynb └── sarsa_cartpole.ipynb /DQN/cartpole_dqn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srnand/Reinforcement-Learning-using-OpenAI-Gym/f2a3732392d2ccd66f3001e0b6a0bc33c5656229/DQN/cartpole_dqn.png -------------------------------------------------------------------------------- /DQN/cartpole_dqn.py: -------------------------------------------------------------------------------- 1 | import gym 2 | import tensorflow as tf 3 | from keras.models import Sequential 4 | from keras.layers import Convolution2D, Flatten, Dense 5 | from collections import deque 6 | import random 7 | from random import randint 8 | import numpy as np 9 | import skimage.color, skimage.transform, skimage.exposure 10 | import matplotlib.pyplot as plt 11 | from keras.optimizers import Adam 12 | import seaborn as sns 13 | 14 | import time 15 | class DQAgent: 16 | def __init__(self): 17 | self.env = gym.make('CartPole-v0') 18 | self.input_size=self.env.observation_space.shape[0] 19 | self.action_size=self.env.action_space.n 20 | self.nets=[] 21 | for i in range(self.action_size): 22 | self.nets.append(self.qnetwork(self.input_size)) 23 | 24 | self.memory=deque(maxlen=2000) 25 | self.batch_size=32 26 | self.epsilon = 1.0 27 | self.gamma=0.95 28 | self.epsilon_min = 0.01 29 | self.epsilon_decay = 0.995 30 | 31 | def qnetwork(self,input_size): 32 | model = Sequential() 33 | model.add(Dense(24, input_dim=input_size, activation='relu')) 34 | model.add(Dense(24, activation='relu')) 35 | model.add(Dense(1, activation='linear')) 36 | model.compile(loss='mse',optimizer=Adam(lr=0.001)) 37 | return model 38 | 39 | def remember(self,s,a,r,s_,d): 40 | self.memory.append((s,a,r,s_,d)) 41 | 42 | def get_action(self,state): 43 | if self.epsilon>np.random.rand(): 44 | return random.randrange(self.action_size) 45 | val=[] 46 | for i in self.nets: 47 | # print i.predict(state) 48 | val.append(i.predict(state)[0]) 49 | # actions = self.dqn.predict(state) 50 | # print val 51 | return np.argmax(val) 52 | 53 | def replay(self): 54 | minibatch = random.sample(self.memory, self.batch_size) 55 | for s,a,r,s_,d in minibatch: 56 | if d: 57 | target=r 58 | else: 59 | val=[] 60 | for i in self.nets: 61 | val.append(i.predict(s_)[0]) 62 | target = r+self.gamma*np.amax(val) 63 | self.nets[a].fit(s,[[target]],epochs=1,verbose=0) 64 | if self.epsilon > self.epsilon_min: 65 | self.epsilon *= self.epsilon_decay 66 | if __name__ == "__main__": 67 | start=time.time() 68 | agent = DQAgent() 69 | timesteps=[] 70 | for e in range(1000): 71 | t=0 72 | state=agent.env.reset() 73 | state=np.reshape(state,[1,agent.input_size]) 74 | print e 75 | while (True): 76 | # agent.env.render() 77 | action = agent.get_action(state) 78 | next_state, reward, done, _ = agent.env.step(action) 79 | if done: 80 | if t!=200: 81 | reward=-10 82 | next_state=np.reshape(next_state,[1,agent.input_size]) 83 | agent.remember(state,action,reward,next_state,done) 84 | state=next_state 85 | t+=1 86 | # print done 87 | if done: 88 | timesteps.append(t) 89 | break 90 | if len(agent.memory)>agent.batch_size: 91 | agent.replay() 92 | end=time.time() 93 | print ("--- %s seconds ---" % (end - start)) 94 | plt.plot(timesteps) 95 | plt.show() -------------------------------------------------------------------------------- /Mountain_Car/q_learning_mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srnand/Reinforcement-Learning-using-OpenAI-Gym/f2a3732392d2ccd66f3001e0b6a0bc33c5656229/Mountain_Car/q_learning_mountain.png -------------------------------------------------------------------------------- /Mountain_Car/q_learning_mountain_cart.py: -------------------------------------------------------------------------------- 1 | import gym 2 | import math 3 | from copy import deepcopy 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | 7 | env = gym.make('MountainCar-v0') 8 | Q_table = np.zeros((20,20,3)) 9 | alpha=0.3 10 | buckets=[20, 20] 11 | gamma=0.99 12 | rewards=[] 13 | 14 | 15 | # observation = env.reset() 16 | print env.observation_space.high 17 | # x=input() 18 | 19 | def toDiscreteStates(observation): 20 | interval=[0 for i in range(len(observation))] 21 | max_range=[1.2,0.07] #[4.8,3.4*(10**38),0.42,3.4*(10**38)] 22 | 23 | for i in range(len(observation)): 24 | data = observation[i] 25 | inter = int(math.floor((data + max_range[i])/(2*max_range[i]/buckets[i]))) 26 | if inter>=buckets[i]: 27 | interval[i]=buckets[i]-1 28 | elif inter<0: 29 | interval[i]=0 30 | else: 31 | interval[i]=inter 32 | return interval 33 | 34 | def get_action(observation,t): 35 | 36 | if np.random.random()=Q_table[tuple(interval)][1]: 41 | # return 0 42 | # else: 43 | # return 1 44 | return np.argmax(np.array(Q_table[tuple(interval)])) 45 | 46 | def updateQ(observation,reward,action,ini_obs,t): 47 | 48 | interval = toDiscreteStates(observation) 49 | 50 | Q_next = max(Q_table[tuple(interval)]) 51 | 52 | ini_interval = toDiscreteStates(ini_obs) 53 | 54 | Q_table[tuple(ini_interval)][action]+=max(0.4, min(0.1, 1.0 - math.log10((t+1)/125.)))*(reward + gamma*(Q_next) - Q_table[tuple(ini_interval)][action]) 55 | 56 | 57 | def updateQ_SARSA(observation,reward,action,ini_obs,next_action,t): 58 | 59 | interval = toDiscreteStates(observation) 60 | 61 | Q_next = Q_table[tuple(interval)][next_action] 62 | 63 | # interval2 = toDiscreteStates(observation2) 64 | 65 | # Q_next2 = Q_table[tuple(interval2)][next2_action] 66 | 67 | ini_interval = toDiscreteStates(ini_obs) 68 | 69 | Q_table[tuple(ini_interval)][action]+=max(0.4, min(0.1, 1.0 - math.log10((t+1)/125.)))*(reward + gamma*(Q_next) - Q_table[tuple(ini_interval)][action]) 70 | 71 | 72 | # print toDiscreteStates([1.4,2,3,0.4,2,4]) 73 | 74 | for i_episode in range(3000): 75 | observation = env.reset() 76 | t=0 77 | while (True): 78 | # env.render() 79 | # print(observation) 80 | #action = env.action_space.sample() 81 | action = get_action(observation,i_episode) 82 | observation1, reward, done, info = env.step(action) 83 | # next_action = get_action(observation1,i_episode) 84 | # observation2, reward, done, info = env.step(next_action) 85 | # next2_action = get_action(observation2,i_episode) 86 | # updateQ_SARSA(observation1,reward,action,observation,next_action,i_episode) 87 | updateQ(observation1,reward,action,observation,t) 88 | observation=observation1 89 | action = next_action 90 | t+=1 91 | if done: 92 | # print("Episode finished after {} timesteps".format(t+1)) 93 | rewards.append(t+1) 94 | break 95 | # print rewards 96 | print Q_table 97 | plt.plot(rewards) 98 | plt.show() 99 | 100 | -------------------------------------------------------------------------------- /Mountain_Car/sarsa_lambda.py: -------------------------------------------------------------------------------- 1 | import gym 2 | import math 3 | from copy import deepcopy 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | import seaborn as sns 7 | 8 | env = gym.make('MountainCar-v0') 9 | Q_table = np.zeros((65,65,3)) 10 | alpha=0.3 11 | buckets=[65, 65] 12 | gamma=0.99 13 | rewards=[] 14 | 15 | def toDiscreteStates(observation): 16 | interval=[0 for i in range(len(observation))] 17 | max_range=[1.2,0.07] #[4.8,3.4*(10**38),0.42,3.4*(10**38)] 18 | 19 | for i in range(len(observation)): 20 | data = observation[i] 21 | inter = int(math.floor((data + max_range[i])/(2*max_range[i]/buckets[i]))) 22 | if inter>=buckets[i]: 23 | interval[i]=buckets[i]-1 24 | elif inter<0: 25 | interval[i]=0 26 | else: 27 | interval[i]=inter 28 | return interval 29 | 30 | def get_action(observation,t): 31 | 32 | if np.random.random()=Q_table[tuple(interval)][1]: 37 | # return 0 38 | # else: 39 | # return 1 40 | return np.argmax(np.array(Q_table[tuple(interval)])) 41 | 42 | def updateQ_SARSA(observation,reward,action,ini_obs,next_action,t,eligibility): 43 | 44 | interval = toDiscreteStates(observation) 45 | 46 | Q_next = Q_table[tuple(interval)][next_action] 47 | 48 | ini_interval = toDiscreteStates(ini_obs) 49 | 50 | lr=max(0.4, min(0.1, 1.0 - math.log10((t+1)/125.))) 51 | 52 | td_error=(reward + gamma*(Q_next) - Q_table[tuple(ini_interval)][action]) 53 | 54 | # print Q_table[tuple(ini_interval)][action], Q_table[tuple(ini_interval)][action]*eligibility[tuple(ini_interval)][action] 55 | 56 | # Q_table[tuple(ini_interval)][action]+=lr*td_error*eligibility[tuple(ini_interval)][action] 57 | 58 | # eligibility[tuple(ini_interval)][action]+=1 59 | 60 | Q_table[:,:,action]+=lr*td_error*(eligibility[:,:,action]) 61 | # print Q_table[:,:,action] 62 | # print lr*td_error*eligibility[tuple(interval)][action] 63 | 64 | # def updateQ_SARSA(observation,reward,action,ini_obs,next_action,t,eligibility): 65 | # interval = toDiscreteStates(observation) 66 | # Q_next = Q_table[tuple(interval)][next_action] 67 | # ini_interval = toDiscreteStates(ini_obs) 68 | 69 | # alpha=max(0.4, min(0.1, 1.0 - math.log10((t+1)/125.))) 70 | 71 | # td= (reward + gamma*(Q_next) - Q_table[tuple(ini_interval)][action]) 72 | 73 | # Q_table[:,action]+=alpha*td#*(eligibility[:,action]) 74 | 75 | # rewards=[] 76 | lambdaa=0.8 77 | 78 | for i_episode in range(2500): 79 | observation = env.reset() 80 | t=0 81 | eligibility = np.zeros((65,65,3)) 82 | while (True): 83 | # env.render() 84 | action = get_action(observation,i_episode) 85 | observation1, reward, done, info = env.step(action) 86 | 87 | interval = toDiscreteStates(observation) 88 | eligibility *= lambdaa * gamma 89 | # # print eligibility 90 | eligibility[tuple(interval)][action]+=1 91 | # print observation1 92 | 93 | next_action = get_action(observation1,i_episode) 94 | updateQ_SARSA(observation1,reward,action,observation,next_action,i_episode,eligibility) 95 | observation=observation1 96 | action = next_action 97 | t+=1 98 | if done: 99 | rewards.append(t+1) 100 | break 101 | 102 | plt.plot(rewards) 103 | plt.show() 104 | -------------------------------------------------------------------------------- /Mountain_Car/sarsa_lambda_mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srnand/Reinforcement-Learning-using-OpenAI-Gym/f2a3732392d2ccd66f3001e0b6a0bc33c5656229/Mountain_Car/sarsa_lambda_mountain.png -------------------------------------------------------------------------------- /Mountain_Car/sarsa_mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srnand/Reinforcement-Learning-using-OpenAI-Gym/f2a3732392d2ccd66f3001e0b6a0bc33c5656229/Mountain_Car/sarsa_mountain.png -------------------------------------------------------------------------------- /Mountain_Car/sarsa_mountain_car.py: -------------------------------------------------------------------------------- 1 | import gym 2 | import math 3 | from copy import deepcopy 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | 7 | env = gym.make('MountainCar-v0') 8 | Q_table = np.zeros((20,20,3)) 9 | alpha=0.3 10 | buckets=[20, 20] 11 | gamma=0.99 12 | rewards=[] 13 | 14 | def toDiscreteStates(observation): 15 | interval=[0 for i in range(len(observation))] 16 | max_range=[1.2,0.07] #[4.8,3.4*(10**38),0.42,3.4*(10**38)] 17 | 18 | for i in range(len(observation)): 19 | data = observation[i] 20 | inter = int(math.floor((data + max_range[i])/(2*max_range[i]/buckets[i]))) 21 | if inter>=buckets[i]: 22 | interval[i]=buckets[i]-1 23 | elif inter<0: 24 | interval[i]=0 25 | else: 26 | interval[i]=inter 27 | return interval 28 | 29 | def get_action(observation,t): 30 | 31 | if np.random.random()=Q_table[tuple(interval)][1]: 36 | # return 0 37 | # else: 38 | # return 1 39 | return np.argmax(np.array(Q_table[tuple(interval)])) 40 | 41 | def updateQ_SARSA(observation,reward,action,ini_obs,next_action,t): 42 | 43 | interval = toDiscreteStates(observation) 44 | 45 | Q_next = Q_table[tuple(interval)][next_action] 46 | 47 | ini_interval = toDiscreteStates(ini_obs) 48 | 49 | Q_table[tuple(ini_interval)][action]+=max(0.4, min(0.1, 1.0 - math.log10((t+1)/125.)))*(reward + gamma*(Q_next) - Q_table[tuple(ini_interval)][action]) 50 | 51 | 52 | # print toDiscreteStates([1.4,2,3,0.4,2,4]) 53 | 54 | for i_episode in range(3000): 55 | observation = env.reset() 56 | t=0 57 | while (True): 58 | # env.render() 59 | # print(observation) 60 | #action = env.action_space.sample() 61 | action = get_action(observation,i_episode) 62 | observation1, reward, done, info = env.step(action) 63 | next_action = get_action(observation1,i_episode) 64 | # observation2, reward, done, info = env.step(next_action) 65 | # next2_action = get_action(observation2,i_episode) 66 | updateQ_SARSA(observation1,reward,action,observation,next_action,i_episode) 67 | # updateQ(observation1,reward,action,observation,t) 68 | observation=observation1 69 | action = next_action 70 | t+=1 71 | if done: 72 | # print("Episode finished after {} timesteps".format(t+1)) 73 | rewards.append(t+1) 74 | break 75 | # print rewards 76 | # print Q_table 77 | plt.plot(rewards) 78 | plt.show() 79 | 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reinforcement-Learning-using-OpenAI-Gym 2 | Reinforcement Learning algorithms SARSA, Q-Learning, DQN, for Classical and MuJoCo Environments and testing them with OpenAI Gym. 3 | ### SARSA Cart Pole 4 | SARSA (State-Action-Reward-State-Action) is a simple on-policy reinforcement learning 5 | algorithm in which the agent tries to learn the optimal policy following the current policy (epsilon-greedy) generating action from current state and also the next state. 6 | 7 | Implemented SARSA for the Cart Pole problem, a classical environment provided by OpenAI gym. 8 | 9 | Problem Goal:
10 | The Cart Pole Problem has 4 states at every time step, 11 | >[**the position of the cart on the horizontal 12 | axis**,
**the cart’s velocity on that same axis**,
**the pole’s angular position on the cart**,
**the angular 13 | velocity of the pole on the cart**] 14 | 15 | and there are 2 actions which the cart can take [**going to the left**, 16 | **going to the right**]. 17 | 18 | The main goal is to balance the pole on the cart for the longest time taking 19 | appropriate actions at every timestep. 20 | 21 | Implementation
22 | * Discretized the 4 states into [2,2,8,4] discrete states respectively and have maintained a specific range of values for each of the states. 23 | * Used decaying exploration rate to decrease random exploration towards the end of the episodes. 24 | 25 | ### Q-Learning (SARSAMAX) Cart Pole 26 | Q-Learning is a simple off-policy reinforcement learning 27 | algorithm in which the agent tries to learn the optimal policy following the current policy (epsilon-greedy) generating action from current state and transitions to the state using the action which has the max Q-value, which is the why it is also called SARSAMAX. 28 | 29 | Implemented Q-learning for the Cart Pole problem, a classical environment provided by OpenAI gym. 30 | 31 | Implementation
32 | * Discretized the 4 states into [2,2,8,4] discrete states respectively and have maintained a specific range of values for each of the states. 33 | * Used decaying exploration rate to decrease random exploration towards the end of the episodes. 34 | 35 | Results: 36 |
37 | It looks from the graph that, the cart is able to balance the pole for the required amount of time almost constantly in about less than 2000 episodes for both algorithms. 38 | 39 | ### SARSA Mountain Car 40 | 41 | Problem Goal:
42 | The Mountain Car Problem has 2 states at every time step, 43 | >[**the position of the car**,
**the car’s velocity**] 44 | 45 | and there are 3 actions which the cart can take [**going to the left**, **no action**, 46 | **going to the right**]. 47 | 48 | The main goal is to make the car reach the goal(up-hill) taking 49 | appropriate actions at every timestep. 50 | 51 | Implementation
52 | * Discretized the 2 states into [20,20] discrete states respectively and have maintained a specific range of values for each of the states. 53 | * Used decaying exploration rate to decrease random exploration towards the end of the episodes. 54 | * Used gradually increasing learning rate because as the exploration rate decreases, confidence level increases and more learning happens towards the end of the episodes. 55 | 56 | ### Q-Learning (SARSAMAX) Mountain Car 57 | 58 | Implementation
59 | * Discretized the 2 states into [20,20] discrete states respectively and have maintained a specific range of values for each of the states. 60 | * Used decaying exploration rate to decrease random exploration towards the end of the episodes. 61 | * Used gradually increasing learning rate because as the exploration rate decreases, confidence level increases and more learning happens towards the end of the episodes. 62 | 63 | Results: 64 |
65 | It looks from the graph that, the car is able to reach the goal almost constantly in about less than 3000 episodes for both algorithms. 66 | 67 | ### SARSA Mountain Car with Backward View (Eligibility Traces) 68 | 69 | Implementation
70 | * Discretized the 2 states into [65,65] discrete states respectively and have maintained a specific range of values for each of the states. 71 | * Used Eligiblity Traces, tuning value for lambda. 72 | * Used decaying exploration rate to decrease random exploration towards the end of the episodes. 73 | * Used gradually increasing learning rate because as the exploration rate decreases, confidence level increases and more learning happens towards the end of the episodes. 74 | 75 | ### Deep Q-Learning Cart Pole 76 | 77 | Implementation
78 | * Created 2 Deep Networks which takes state as input and outputs the Target Q-Value for respective actions in respective networks. 79 | * Used Experience Replay which does off-line updates sampling batches from memory, and trains the network reducing the MSE. 80 | * Used decaying exploration rate to decrease random exploration towards the end of the episodes. 81 | * Explicitly for this problem, gave the reard of -10 if the done bool value is True and the timesteps is not 200. So the agent tries to avoid the bool value and keeps on balancing the pole on the cart. 82 | -------------------------------------------------------------------------------- /q-learning cart pole.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 6, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import gym\n", 10 | "import math\n", 11 | "from copy import deepcopy\n", 12 | "import numpy as np\n", 13 | "import matplotlib.pyplot as plt\n", 14 | "import seaborn as sns" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 7, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "\u001b[33mWARN: gym.spaces.Box autodetected dtype as . Please provide explicit dtype.\u001b[0m\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "env = gym.make('CartPole-v0')\n", 32 | "Q_table = np.zeros((2,2,8,4,2))\n", 33 | "alpha=0.3\n", 34 | "buckets=[2, 2, 8, 4]\n", 35 | "gamma=0.99\n", 36 | "rewards=[]" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 8, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "def toDiscreteStates(observation):\n", 46 | " interval=[0 for i in range(len(observation))]\n", 47 | " max_range=[2,3,0.42,3] #[4.8,3.4*(10**38),0.42,3.4*(10**38)]\n", 48 | "\n", 49 | " for i in range(len(observation)):\n", 50 | " data = observation[i]\n", 51 | " inter = int(math.floor((data + max_range[i])/(2*max_range[i]/buckets[i])))\n", 52 | " if inter>=buckets[i]:\n", 53 | " interval[i]=buckets[i]-1\n", 54 | " elif inter<0:\n", 55 | " interval[i]=0\n", 56 | " else:\n", 57 | " interval[i]=inter\n", 58 | " return interval" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 9, 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "def get_action(observation,t):\n", 68 | "# print get_explore_rate(t)\n", 69 | " if np.random.random()=Q_table[tuple(interval)][1]:\n", 74 | " return 0\n", 75 | " else:\n", 76 | " return 1\n", 77 | "\n", 78 | "def updateQ(observation,reward,action,ini_obs,t):\n", 79 | " interval = toDiscreteStates(observation)\n", 80 | " Q_next = max(Q_table[tuple(interval)][0],Q_table[tuple(interval)][1])\n", 81 | " ini_interval = toDiscreteStates(ini_obs)\n", 82 | " Q_table[tuple(ini_interval)][action]+=0.1*(reward + gamma*(Q_next) - Q_table[tuple(ini_interval)][action])\n", 83 | "\n" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 10, 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "for i_episode in range(2000):\n", 93 | " observation = env.reset()\n", 94 | " t=0\n", 95 | " while (True):\n", 96 | " env.render()\n", 97 | " action = get_action(observation,i_episode)\n", 98 | " observation1, reward, done, info = env.step(action)\n", 99 | "# print observation1\n", 100 | "# next_action = get_action(observation1,i_episode)\n", 101 | "# updateQ_SARSA(observation1,reward,action,observation,next_action,t)\n", 102 | " updateQ(observation1,reward,action,observation,t)\n", 103 | " observation=observation1\n", 104 | "# action = next_action\n", 105 | " t+=1\n", 106 | " if done:\n", 107 | "# print(\"Episode finished after {} timesteps\".format(t+1))\n", 108 | " rewards.append(t+1)\n", 109 | " break" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 11, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "image/png": "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\n", 120 | "text/plain": [ 121 | "" 122 | ] 123 | }, 124 | "metadata": {}, 125 | "output_type": "display_data" 126 | } 127 | ], 128 | "source": [ 129 | "plt.plot(rewards)\n", 130 | "plt.show()" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [] 139 | } 140 | ], 141 | "metadata": { 142 | "kernelspec": { 143 | "display_name": "Python 2", 144 | "language": "python", 145 | "name": "python2" 146 | }, 147 | "language_info": { 148 | "codemirror_mode": { 149 | "name": "ipython", 150 | "version": 2 151 | }, 152 | "file_extension": ".py", 153 | "mimetype": "text/x-python", 154 | "name": "python", 155 | "nbconvert_exporter": "python", 156 | "pygments_lexer": "ipython2", 157 | "version": "2.7.14" 158 | } 159 | }, 160 | "nbformat": 4, 161 | "nbformat_minor": 2 162 | } 163 | -------------------------------------------------------------------------------- /sarsa_cartpole.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import gym\n", 10 | "import math\n", 11 | "from copy import deepcopy\n", 12 | "import numpy as np\n", 13 | "import matplotlib.pyplot as plt\n", 14 | "import seaborn as sns" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 2, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "\u001b[33mWARN: gym.spaces.Box autodetected dtype as . Please provide explicit dtype.\u001b[0m\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "env = gym.make('CartPole-v0')\n", 32 | "Q_table = np.zeros((2,2,8,4,2))\n", 33 | "alpha=0.3\n", 34 | "buckets=[2, 2, 8, 4]\n", 35 | "gamma=0.99\n", 36 | "rewards=[]" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "def toDiscreteStates(observation):\n", 46 | " interval=[0 for i in range(len(observation))]\n", 47 | " max_range=[2,3,0.42,3]\t#[4.8,3.4*(10**38),0.42,3.4*(10**38)]\n", 48 | "\n", 49 | " for i in range(len(observation)):\n", 50 | " data = observation[i]\n", 51 | " inter = int(math.floor((data + max_range[i])/(2*max_range[i]/buckets[i])))\n", 52 | " if inter>=buckets[i]:\n", 53 | " interval[i]=buckets[i]-1\n", 54 | " elif inter<0:\n", 55 | " interval[i]=0\n", 56 | " else:\n", 57 | " interval[i]=inter\n", 58 | " return interval" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 4, 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "def get_action(observation,t):\n", 68 | "# print get_explore_rate(t)\n", 69 | " if np.random.random()=Q_table[tuple(interval)][1]:\n", 74 | " return 0\n", 75 | " else:\n", 76 | " return 1\n", 77 | "\n", 78 | "def updateQ_SARSA(observation,reward,action,ini_obs,next_action,t):\n", 79 | " interval = toDiscreteStates(observation)\n", 80 | " Q_next = Q_table[tuple(interval)][next_action]\n", 81 | " ini_interval = toDiscreteStates(ini_obs)\n", 82 | " Q_table[tuple(ini_interval)][action]+=0.1*(reward + gamma*(Q_next) - Q_table[tuple(ini_interval)][action])\n" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 5, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "for i_episode in range(2000):\n", 92 | " observation = env.reset()\n", 93 | " t=0\n", 94 | " while (True):\n", 95 | " env.render()\n", 96 | " action = get_action(observation,i_episode)\n", 97 | " observation1, reward, done, info = env.step(action)\n", 98 | "# print observation1\n", 99 | " next_action = get_action(observation1,i_episode)\n", 100 | " updateQ_SARSA(observation1,reward,action,observation,next_action,t)\n", 101 | " observation=observation1\n", 102 | " action = next_action\n", 103 | " t+=1\n", 104 | " if done:\n", 105 | "# print(\"Episode finished after {} timesteps\".format(t+1))\n", 106 | " rewards.append(t+1)\n", 107 | " break" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 7, 113 | "metadata": { 114 | "scrolled": true 115 | }, 116 | "outputs": [ 117 | { 118 | "data": { 119 | "image/png": "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\n", 120 | "text/plain": [ 121 | "" 122 | ] 123 | }, 124 | "metadata": {}, 125 | "output_type": "display_data" 126 | } 127 | ], 128 | "source": [ 129 | "plt.plot(rewards)\n", 130 | "plt.show()" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [] 153 | } 154 | ], 155 | "metadata": { 156 | "kernelspec": { 157 | "display_name": "Python 2", 158 | "language": "python", 159 | "name": "python2" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 2 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython2", 171 | "version": "2.7.14" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 2 176 | } 177 | --------------------------------------------------------------------------------