From 5006346293c9a3c7520c3af8d6b0ee06d3777966 Mon Sep 17 00:00:00 2001 From: Douglas-Cho Date: Tue, 25 Dec 2018 13:18:30 +0800 Subject: [PATCH 1/3] Create cartpole-drqn.py This shows the way to implement Deep Recurrent Q-Network (DRQN) model for the Cartpole case. I had to expand the state input to include a few number of past state data and created a meaningful sequential input stream for Long and Short-Term Memory (LSTM) model. Otherwise, it did not work with just current state information. This sounds like violating the Markov property assumption but this does the job. --- 2-cartpole/1-dqn/cartpole-drqn.py | 197 ++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 2-cartpole/1-dqn/cartpole-drqn.py diff --git a/2-cartpole/1-dqn/cartpole-drqn.py b/2-cartpole/1-dqn/cartpole-drqn.py new file mode 100644 index 00000000..1060650b --- /dev/null +++ b/2-cartpole/1-dqn/cartpole-drqn.py @@ -0,0 +1,197 @@ +import sys +import gym +import pylab +import random +import numpy as np +from collections import deque +from keras.layers import Dense, LSTM +from keras.optimizers import Adam +from keras.models import Sequential + +EPISODES = 500 + + +# DRQN Agent for the Cartpole +# it uses Neural Network to approximate q function +# and replay memory & target q network +class DRQNAgent: + def __init__(self, state_size, action_size): + # if you want to see Cartpole learning, then change to True + self.render = False + self.load_model = False + + # get size of state and action + self.state_size = state_size + self.action_size = action_size + + # These are hyper parameters for the DRQN + self.discount_factor = 0.99 + self.learning_rate = 0.001 + self.epsilon = 1.0 + self.epsilon_decay = 0.999 + self.epsilon_min = 0.01 + self.batch_size = 64 + self.train_start = 1000 + # create replay memory using deque + self.memory = deque(maxlen=2000) + + # create main model and target model + self.model = self.build_model() + self.target_model = self.build_model() + + # initialize target model + self.update_target_model() + + if self.load_model: + self.model.load_weights("./save_model/cartpole_drqn.h5") + + # approximate Q function using Neural Network + # state is input and Q Value of each action is output of network + def build_model(self): + model = Sequential() + model.add(LSTM(32, input_shape=(self.state_size, 2))) + model.add(Dense(self.action_size)) + model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate)) + return model + + # after some time interval update the target model to be same with model + def update_target_model(self): + self.target_model.set_weights(self.model.get_weights()) + + # get action from model using epsilon-greedy policy + def get_action(self, state): + if np.random.rand() <= self.epsilon: + return random.randrange(self.action_size) + else: + q_value = self.model.predict(state) + return np.argmax(q_value[0]) + + # save sample to the replay memory + def append_sample(self, state, action, reward, next_state, done): + self.memory.append((state, action, reward, next_state, done)) + if self.epsilon > self.epsilon_min: + self.epsilon *= self.epsilon_decay + + # pick samples randomly from replay memory (with batch_size) + def train_model(self): + if len(self.memory) < self.train_start: + return + batch_size = min(self.batch_size, len(self.memory)) + mini_batch = random.sample(self.memory, batch_size) + + update_input = np.zeros((batch_size, self.state_size, 2)) + update_target = np.zeros((batch_size, self.state_size, 2)) + action, reward, done = [], [], [] + + for i in range(self.batch_size): + update_input[i] = mini_batch[i][0] + action.append(mini_batch[i][1]) + reward.append(mini_batch[i][2]) + update_target[i] = mini_batch[i][3] + done.append(mini_batch[i][4]) + + target = self.model.predict(update_input) + target_val = self.target_model.predict(update_target) + + for i in range(self.batch_size): + # Q Learning: get maximum Q value at s' from target model + if done[i]: + target[i][action[i]] = reward[i] + else: + target[i][action[i]] = reward[i] + self.discount_factor * ( + np.amax(target_val[i])) + + # and do the model fit! + self.model.fit(update_input, target, batch_size=self.batch_size, + epochs=1, verbose=0) + + +if __name__ == "__main__": + # In case of CartPole-v1, maximum length of episode is 500 + env = gym.make('CartPole-v1') + + # Number of past state to use + number_of_past_state = 4 + + # get size of state and action from environment + state_size = env.observation_space.shape[0] + expanded_state_size = state_size * number_of_past_state + action_size = env.action_space.n + + agent = DRQNAgent(expanded_state_size, action_size) + + scores, episodes = [], [] + + for e in range(EPISODES): + done = False + score = 0 + state = env.reset() + + # expand the state with past states and initialize + expanded_state = np.zeros(expanded_state_size) + expanded_next_state = np.zeros(expanded_state_size) + for h in range(state_size): + expanded_state[(h + 1) * number_of_past_state - 1] = state[h] + + # reshape states for LSTM input without embedding layer + reshaped_state = np.zeros((1, expanded_state_size, 2)) + for i in range(expanded_state_size): + for j in range(2): + reshaped_state[0, i, j] = expanded_state[i] + + while not done: + if agent.render: + env.render() + + # get action for the current state and go one step in environment + action = agent.get_action(reshaped_state) + next_state, reward, done, info = env.step(action) + + # update the expanded next state with next state values + for h in range(state_size): + expanded_next_state[(h + 1) * number_of_past_state - 1] = next_state[h] + + # reshape expanded next state for LSTM input without embedding layer + reshaped_next_state = np.zeros((1, expanded_state_size, 2)) + for i in range(expanded_state_size): + for j in range(2): + reshaped_next_state[0, i, j] = expanded_next_state[i] + + # if an action make the episode end, then gives penalty of -100 + reward = reward if not done or score == 499 else -100 + + # save the sample to the replay memory + agent.append_sample(reshaped_state, action, reward, reshaped_next_state, done) + + # every time step do the training + agent.train_model() + score += reward + reshaped_state = reshaped_next_state + + # Shifting past state elements to the left by one + expanded_next_state = np.roll(expanded_next_state, -1) + + if done: + # every episode update the target model to be same with model + agent.update_target_model() + + # every episode, plot the play time + score = score if score == 500 else score + 100 + scores.append(score) + episodes.append(e) + pylab.plot(episodes, scores, 'b') + pylab.savefig("./save_graph/cartpole_drqn.png") + print("episode:", e, " score:", score, " memory length:", + len(agent.memory), " epsilon:", agent.epsilon) + + # if the mean of scores of last 10 episode is bigger than 490 + # stop training + # revised to exit cleanly on Jupiter notebook + if np.mean(scores[-min(10, len(scores)):]) > 490: + #sys.exit() + env.close() + break + + # save the model + if e % 50 == 0: + agent.model.save_weights("./save_model/cartpole_drqn.h5") From e9b27c12ca0ba129e14537bd71874896cf6163eb Mon Sep 17 00:00:00 2001 From: Douglas-Cho Date: Tue, 25 Dec 2018 13:55:54 +0800 Subject: [PATCH 2/3] the graph for drqn --- 2-cartpole/1-dqn/save_graph/cartpole_drqn.png | Bin 0 -> 8689 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 2-cartpole/1-dqn/save_graph/cartpole_drqn.png diff --git a/2-cartpole/1-dqn/save_graph/cartpole_drqn.png b/2-cartpole/1-dqn/save_graph/cartpole_drqn.png new file mode 100644 index 0000000000000000000000000000000000000000..0003d2ab155bea2d9e53dfaa967b19793683863a GIT binary patch literal 8689 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 Na77J;+&gAZ{|lX@!ae{1 literal 0 HcmV?d00001 From 83f7e65abd348b64697de92efcc0c03a83efbe97 Mon Sep 17 00:00:00 2001 From: Douglas-Cho Date: Tue, 25 Dec 2018 13:57:45 +0800 Subject: [PATCH 3/3] saved weights for drqn --- 2-cartpole/1-dqn/save_model/cartpole_drqn.h5 | Bin 0 -> 29872 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 2-cartpole/1-dqn/save_model/cartpole_drqn.h5 diff --git a/2-cartpole/1-dqn/save_model/cartpole_drqn.h5 b/2-cartpole/1-dqn/save_model/cartpole_drqn.h5 new file mode 100644 index 0000000000000000000000000000000000000000..8a4964ea4d103a245f9c5a504570128ac592aa99 GIT binary patch literal 29872 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 TpnSUX530y&lTRc6+w0!|dG1%b literal 0 HcmV?d00001