woodsja

pg-pong py3

Aug 27th, 2018
391
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.11 KB | None | 0 0
  1. """
  2. Trains an agent with stochastic policy gradients on Pong
  3. from OpenAI Gym following Karpathy's example
  4. """
  5.  
  6. import numpy as np
  7. import pickle
  8. import gym
  9.  
  10. # hyperparameters
  11. H = 200  # number of hidden layer neurons
  12. batch_size = 2  # update parameters after this many episodes
  13. learning_rate = 1e-4
  14. gamma = 0.99  # discount factor for reward
  15. decay_rate = 0.99  # decay factor for RMS prop leaky sum of grad^2
  16. resume = False  # Resume from previous checkpoint?
  17. render = False
  18.  
  19. # model initialization
  20. D = 80 * 80  # input dimensionality: 80x80 grid
  21. if resume:
  22.     model = pickle.load(open('save.p', 'rb'))
  23. else:
  24.     model = dict()
  25.     model['W1'] = np.random.randn(H, D) / np.sqrt(D)  # use xavier intialization
  26.     model['W2'] = np.random.randn(H) / np.sqrt(H)
  27.  
  28. grad_buffer = {k: np.zeros_like(v) for k, v in model.items()}
  29. rms_prop_cache = {k: np.zeros_like(v) for k, v in model.items()}
  30.  
  31.  
  32. def sigmoid(x):
  33.   return 1.0 / (1.0 + np.exp(-x))  # sigmoid function to sqash
  34.  
  35.  
  36. def prepro(I):
  37.     """ Prepro 210x160x3 uint frame into 6400 (80x80) 1D float vector """
  38.     I = I[35:195]  # crop to game board
  39.     I = I[::2, ::2, 0]  # down sample by a factor of 2
  40.     I[I == 144] = 0  # erase background type 1
  41.     I[I == 109] = 0  # erase background type 2
  42.     I[I != 0] = 1  # everything else is just 1
  43.     return I.astype(np.float).ravel()
  44.  
  45.  
  46. def discount_rewards(r):
  47.     """ take 1D float array of rewards and compute discounted reward """
  48.     discounted_r = np.zeros_like(r)
  49.     running_add = 0
  50.     for t in reversed(range(0, r.size)):
  51.         if r[t] != 0:
  52.             running_add = 0
  53.             # reset sum since the ball hit a wall
  54.         discounted_r[t] = running_add
  55.     return discounted_r
  56.  
  57.  
  58. def policy_forward(x):
  59.     h = np.dot(model['W1'], x)
  60.     # print('h is {}'.format(h))
  61.     h[h < 0] = 0  # apply ReLU
  62.     logp = np.dot(model['W2'], h)
  63.     p = sigmoid(logp)
  64.     return p, h # probability of action 2 and hidden state
  65.  
  66.  
  67. def policy_backward(eph, epdlogp):
  68.     """ backward pass. (epdh is array of intermediate hidden states) """
  69.     dW2 = np.dot(eph.T, epdlogp).ravel()
  70.     dh = np.outer(epdlogp, model['W2'])
  71.     dh[eph <= 0] = 0  # ReLU for back prop
  72.     dW1 = np.dot(dh.T, epx)
  73.     return {'W1': dW1, 'W2': dW2}
  74.  
  75.  
  76. env = gym.make("Pong-v0")
  77. observation = env.reset()
  78. prev_x = None  # used to compute difference frame
  79. xs, hs, dlogps, drs = [], [], [], []
  80. running_reward = None
  81. reward_sum = 0
  82. episode_number = 0
  83. while True:
  84.     if render:
  85.         env.render()
  86.  
  87.     # useful later for scrabble!
  88.     # pre-process observation, set input to network as difference image
  89.     cur_x = prepro(observation)
  90.     x = cur_x - prev_x if prev_x is not None else np.zeros(D)
  91.     #print(x)
  92.     prev_x = cur_x
  93.  
  94.     # forward the policy network and sample an action from the returned probability
  95.     aprob, h = policy_forward(x)
  96.     action = 2 if np.random.uniform() < aprob else 3
  97.  
  98.     # record various intermediates necessary later for backprop
  99.     xs.append(x) # observation
  100.     hs.append(h) # hidden state
  101.     y = 1 if action == 2 else 0 # fake label
  102.     dlogps.append(y - aprob) # grad encourages actions taken to be taken
  103.     # http://cs231n.github.io/neural-networks-2/#losses
  104.  
  105.     # step the environment and get new measurements
  106.     observation, reward, done, info = env.step(action)
  107.     reward_sum += reward
  108.  
  109.     drs.append(reward) # record reward
  110.  
  111.     if done:
  112.         print(episode_number)
  113.         episode_number += 1
  114.  
  115.         # stack together all inputs, hidden states, action gradients, and rewards for this episode
  116.         epx = np.vstack(xs)
  117.         eph = np.vstack(hs)
  118.         epdlogp = np.vstack(dlogps)
  119.         epr = np.vstack(drs)
  120.         xs, hs, dlogps, drs = [], [], [], [] # reset array memory
  121.  
  122.         # compute discounted reward backwards through time
  123.         discounted_epr = discount_rewards(epr)
  124.         # standardize rewards to unit normal
  125.         discounted_epr -= np.mean(discounted_epr)
  126.         discounted_epr /= np.std(discounted_epr)
  127.  
  128.         epdlogp *= discounted_epr # modulate gradient with advantage (what...?)
  129.         grad = policy_backward(eph, epdlogp)
  130.         #print(grad)
  131.         for k in model:  grad_buffer[k] += grad[k] # accumulate grad over batch
  132.         #print(grad_buffer)
  133.  
  134.         # perform rms prop update every batch_size episodes
  135.         if episode_number % batch_size == 0:
  136.           print(model.items())
  137.           for k, v in model.items():
  138.             g = grad_buffer[k] # gradient
  139.             rms_prop_cache[k] = decay_rate * rms_prop_cache[k] + (1 - decay_rate) * g ** 2
  140.             model[k] += learning_rate * g / (np.sqrt(rms_prop_cache[k]) + 1e-5)
  141.             grad_buffer[k] = np.zeros_like(v) # reset gradient buffer
  142.  
  143.         # bookkeeping
  144.         running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01
  145.         print('Resetting env. Episode reward total was {}. Running mean: {}'.format(reward_sum, running_reward))
  146.         if episode_number % 20 == 0:
  147.           pickle.dump(model, open('save.p', 'wb'))
  148.         reward_sum = 0
  149.         observation = env.reset()
  150.         prev_x = None
Advertisement
Add Comment
Please, Sign In to add comment