fix some errors

This commit is contained in:
qiwang067
2020-07-18 17:30:07 +08:00
parent 9493c674b4
commit 99fd30d035
2 changed files with 55 additions and 8 deletions

View File

@@ -26,7 +26,7 @@ MDP 就是序列决策这样一个经典的表达方式。MDP 也是强化学习
我们把这些可能的动作和可能的状态转移的关系画成这样子的一个树状图。它们之间的关系就是一个从 $s_t$ 到 $a_t$ ,再到 $s_{t+1}$ ,再到 $a_{t+1}$,再到 $s_{t+2}$ 这样子的一个过程。
我们去跟环境交互,我们只能走完整的一条通路。这里面产生了一系列的一个决策的过程,就是我们跟环境交互产生了一个经验。然后我们会使用 P 函数和 R 函数来去描述环境。P 函数就是状态转移的概率R 函数就是 Reward function。P 函数实际上反映的是环境的一个随机性。比方说,在熊发怒的情况下,我如果选择装死,假设熊看到人装死就一定会走的话,我们就称在这里面的这个状态转移概率就是百分之百。但如果说在熊发怒的情况下,我选择跑路而导致说我有可能跑成功以及跑失败,出现这两种情况。那我们就可以用概率去表达一下说转移到其中一种情况的概率大概 10%另外一种情况的概率大概是90%会跑失败。**如果我们知道这些状态转移概率和奖励函数的话,我们就说这个环境是已知的,因为我们是用这两个函数去描述环境的。**如果是已知的话,我们其实可以用动态规划去计算说,我如果要逃脱熊,那么能够逃脱熊概率最大的最优策略是什么。很多强化学习的经典的算法都是 model-free 的,就是环境是未知的这样子的一个情况下,我们强化学习怎么去解决。
我们去跟环境交互,我们只能走完整的一条通路。这里面产生了一系列的一个决策的过程,就是我们跟环境交互产生了一个经验。然后我们会使用 P 函数和 R 函数来去描述环境。P 函数就是状态转移的概率R 函数就是 Reward function。P 函数实际上反映的是环境的一个随机性。比方说,在熊发怒的情况下,我如果选择装死,假设熊看到人装死就一定会走的话,我们就称在这里面的这个状态转移概率就是百分之百。但如果说在熊发怒的情况下,我选择跑路而导致说我有可能跑成功以及跑失败,出现这两种情况。那我们就可以用概率去表达一下说转移到其中一种情况的概率大概 10%,另外一种情况的概率大概是 90% 会跑失败。**如果我们知道这些状态转移概率和奖励函数的话,我们就说这个环境是已知的,因为我们是用这两个函数去描述环境的。**如果是已知的话,我们其实可以用动态规划去计算说,我如果要逃脱熊,那么能够逃脱熊概率最大的最优策略是什么。很多强化学习的经典的算法都是 model-free 的,就是环境是未知的这样子的一个情况下,我们强化学习怎么去解决。
![](img/2.3.png)
因为现实世界中人类第一次遇到熊之前我们根本不知道我们能不能跑得过熊。所以刚刚那个10%、90%的概率也就是虚构出来的概率,熊到底在什么时候会往什么方向去转变的话,我们经常是不知道的。我们是处在一个未知的环境里的,也就是这一系列的决策的 P 函数和 R 函数是未知的。这就是 model-based 跟 model-free 的一个最大的区别。强化学习就是可以用来解决用完全未知的和随机的环境。
@@ -135,6 +135,28 @@ $$
![](img/2.16.png)我们直接看这个框框里面的更新公式, 和之前的公式是一模一样的。$S'$ 就是 $S_{t+1}$ 。我们就是拿下一步的 Q 值来更新这一步的 Q 值,不断地强化每一个 Q。
## Sarsa($\lambda$)
Sarsa 属于单步更新法,也就是说每执行一个动作,就会更新一次价值和策略。如果不进行单步更新,而是采取 $n$ 步更新或者回合更新,即在执行 $n$ 步之后再来更新价值和策略,这样就得到了 $n$ 步 Sarsa。具体来说对于 Sarsa在 $t$ 时刻其价值的计算公式为
$$
q_{t}=r_{t}+\gamma Q\left(s_{t+1}, a_{t+1}\right)
$$
而对于 $n$ 步 Sarsa它的 $n$ 步 Q 收获为
$$
q_{t}^{(n)}=r_{t}+\gamma r_{t+1}+\cdots+\gamma^{n-1} r_{t+n-1}+\gamma^{n} Q\left(s_{t+n}, a_{t+n}\right)
$$
如果给 $q_t^{(n)}$ 加上衰减因子 $\lambda$ 并进行求和,即可得到 Sarsa($\lambda$) 的 Q 收获:
$$
q_{t}^{\lambda}=(1-\lambda) \sum_{n=1}^{\infty} \lambda^{n-1} q_{t}^{(n)}
$$
因此,$n$ 步 Sarsa($\lambda$)的更新策略可以表示为
$$
Q\left(s_{t}, a_{t}\right) \leftarrow Q\left(s_{t}, a_{t}\right)+\alpha\left(q_{t}^{\lambda}-Q\left(s_{t}, a_{t}\right)\right)
$$
总的来说Sarsa 和 Sarsa($\lambda$) 的差别主要体现在价值的更新上。
## Q-learning
![](img/2.17.png)
@@ -168,11 +190,14 @@ Sarsa 实际上都是用自己的策略产生了 S,A,R,S',A' 这一条轨迹。
然后Q-learning 的这个逐步的一个拆解的话跟Sarsa 唯一一点不一样就是我并不需要提前知道我 $A_2$ ,我就能更新 $Q(S_1,A_1)$ 。在训练一个 episode 这个流程图当中Q-leanring 在 learn 之前它也不需要去拿到 next action A',它只需要前面四个 $(S,A,R,S')$也就可以了。这一点就是跟 Sarsa 有一个很明显的区别。
### Bellman Equation
### Q-function Bellman Equation
记策略 $\pi $ 的状态-动作值函数为 $Q^{\pi}(s_t,a_t)$,它表示在状态 $s_t$ 下,执行动作 $a_t$ 会带来的累积奖励 $G_t$ 的期望,具体公式为:
$$
\begin{aligned} Q ^ { \pi } \left( s _ { t } , a _ { t } \right) & = \mathbb { E } \left[ G _ { t } \mid s _ { t } , a _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma r _ { t + 1 } + \gamma ^ { 2 } r _ { t + 2 } + \cdots \mid s _ { t } , a _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma \left( r _ { t + 1 } + \gamma r _ { t + 2 } + \cdots \right) \mid s _ { t } , a _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma Q ^ { \pi } \left( s _ { t + 1 } , a _ { t + 1 } \right) \mid s _ { t } , a _ { t } \right] \end{aligned}
\begin{aligned} Q ^ { \pi } \left( s _ { t } , a _ { t } \right) & = \mathbb { E } \left[ G _ { t } \mid s _ { t } , a _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma r _ { t + 1 } + \gamma ^ { 2 } r _ { t + 2 } + \cdots \mid s _ { t } , a _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma \left( r _ { t + 1 } + \gamma r _ { t + 2 } + \cdots \right) \mid s _ { t } , a _ { t } \right]
\\ & =\mathbb { E } [ r _ { t }|s_t,a_t] + \gamma \mathbb{E}[r_{t+1}+ \gamma r_{t+2}+\cdots|s_t,a_t] \\
& = \mathbb{E}[ r _ { t }|s_t,a_t]+ \gamma \mathbb{E}[G_{t+1}|s_t,a_t]
\\ &= \mathbb { E } \left[ r _ { t } + \gamma Q ^ { \pi } \left( s _ { t + 1 } , a _ { t + 1 } \right) \mid s _ { t } , a _ { t } \right] \end{aligned}
$$
上式是 MDP 中 Bellman 方程的基本形式。累积奖励 $G_t$ 的计算,不仅考虑当下 $t$ 时刻的动作 $a_t$ 的奖励 $r_t$,还会累积计算对之后決策带来的影响(公式中的 $\gamma$ 是后续奖励的衰减因子)。从上式可以看出,当前状态的动作价值 $Q^{\pi}(s_t,a_t)$ ,与当前动作的奖励 $r_t$ 以及下一状态的动作价值 $Q^{\pi}(s_{t+1},a_{t+1})$ 有关,因此,状态-动作值函数的计算可以通过动态规划算法来实现。

View File

@@ -1,6 +1,6 @@
# Q-learning
## Q-learning
## State Value Function
![](img/5.1.png)
@@ -15,6 +15,18 @@ Q-learning 是 `value-based` 的方法。在 value based 的方法里面,我
这边需要强调的一个点是说,当你在讲这一个 critic 的时候critic 都是绑一个 actor 的critic 没有办法去凭空去 evaluate 一个 state 的好坏,它所 evaluate 的东西是在给定某一个 state 的时候, 假设接下来互动的 actor 是 $\pi$,那我会得到多少 reward。因为就算是给同样的 state你接下来的 $\pi$ 不一样,你得到的 reward 也是不一样的。举例来说在左边那个case虽然假设是一个正常的 $\pi$,它可以杀很多怪,那假设他是一个很弱的 $\pi$,它就站在原地不动,然后马上就被射死了,那你得到的 V 还是很小。所以 critic output 值有多大其实是取决于两件事state 和 actor。所以你的 critic 其实都要绑一个 actor它是在衡量某一个 actor 的好坏,而不是 generally 衡量一个 state 的好坏。这边要强调一下critic output 是跟 actor 有关的state value 其实是 depend on 你的 actor。当你的 actor 变的时候state value function 的output 其实也是会跟着改变的。
### State-value Function Bellman Equation
记策略 $\pi $ 的状态值函数为 $V^{\pi}(s_t)$ ,它表示在状态 $s_t$ 下带来的累积奖励 $G_t$ 的期望,具体公式为:
$$
\begin{aligned} V ^ { \pi } \left( s _ { t } \right) & = \mathbb { E } \left[ G _ { t } \mid s _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma r _ { t + 1 } + \gamma ^ { 2 } r _ { t + 2 } + \cdots \mid s _ { t } \right] \\ & = \mathbb { E } \left[ r _ { t } + \gamma \left( r _ { t + 1 } + \gamma r _ { t + 2 } + \cdots \right) \mid s _ { t } \right] \\
&= \mathbb{E}[r_t|s_t]+ \gamma\mathbb{E}[r_{t+1}+\gamma r_{t+2}+\cdots|s_t] \\
& =\mathbb{E}[r_t|s_t]+ \gamma\mathbb{E}[G_{t+1}|s_t]
\\& = \mathbb { E } \left[ r _ { t } + \gamma V ^ { \pi } \left( s _ { t + 1 } \right) \mid s _ { t} \right] \end{aligned}
$$
上式是 State-value Function 的 Bellman Equation。
### State Value Function Estimation
![](img/5.2.png)
@@ -89,6 +101,8 @@ $$
时序差分强化学习能够在知道结果之前就开始学习,相比蒙特卡洛强化学习,其更快速、灵活。
## State-action Value Function
![](img/5.7.png)
还有另外一种critic这种critic 叫做 `Q-function`。它又叫做`state-action value function`
@@ -261,7 +275,7 @@ $$
## Exploration
![](img/5.16.png)第二个 tip 是`Exploration`。当我们使用 Q-function 的时候policy 完全 depend on Q-function。给定某一个 state你就穷举所有的 a 看哪个 a 可以让 Q value 最大它就是采取的action。那其实这个跟 policy gradient 不一样,在做 policy gradient 的时候output 其实是 stochastic 的。我们 output 一个action 的distribution根据这个action 的distribution 去做sample 所以在policy gradient 里面你每次采取的action 是不一样的是有随机性的。那像这种Q-function 如果你采取的action 总是固定的,会有什么问题呢?你会遇到的问题就是这不是一个好的收集 data 的方式。因为假设我们今天真的要估某一个state你可以采取action $a_{1}$, $a_{2}$, $a_{3}$。你要估测在某一个state 采取某一个action 会得到的Q value你一定要在那一个 state 采取过那一个action才估得出它的value。如果你没有在那个state 采取过那个action你其实估不出那个value 的。当然如果是用deep 的network就你的Q-function 其实是一个network这种情形可能会没有那么严重。但是 in general 而言,假设 Q-function 是一个table没有看过的 state-action pair它就是估不出值来。Network 也是会有一样的问题就是, 只是没有那么严重。所以今天假设你在某一个stateaction $a_{1}$, $a_{2}$, $a_{3}$ 你都没有采取过,那你估出来的 $Q(s,a_{1})$, $Q(s,a_{2})$, $Q(s,a_{3})$ 的 value 可能都是一样的,就都是一个初始值,比如说 0
![](img/5.16.png)第二个 tip 是`Exploration`。当我们使用 Q-function 的时候policy 完全 depend on Q-function。给定某一个 state你就穷举所有的 a 看哪个 a 可以让 Q value 最大它就是采取的action。那其实这个跟 policy gradient 不一样,在做 policy gradient 的时候output 其实是 stochastic 的。我们 output 一个action 的distribution根据这个action 的distribution 去做sample 所以在policy gradient 里面你每次采取的action 是不一样的,是有随机性的。那像这种 Q-function 如果你采取的action 总是固定的,会有什么问题呢?你会遇到的问题就是这不是一个好的收集 data 的方式。因为假设我们今天真的要估某一个state你可以采取 action $a_{1}$, $a_{2}$, $a_{3}$。你要估测在某一个state 采取某一个action 会得到的Q value你一定要在那一个 state 采取过那一个action才估得出它的value。如果你没有在那个state 采取过那个action你其实估不出那个value 的。当然如果是用 deep 的network就你的 Q-function 其实是一个 network这种情形可能会没有那么严重。但是 in general 而言,假设 Q-function 是一个 table没有看过的 state-action pair它就是估不出值来。Network 也是会有一样的问题就是, 只是没有那么严重。所以今天假设你在某一个stateaction $a_{1}$, $a_{2}$, $a_{3}$ 你都没有采取过,那你估出来的 $Q(s,a_{1})$, $Q(s,a_{2})$, $Q(s,a_{3})$ 的 value 可能都是一样的,就都是一个初始值,比如说 0
$$
\begin{array}{l}
@@ -271,13 +285,21 @@ Q(s, a_3)=0
\end{array}
$$
但是假设你在state s你sample 过某一个action $a_{2}$ ,它得到的值是 positive 的 reward。那 $Q(s, a_2)$ 就会比其他的action 都要好。在采取action 的时候, 就看说谁的Q value 最大就采取谁所以之后你永远都只会sample 到$a_{2}$其他的action 就再也不会被做了,所以就会有问题。就好像说你进去一个餐厅吃饭,其实你都很难选。你今天点了某一个东西以后,假说点了某一样东西, 比如说椒麻鸡,你觉得还可以。接下来你每次去就都会点椒麻鸡,再也不会点别的东西了,那你就不知道说别的东西是不是会比椒麻鸡好吃,这个是一样的问题。
但是假设你在state s sample 过某一个action $a_{2}$ ,它得到的值是 positive 的 reward。那 $Q(s, a_2)$ 就会比其他的action 都要好。在采取action 的时候, 就看说谁的Q value 最大就采取谁,所以之后你永远都只会 sample 到 $a_{2}$其他的action 就再也不会被做了,所以就会有问题。就好像说你进去一个餐厅吃饭,其实你都很难选。你今天点了某一个东西以后,假说点了某一样东西, 比如说椒麻鸡,你觉得还可以。接下来你每次去就都会点椒麻鸡,再也不会点别的东西了,那你就不知道说别的东西是不是会比椒麻鸡好吃,这个是一样的问题。
如果你没有好的 exploration 的话, 你在training 的时候就会遇到这种问题。举一个实际的例子, 假设你今天是用 Q-learning 来玩比如说`slither.io`。在玩`slither.io` 你会有一个蛇,然后它在环境里面就走来走去, 然后就吃到星星它就加分。假设这个游戏一开始它采取往上走然后就吃到那个星星它就得到分数它就知道说往上走是positive。接下来它就再也不会采取往上走以外的action 了所以接下来就会变成每次游戏一开始它就往上冲然后就死掉再也做不了别的事。所以今天需要有exploration 的机制,需要让 machine 知道说虽然根据之前sample 的结果,$a_2$ 好像是不错的,但你至少偶尔也试一下$a_{1}$ 跟$a_{3}$,搞不好他们更好也说不定。
这个问题其实就是`探索-利用窘境(Exploration-Exploitation dilemma)`问题。
有两个方法解这个问题,一个是`Epsilon Greedy`。Epsilon Greedy 的意思是说,我们有$1-\varepsilon$ 的机率,通常$\varepsilon$ 就设一个很小的值, $1-\varepsilon$ 可能是90%也就是90% 的机率完全按照Q-function 来决定action。但是你有10% 的机率是随机的。通常在实现上 $\varepsilon$ 会随着时间递减。也就是在最开始的时候。因为还不知道那个action 是比较好的,所以你会花比较大的力气在做 exploration。接下来随着training 的次数越来越多。已经比较确定说哪一个Q 是比较好的。你就会减少你的exploration你会把 $\varepsilon$ 的值变小主要根据Q-function 来决定你的action比较少做random这是Epsilon Greedy。
还有一个方法叫做 `Boltzmann Exploration`,这个方法就比较像是 policy gradient。在 policy gradient 里面我们说network 的output 是一个 expected action space 上面的一个的 probability distribution。再根据 probability distribution 去做sample。那其实你也可以根据 Q value 去定一个probability distribution你可以说,假设某一个action 的Q value 越大代表它越好那我们采取这个action 的机率就越高。但是某一个action 的Q value 小不代表我们不能trytry 看它好不好用。所以我们有时候也要trytry 那些 Q value 比较差的 action怎么做呢因为Q value 是有正有负的所以你要把它弄成一个概率你可能就先取exponential然后再做normalize。然后把 $exp(Q(s,a))$ 做normalize 的这个概率当作是你在决定action 的时候sample 的概率。在实现上Q 是一个network所以你有点难知道 在一开始的时候network 的output 到底会长怎么样子。但是你可以猜测说, 假设你一开始没有任何的training data你的参数是随机的那给定某一个state s不同的 a output 的值,可能就是差不多的所以一开始$Q(s,a)$ 应该会倾向于是uniform。也就是在一开始的时候你这个probability distribution 算出来它可能是比较uniform 的。
还有一个方法叫做 `Boltzmann Exploration`,这个方法就比较像是 policy gradient。在 policy gradient 里面我们说network 的output 是一个 expected action space 上面的一个的 probability distribution。再根据 probability distribution 去做 sample。那其实你也可以根据 Q value 去定一个 probability distribution假设某一个 action 的 Q value 越大,代表它越好,那我们采取这个 action 的机率就越高。但是某一个 action 的 Q value 小不代表我们不能trytry 看它好不好用。所以我们有时候也要 trytry 那些 Q value 比较差的 action怎么做呢因为 Q value 是有正有负的所以你要把它弄成一个概率,你可能就先取 exponential再做 normalize。然后把 $exp(Q(s,a))$ 做 normalize 的这个概率当作是你在决定 action 的时候 sample 的概率。在实现上Q 是一个 network所以你有点难知道 在一开始的时候 network 的 output 到底会长怎么样子。假设你一开始没有任何的 training data你的参数是随机的那给定某一个 state s不同的 a output 的值,可能就是差不多的所以一开始$ Q(s,a)$ 应该会倾向于是 uniform。也就是在一开始的时候你这个probability distribution 算出来,它可能是比较 uniform 的。
## Experience Replay
@@ -293,7 +315,7 @@ $$
当我们这么做的时候, 它变成了一个 `off-policy` 的做法。因为本来我们的 Q 是要观察 $\pi$ 的 experience但实际上存在你的 replay buffer 里面的这些 experiences 不是通通来自于 $\pi$,有些是过去其他的 $\pi$ 所遗留下来的 experience。因为你不会拿某一个 $\pi$ 就把整个 buffer 装满,然后拿去测 Q-function这个 $\pi$ 只是 sample 一些 data 塞到那个 buffer 里面去,然后接下来就让 Q 去 train。所以 Q 在 sample 的时候, 它会 sample 到过去的一些资料。
但是这样做有什么好处呢?这么做有两个好处。
这么做有两个好处。
* 第一个好处,其实在做 reinforcement learning 的时候, 往往最花时间的 step 是在跟环境做互动train network 反而是比较快的。因为你用 GPU train 其实很快, 真正花时间的往往是在跟环境做互动。用 replay buffer 可以减少跟环境做互动的次数,因为在做 training 的时候,你的 experience 不需要通通来自于某一个policy。一些过去的 policy 所得到的 experience 可以放在 buffer 里面被使用很多次,被反复的再利用,这样让你的 sample 到 experience 的利用是比较 efficient。