| 70 | |
| 71 | |
| 72 | class Model(ModelDesc): |
| 73 | def inputs(self): |
| 74 | assert NUM_ACTIONS is not None |
| 75 | return [tf.TensorSpec((None,) + STATE_SHAPE + (FRAME_HISTORY, ), tf.uint8, 'state'), |
| 76 | tf.TensorSpec((None,), tf.int64, 'action'), |
| 77 | tf.TensorSpec((None,), tf.float32, 'futurereward'), |
| 78 | tf.TensorSpec((None,), tf.float32, 'action_prob'), |
| 79 | ] |
| 80 | |
| 81 | def _get_NN_prediction(self, state): |
| 82 | assert state.shape.rank == 5 # Batch, H, W, Channel, History |
| 83 | state = tf.transpose(state, [0, 1, 2, 4, 3]) # swap channel & history, to be compatible with old models |
| 84 | image = tf.reshape(state, [-1] + list(STATE_SHAPE[:2]) + [STATE_SHAPE[2] * FRAME_HISTORY]) |
| 85 | image = tf.cast(image, tf.float32) |
| 86 | |
| 87 | image = image / 255.0 |
| 88 | with argscope(Conv2D, activation=tf.nn.relu): |
| 89 | l = Conv2D('conv0', image, 32, 5) |
| 90 | l = MaxPooling('pool0', l, 2) |
| 91 | l = Conv2D('conv1', l, 32, 5) |
| 92 | l = MaxPooling('pool1', l, 2) |
| 93 | l = Conv2D('conv2', l, 64, 4) |
| 94 | l = MaxPooling('pool2', l, 2) |
| 95 | l = Conv2D('conv3', l, 64, 3) |
| 96 | |
| 97 | l = FullyConnected('fc0', l, 512) |
| 98 | l = PReLU('prelu', l) |
| 99 | logits = FullyConnected('fc-pi', l, NUM_ACTIONS) # unnormalized policy |
| 100 | value = FullyConnected('fc-v', l, 1) |
| 101 | return logits, value |
| 102 | |
| 103 | def build_graph(self, state, action, futurereward, action_prob): |
| 104 | logits, value = self._get_NN_prediction(state) |
| 105 | value = tf.squeeze(value, [1], name='pred_value') # (B,) |
| 106 | policy = tf.nn.softmax(logits, name='policy') |
| 107 | if not self.training: |
| 108 | return |
| 109 | log_probs = tf.log(policy + 1e-6) |
| 110 | |
| 111 | log_pi_a_given_s = tf.reduce_sum( |
| 112 | log_probs * tf.one_hot(action, NUM_ACTIONS), 1) |
| 113 | advantage = tf.subtract(tf.stop_gradient(value), futurereward, name='advantage') |
| 114 | |
| 115 | pi_a_given_s = tf.reduce_sum(policy * tf.one_hot(action, NUM_ACTIONS), 1) # (B,) |
| 116 | importance = tf.stop_gradient(tf.clip_by_value(pi_a_given_s / (action_prob + 1e-8), 0, 10)) |
| 117 | |
| 118 | policy_loss = tf.reduce_sum(log_pi_a_given_s * advantage * importance, name='policy_loss') |
| 119 | xentropy_loss = tf.reduce_sum(policy * log_probs, name='xentropy_loss') |
| 120 | value_loss = tf.nn.l2_loss(value - futurereward, name='value_loss') |
| 121 | |
| 122 | pred_reward = tf.reduce_mean(value, name='predict_reward') |
| 123 | advantage = tf.sqrt(tf.reduce_mean(tf.square(advantage)), name='rms_advantage') |
| 124 | entropy_beta = tf.get_variable('entropy_beta', shape=[], |
| 125 | initializer=tf.constant_initializer(0.01), trainable=False) |
| 126 | cost = tf.add_n([policy_loss, xentropy_loss * entropy_beta, value_loss]) |
| 127 | cost = tf.truediv(cost, tf.cast(tf.shape(futurereward)[0], tf.float32), name='cost') |
| 128 | summary.add_moving_summary(policy_loss, xentropy_loss, |
| 129 | value_loss, pred_reward, advantage, |
no outgoing calls
no test coverage detected
searching dependent graphs…