---
description: Q Learning that actually works :)
---

# DQN and beyond

The main goal of this part would be understanding how DQN and its variants solve the key challenges in fitted-Q iteration. Note how seemingly-small changes to fitted-Q such as replay buffers and target networks play just as important a role as deep neural nets in making DQN work successfully.

*   **Replay Buffer: Avoids Correlated Samples**\
    If we look at the online Q-learning algorithm \
    <img src="https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTEzIOE91KRtv9wDTja%2F-MTEzc-LGx3bmuLzsHn7%2Flec7_7.png?alt=media&#x26;token=128562bc-9b41-4a4c-a8fc-744a6540f900" alt="" data-size="original"> \


    we are updating Q-function after every executed action, which means the samples collected in this fashion will be highly correlated. And the algorithm will be _locally overfitting_ to Q-values in its "neighborhood", as illustrated below: \
    \
    <img src="https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTEzIOE91KRtv9wDTja%2F-MTEzzwG8rYIjXHykOIB%2Flec8_1.png?alt=media&#x26;token=02ad6742-5636-4082-b805-706b20b2a7ba" alt="" data-size="original"> \


    so that towards the end of these longer trajectories, the Q-values for previous states will become inaccurate. Parallel workers is an option but only partially solve this problem: by adding synchronized or asynchronous workers, the Q-values will be better averaged out _across_ parallel environments at each timestep, but this still doesn't help "remembering" Q-estimates in previous states from earlier in each worker's trajectory. On the other hand, replay buffer is a simple idea that breaks this sample correlation: by putting all experienced sample transitions in one buffer and sampling uniformly (or more smartly by prioritization). Another advantage is that samples in the buffer don't have to be on-policy, since we are only evaluating state-action pairs.\

*   **Target Network: Avoids Moving Target** If we compare the Q-function update step in Q learning and fitted-Q:\
    &#x20; \




![](https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTEzIOE91KRtv9wDTja%2F-MTF-MbM4omgwNavIpXJ%2Flec8_2.png?alt=media\&token=cdd50f37-d7d7-4b73-a65e-7c2bfc2dc4b1)

in fitted-Q below, gradient update for Q is a regression problem minimizing a l2-loss, this is stable in estimating a Q-value for every $$(s,a)$$ under that policy; but in the above (Q-learning), the samples are de-correlated (coming from the buffer), and we are using the Q-function to update itself, i.e. "moving target", this is unstable and might not converge.\


![](https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTEzIOE91KRtv9wDTja%2F-MTF-dvJVegawOe4XjH8%2Flec8_3.png?alt=media\&token=e45b3925-c673-464c-8a3f-42e43948d8c9)

Using a target network that only gets updated periodically helps tackle this problem. Note how "classic" analogy of deep-Q is setting $$N = K = 1$$

![](https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTEzIOE91KRtv9wDTja%2F-MTF-hPbfiPqeDmEKtF5%2Flec8_4.png?alt=media\&token=627b7593-bb72-4128-befe-993f43c35d85)

## Major Improvements on DQN

Quickly after the seminal DQN paper came out, many follow-up work on further improving this algorithm were introduced. Below are some of the most commonly used ones:

#### **Double-DQN**&#x20;

In implementation, double-Q is just a one-line change in the loss function inside the original DQN's gradient update step. But to understand why it's important and consistently outperforms DQN, it's better to understand why DQN tends to over-estimate Q-values:  &#x20;

![](https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTF-kJ7YV0FwFUdRFng%2F-MTF03AsiDOgg9A6FQLm%2Flec8_5.png?alt=media\&token=2cba6f25-5f83-495a-8a41-bf2ee0ea8cf9)

###

I find this simple general case with random variables $$X1, X_2$$ pretty intuitive: because both Q-value and argmax action come from the current Q-function network, the target value easily gets over-estimated. But by using Double-Q:

![](https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTF-kJ7YV0FwFUdRFng%2F-MTF0Uw8bZZd1oCm7Vpi%2Flec8_6.png?alt=media\&token=a9a652cc-90d4-4271-9942-b1df367e99ee)

we use current Q to eval/select action and target Q to get state-action values, so that we use two Q's that are "noisy in different ways", and solve the problem.

#### **Multi-step return**

\[insert very straightforward formula from Rainbow DQN paper]

#### Q-learning with Continuous Actions

The above classic Q-learning algorithms always select exactly _one_ $$\text{argmax}$$ action for the Q-function, but what if we have a continuous action space, and can't do this discrete action selection? There are a few ways to incorporate this continuity in Q-learning:

**Optimization**: cross-entropy method (CEM); CMA-ES

**Normalized Advantage Functions (NAF)**: use function class that is easy to optimize

**DDPG**: learn an approximate maximizer.

The idea is to train a second network that takes in a state, and outputs one action that _approximates_ the true Q-value-maximizing action. So we can train this network with the current Q-function:\


![](https://1896916525-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSZWjXi87wJwJVBghav%2F-MTF-kJ7YV0FwFUdRFng%2F-MTF1GreGHYfQZjlT0eT%2Flec8_7.png?alt=media\&token=ac38bf59-73b2-4f75-ac53-9c92c560fbd1)



All included screenshots credit to  Lecture 8 [(slides)](http://rail.eecs.berkeley.edu/deeprlcourse/static/slides/lec-8.pdf)
