There are two networks required for PPO training.
The "Policy Network", which we'll denote with the function , is a mapping from the state space to a distribution over actions.
Mathematically, where and where is the dimension of the state space and is the dimension of the action space. Note that since maps to the state space, for all and .
The "Value Network", which we'll denote with the function , is a mapping from the state space to "rewards" over the action space.
Concisely, where is the same as defined before and . Notice that unlike , is scalar valued. It's a measure of the desirability of the given state.
Information about and needs to be revealed somehow. In reinforcement learning, this information comes from the "environment" which we'll represent with the function . The environment is responsible for knowing how to 1) generate an initial state 2) update the state based on an action 3) provide an award associated with an action 4) know when the game is over.
A classic environment where reinforcement learning can be used is the "cart pole" simulation (also known as an inverted pendulum to physicists). The game is simple; there is a pole on a cart and the objective is the keep the pole in the air. We'll do this experiment in a 2-D world where the cart can either be moved left or right (). Although there are only 2 directions our cart can move, we'll need to choose a single direction to move the cart at each point in time. We'll call our choice where represents moving left and represent moving right.
The state of the cart pole system can be summarized by a vector of 4 values: position of the cart, velocity of the cart, angle of the pole, and rotation of the pole ().
Now that we know the parts of our system we can describe as being a list-valued function . Here, is known as the "reward" which is the reward associated with the action (choice) . The element, , is an indicator variable for if the game is over.
In the cart pole scenario, once the pole has fallen over the game is over. When training a netork, nothing after this point should be learned because no action has an effect on the end result from this point onward.
We've been introduced to our three main components of reinforcement learning: the policy , The value , and the environment . Though must be known before training time, nothing is known about and so we initialize networks and . The initial versions of this network we'll denote and where the superscript indicates that no training has taken place. If all goes well, as more training takes place and will converge to and respectively. That is to say, as long as our networks have a good architecture then and .
Though and start off no better than random number generators, through interacting with they'll become more like and . First, we run a full simulation to see how we're doing.
We start off with some initial state (from our environment) and we want to let our network choose what to do given this state. Therefore we compute where is a distribution of choices over our discrete action space. We sample from by treating it as a discrete distribution where the probability of selecting each action is given by .
After sampling the action, we'll have scalar which is our network's response to .
It is key to note that since we are sampling from our distribution, there is an element of randomness in our model's deciding which path to take.
We now compute . We now have reward associated with action given under which was generated by .
Given the new and assuming we repeat the process some times.
In pseudocode we have:
s = E.start();
game_over = False;
steps = 0;
experience = set();
while (not game_over and steps < T) {
c, pmf = policy(s);
next_s, r, game_over = E(s, c);
steps += 1;
experience.add(s, c, r, pmf);
s = next_s;
};
Though each action has a reward associated with it, some actions with lower initial rewards by lead to higher rewards in the future.
Therefore the rewards with each action aren't actually the raw rewards that we've collected. We update these rewards with information about future rewards via:
Where and called the "discount rate" or "patience factor". A reward today is worth more than a reward tomorrow. If then a reward tomorrow is just as good as reward today and if then a reward tomorrow is worth nothing today.
Now that the rewards have been updated to more reasonable measurements, our network is ready to learn from its experience.
Now we'll use our set of experiences, call it , to learn. This set looks like this . We'll sample from these experiences to learn.
There's two losses that will make up the total loss: value loss and policy loss
Value loss is a straightforward intuitive calculation. It's the mean squared error (MSE) between the predicted rewards by the value network and the returns obtained from experience.
Where and is the adjusted reward.
Policy loss is bit more involved. The equation is
Where is what would happen if we accepted the random walk as the new policy and is the current (old) policy. is a function that uses to determine how large of a step we're comfortable iwth making in the optimization space. Finally is defined as
And is referred to as "advantage". Advantage is positive when tilting the distribution toward the explored route would increase rewards compared to the decision under the current policy. Since capitalizing on advantage is good, that's why PolicyLoss has a negative sign on the outside of mean.
The term is called the "policy ratio" which determines how much the network follows the advantage signal. When then the advatange signal is amplified. This is desirable because as an action's relative weighting increases, the importance of accurately gauging the reward associated with that action also increases which is precisely what this policy ratio reflects.
The policy ratio will be before updating the function because initially we have however after backpropping on the the total loss (which is equal to ) we'll be computing the after sampling the next batch from memories. We continually update by sampling new batches from the given set of memories until we decide to get a obtain a new set of memories.
The minimum loss term is chosen from the two policy terms for optimization stability.
In pseudo code this training process looks like
function learn_from_memory(policy, value, memories) {
for (number_of_epochs) {
for mem in memories {
s, c, r, pmf = mem;
hat_r = value(s);
value_loss = MSE(hat_r, r);
proba_c = policy(s).at(c);
old_proba_c = pmf.at(c);
change = proba_c / old_proba_c;
adv = r - hat_r;
policy_loss = min([
change * adv,
clip(change, 1-eps, 1+eps) * adv
]);
tot_loss = value_loss + policy_loss;
back_prop_step(tot_loss);
};
};
};
When this point is reached, we repeat the process outlined except now we have where denotes that the model has learned from one set of memories. Each successive set of memories should be more advanced than the previous. After enough training, if the architecture is good and and our model now understands the game it's playing.