Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import gym
- import tensorflow as tf
- from tensorflow.python.framework import ops
- import numpy as np
- env = gym.make('CartPole-v1')
- env.seed(1)
- print("env.action_space", env.action_space)
- print("env.observation_space", env.observation_space)
- print("env.observation_space.high", env.observation_space.high)
- print("env.observation_space.low", env.observation_space.low)
- RENDER_ENV = True
- EPISODES = 500
- rewards = []
- RENDER_REWARD_MIN = -1000
- class PolicyGradient:
- def __init__(self, n_x, n_y, learning_rate=0.01, reward_decay=0.95, load_path=None, save_path=None):
- self.n_x = n_x
- self.n_y = n_y
- self.lr = learning_rate
- self.gamma = reward_decay
- self.save_path = None
- if save_path is not None:
- self.save_path = save_path
- self.episode_observations = []
- self.episode_actions = []
- self.episode_rewards = []
- self.build_network()
- self.cost_history = []
- self.sess = tf.Session()
- # $ tensorboard --logdir=logs
- # http://0.0.0.0:6006/
- tf.summary.FileWriter("logs/", self.sess.graph)
- self.sess.run(tf.global_variables_initializer())
- # saver op to save/restore all variables
- self.saver = tf.train.Saver()
- # restore model
- if load_path is not None:
- self.load_path = load_path
- self.saver.restore(self.sess, self.load_path)
- # trying to get tensorboard summaries working...
- def variable_summaries(self, var):
- with tf.name_scope('summaries'):
- mean = tf.reduce_mean(var)
- tf.summary.scalar('mean', mean)
- with tf.name_scope('stddev'):
- stdev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
- tf.summary.scalar('stddev', stddev)
- tf.summary.scalar('max', tf.reduce_max(var))
- tf.summary.scalar('min', tf.reduce_min(var))
- tf.summary.histogram('histogram', var)
- def build_network(self):
- # create placeholders
- with tf.name_scope('inputs'):
- self.X = tf.placeholder(tf.float32, shape=(self.n_x, None), name="X")
- self.Y = tf.placeholder(tf.float32, shape=(self.n_y, None), name="Y")
- self.discounted_episode_rewards_norm = tf.placeholder(tf.float32, [None, ], name="actions_value")
- units_layer_1 = 10
- units_layer_2 = 10
- units_output_layer = self.n_y
- with tf.name_scope('parameters'):
- W1 = tf.get_variable("W1", [units_layer_1, self.n_x], initializer=tf.contrib.layers.xavier_initializer(seed=1))
- b1 = tf.get_variable("b1", [units_layer_1, 1], initializer=tf.contrib.layers.xavier_initializer(seed=1))
- W2 = tf.get_variable("W2", [units_layer_2, units_layer_1],
- initializer=tf.contrib.layers.xavier_initializer(seed=1))
- b2 = tf.get_variable("b2", [units_layer_2, 1], initializer=tf.contrib.layers.xavier_initializer(seed=1))
- W3 = tf.get_variable("W3", [self.n_y, units_layer_2], initializer=tf.contrib.layers.xavier_initializer(seed=1))
- b3 = tf.get_variable("b3", [self.n_y, 1], initializer=tf.contrib.layers.xavier_initializer(seed=1))
- # forward prop
- with tf.name_scope('layer_1'):
- Z1 = tf.add(tf.matmul(W1, self.X), b1)
- A1 = tf.nn.relu(Z1)
- with tf.name_scope('layer_2'):
- Z2 = tf.add(tf.matmul(W2, A1), b2)
- A2 = tf.nn.relu(Z2)
- with tf.name_scope('layer_3'):
- Z3 = tf.add(tf.matmul(W3, A2), b3)
- A3 = tf.nn.softmax(Z3)
- # softmax outputs need to be transposed
- logits = tf.transpose(Z3)
- labels = tf.transpose(self.Y)
- self.outputs_softmax = tf.nn.softmax(logits, name='A3')
- with tf.name_scope('loss'):
- neg_log_prob = tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=labels)
- loss = tf.reduce_mean(neg_log_prob * self.discounted_episode_rewards_norm)
- with tf.name_scope('train'):
- self.train_op = tf.train.AdamOptimizer(self.lr).minimize(loss)
- def plot_cost(self):
- import matplotlib
- matplotlib.use("MacOSX")
- import matplotlib.pyplot as plt
- plt.plot(np.arange(len(self.cost_history)), self.cost_history)
- plt.ylabel('Cost')
- plt.xlabel('Training Steps')
- plt.show()
- def discount_and_norm_rewards(self):
- discounted_episode_rewards = np.zeros_like(self.episode_rewards)
- cumulative = 0
- for t in reversed(range(len(self.episode_rewards))):
- cumulative = cumulative * self.gamma + self.episode_rewards[t]
- discounted_episode_rewards[t] = cumulative
- discounted_episode_rewards -= np.mean(discounted_episode_rewards)
- discounted_episode_rewards /= np.std(discounted_episode_rewards)
- return discounted_episode_rewards
- def store_transition(self, s, a, r):
- """
- Store play memory for training
- Arguments:
- s: observation
- a: action taken
- r: reward after action
- """
- self.episode_observations.append(s)
- self.episode_rewards.append(r)
- # Store actions as list of arrays
- # e.g. for n_y = 2 -> [ array([ 1., 0.]), array([ 0., 1.]), array([ 0., 1.]), array([ 1., 0.]) ]
- action = np.zeros(self.n_y)
- action[a] = 1
- self.episode_actions.append(action)
- def choose_action(self, observation):
- """
- Choose action based on observation
- Arguments:
- observation: array of state, has shape (num_features)
- Returns: index of action we want to choose
- """
- # Reshape observation to (num_features, 1)
- observation = observation[:, np.newaxis]
- # Run forward propagation to get softmax probabilities
- prob_weights = self.sess.run(self.outputs_softmax, feed_dict={self.X: observation})
- # Select action using a biased sample
- # this will return the index of the action we've sampled
- action = np.random.choice(range(len(prob_weights.ravel())), p=prob_weights.ravel())
- return action
- def learn(self):
- # Discount and normalize episode reward
- discounted_episode_rewards_norm = self.discount_and_norm_rewards()
- # Train on episode
- self.sess.run(self.train_op, feed_dict={
- self.X: np.vstack(self.episode_observations).T,
- self.Y: np.vstack(np.array(self.episode_actions)).T,
- self.discounted_episode_rewards_norm: discounted_episode_rewards_norm,
- })
- # Reset the episode data
- self.episode_observations, self.episode_actions, self.episode_rewards = [], [], []
- # Save checkpoint
- if self.save_path is not None:
- save_path = self.saver.save(self.sess, self.save_path)
- print("Model saved in file: %s" % save_path)
- return discounted_episode_rewards_norm
- if __name__ == "__main__":
- PG = PolicyGradient(
- n_x = env.observation_space.shape[0],
- n_y = env.action_space.n,
- learning_rate=0.02,
- reward_decay=0.99
- )
- for episode in range(EPISODES):
- observation = env.reset()
- episode_reward = 0
- while True:
- if RENDER_ENV: env.render()
- # 1. Choose an action based on observation
- action = PG.choose_action(observation)
- # 2. Take action in the environment
- observation_, reward, done, info = env.step(action)
- # 4. Store transition for training
- PG.store_transition(observation, action, reward)
- if done:
- episode_rewards_sum = sum(PG.episode_rewards)
- rewards.append(episode_rewards_sum)
- max_reward_so_far = np.amax(rewards)
- print("==========================================")
- print("Episode: ", episode)
- print("Reward: ", episode_rewards_sum)
- print("Max reward so far: ", max_reward_so_far)
- # 5. Train neural network
- discounted_episode_rewards_norm = PG.learn()
- if max_reward_so_far > RENDER_REWARD_MIN: RENDER_ENV = True
- break
- # Save new observation
- observation = observation_
Advertisement
Add Comment
Please, Sign In to add comment