이번에는 Model-Based Reinforcement Learning 에 대한 포스팅입니다.
이 포스팅에서는 Model-Based 라는 새로운 개념이 소개됩니다.
여기서 말하는 모델이란 실제 환경의 dynamics 을 배운 신경망을 의미합니다. 이렇게 만들어진 모델은 실제 환경 대신에 에이전트에게 환경과 행동에 따른 결과 정보를 제공하여 에이전트가 학습될 수 있게 합니다. 사실 gym 에서 제공하는 게임의 경우 실제 환경을 쉽게 이용할 수 있지만 실제 환경을 이용하기 힘든 상황에서는 이 방법이 유용할 수 있을 것입니다.
이런 모델을 학습하기 위해 초반에는 에이전트를 학습하는 것 처럼 실제 환경을 이용해 모델을 학습시키고 어느 정도 모델이 학습된 이후에는 학습된 모델을 통해 에이전트를 학습시킬 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | import numpy as np import _pickle as pickle import tensorflow as tf import matplotlib.pyplot as plt import gym env = gym.make('CartPole-v0') # hyperparameters H = 8 # number of hidden layer neurons learning_rate = 1e-2 gamma = 0.99 # discount factor for reward decay_rate = 0.99 # decay factor for RMSProp leaky sum of grad^2 resume = False # resume from previous checkpoint? model_bs = 3 # Batch size when learning from model real_bs = 3 # Batch size when learning from real environment # model initialization D = 4 # input dimensionality tf.reset_default_graph() observations = tf.placeholder(tf.float32, [None,4] , name="input_x") W1 = tf.get_variable("W1", shape=[4, H], initializer=tf.contrib.layers.xavier_initializer()) layer1 = tf.nn.relu(tf.matmul(observations,W1)) W2 = tf.get_variable("W2", shape=[H, 1], initializer=tf.contrib.layers.xavier_initializer()) score = tf.matmul(layer1,W2) probability = tf.nn.sigmoid(score) tvars = tf.trainable_variables() input_y = tf.placeholder(tf.float32,[None,1], name="input_y") advantages = tf.placeholder(tf.float32,name="reward_signal") adam = tf.train.AdamOptimizer(learning_rate=learning_rate) W1Grad = tf.placeholder(tf.float32,name="batch_grad1") W2Grad = tf.placeholder(tf.float32,name="batch_grad2") batchGrad = [W1Grad,W2Grad] loglik = tf.log(input_y*(input_y - probability) + (1 - input_y)*(input_y + probability)) loss = -tf.reduce_mean(loglik * advantages) newGrads = tf.gradients(loss,tvars) updateGrads = adam.apply_gradients(zip(batchGrad,tvars)) mH = 256 # model layer size input_data = tf.placeholder(tf.float32, [None, 5]) with tf.variable_scope('rnnlm'): softmax_w = tf.get_variable("softmax_w", [mH, 50]) softmax_b = tf.get_variable("softmax_b", [50]) previous_state = tf.placeholder(tf.float32, [None,5] , name="previous_state") W1M = tf.get_variable("W1M", shape=[5, mH], initializer=tf.contrib.layers.xavier_initializer()) B1M = tf.Variable(tf.zeros([mH]),name="B1M") layer1M = tf.nn.relu(tf.matmul(previous_state,W1M) + B1M) W2M = tf.get_variable("W2M", shape=[mH, mH], initializer=tf.contrib.layers.xavier_initializer()) B2M = tf.Variable(tf.zeros([mH]),name="B2M") layer2M = tf.nn.relu(tf.matmul(layer1M,W2M) + B2M) wO = tf.get_variable("wO", shape=[mH, 4], initializer=tf.contrib.layers.xavier_initializer()) wR = tf.get_variable("wR", shape=[mH, 1], initializer=tf.contrib.layers.xavier_initializer()) wD = tf.get_variable("wD", shape=[mH, 1], initializer=tf.contrib.layers.xavier_initializer()) bO = tf.Variable(tf.zeros([4]),name="bO") bR = tf.Variable(tf.zeros([1]),name="bR") bD = tf.Variable(tf.ones([1]),name="bD") predicted_observation = tf.matmul(layer2M,wO,name="predicted_observation") + bO predicted_reward = tf.matmul(layer2M,wR,name="predicted_reward") + bR predicted_done = tf.sigmoid(tf.matmul(layer2M,wD,name="predicted_done") + bD) true_observation = tf.placeholder(tf.float32,[None,4],name="true_observation") true_reward = tf.placeholder(tf.float32,[None,1],name="true_reward") true_done = tf.placeholder(tf.float32,[None,1],name="true_done") predicted_state = tf.concat([predicted_observation,predicted_reward,predicted_done], 1) observation_loss = tf.square(true_observation - predicted_observation) reward_loss = tf.square(true_reward - predicted_reward) done_loss = tf.multiply(predicted_done, true_done) + tf.multiply(1-predicted_done, 1-true_done) done_loss = -tf.log(done_loss) model_loss = tf.reduce_mean(observation_loss + done_loss + reward_loss) modelAdam = tf.train.AdamOptimizer(learning_rate=learning_rate) updateModel = modelAdam.minimize(model_loss) def resetGradBuffer(gradBuffer): for ix, grad in enumerate(gradBuffer): gradBuffer[ix] = grad * 0 return gradBuffer def discount_rewards(r): """ take 1D float array of rewards and compute discounted reward """ discounted_r = np.zeros_like(r) running_add = 0 for t in reversed(range(0, r.size)): running_add = running_add * gamma + r[t] discounted_r[t] = running_add return discounted_r # This function uses our model to produce a new state when given a previous state and action def stepModel(sess, xs, action): toFeed = np.reshape(np.hstack([xs[-1][0], np.array(action)]), [1, 5]) myPredict = sess.run([predicted_state], feed_dict={previous_state: toFeed}) reward = myPredict[0][:, 4] observation = myPredict[0][:, 0:4] observation[:, 0] = np.clip(observation[:, 0], -2.4, 2.4) observation[:, 2] = np.clip(observation[:, 2], -0.4, 0.4) doneP = np.clip(myPredict[0][:, 5], 0, 1) if doneP > 0.1 or len(xs) >= 300: done = True else: done = False return observation, reward, done xs, drs, ys, ds = [], [], [], [] running_reward = None reward_sum = 0 episode_number = 1 real_episodes = 1 init = tf.initialize_all_variables() batch_size = real_bs drawFromModel = False # When set to True, will use model for observations trainTheModel = True # Whether to train the model trainThePolicy = False # Whether to train the policy switch_point = 1 # Launch the graph with tf.Session() as sess: rendering = False sess.run(init) observation = env.reset() x = observation gradBuffer = sess.run(tvars) gradBuffer = resetGradBuffer(gradBuffer) while episode_number <= 5000: # Start displaying environment once performance is acceptably high. if (reward_sum / batch_size > 150 and drawFromModel == False) or rendering == True: env.render() rendering = True x = np.reshape(observation, [1, 4]) tfprob = sess.run(probability, feed_dict={observations: x}) action = 1 if np.random.uniform() < tfprob else 0 # record various intermediates (needed later for backprop) xs.append(x) y = 1 if action == 0 else 0 ys.append(y) # step the model or real environment and get new measurements if drawFromModel == False: observation, reward, done, info = env.step(action) else: observation, reward, done = stepModel(sess, xs, action) reward_sum += reward ds.append(done * 1) drs.append(reward) # record reward (has to be done after we call step() to get reward for previous action) if done: if drawFromModel == False: real_episodes += 1 episode_number += 1 # stack together all inputs, hidden states, action gradients, and rewards for this episode epx = np.vstack(xs) epy = np.vstack(ys) epr = np.vstack(drs) epd = np.vstack(ds) xs, drs, ys, ds = [], [], [], [] # reset array memory if trainTheModel == True: actions = np.array([np.abs(y - 1) for y in epy][:-1]) state_prevs = epx[:-1, :] state_prevs = np.hstack([state_prevs, actions]) state_nexts = epx[1:, :] rewards = np.array(epr[1:, :]) dones = np.array(epd[1:, :]) state_nextsAll = np.hstack([state_nexts, rewards, dones]) feed_dict = {previous_state: state_prevs, true_observation: state_nexts, true_done: dones, true_reward: rewards} loss, pState, _ = sess.run([model_loss, predicted_state, updateModel], feed_dict) if trainThePolicy == True: discounted_epr = discount_rewards(epr).astype('float32') discounted_epr -= np.mean(discounted_epr) discounted_epr /= np.std(discounted_epr) tGrad = sess.run(newGrads, feed_dict={observations: epx, input_y: epy, advantages: discounted_epr}) # If gradients becom too large, end training process if np.sum(tGrad[0] == tGrad[0]) == 0: break for ix, grad in enumerate(tGrad): gradBuffer[ix] += grad if switch_point + batch_size == episode_number: switch_point = episode_number if trainThePolicy == True: sess.run(updateGrads, feed_dict={W1Grad: gradBuffer[0], W2Grad: gradBuffer[1]}) gradBuffer = resetGradBuffer(gradBuffer) running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01 if drawFromModel == False: print('World Perf: Episode %f. Reward %f. action: %f. mean reward %f.' % ( real_episodes, reward_sum / real_bs, action, running_reward / real_bs)) if reward_sum / batch_size > 200: break reward_sum = 0 # Once the model has been trained on 100 episodes, we start alternating between training the policy # from the model and training the model from the real environment. if episode_number > 100: drawFromModel = not drawFromModel trainTheModel = not trainTheModel trainThePolicy = not trainThePolicy if drawFromModel == True: observation = np.random.uniform(-0.1, 0.1, [4]) # Generate reasonable starting point batch_size = model_bs else: observation = env.reset() batch_size = real_bs print(real_episodes) plt.figure(figsize=(8, 12)) for i in range(6): plt.subplot(6, 2, 2*i + 1) plt.plot(pState[:,i]) plt.subplot(6,2,2*i+1) plt.plot(state_nextsAll[:,i]) plt.tight_layout() | cs |
직전 포스팅과 다르게 decay_rate 라는 인자가 추가되었습니다. 이는 RMS propagation 을 위한 인자로써 RMS 는 root mean square 의 약자입니다.
기존의 propagation이 error을 계산할 때 오차의 제곱의 평균값을 이용했다면 RMS 는 오차의 제곱의 평균값에 제곱근을 한 값을 이용하는 방법입니다.
https://en.wikipedia.org/wiki/Root-mean-square_deviation
그런데 이 포스팅에서는 인자만 추가하고 RMS propagation 을 사용하지는 않았네요.
model_bs 와 real_bs 는 각각 모델 환경과 실제 환경인 경우의 batch_size 값입니다.
batch_size 는 직전 포스팅과 마찬가지로 몇 번의 에피소드에 한 번씩 에이전트를 학습시킬지에 대한 인자입니다.
# hyperparameters H = 8 # number of hidden layer neurons learning_rate = 1e-2 gamma = 0.99 # discount factor for reward decay_rate = 0.99 # decay factor for RMSProp leaky sum of grad^2 resume = False # resume from previous checkpoint? model_bs = 3 # Batch size when learning from model real_bs = 3 # Batch size when learning from real environment # model initialization D = 4 # input dimensionality | cs |
Policy Network 을 구성하는 부분은 직전 포스팅과 내용이 동일합니다.
tf.reset_default_graph() observations = tf.placeholder(tf.float32, [None,4] , name="input_x") W1 = tf.get_variable("W1", shape=[4, H], initializer=tf.contrib.layers.xavier_initializer()) layer1 = tf.nn.relu(tf.matmul(observations,W1)) W2 = tf.get_variable("W2", shape=[H, 1], initializer=tf.contrib.layers.xavier_initializer()) score = tf.matmul(layer1,W2) probability = tf.nn.sigmoid(score) tvars = tf.trainable_variables() input_y = tf.placeholder(tf.float32,[None,1], name="input_y") advantages = tf.placeholder(tf.float32,name="reward_signal") adam = tf.train.AdamOptimizer(learning_rate=learning_rate) W1Grad = tf.placeholder(tf.float32,name="batch_grad1") W2Grad = tf.placeholder(tf.float32,name="batch_grad2") batchGrad = [W1Grad,W2Grad] loglik = tf.log(input_y*(input_y - probability) + (1 - input_y)*(input_y + probability)) loss = -tf.reduce_mean(loglik * advantages) newGrads = tf.gradients(loss,tvars) updateGrads = adam.apply_gradients(zip(batchGrad,tvars)) | cs |
이 포스팅에서 가장 핵심인 Model Network 을 구성하는 부분입니다.
먼저 input이 none, 5의 배열로 정의되었습니다. cartPole 의 input이 4개인 것과 다르게 5개로 input이 정의된 이유는 추가적으로 행동에 대한 정보도 같이 받기 때문입니다.
첫 번째 weights W1M 은 5, 256 으로 만들고 previous_state 와 곱한 후 ReLU 처리를 하여 layer1M 을 만듭니다.
여기서 previous_state 은 실제 환경에서 전달받은 값입니다. 이 실제 환경에서 전달받은 상태값을 이용해 얻어지는 step 의 결과의 차이를 줄이는 것이 모델을 학습시키는 방향이 될 것입니다.
두 번째 weights W2M 은 256,256 으로 만들고 layer1M와 곱한 후 마찬가지로 ReLU 처리를 하였습니다.
다음으로 상태에 대한 output 을 내기 위해 256,4 의 w0
보상에 대한 output 을 내기 위해 256,1 의 wR
종료 여부에 대한 output 을 내기 위해 256,1 의 wD 을 만들고
mH = 256 # model layer size input_data = tf.placeholder(tf.float32, [None, 5]) with tf.variable_scope('rnnlm'): softmax_w = tf.get_variable("softmax_w", [mH, 50]) softmax_b = tf.get_variable("softmax_b", [50]) previous_state = tf.placeholder(tf.float32, [None,5] , name="previous_state") W1M = tf.get_variable("W1M", shape=[5, mH], initializer=tf.contrib.layers.xavier_initializer()) B1M = tf.Variable(tf.zeros([mH]),name="B1M") layer1M = tf.nn.relu(tf.matmul(previous_state,W1M) + B1M) W2M = tf.get_variable("W2M", shape=[mH, mH], initializer=tf.contrib.layers.xavier_initializer()) B2M = tf.Variable(tf.zeros([mH]),name="B2M") layer2M = tf.nn.relu(tf.matmul(layer1M,W2M) + B2M) wO = tf.get_variable("wO", shape=[mH, 4], initializer=tf.contrib.layers.xavier_initializer()) wR = tf.get_variable("wR", shape=[mH, 1], initializer=tf.contrib.layers.xavier_initializer()) wD = tf.get_variable("wD", shape=[mH, 1], initializer=tf.contrib.layers.xavier_initializer()) bO = tf.Variable(tf.zeros([4]),name="bO") bR = tf.Variable(tf.zeros([1]),name="bR") bD = tf.Variable(tf.ones([1]),name="bD") | cs |
layer2M * wO 을 하여 predicted_observation
layer2M * wR 을 하여 predicted_reward
layer2M * wD 을 하여 predicted_done 을 만들어 모델을 통해 상태, 보상, 종료 여부를 얻을 수 있게 신경망을 구성하였습니다.
predicted_observation = tf.matmul(layer2M,wO,name="predicted_observation") + bO predicted_reward = tf.matmul(layer2M,wR,name="predicted_reward") + bR predicted_done = tf.sigmoid(tf.matmul(layer2M,wD,name="predicted_done") + bD) | cs |
true_observation, true_reward, true_done 은 실제 환경에서 값을 받는 변수들입니다.
true_observation = tf.placeholder(tf.float32,[None,4],name="true_observation") true_reward = tf.placeholder(tf.float32,[None,1],name="true_reward") true_done = tf.placeholder(tf.float32,[None,1],name="true_done") | cs |
tf.concat 은 배열을 하나의 차원으로 합치는 함수입니다. predicted_observation,predicted_reward,predicted_done 3개를 합쳐 하나의 모델에서의 예측 상태 배열(predicted_state)을 만들었습니다.
실제 환경의 값과 모델에서의 예측 상태의 차이의 제곱을 통해 observation_loss 을 구합니다.
실제 환경의 보상과 모델에서의 예측 보상의 차이의 제곱을 통해 reward_loss 을 구합니다.
종료 여부 done 은 1 또는 0의 값이기에 조금 다르게 처리하여 done_loss 을 구했습니다.
이런 loss 들의 평균으로 model_loss 을 구한 후 AdamOptimizer 을 이용하여 loss가 최소화되도록 훈련을 만듭니다.
predicted_state = tf.concat([predicted_observation,predicted_reward,predicted_done], 1) observation_loss = tf.square(true_observation - predicted_observation) reward_loss = tf.square(true_reward - predicted_reward) done_loss = tf.multiply(predicted_done, true_done) + tf.multiply(1-predicted_done, 1-true_done) done_loss = -tf.log(done_loss) model_loss = tf.reduce_mean(observation_loss + done_loss + reward_loss) modelAdam = tf.train.AdamOptimizer(learning_rate=learning_rate) updateModel = modelAdam.minimize(model_loss) | cs |
gym의 step 과 같은 기능을 하는 모델의 step 함수입니다.
먼저 상태와 행동을 합쳐 toFeed(1, 5) 을 만듭니다. numpy.hstack 은 horizontally 하게 배열을 합치는 함수입니다.
위에서 만든 predicted_state 을 실행시켜 예상값들을 myPredict 에 가져옵니다.
myPredict은 list 로써 1, 6의 배열을 원소로 가지고 있습니다. myPredict가 list이긴 하지만 여기서는 항상 1개의 원소를 가지고 있습니다.
myPredict 에서 보상과 상태를 가져옵니다.
reward 는 myPredict[0][:, 4] 으로 1, 6의 배열을 [:, 4] 으로 slicing 함으로써 5번째 값 즉 4번 index 의 값만 가지고 오게 됩니다.
observation 은 myPredict[0] 의 [:, 0:4] 즉 0~3번 index 만 가지와 1, 4의 배열이 됩니다.
numpy.clip 을 통해 상태 값을 일부 조정합니다. clip 은 주어진 최소 최대 값을 넘는 값들을 최소 최대값으로 조정하는 함수입니다.
doneP 는 myPredict[0] 의 [:, 5] 즉 5번 index 값을 0, 1 사이로 clip 하여 가져온 후
값이 0.1을 넘거나 상태(xs)의 개수가 300개를 넘어가면 종료로 처리를 합니다.
# This function uses our model to produce a new state when given a previous state and action def stepModel(sess, xs, action): toFeed = np.reshape(np.hstack([xs[-1][0], np.array(action)]), [1, 5]) myPredict = sess.run([predicted_state], feed_dict={previous_state: toFeed}) reward = myPredict[0][:, 4] observation = myPredict[0][:, 0:4] observation[:, 0] = np.clip(observation[:, 0], -2.4, 2.4) observation[:, 2] = np.clip(observation[:, 2], -0.4, 0.4) doneP = np.clip(myPredict[0][:, 5], 0, 1) if doneP > 0.1 or len(xs) >= 300: done = True else: done = False return observation, reward, done | #cs |
처음 batch_size 는 실제 환경의 batch_size 을 사용합니다.
drawFromModel 모델을 사용할지 여부도 처음에는 false 로 합니다.
trainTheModel 모델의 훈련 여부는 true 로 합니다.
trainThePolicy 처음에는 policy(정책)을 학습하지 않도록 false로 합니다. 모델의 효과를 알기 위해 모델로만 에이전트를 학습하기 위함입니다.
switch_point 은 에피소드가 일정 횟수 이상 지나면 정책을 학습하기 위한 count 변수입니다.
나머지 변수들은 직전 포스팅과 동일합니다.
xs, drs, ys, ds = [], [], [], [] running_reward = None reward_sum = 0 episode_number = 1 real_episodes = 1 init = tf.initialize_all_variables() batch_size = real_bs drawFromModel = False # When set to True, will use model for observations trainTheModel = True # Whether to train the model trainThePolicy = False # Whether to train the policy switch_point = 1 | cs |
앞부분은 직전 포스팅과 같고 drawFromModel 값에 따라 실제 환경과 모델 환경을 스위칭 합니다.
x = np.reshape(observation, [1, 4]) tfprob = sess.run(probability, feed_dict={observations: x}) action = 1 if np.random.uniform() < tfprob else 0 # record various intermediates (needed later for backprop) xs.append(x) y = 1 if action == 0 else 0 ys.append(y) # step the model or real environment and get new measurements if drawFromModel == False: observation, reward, done, info = env.step(action) else: observation, reward, done = stepModel(sess, xs, action) | cs |
보상과 종료 여부를 배열에 담습니다.
reward_sum += reward ds.append(done * 1) drs.append(reward) # record reward (has to be done after we call step() to get reward for previous action) | cs |
에피소드가 종료되면 실제 환경을 사용했을 경우 real_episodes 에 1을 더합니다.
직전 포스팅과 같이 에피소드 변수 배열들로 기록된 값들을 기록합니다.
if done: if drawFromModel == False: real_episodes += 1 episode_number += 1 # stack together all inputs, hidden states, action gradients, and rewards for this episode epx = np.vstack(xs) epy = np.vstack(ys) epr = np.vstack(drs) epd = np.vstack(ds) xs, drs, ys, ds = [], [], [], [] # reset array memory | cs |
모델을 훈련시키기로 했다면
y 를 통해 actions 을 만들고 (여기서 다시 원래대로 1->0, 0->1 으로 원래 action 값으로 변경)
이전 행동과 상태를 합쳐 state_prevs 을 만듭니다. 이 배열은 none, 5 이며, (none는 종료되기 전 까지 쌓인 행동의 개수)
epx의 0번 index 부터 (last -1) index 까지의 배열입니다.
다음으로 state_nexts 에는 epx 의 1번 index 부터 마지막 index 까지의 값을 할당합니다.
이렇게 이전 상태와 다음 상태를 만듦으로써 만들어진 state_prevs 와 state_nexts 의 동일한 index 에 직전 상태와 직후 상태 즉 환경과 그 환경의 step에 따른 결과를 담아둘 수 있습니다.
그리고 다음 상태, 보상, 종료 여부를 얻은 후 model_loss, predicted_state, updateModel 을 실행시켜 모델을 훈련시킵니다.
if trainTheModel == True: actions = np.array([np.abs(y - 1) for y in epy][:-1]) state_prevs = epx[:-1, :] state_prevs = np.hstack([state_prevs, actions]) state_nexts = epx[1:, :] rewards = np.array(epr[1:, :]) dones = np.array(epd[1:, :]) state_nextsAll = np.hstack([state_nexts, rewards, dones]) feed_dict = {previous_state: state_prevs, true_observation: state_nexts, true_done: dones, true_reward: rewards} loss, pState, _ = sess.run([model_loss, predicted_state, updateModel], feed_dict) | cs |
정책을 훈련시키기로 했다면 직전 포스팅과 같이 버퍼에 gradients 을 담아둡니다. 이때 다른 점은 버퍼가 너무 클 경우 종료시킵니다.
if trainThePolicy == True: discounted_epr = discount_rewards(epr).astype('float32') discounted_epr -= np.mean(discounted_epr) discounted_epr /= np.std(discounted_epr) tGrad = sess.run(newGrads, feed_dict={observations: epx, input_y: epy, advantages: discounted_epr}) # If gradients becom too large, end training process if np.sum(tGrad[0] == tGrad[0]) == 0: break for ix, grad in enumerate(tGrad): gradBuffer[ix] += grad | cs |
직전 포스팅과 같이 batch_size 에 한 번씩 정책을 훈련시킵니다.
if switch_point + batch_size == episode_number: switch_point = episode_number if trainThePolicy == True: sess.run(updateGrads, feed_dict={W1Grad: gradBuffer[0], W2Grad: gradBuffer[1]}) gradBuffer = resetGradBuffer(gradBuffer) | cs |
모델을 사용하지 않을 경우 보상이 200이 넘을 경우 종료시킵니다.
running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01 if drawFromModel == False: print('World Perf: Episode %f. Reward %f. action: %f. mean reward %f.' % ( real_episodes, reward_sum / real_bs, action, running_reward / real_bs)) if reward_sum / batch_size > 200: break reward_sum = 0 | cs |
100 에피소드가 지난 후 모델을 학습시키도록 (정책도 학습) 변경합니다.
# Once the model has been trained on 100 episodes, we start alternating between training the policy # from the model and training the model from the real environment. if episode_number > 100: drawFromModel = not drawFromModel trainTheModel = not trainTheModel trainThePolicy = not trainThePolicy | cs |
모델을 사용할 경우 상태를 균일 분포를 통해 초기화 시키고 실제 환경을 사용할 경우 gym 을 이용해 reset 합니다.
if drawFromModel == True: observation = np.random.uniform(-0.1, 0.1, [4]) # Generate reasonable starting point batch_size = model_bs else: observation = env.reset() batch_size = real_bs | cs |