Recall dynamic programming algorithms Policy & value iteration

We have the analogous model -free TD algorithms:

Of course the value iteration on state cannot be sampled, so there’s no TD algorithm.

Q learning is an Off-Policy algorithm. It estimates the value of the greedy policy, whatever policy generated the data. (Why that is legitimate: Why one-step TD works off-policy.)

Acting greedy all the time would not explore sufficiently.

It’s soundness depend on a new theorem:

Q-learning control converges to the optimal action-value function, , as long as we take each action in each state infinitely often.

This is different from GLIE: the policy doesn’t need to converge to greedy. Works for any policy that eventually selects all actions sufficiently often (Requires appropriately decaying step sizes , , E.g., , with )

A comparison of SARSA and Q learning

In training time, SARSA gets higher reward since it learns that walking on the edge is dangerous, and it learns a safer path. Recall it’s using -greedy for both prediction and control. On the other hand, Q learning would stick to the optimal path, since according to its value estimation the optimal path is just the better one, since it has a larger . So it would explore that path more often and got down more often. Note the final policy may be a more optimal one.

Overestimation

Recall

Uses same values to select and to evaluate. … but values are approximate

  • more likely to select overestimated values
  • less likely to select underestimated values

That “max” is persisting. Imagine you are in a state with 100 actions with stochastic outcome. If one of the action by chance got jackpot, then you would keep exploring that state. That leads to super slow convergence: blinded by overestimated values.

Another way to think about it: say we have two random variables: and ,

our q estimation is a noisy estimation, and we are using the left one to estimate the right.

Double Q-learning

Store two action-value functions: and

Each , pick or (e.g., randomly) and update using (1) for or (2) for .

This solves the issue because now the noise is decorrelated. The “max” when selecting the action may not actually leads to the “max” when actually getting the estimated Q value.

We can also extend this to SARSA.

Deep Q (DQN)

Use a NN as the function estimator for Q. The loss is TD loss. It comes from Fitted Q Iteration: we basically add a replay buffer and use transitions from the buffer instead of sampling with the policy.

  • A neural network: (action-out)
  • An exploration policy: , and then
  • A replay buffer to store and sample past transitions
  • Target network parameters , updated occasionally (e.g., every 10000 steps)
  • An optimizer to minimize the loss (e.g., SGD, RMSprop, or Adam)
  • A Q-learning weight update on (uses replay and target network):

But wait, there’s still , so it can’t really handle continuous space well. It can handle complicated state space though.

\begin{algorithm}
\begin{algorithmic}
\STATE Initialize replay memory $D$ to capacity $N$
\STATE Initialize action-value function $Q$ with random weights $\theta$
\STATE Initialize target action-value function $\hat{Q}$ with weights $\theta^- = \theta$
\FOR{episode $= 1, \dots, M$}
    \STATE Initialize $s_1 = \{ x_1 \}$ and preprocessed $\phi_1 = \phi(s_1)$
    \FOR{$t = 1, \dots, T$}
        \STATE \COMMENT{Sampling}
        \STATE With probability $\varepsilon$ select a random action $a_t$, otherwise $a_t = \arg\max_a Q(\phi(s_t), a; \theta)$
        \STATE Execute $a_t$, observe reward $r_t$ and image $x_{t+1}$
        \STATE Set $s_{t+1} = s_t, a_t, x_{t+1}$ and preprocess $\phi_{t+1} = \phi(s_{t+1})$
        \STATE Store transition $(\phi_t, a_t, r_t, \phi_{t+1})$ in $D$
        \STATE \COMMENT{Training}
        \STATE Sample random minibatch of transitions $(\phi_j, a_j, r_j, \phi_{j+1})$ from $D$
        \IF{episode terminates at step $j+1$}
            \STATE $y_j \gets r_j$
        \ELSE
            \STATE $y_j \gets r_j + \gamma \max_{a'} \hat{Q}(\phi_{j+1}, a'; \theta^-)$
        \ENDIF
        \STATE Gradient descent step on $\big(y_j - Q(\phi_j, a_j; \theta)\big)^2$ w.r.t. $\theta$
        \STATE Every $C$ steps reset $\hat{Q} = Q$
    \ENDFOR
\ENDFOR
\end{algorithmic}
\end{algorithm}

Several ways to make training stable

Note the experience replay here. Since this is off policy, it can use previous samples to

  • Reuse the interaction with the env.
  • Avoid forgetting previous experiments and reduce the correlation between experiments

The latter part in TD loss can be fixed (the target network), so it’s a fixed target, more like supervised learning.

We can also avoid the sudden jump of “copy param every ” by using Polyak Averaging idea, linearly interpolating in parameter space:

Double DQN is Double Q-learning with the target network playing the role of , so no extra network is needed:

  • standard:
  • double:

Use the current network to select the action, the target network to evaluate it.

N step returns

See Multi-step returns. We can use n step return instead of single stage return:

  • Less biased target values when Q-values are inaccurate
  • Typically faster training, especially early on: value propagates steps per backup instead of 1.
  • Only actually correct when on-policy: the intermediate actions were picked by whoever filled the buffer, not by the policy we’re evaluating. See Why n-step returns break this.
  • But we can ignore the problem and it seems to still be working well, or dynamically choose N to only on-policy data, or importance sampling. Or make take all actions as input, which removes the bias entirely: Q-chunking.

Continuous Actions

There’s this here that’s hard to do for continuous actions.

Stochastic optimization

Use function class that’s easy to optimize

That’s based on the NAF paper, with Ilya Sutskever and Sergey Levine in the author list. The basic idea is to use a specific formula that can easily.

Use a NN to tell what’s the max

This is the DDPG idea: train another network such that . And we do not really train a new network. We just stitch them together, if the network outputs as we hope it outputs, the loss function would just optimize these two together.

You can argue this is quite similar to Actor-Critic

Practical tips

  • Take times, may not stabilize easily
  • Large replay buffers help stability
  • Start with high exploration.
  • Bellman error can be big. We can clip gradients or use Huber loss
  • Double Q-learning help a lot, no downsides
  • N-step return also help a lot, some downsides
  • Needs tuning for exploration and learning rates
  • Run multiple random seed, very inconsistent