fix some typos
This commit is contained in:
@@ -7,30 +7,36 @@
|
||||
## Behavior Cloning
|
||||

|
||||
|
||||
其实 `Behavior Cloning` 跟 supervised learning 是一模一样的。我们以自动驾驶汽车为例,你可以收集到人开自动驾驶汽车的所有资料,比如说可以通过行车记录器进行收集。看到这样子的 observation 的时候,人会决定向前。机器就采取跟人一样的行为,也向前,就结束了,这个就叫做 Behavior Cloning。Expert 做什么,机器就做一模一样的事,怎么让机器学会跟 expert 一模一样的行为呢?就把它当作一个 supervised learning 的问题,你去收集很多行车纪录器。然后再收集人在那个情境下会采取什么样的行为。你知道说人在 state $s_1$ 会采取action $a_1$,人在state $s_2$ 会采取action $a_2$。人在state, $s_3$ 会采取action $a_3$。接下来,你就learn 一个 network。这个 network 就是你的 actor,他input $s_i$ 的时候,你就希望他的output 是$a_i$,就这样结束了。它就是一个的 supervised learning 的problem。
|
||||
其实 `Behavior Cloning` 跟 supervised learning 是一模一样的。我们以自动驾驶汽车为例,你可以收集到人开自动驾驶汽车的所有资料,比如说可以通过行车记录器进行收集。看到这样子的 observation 的时候,人会决定向前。机器就采取跟人一样的行为,也向前,就结束了,这个就叫做 Behavior Cloning,Expert 做什么,机器就做一模一样的事。
|
||||
|
||||
怎么让机器学会跟 expert 一模一样的行为呢?就把它当作一个 supervised learning 的问题,你去收集很多行车纪录器,然后再收集人在那个情境下会采取什么样的行为。你知道说人在 state $s_1$ 会采取action $a_1$,人在 state $s_2$ 会采取 action $a_2$。人在 state, $s_3$ 会采取 action $a_3$。接下来,你就 learn 一个 network。这个 network 就是你的 actor,它 input $s_i$ 的时候,你就希望它的 output 是$a_i$,就这样结束了。它就是一个的 supervised learning 的 problem。
|
||||
|
||||

|
||||
|
||||
Behavior Cloning 虽然非常简单,但它的问题是如果你只收集expert 的资料,你可能看过的 observation 会是非常 limited。举例来说,假设你要 learn 一部自动驾驶汽车,自动驾驶汽车就是要过这个弯道。如果是 expert 的话,他就是把车顺着这个红线就开过去了。但假设你的 agent 很笨,他今天开着开着,就开到撞墙了,他永远不知道撞墙这种状况要怎么处理,为什么?因为 training data 里面从来没有撞过墙,所以他根本就不知道撞墙这一种 case 要怎么处理。或是打电玩,电玩也是一样,让人去玩 Mario,那 expert 可能非常强,他从来不会跳不上水管,所以机器根本不知道跳不上水管时要怎么处理。人从来不会跳不上水管,但是机器如果跳不上水管时,就不知道要怎么处理。所以光是做Behavior Cloning 是不够的。只观察 expert 的行为是不够的,需要一个招数,这个招数叫作`Dataset Aggregation`。
|
||||
Behavior Cloning 虽然非常简单,但它的问题是如果你只收集expert 的资料,你可能看过的 observation 会是非常 limited。
|
||||
|
||||
举例来说,假设你要 learn 一部自动驾驶汽车,自动驾驶汽车就是要过这个弯道。如果是 expert 的话,它就是把车顺着这个红线就开过去了。但假设你的 agent 很笨,它今天开着开着,就开到撞墙了,它永远不知道撞墙这种状况要怎么处理,为什么?因为 training data 里面从来没有撞过墙,所以它根本就不知道撞墙这一种 case 要怎么处理。
|
||||
|
||||
或是打电玩,电玩也是一样,让人去玩 Mario,那 expert 可能非常强,它从来不会跳不上水管,所以机器根本不知道跳不上水管时要怎么处理。人从来不会跳不上水管,但是机器如果跳不上水管时,就不知道要怎么处理。所以光是做Behavior Cloning 是不够的。只观察 expert 的行为是不够的,需要一个招数,这个招数叫作`Dataset Aggregation`。
|
||||
|
||||

|
||||
|
||||
我们会希望收集更多样性的 data,而不是只收集 expert 所看到的 observation。我们会希望能够收集 expert 在各种极端的情况下,他会采取什么样的行为。以自动驾驶汽车为例的话,假设一开始,你的actor 叫作 $\pi_1$,你让 $\pi_1$去开这个车。但车上坐了一个 expert。这个 expert 会不断地告诉machine 说,如果在这个情境里面,我会怎么样开。所以 $\pi_1$ 自己开自己的,但是expert 会不断地表示他的想法。比如说,在这个时候,expert 可能说那就往前走。这个时候,expert 可能就会说往右转。但 $\pi_1$ 是不管 expert 的指令的,所以他会继续去撞墙。虽然 expert 说往右转,但是不管他怎么下指令都是没有用的。$\pi_1$ 会自己做自己的事情,因为我们要做的记录的是说,今天expert 在 $\pi_1$ 看到这种observation 的情况下,他会做什么样的反应。这个方法显然是有一些问题的,因为每次你开一次自动驾驶汽车都会牺牲一个人。那你用这个方法,你牺牲一个expert 以后,你就会得到说,人类在这样子的 state 下,在快要撞墙的时候,会采取什么样的反应。再把这个data 拿去train 新的 $\pi_2$。这个process 就反复继续下去,这个方法就叫做`Dataset Aggregation`。
|
||||
我们会希望收集更多样性的 data,而不是只收集 expert 所看到的 observation。我们会希望能够收集 expert 在各种极端的情况下,它会采取什么样的行为。以自动驾驶汽车为例的话,假设一开始,你的 actor 叫作 $\pi_1$,你让 $\pi_1$去开这个车。但车上坐了一个 expert。这个 expert 会不断地告诉 machine 说,如果在这个情境里面,我会怎么样开。所以 $\pi_1$ 自己开自己的,但是 expert 会不断地表示它的想法。比如说,在这个时候,expert 可能说那就往前走。这个时候,expert 可能就会说往右转。但 $\pi_1$ 是不管 expert 的指令的,所以它会继续去撞墙。虽然 expert 说往右转,但是不管它怎么下指令都是没有用的。$\pi_1$ 会自己做自己的事情,因为我们要做的记录的是说,今天 expert 在 $\pi_1$ 看到这种 observation 的情况下,它会做什么样的反应。这个方法显然是有一些问题的,因为每次你开一次自动驾驶汽车都会牺牲一个人。那你用这个方法,你牺牲一个 expert 以后,你就会得到说,人类在这样子的 state 下,在快要撞墙的时候,会采取什么样的反应。再把这个 data 拿去 train 新的 $\pi_2$。这个 process 就反复继续下去,这个方法就叫做`Dataset Aggregation`。
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
Behavior Cloning 还有一个 issue 是说,机器会完全 copy expert 的行为,不管 expert 的行为是否有道理,就算没有道理,没有什么用的,这是expert 本身的习惯,机器也会硬把它记下来。如果机器确实可以记住所有 expert 的行为,那也许还好,为什么呢?因为如果 expert 这么做,有些行为是多余的。但是没有问题,假设机器的行为可以完全仿造 expert 行为,那也就算了,那他是跟 expert 一样得好,只是做一些多余的事。但问题就是它是一个 machine,它是一个 network,network 的capacity 是有限的。就算给 network training data,它在training data 上得到的正确率往往也不是100%,他有些事情是学不起来的。这个时候,什么该学,什么不该学就变得很重要。
|
||||
Behavior Cloning 还有一个 issue 是说,机器会完全 copy expert 的行为,不管 expert 的行为是否有道理,就算没有道理,没有什么用的,这是expert 本身的习惯,机器也会硬把它记下来。如果机器确实可以记住所有 expert 的行为,那也许还好,为什么呢?因为如果 expert 这么做,有些行为是多余的。但是没有问题,假设机器的行为可以完全仿造 expert 行为,那也就算了,那它是跟 expert 一样得好,只是做一些多余的事。但问题就是它是一个 machine,它是一个 network,network 的 capacity 是有限的。就算给 network training data,它在training data 上得到的正确率往往也不是100%,它有些事情是学不起来的。这个时候,什么该学,什么不该学就变得很重要。
|
||||
|
||||
举例来说,在学习中文的时候,你的老师,他有语音,他也有行为,他也有知识,但其实只有语音部分是重要的,知识的部分是不重要的。也许 machine 只能够学一件事,也许他就只学到了语音,那没有问题。如果他只学到了手势,这样子就有问题了。所以让机器学习什么东西是需要 copy,什么东西是不需要 copy,这件事情是重要的。而单纯的 Behavior Cloning 就没有把这件事情学进来,因为机器只是复制 expert 所有的行为而已,它不知道哪些行为是重要,是对接下来有影响的,哪些行为是不重要的,是对接下来是没有影响的。
|
||||
举例来说,在学习中文的时候,你的老师,它有语音,它也有行为,它也有知识,但其实只有语音部分是重要的,知识的部分是不重要的。也许 machine 只能够学一件事,也许它就只学到了语音,那没有问题。如果它只学到了手势,这样子就有问题了。所以让机器学习什么东西是需要 copy,什么东西是不需要 copy,这件事情是重要的。而单纯的 Behavior Cloning 就没有把这件事情学进来,因为机器只是复制 expert 所有的行为而已,它不知道哪些行为是重要,是对接下来有影响的,哪些行为是不重要的,是对接下来是没有影响的。
|
||||
|
||||
|
||||

|
||||
|
||||
Behavior Cloning 还有什么样的问题呢?在做 Behavior Cloning 的时候,training data 跟 testing data 是 mismatch 的。我们可以用 Dataset Aggregation 的方法来缓解这个问题。这个问题是,在 training 跟 testing 的时候,data distribution 其实是不一样的。因为在 reinforcement learning 里面,action 会影响到接下来所看到的 state。我们是先有 state $s_1$,然后采取 action $a_1$,action $a_1$ 其实会决定接下来你看到什么样的 state $s_2$。所以在 reinforcement learning 里面有一个很重要的特征,就是你采取了 action 会影响你接下来所看到的 state。如果做了Behavior Cloning 的话,我们只能观察到 expert 的一堆 state 跟 action 的pair。然后我们希望可以 learn 一个 $\pi^*$,我们希望 $\pi^*$ 跟 $\hat{\pi}$ 越接近越好。如果 $\pi^*$ 可以跟 $\hat{\pi}$ 一模一样的话,你 training 的时候看到的 state 跟 testing 的时候所看到的 state 会是一样的。因为虽然 action 会影响我们看到的 state,但假设两个 policy 一模一样, 在同一个 state 都会采取同样的 action,那你接下来所看到的 state 都会是一样的。但问题就是你很难让你的 learn 出来的 policy 跟expert 的 policy 一模一样。Expert 可是一个人,network 要跟人一模一样,感觉很难吧。
|
||||
Behavior Cloning 还有什么样的问题呢?在做 Behavior Cloning 的时候,training data 跟 testing data 是 mismatch 的。我们可以用 Dataset Aggregation 的方法来缓解这个问题。这个问题是,在 training 跟 testing 的时候,data distribution 其实是不一样的。因为在 reinforcement learning 里面,action 会影响到接下来所看到的 state。我们是先有 state $s_1$,然后采取 action $a_1$,action $a_1$ 其实会决定接下来你看到什么样的 state $s_2$。所以在 reinforcement learning 里面有一个很重要的特征,就是你采取了 action 会影响你接下来所看到的 state。如果做了 Behavior Cloning 的话,我们只能观察到 expert 的一堆 state 跟 action 的pair。然后我们希望可以 learn 一个 $\pi^*$,我们希望 $\pi^*$ 跟 $\hat{\pi}$ 越接近越好。如果 $\pi^*$ 可以跟 $\hat{\pi}$ 一模一样的话,你 training 的时候看到的 state 跟 testing 的时候所看到的 state 会是一样的。因为虽然 action 会影响我们看到的 state,但假设两个 policy 一模一样, 在同一个 state 都会采取同样的 action,那你接下来所看到的 state 都会是一样的。但问题就是你很难让你的 learn 出来的 policy 跟 expert 的 policy 一模一样。Expert 可是一个人,network 要跟人一模一样,感觉很难吧。
|
||||
|
||||
如果你的 $\pi^*$ 跟 $\hat{\pi}$ 有一点误差。这个误差在一般 supervised learning problem 里面,每一个 example 都是 independent 的,也许还好。但对 reinforcement learning 的 problem 来说,你可能在某个地方就是失之毫厘,差之千里。可能在某个地方,也许 machine 没有办法完全复制 expert 的行为,它只复制了一点点,差了一点点,也许最后得到的结果就会差很多这样。所以 Behavior Cloning 并不能够完全解决 Imatation learning 这件事情。所以就有另外一个比较好的做法叫做 `Inverse Reinforcement Learning`。
|
||||
如果你的 $\pi^*$ 跟 $\hat{\pi}$ 有一点误差。这个误差在一般 supervised learning problem 里面,每一个 example 都是 independent 的,也许还好。但对 reinforcement learning 的 problem 来说,你可能在某个地方就是失之毫厘,差之千里。可能在某个地方,也许 machine 没有办法完全复制 expert 的行为,它只复制了一点点,差了一点点,也许最后得到的结果就会差很多这样。所以 Behavior Cloning 并不能够完全解决 imitation learning 这件事情。所以就有另外一个比较好的做法叫做 `Inverse Reinforcement Learning`。
|
||||
|
||||
|
||||
## Inverse RL
|
||||
@@ -39,35 +45,33 @@ Behavior Cloning 还有什么样的问题呢?在做 Behavior Cloning 的时候
|
||||
为什么叫 Inverse Reinforcement Learning,因为原来的 Reinforcement Learning 里面,有一个环境和一个 reward function。根据环境和 reward function,通过 Reinforcement Learning 这个技术,你会找到一个 actor,你会 learn 出一个optimal actor。但 Inverse Reinforcement Learning 刚好是相反的,你没有 reward function,你只有一堆 expert 的 demonstration。但你还是有环境的。IRL 的做法是说假设我们现在有一堆 expert 的demonstration,我们用 $\hat{\tau}$ 来代表expert 的demonstration。如果是在玩电玩的话,每一个 $\tau$ 就是一个很会玩电玩的人玩一场游戏的纪录,如果是自动驾驶汽车的话,就是人开自动驾驶汽车的纪录。这一边就是 expert 的 demonstration,每一个 $\tau$ 是一个 trajectory。
|
||||
|
||||
|
||||
把所有 expert demonstration 收集起来,然后,使用Inverse Reinforcement Learning 这个技术。使用 Inverse Reinforcement Learning 技术的时候,机器是可以跟环境互动的。但他得不到reward。他的 reward 必须要从 expert 那边推出来,有了环境和 expert demonstration 以后,去反推出 reward function 长什么样子。之前 reinforcement learning 是由 reward function 反推出什么样的 action、actor 是最好的。Inverse Reinforcement Learning 是反过来,我们有expert 的demonstration,我们相信他是不错的,我就反推说,expert 是因为什么样的 reward function 才会采取这些行为。你有了reward function 以后,接下来,你就可以套用一般的 reinforcement learning 的方法去找出 optimal actor。所以 Inverse Reinforcement Learning 是先找出 reward function,找出 reward function 以后,再去用 Reinforcement Learning 找出 optimal actor。
|
||||
把所有 expert demonstration 收集起来,然后,使用 Inverse Reinforcement Learning 这个技术。使用 Inverse Reinforcement Learning 技术的时候,机器是可以跟环境互动的。但它得不到reward。它的 reward 必须要从 expert 那边推出来,有了环境和 expert demonstration 以后,去反推出 reward function 长什么样子。之前 reinforcement learning 是由 reward function 反推出什么样的 action、actor 是最好的。Inverse Reinforcement Learning 是反过来,我们有expert 的demonstration,我们相信它是不错的,我就反推说,expert 是因为什么样的 reward function 才会采取这些行为。你有了reward function 以后,接下来,你就可以套用一般的 reinforcement learning 的方法去找出 optimal actor。所以 Inverse Reinforcement Learning 是先找出 reward function,找出 reward function 以后,再去用 Reinforcement Learning 找出 optimal actor。
|
||||
|
||||
把这个 reward function learn 出来,相较于原来的 Reinforcement Learning 有什么样好处。一个可能的好处是也许 reward function 是比较简单的。也许,虽然这个 expert 的行为非常复杂,但也许简单的 reward function 就可以导致非常复杂的行为。一个例子就是也许人类本身的 reward function 就只有活着这样,每多活一秒,你就加一分。但人类有非常复杂的行为,但是这些复杂的行为,都只是围绕着要从这个 reward function 里面得到分数而已。有时候很简单的 reward function 也许可以推导出非常复杂的行为。
|
||||
|
||||

|
||||
|
||||
Inverse Reinforcement Learning 实际上是怎么做的呢?首先,我们有一个 expert $\hat{\pi}$,这个 expert 去跟环境互动,给我们很多 $\hat{\tau_1}$ 到 $\hat{\tau_n}$。如果是玩游戏的话,就让某一个电玩高手,去玩 n 场游戏。把 n 场游戏的 state 跟 action 的 sequence 都记录下来。接下来,你有一个actor $\pi$,一开始actor 很烂,这个 actor 也去跟环境互动。他也去玩了n 场游戏,他也有 n 场游戏的纪录。接下来,我们要反推出 reward function。怎么推出 reward function 呢?**原则就是 expert 永远是最棒的,是先射箭,再画靶的概念。**
|
||||
Inverse Reinforcement Learning 实际上是怎么做的呢?首先,我们有一个 expert $\hat{\pi}$,这个 expert 去跟环境互动,给我们很多 $\hat{\tau_1}$ 到 $\hat{\tau_n}$。如果是玩游戏的话,就让某一个电玩高手,去玩 n 场游戏。把 n 场游戏的 state 跟 action 的 sequence 都记录下来。接下来,你有一个actor $\pi$,一开始actor 很烂,这个 actor 也去跟环境互动。它也去玩了n 场游戏,它也有 n 场游戏的纪录。接下来,我们要反推出 reward function。怎么推出 reward function 呢?**原则就是 expert 永远是最棒的,是先射箭,再画靶的概念。**
|
||||
|
||||
Expert 去玩一玩游戏,得到这一些游戏的纪录,你的 actor 也去玩一玩游戏,得到这些游戏的纪录。接下来,你要定一个 reward function,这个 reward function 的原则就是 expert 得到的分数要比 actor 得到的分数高,先射箭,再画靶。所以我们就 learn 出一个 reward function。你就找出一个 reward function。这个 reward function 会使 expert 所得到的 reward 大过于 actor 所得到的reward。你有了新的 reward function 以后,就可以套用一般 Reinforcement Learning 的方法去learn 一个actor,这个actor 会针对 reward function 去 maximize 他的reward。他也会采取一大堆的action。但是,今天这个 actor 虽然可以 maximize 这个 reward function,采取一大堆的行为,得到一大堆游戏的纪录。
|
||||
Expert 去玩一玩游戏,得到这一些游戏的纪录,你的 actor 也去玩一玩游戏,得到这些游戏的纪录。接下来,你要定一个 reward function,这个 reward function 的原则就是 expert 得到的分数要比 actor 得到的分数高,先射箭,再画靶。所以我们就 learn 出一个 reward function。你就找出一个 reward function。这个 reward function 会使 expert 所得到的 reward 大过于 actor 所得到的reward。你有了新的 reward function 以后,就可以套用一般 Reinforcement Learning 的方法去learn 一个actor,这个actor 会针对 reward function 去 maximize 它的 reward。它也会采取一大堆的 action。但是,今天这个 actor 虽然可以 maximize 这个 reward function,采取一大堆的行为,得到一大堆游戏的纪录。
|
||||
|
||||
但接下来,我们就改 reward function。这个 actor 就会很生气,它已经可以在这个reward function 得到高分。但是他得到高分以后,我们就改 reward function,仍然让 expert 可以得到比 actor 更高的分数。这个就是 `Inverse Reinforcement learning`。有了新的 reward function 以后,根据这个新的 reward function,你就可以得到新的 actor,新的 actor 再去跟环境做一下互动,他跟环境做互动以后, 你又会重新定义你的 reward function,让 expert 得到的 reward 比 actor 大。
|
||||
但接下来,我们就改 reward function。这个 actor 就会很生气,它已经可以在这个 reward function 得到高分。但是它得到高分以后,我们就改 reward function,仍然让 expert 可以得到比 actor 更高的分数。这个就是 `Inverse Reinforcement learning`。有了新的 reward function 以后,根据这个新的 reward function,你就可以得到新的 actor,新的 actor 再去跟环境做一下互动,它跟环境做互动以后, 你又会重新定义你的 reward function,让 expert 得到的 reward 比 actor 大。
|
||||
|
||||
怎么让 expert 得到的 reward 大过 actor 呢?其实你在 learning 的时候,你可以很简单地做一件事就是,reward function 也许就是 neural network。这个 neural network 就是吃一个 $\tau$,output 就是应该要给这个 $\tau$ 多少的分数。或者说,你假设觉得 input 整个$\tau$ 太难了。因为$\tau$ 是 s 和 a 的一个很强的sequence。也许他就是 input 一个 s 和 a 的 pair,然后 output 一个real number。把整个 sequence,整个$\tau$ 会得到的 real number 都加起来就得到 $R(\tau)$。在training 的时候,对于 $\left\{\hat{\tau}_{1}, \hat{\tau}_{2}, \cdots, \hat{\tau}_{N}\right\}$,我们希望它 output 的 R 越大越好。对于 $\left\{\tau_{1}, \tau_{2}, \cdots, \tau_{N}\right\}$,我们就希望它 R 的值越小越好。
|
||||
怎么让 expert 得到的 reward 大过 actor 呢?其实你在 learning 的时候,你可以很简单地做一件事就是,reward function 也许就是 neural network。这个 neural network 就是吃一个 $\tau$,output 就是应该要给这个 $\tau$ 多少的分数。或者说,你假设觉得 input 整个$\tau$ 太难了。因为$\tau$ 是 s 和 a 的一个很强的 sequence。也许它就是 input 一个 s 和 a 的 pair,然后 output 一个 real number。把整个 sequence,整个$\tau$ 会得到的 real number 都加起来就得到 $R(\tau)$。在 training 的时候,对于 $\left\{\hat{\tau}_{1}, \hat{\tau}_{2}, \cdots, \hat{\tau}_{N}\right\}$,我们希望它 output 的 R 越大越好。对于 $\left\{\tau_{1}, \tau_{2}, \cdots, \tau_{N}\right\}$,我们就希望它 R 的值越小越好。
|
||||
|
||||
什么叫做一个最好的 reward function。最后你 learn 出来的 reward function 应该就是 expert 和 actor 在这个 reward function 都会得到一样高的分数。最终你的 reward function 没有办法分辨出谁应该会得到比较高的分数。
|
||||
|
||||
通常在 train 的时候,你会 iterative 的去做。那今天的状况是这样,最早的 Inverse Reinforcement Learning 对 reward function 有些限制,他是假设 reward function 是 linear 的。如果reward function 是 linear 的话,你可以 prove 这个algorithm 会 converge。但是如果不是 linear 的,你就没有办法 prove 说它会 converge。你有没有觉得这个东西,看起来还挺熟悉呢?其实你只要把他换个名字,说 actor 就是 generator,然后说 reward function 就是discriminator,它就是GAN。所以它会不会收敛这个问题就等于是问说 GAN 会不会收敛。如果你已经实现过,你会知道不一定会收敛。但除非你对 R 下一个非常严格的限制,如果你的 R 是一个 general 的network 的话,你就会有很大的麻烦。
|
||||
通常在 train 的时候,你会 iterative 的去做。那今天的状况是这样,最早的 Inverse Reinforcement Learning 对 reward function 有些限制,它是假设 reward function 是 linear 的。如果 reward function 是 linear 的话,你可以 prove 这个algorithm 会 converge。但是如果不是 linear 的,你就没有办法 prove 说它会 converge。你有没有觉得这个东西,看起来还挺熟悉呢?其实你只要把它换个名字,说 actor 就是 generator,然后说 reward function 就是 discriminator,它就是 GAN。所以它会不会收敛这个问题就等于是问说 GAN 会不会收敛。如果你已经实现过,你会知道不一定会收敛。但除非你对 R 下一个非常严格的限制,如果你的 R 是一个 general 的 network 的话,你就会有很大的麻烦。
|
||||
|
||||
|
||||

|
||||
|
||||
那怎么说它像是一个GAN,我们来跟GAN 比较一下。GAN 里面,你有一堆很好的图。然后你有一个generator,一开始他根本不知道要产生什么样的图,他就乱画。然后你有一个discriminator,discriminator 的工作就是给画的图打分,expert 画的图就是高分,generator 画的图就是低分。你有discriminator 以后,generator 会想办法去骗过 discriminator。Generator 会希望 discriminator 也会给它画的图高分。整个 process 跟 Inverse Reinforcement Learning 是一模一样的。
|
||||
那怎么说它像是一个 GAN,我们来跟 GAN 比较一下。GAN 里面,你有一堆很好的图。然后你有一个 generator,一开始它根本不知道要产生什么样的图,它就乱画。然后你有一个 discriminator,discriminator 的工作就是给画的图打分,expert 画的图就是高分,generator 画的图就是低分。你有 discriminator 以后,generator 会想办法去骗过 discriminator。Generator 会希望 discriminator 也会给它画的图高分。整个 process 跟 Inverse Reinforcement Learning 是一模一样的。
|
||||
|
||||
* 画的图就是 expert 的 demonstration。generator 就是actor,generator 画很多图,actor 会去跟环境互动,产生很多 trajectory。这些 trajectory 跟环境互动的记录,游戏的纪录其实就是等于 GAN 里面的这些图。
|
||||
* 然后你 learn 一个reward function。Reward function 就是 discriminator。Rewards function 要给 expert 的 demonstration 高分,给 actor 互动的结果低分。
|
||||
* 接下来,actor 会想办法,从这个已经 learn 出来的 reward function 里面得到高分,然后 iterative 地去循环。跟GAN 其实是一模一样的,我们只是换个说法来而已。
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
IRL 有很多的application,举例来说,可以用开来自动驾驶汽车。然后,有人用这个技术来学开自动驾驶汽车的不同风格,每个人在开车的时候,其实你会有不同风格。举例来说,能不能够压到线,能不能够倒退,要不要遵守交通规则等等。每个人的风格是不同的,然后用 Inverse Reinforcement Learning 可以让自动驾驶汽车学会各种不同的开车风格。
|
||||
@@ -76,25 +80,25 @@ IRL 有很多的application,举例来说,可以用开来自动驾驶汽车
|
||||
|
||||
上图是文献上真实的例子,在这个例子里面, Inverse Reinforcement Learning 有一个有趣的地方,通常你不需要太多的 training data,因为 training data 往往都是个位数。因为 Inverse Reinforcement Learning 只是一种 demonstration,只是一种范例,实际上机器可以去跟环境互动非常多次。所以在 Inverse Reinforcement Learning 的文献, 往往会看到说只用几笔 data 就训练出一些有趣的结果。
|
||||
|
||||
比如说,在这个例子里面是要让自动驾驶汽车学会在停车场里面停。这边的demonstration 是这样,蓝色是终点,自动驾驶汽车要开到蓝色终点停车。给机器只看一行的四个 demonstration,然后让他去学怎么样开车,最后他就可以学出,在红色的终点位置,如果他要停车的话,他会这样开。今天给机器看不同的demonstration,最后他学出来开车的风格就会不太一样。举例来说,上图第二行是不守规矩的开车方式,因为他会开到道路之外,这边,他会穿过其他的车,然后从这边开进去。所以机器就会学到说,不一定要走在道路上,他可以走非道路的地方。上图第三行是倒退来停车,机器也会学会说,他可以倒退,
|
||||
比如说,在这个例子里面是要让自动驾驶汽车学会在停车场里面停。这边的demonstration 是这样,蓝色是终点,自动驾驶汽车要开到蓝色终点停车。给机器只看一行的四个 demonstration,然后让它去学怎么样开车,最后它就可以学出,在红色的终点位置,如果它要停车的话,它会这样开。今天给机器看不同的demonstration,最后它学出来开车的风格就会不太一样。举例来说,上图第二行是不守规矩的开车方式,因为它会开到道路之外,这边,它会穿过其它的车,然后从这边开进去。所以机器就会学到说,不一定要走在道路上,它可以走非道路的地方。上图第三行是倒退来停车,机器也会学会说,它可以倒退,
|
||||
|
||||

|
||||
|
||||
这种技术也可以拿来训练机器人。你可以让机器人,做一些你想要他做的动作,过去如果你要训练机器人,做你想要他做的动作,其实是比较麻烦的。怎么麻烦呢?过去如果你要操控机器的手臂,你要花很多力气去写 program 才让机器做一件很简单的事看。假设你有 Imitation Learning 的技术,你可以让人做一下示范,然后机器就跟着人的示范来进行学习,比如学会摆盘子,拉着机器人的手去摆盘子,机器自己动。让机器学会倒水,人只教他20 次,杯子每次放的位置不太一样。用这种方法来教机械手臂。
|
||||
这种技术也可以拿来训练机器人。你可以让机器人,做一些你想要它做的动作,过去如果你要训练机器人,做你想要它做的动作,其实是比较麻烦的。怎么麻烦呢?过去如果你要操控机器的手臂,你要花很多力气去写 program 才让机器做一件很简单的事看。假设你有 Imitation Learning 的技术,你可以让人做一下示范,然后机器就跟着人的示范来进行学习,比如学会摆盘子,拉着机器人的手去摆盘子,机器自己动。让机器学会倒水,人只教它20 次,杯子每次放的位置不太一样。用这种方法来教机械手臂。
|
||||
|
||||
## Third Person lmitation Learning
|
||||

|
||||
|
||||
其实还有很多相关的研究,举例来说,你在教机械手臂的时候,要注意就是也许机器看到的视野跟人看到的视野是不太一样的。在刚才那个例子里面,人跟机器的动作是一样的。但是在未来的世界里面,也许机器是看着人的行为学的。刚才是人拉着,假设你要让机器学会打高尔夫球,在刚才的例子里面就是人拉着机器人手臂去打高尔夫球,但是在未来有没有可能机器就是看着人打高尔夫球,他自己就学会打高尔夫球了呢?但这个时候,要注意的事情是机器的视野跟他真正去采取这个行为的时候的视野是不一样的。机器必须了解到当他是第三人的视角的时候,看到另外一个人在打高尔夫球,跟他实际上自己去打高尔夫球的时候,看到的视野显然是不一样的。但他怎么把他是第三人的时间所观察到的经验把它 generalize 到他是第一人称视角的时候所采取的行为,这就需要用到`Third Person Imitation Learning`的技术。
|
||||
其实还有很多相关的研究,举例来说,你在教机械手臂的时候,要注意就是也许机器看到的视野跟人看到的视野是不太一样的。在刚才那个例子里面,人跟机器的动作是一样的。但是在未来的世界里面,也许机器是看着人的行为学的。刚才是人拉着,假设你要让机器学会打高尔夫球,在刚才的例子里面就是人拉着机器人手臂去打高尔夫球,但是在未来有没有可能机器就是看着人打高尔夫球,它自己就学会打高尔夫球了呢?但这个时候,要注意的事情是机器的视野跟它真正去采取这个行为的时候的视野是不一样的。机器必须了解到当它是第三人的视角的时候,看到另外一个人在打高尔夫球,跟它实际上自己去打高尔夫球的时候,看到的视野显然是不一样的。但它怎么把它是第三人的时间所观察到的经验把它 generalize 到它是第一人称视角的时候所采取的行为,这就需要用到`Third Person Imitation Learning`的技术。
|
||||
|
||||

|
||||
|
||||
这个怎么做呢?它的技术其实也是不只是用到 Imitation Learning,他用到了 `Domain-Adversarial Training`。我们在讲 Domain-Adversarial Training 的时候,我们有讲说这也是一个GAN 的技术。那我们希望今天有一个 extractor,有两个不同 domain 的image,通过 feature extractor 以后,没有办法分辨出他来自哪一个 domain。其实第一人称视角和第三人称视角,Imitation Learning 用的技术其实也是一样的,希望 learn 一个 Feature Extractor,机器在第三人称的时候跟他在第一人称的时候看到的视野其实是一样的,就是把最重要的东西抽出来就好了。
|
||||
这个怎么做呢?它的技术其实也是不只是用到 Imitation Learning,它用到了 `Domain-Adversarial Training`。我们在讲 Domain-Adversarial Training 的时候,我们有讲说这也是一个GAN 的技术。那我们希望今天有一个 extractor,有两个不同 domain 的image,通过 feature extractor 以后,没有办法分辨出它来自哪一个 domain。其实第一人称视角和第三人称视角,Imitation Learning 用的技术其实也是一样的,希望 learn 一个 Feature Extractor,机器在第三人称的时候跟它在第一人称的时候看到的视野其实是一样的,就是把最重要的东西抽出来就好了。
|
||||
|
||||
## Recap: Sentence Generation & Chat-bot
|
||||

|
||||
|
||||
在讲 Sequence GAN 的时候,我们有讲过 Sentence Generation 跟 Chat-bot。那其实 Sentence Generation 或 Chat-bot 也可以想成是 Imitation Learning。机器在 imitate 人写的句子,你在写句子的时候,你写下去的每一个 word 都想成是一个 action,所有的 word 合起来就是一个 episode。举例来说, sentence generation 里面,你会给机器看很多人类写的文字。你要让机器学会写诗,那你就要给他看唐诗三百首。人类写的文字其实就是 expert 的 demonstration。每一个词汇其实就是一个 action。今天,你让机器做Sentence Generation 的时候其实就是在 imitate expert 的trajectory。Chat-bot 也是一样,在Chat-bot 里面你会收集到很多人互动对话的纪录,那些就是 expert 的 demonstration。
|
||||
在讲 Sequence GAN 的时候,我们有讲过 Sentence Generation 跟 Chat-bot。那其实 Sentence Generation 或 Chat-bot 也可以想成是 Imitation Learning。机器在 imitate 人写的句子,你在写句子的时候,你写下去的每一个 word 都想成是一个 action,所有的 word 合起来就是一个 episode。举例来说, sentence generation 里面,你会给机器看很多人类写的文字。你要让机器学会写诗,那你就要给它看唐诗三百首。人类写的文字其实就是 expert 的 demonstration。每一个词汇其实就是一个 action。今天,你让机器做Sentence Generation 的时候其实就是在 imitate expert 的trajectory。Chat-bot 也是一样,在Chat-bot 里面你会收集到很多人互动对话的纪录,那些就是 expert 的 demonstration。
|
||||
|
||||
如果我们今天单纯用 maximum likelihood 这个技术来 maximize 会得到 likelihood,这个其实就是behavior cloning。我们今天做 behavior cloning 就是看到一个 state,接下来预测我们会得到什么样的 action。看到一个state,然后有一个 ground truth 告诉机器说什么样的 action 是最好的。在做 likelihood 的时候也是一样,given sentence 已经产生的部分。接下来 machine 要 predict 说接下来要写哪一个word 才是最好的。所以,其实 maximum likelihood 在做Sequence generation 的时候,它对应到 Imitation Learning 里面就是 behavior cloning。只有 maximum likelihood 是不够的,我们想要用 Sequence GAN,其实 Sequence GAN 就是对应到 Inverse Reinforcement Learning,Inverse Reinforcement Learning 就是一种 GAN 的技术。你把 Inverse Reinforcement Learning 的技术放在 Sentence generation,放到 Chat-bot 里面,其实就是 Sequence GAN 跟它的种种的变形。
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## 离散动作 vs. 连续动作
|
||||
|
||||

|
||||
离散动作与连续动作是相对的概念,一个是可数的,一个是不可数的。 在 CartPole 环境中,可以有向左推小车、向右推小车两个动作。在 Frozen Lake 环境中,小乌龟可以有上下左右四个动作。在 Atari 的 Pong 游戏中,游戏有6个按键的动作可以输出。
|
||||
离散动作与连续动作是相对的概念,一个是可数的,一个是不可数的。 在 CartPole 环境中,可以有向左推小车、向右推小车两个动作。在 Frozen Lake 环境中,小乌龟可以有上下左右四个动作。在 Atari 的 Pong 游戏中,游戏有 6 个按键的动作可以输出。
|
||||
|
||||
但在实际情况中,经常会遇到连续动作空间的情况,也就是输出的动作是不可数的。比如说推小车力的大小、 选择下一时刻方向盘的转动角度或者四轴飞行器的四个螺旋桨给的电压的大小等等。
|
||||
|
||||
@@ -34,19 +34,19 @@
|
||||
|
||||
DDPG 是 DQN 的一个扩展的版本。在 DDPG 的训练中,它借鉴了 DQN 的技巧:目标网络和经验回放。经验回放这一块跟 DQN 是一样的,但 target network 这一块的更新跟 DQN 有点不一样。
|
||||

|
||||
提出 DDPG 是为了让 DQN 可以扩展到连续的动作空间,就是我们刚才提到的小车速度、角度和电压的电流量这样的连续值。所以 DDPG 直接在 DQN 基础上加了一个策略网络,就是蓝色的这个,用来直接输出动作值。所以 DDPG 需要一边学习 Q网络,一边学习策略网络。Q网络的参数用 $w$ 来表示。策略网络的参数用 $\theta$ 来表示。我们称这样的结构为 `Actor-Critic` 的结构。
|
||||
提出 DDPG 是为了让 DQN 可以扩展到连续的动作空间,就是我们刚才提到的小车速度、角度和电压的电流量这样的连续值。所以 DDPG 直接在 DQN 基础上加了一个策略网络,就是蓝色的这个,用来直接输出动作值。所以 DDPG 需要一边学习 Q 网络,一边学习策略网络。Q 网络的参数用 $w$ 来表示。策略网络的参数用 $\theta$ 来表示。我们称这样的结构为 `Actor-Critic` 的结构。
|
||||
|
||||

|
||||
通俗的去解释一下 Actor-Critic 的结构,
|
||||
|
||||
* 策略网络扮演的就是 actor 的角色,它负责对外展示输出,输出舞蹈动作。Q网络就是评论家(critic),它会在每一个 step 都对 actor 输出的动作做一个评估,打一个分,估计一下它做一次的 action 未来能有多少收益,也就是去估计这个 actor 输出的这个 action 的 Q值大概是多少,即 $Q_w(s,a)$。 Actor 就需要根据舞台目前的状态来做出一个 action。
|
||||
* 策略网络扮演的就是 actor 的角色,它负责对外展示输出,输出舞蹈动作。Q 网络就是评论家(critic),它会在每一个 step 都对 actor 输出的动作做一个评估,打一个分,估计一下它做一次的 action 未来能有多少收益,也就是去估计这个 actor 输出的这个 action 的 Q 值大概是多少,即 $Q_w(s,a)$。 Actor 就需要根据舞台目前的状态来做出一个 action。
|
||||
|
||||
* 评论家就是评委,它需要根据舞台现在的状态和演员输出的 action 这两个值对 actor 刚刚的表现去打一个分数 $Q_w(s,a)$。所以 actor 就是要根据评委的打分来调整自己的策略。也就是更新 actor 的神经网络参数 $\theta$, 争取下次可以做得更好。而 critic 就是要根据观众的反馈,也就是环境的反馈 reward 来调整自己的打分策略,也就是要更新 critic 的神经网络的参数 $w$ ,它的目标是要让每一场表演都获得观众尽可能多的欢呼声跟掌声,也就是要最大化未来的总收益。
|
||||
* 最开始训练的时候,这两个神经网络参数是随机的。所以 critic 最开始是随机打分的,然后 actor 也跟着乱来,就随机表演,随机输出动作。但是由于我们有环境反馈的 reward 存在,所以 critic 的评分会越来越准确,也会评判的那个 actor 的表现会越来越好。既然 actor 是一个神经网络,是我们希望训练好的这个策略网络,那我们就需要计算梯度来去更新优化它里面的参数 $\theta$ 。简单的说,我们希望调整 actor 的网络参数,使得评委打分尽可能得高。注意,这里的 actor 是不管观众的,它只关注评委,它就是迎合评委的打分,打的这个 $Q_w(s,a)$ 而已。
|
||||
|
||||

|
||||
|
||||
接下来就是类似 DQN。DQN 的最佳策略是想要学出一个很好的 Q网络。 学好这个网络之后,我们希望选取的那个动作使你的 Q 值最大。DDPG 的目的也是为了求解让 Q 值最大的那个 action。Actor 只是为了迎合评委的打分而已,所以用来优化策略网络的梯度就是要最大化这个 Q 值,所以构造的 loss 函数就是让 Q 取一个负号。我们写代码的时候要做的就是把这个 loss 函数扔到优化器里面,它就会自动最小化 loss,也就是最大化这个 Q。然后这里注意,除了策略网络要做优化,DDPG 还有一个 Q 网络也要优化。评委一开始也不知道怎么评分,它也是在一步一步的学习当中,慢慢地去给出准确的打分。那我们优化 Q网络的方法其实跟 DQN 优化 Q网络的方法是一模一样的,我们用真实的 reward $r$ 和下一步的 Q 即 Q' 来去拟合未来的收益也就是 Q_target。
|
||||
接下来就是类似 DQN。DQN 的最佳策略是想要学出一个很好的 Q 网络。 学好这个网络之后,我们希望选取的那个动作使你的 Q 值最大。DDPG 的目的也是为了求解让 Q 值最大的那个 action。Actor 只是为了迎合评委的打分而已,所以用来优化策略网络的梯度就是要最大化这个 Q 值,所以构造的 loss 函数就是让 Q 取一个负号。我们写代码的时候要做的就是把这个 loss 函数扔到优化器里面,它就会自动最小化 loss,也就是最大化这个 Q。然后这里注意,除了策略网络要做优化,DDPG 还有一个 Q 网络也要优化。评委一开始也不知道怎么评分,它也是在一步一步的学习当中,慢慢地去给出准确的打分。那我们优化 Q 网络的方法其实跟 DQN 优化 Q 网络的方法是一模一样的,我们用真实的 reward $r$ 和下一步的 Q 即 Q' 来去拟合未来的收益也就是 Q_target。
|
||||
|
||||
然后让 Q 网络的输出去逼近这个 Q_target。所以构造的 loss function 就是直接求这两个值的均方差。构造好 loss 后,之后我们就扔进去那个优化器,让它自动去最小化 loss 就好了。
|
||||
|
||||
@@ -54,7 +54,7 @@ DDPG 是 DQN 的一个扩展的版本。在 DDPG 的训练中,它借鉴了 DQN
|
||||
|
||||
那我们把两个网络的 loss function 就可以构造出来。我们可以看到策略网络的 loss function 是一个复合函数。我们把那个 $a = \mu_\theta(s)$ 代进去,最终策略网络要优化的是策略网络的参数 $\theta$ 。
|
||||
|
||||
Q 网络要优化的是那个 Q 的输出 $Q_w(s,a)$ 和那个 Q_target 之间的一个均方差。但是 Q网络的优化存在一个和 DQN 一模一样的问题就是它后面的这个 Q_target 是不稳定的。这个在之前的 DQN 有讲过。后面的 $Q_{\bar{w}}\left(s^{\prime}, a^{\prime}\right)$ 也是不稳定的。因为 $Q_{\bar{w}}\left(s^{\prime}, a^{\prime}\right)$ 也是一个预估的值。为了稳定这个 Q_target。DDPG 分别给 Q网络和策略网络都搭建了 target network,专门就是为了用来稳定这个 Q_target。
|
||||
Q 网络要优化的是那个 Q 的输出 $Q_w(s,a)$ 和那个 Q_target 之间的一个均方差。但是 Q网络的优化存在一个和 DQN 一模一样的问题就是它后面的这个 Q_target 是不稳定的。这个在之前的 DQN 有讲过。后面的 $Q_{\bar{w}}\left(s^{\prime}, a^{\prime}\right)$ 也是不稳定的。因为 $Q_{\bar{w}}\left(s^{\prime}, a^{\prime}\right)$ 也是一个预估的值。为了稳定这个 Q_target。DDPG 分别给 Q 网络和策略网络都搭建了 target network,专门就是为了用来稳定这个 Q_target。
|
||||
|
||||
|
||||
target Q 网络就为了来计算 Q_target 里面的 $Q_{\bar{w}}\left(s^{\prime}, a^{\prime}\right)$。然后 $Q_{\bar{w}}\left(s^{\prime}, a^{\prime}\right)$ 里面的需要的 next action $a'$ 就是通过 target_P 网络来去输出,即 $a^{\prime}=\mu_{\bar{\theta}}\left(s^{\prime}\right)$。
|
||||
|
||||
@@ -97,7 +97,7 @@ $$
|
||||
|
||||

|
||||
|
||||
Bellman Equation 定义了状态之间的迭代关系。假设有一个马尔可夫转移矩阵是右边这个样子。Bellman Equation 描述的就是当前状态到未来状态的一个转移。假设我们当前是在 $s_1$, 那么它只可能去到三个未来的状态:有 0.1 的概率留在它当前这个位置,有 0.2 的概率去到 $s_2$ 状态,有 0.7 的概率去到 $s_4$ 的状态,所以我们要把这个转移乘以它未来的状态的价值,再加上它的 immediate reward 就会得到它当前状态的价值。所以 Bellman Equation 定义的就是当前状态跟未来状态的一个迭代的关系。
|
||||
**Bellman Equation 定义了状态之间的迭代关系。**假设有一个马尔可夫转移矩阵是右边这个样子。Bellman Equation 描述的就是当前状态到未来状态的一个转移。假设我们当前是在 $s_1$, 那么它只可能去到三个未来的状态:有 0.1 的概率留在它当前这个位置,有 0.2 的概率去到 $s_2$ 状态,有 0.7 的概率去到 $s_4$ 的状态,所以我们要把这个转移乘以它未来的状态的价值,再加上它的 immediate reward 就会得到它当前状态的价值。所以 Bellman Equation 定义的就是当前状态跟未来状态的一个迭代的关系。
|
||||
|
||||

|
||||
|
||||
@@ -113,7 +113,7 @@ $$
|
||||
|
||||

|
||||
|
||||
接下来我们来求解这个价值函数。我们有这个迭代的方法来解这种状态非常多的 MRP。这里迭代的方法就有几种,比如说我们可以通过动态规划的方法,也可以通过蒙特卡罗的办法,就通过采样的办法去计算它。另外我们也可以通过 Temporal-Difference Learning 的那个办法。这个 `Temporal-Difference Learning` 叫 `TD Leanring`,就是动态规划和蒙特卡罗的一个结合。
|
||||
接下来我们来求解这个价值函数。我们有迭代的方法来解这种状态非常多的 MRP。这里迭代的方法就有几种,比如说我们可以通过动态规划的方法,也可以通过蒙特卡罗的办法,就通过采样的办法去计算它。另外我们也可以通过 Temporal-Difference Learning 的那个办法。这个 `Temporal-Difference Learning` 叫 `TD Leanring`,就是动态规划和蒙特卡罗的一个结合。
|
||||
|
||||

|
||||
|
||||
@@ -214,7 +214,7 @@ $$
|
||||
|
||||

|
||||
|
||||
首先看一下 policy evaluation,就是当给定一个 MDP 的时候,我们有一个事先定好的 policy。那么我们可以获得多少的价值。就对于当前这个策略,我们可以得到多大的这个 value function。这里一个方法是说,我们直接把这个 Bellman Expectation Backup,这个等式拿出来,变成一个迭代的过程,这样反复迭代直到收敛。这样就可以计算它的一个过程。这个迭代过程是可以看作是 `synchronous backup` 的一个过程。等式 14 说的就是这个 Bellman Expectation Backup,我们把这个转换成一个动态规划的迭代。当我们得到上一时刻的 $v_t$ 的时候,那我们下一时刻就通过这个递归的一个关系,我们可以推出下一时刻的这个值,那么反复去迭代它,最后它的值就是从 $v_1,v_2$,到最后收敛过后这个值。这个值就是我们当前给定的 policy 对应的价值函数。
|
||||
首先看一下 policy evaluation,就是当给定一个 MDP 的时候,我们有一个事先定好的 policy。那么我们可以获得多少的价值。就对于当前这个策略,我们可以得到多大的这个 value function。这里一个方法是说,我们直接把这个 Bellman Expectation Backup,这个等式拿出来,变成一个迭代的过程,这样反复迭代直到收敛。这样就可以计算它的一个过程。这个迭代过程是可以看作是 `synchronous backup` 的一个过程。等式 14 说的就是这个 Bellman Expectation Backup,我们把这个转换成一个动态规划的迭代。当我们得到上一时刻的 $v_t$ 的时候,那我们下一时刻就通过这个递归的一个关系,我们可以推出下一时刻的这个值,那么反复去迭代它,最后它的值就是从 $v_1,v_2$ 到最后收敛过后这个值。这个值就是我们当前给定的 policy 对应的价值函数。
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# 贪吃蛇
|
||||
|
||||
贪吃蛇是一个起源于1976年的街机游戏 Blockade,玩家控制蛇上下左右吃到食物并将身体增长,吃到食物后移动速度逐渐加快,直到碰到墙体或者蛇的身体算游戏结束。
|
||||
|
||||

|
||||
|
||||
如图,本次任务整个游戏版面大小为560X560,绿色部分就是我们的智能体贪吃蛇,红色方块就是食物,墙位于四周,一旦食物被吃掉,会在下一个随机位置刷出新的食物。蛇的每一节以及食物的大小为40X40,除开墙体(厚度也为40),蛇可以活动的范围为480X480,也就是12X12的栅格。环境的状态等信息如下:
|
||||
|
||||
* state:为一个元组,包含(adjoining_wall_x, adjoining_wall_y, food_dir_x, food_dir_y, adjoining_body_top, adjoining_body_bottom, adjoining_body_left, adjoining_body_right).
|
||||
|
||||
* [adjoining_wall_x, adjoining_wall_y]:提供蛇头是否与墙体相邻的信息,具体包含9个状态
|
||||
|
||||
adjoining_wall_x:0表示x轴方向蛇头无墙体相邻,1表示有墙在蛇头左边,2表示有墙在右边adjoining_wall_y:0表示y轴方向蛇头无墙体相邻,1表示有墙在蛇头上边,2表示有墙在下边
|
||||
|
||||
注意[0,0]也包括蛇跑出480X480范围的情况
|
||||
|
||||
* [food_dir_x, food_dir_y]:表示食物与蛇头的位置关系
|
||||
|
||||
food_dir_x:0表示食物与蛇头同在x轴上,1表示食物在蛇头左侧(不一定相邻),2表示在右边
|
||||
|
||||
food_dir_y:0表示食物与蛇头同在y轴上,1表示食物在蛇头上面,2表示在下面
|
||||
|
||||
* [adjoining_body_top, adjoining_body_bottom, adjoining_body_left, adjoining_body_right]:用以检查蛇的身体是否在蛇头的附近
|
||||
|
||||
adjoining_body_top:1表示蛇头上边有蛇的身体,0表示没有
|
||||
|
||||
adjoining_body_bottom:1表示蛇头下边有蛇的身体,0表示没有
|
||||
|
||||
adjoining_body_left:1表示蛇头左边有蛇的身体,0表示没有
|
||||
|
||||
adjoining_body_right:1表示蛇头右边有蛇的身体,0表示没有
|
||||
|
||||
* action:即上下左右
|
||||
|
||||
* reward:如果吃到食物给一个+1的reward,如果蛇没了就-1,其他情况给-0.1的reward
|
||||
|
||||
## 任务要求
|
||||
|
||||
设计一个Q网络用于学习snake游戏,并绘制reward以及滑动平均后的reward随epiosde的变化曲线图并记录超参数写成报告。
|
||||
|
||||
|
||||
|
||||
[参考代码](https://github.com/datawhalechina/leedeeprl-notes/tree/master/codes/snake)
|
||||
@@ -12,13 +12,15 @@
|
||||
|
||||

|
||||
|
||||
PPO 是 policy gradient 的一个变形,它是现在 OpenAI default reinforcement learning 的 algorithm。
|
||||
PPO 是 policy gradient 的一个变形,它是现在 OpenAI 默认的 reinforcement learning 的 algorithm。
|
||||
|
||||
$$
|
||||
\nabla \bar{R}_{\theta}=E_{\tau \sim p_{\theta}(\tau)}\left[R(\tau) \nabla \log p_{\theta}(\tau)\right]
|
||||
$$
|
||||
|
||||
问题是上面这个 update 的式子中的 $E_{\tau \sim p_{\theta}(\tau)}$ 应该是你现在的 policy $\theta$ 所 sample 出来的 trajectory $\tau$ 做 expectation。一旦 update 了参数,从 $\theta$ 变成 $\theta'$ ,$p_\theta(\tau)$这个概率就不对了,之前 sample 出来的 data 就变的不能用了。所以 policy gradient 是一个会花很多时间来 sample data 的 algorithm,你会发现大多数时间都在 sample data,agent 去跟环境做互动以后,接下来就要 update 参数。你只能 update 参数一次。接下来你就要重新再去 collect data, 然后才能再次update 参数,这显然是非常花时间的。所以我们想要从 on-policy 变成 off-policy。 这样做就可以用另外一个 policy, 另外一个 actor $\theta'$ 去跟环境做互动。用 $\theta'$ collect 到的 data 去训练 $\theta$。假设我们可以用 $\theta'$ collect 到的 data 去训练 $\theta$,意味着说我们可以把 $\theta'$ collect 到的data 用非常多次。我们可以执行 gradient ascent 好几次,我们可以 update 参数好几次, 都只要用同一笔 data 就好了。因为假设 $\theta$ 有能力学习另外一个 actor $\theta'$ 所 sample 出来的 data 的话, 那 $\theta'$ 就只要sample 一次,也许s ample 多一点的data, 让 $\theta$ 去 update 很多次,这样就会比较有效率。
|
||||
问题是上面这个 update 的式子中的 $E_{\tau \sim p_{\theta}(\tau)}$ 应该是你现在的 policy $\theta$ 所 sample 出来的 trajectory $\tau$ 做 expectation。一旦 update 了参数,从 $\theta$ 变成 $\theta'$ ,$p_\theta(\tau)$这个概率就不对了,之前 sample 出来的 data 就变的不能用了。所以 policy gradient 是一个会花很多时间来 sample data 的 algorithm,你会发现大多数时间都在 sample data,agent 去跟环境做互动以后,接下来就要 update 参数。你只能 update 参数一次。接下来你就要重新再去 collect data, 然后才能再次update 参数。
|
||||
|
||||
这显然是非常花时间的,所以我们想要从 on-policy 变成 off-policy。 这样做就可以用另外一个 policy, 另外一个 actor $\theta'$ 去跟环境做互动。用 $\theta'$ collect 到的 data 去训练 $\theta$。假设我们可以用 $\theta'$ collect 到的 data 去训练 $\theta$,意味着说我们可以把 $\theta'$ collect 到的 data 用非常多次,我们可以执行 gradient ascent 好几次,我们可以 update 参数好几次, 都只要用同一笔 data 就好了。因为假设 $\theta$ 有能力学习另外一个 actor $\theta'$ 所 sample 出来的 data 的话, 那 $\theta'$ 就只要 sample 一次,也许 sample 多一点的 data, 让 $\theta$ 去 update 很多次,这样就会比较有效率。
|
||||
|
||||
### Importance Sampling
|
||||
|
||||
@@ -63,9 +65,9 @@ $\operatorname{Var}_{x \sim p}[f(x)]$ 和 $\operatorname{Var}_{x \sim q}\left[f(
|
||||
|
||||

|
||||
|
||||
举个例子,当 $p(x)$ 和 $q(x)$ 差距很大的时候,会发生什么样的问题。假设蓝线是 $p(x)$ 的distribution,绿线是 $q(x)$ 的 distribution,红线是 $f(x)$。如果我们要计算$f(x)$的期望值,从 $p(x)$ 这个distribution 做 sample 的话,那显然 $E_{x \sim p}[f(x)]$ 是负的,因为左边那块区域 $p(x)$ 的概率很高,所以要 sample 的话,都会 sample 到这个地方,而 $f(x)$ 在这个区域是负的, 所以理论上这一项算出来会是负。
|
||||
举个例子,当 $p(x)$ 和 $q(x)$ 差距很大的时候,会发生什么样的问题。假设蓝线是 $p(x)$ 的distribution,绿线是 $q(x)$ 的 distribution,红线是 $f(x)$。如果我们要计算$f(x)$的期望值,从 $p(x)$ 这个 distribution 做 sample 的话,那显然 $E_{x \sim p}[f(x)]$ 是负的,因为左边那块区域 $p(x)$ 的概率很高,所以要 sample 的话,都会 sample 到这个地方,而 $f(x)$ 在这个区域是负的, 所以理论上这一项算出来会是负。
|
||||
|
||||
接下来我们改成从 $q(x)$ 这边做 sample,因为 $q(x)$ 在右边这边的概率比较高,所以如果你sample 的点不够的话,那你可能都只 sample 到右侧。如果你都只 sample 到右侧的话,你会发现说,算 $E_{x \sim q}\left[f(x) \frac{p(x)}{q(x)}\right]$这一项,搞不好还应该是正的。你这边 sample 到这些点,然后你去计算它们的 $f(x) \frac{p(x)}{q(x)}$都是正的,所以你 sample 到这些点都是正的。 你取期望值以后,也都是正的。为什么会这样,因为你 sample 的次数不够多,因为假设你 sample 次数很少,你只能 sample 到右边这边。左边这边虽然概率很低,但也不是没有可能被 sample 到。假设你今天好不容易 sample 到左边的点,因为左边的点,$p(x)$ 和 $q(x)$ 是差很多的, 这边 $p(x)$ 很小,$q(x)$ 很大。今天 $f(x)$ 好不容易终于 sample 到一个负的,这个负的就会被乘上一个非常大的 weight ,这样就可以平衡掉刚才那边一直 sample 到 positive 的 value 的情况。最终你算出这一项的期望值,终究还是负的。但前提是你要 sample 够多次,这件事情才会发生。但有可能 sample 不够,$E_{x \sim p}[f(x)]$跟$E_{x \sim q}\left[f(x) \frac{p(x)}{q(x)}\right]$就有可能有很大的差距。这就是 importance sampling 的问题。
|
||||
接下来我们改成从 $q(x)$ 这边做 sample,因为 $q(x)$ 在右边这边的概率比较高,所以如果你 sample 的点不够的话,那你可能都只 sample 到右侧。如果你都只 sample 到右侧的话,你会发现说,算 $E_{x \sim q}\left[f(x) \frac{p(x)}{q(x)}\right]$这一项,搞不好还应该是正的。你这边 sample 到这些点,然后你去计算它们的 $f(x) \frac{p(x)}{q(x)}$ 都是正的,所以你 sample 到这些点都是正的。 你取期望值以后,也都是正的。为什么会这样,因为你 sample 的次数不够多,因为假设你 sample 次数很少,你只能 sample 到右边这边。左边这边虽然概率很低,但也不是没有可能被 sample 到。假设你今天好不容易 sample 到左边的点,因为左边的点,$p(x)$ 和 $q(x)$ 是差很多的, 这边 $p(x)$ 很小,$q(x)$ 很大。今天 $f(x)$ 好不容易终于 sample 到一个负的,这个负的就会被乘上一个非常大的 weight ,这样就可以平衡掉刚才那边一直 sample 到 positive 的 value 的情况。最终你算出这一项的期望值,终究还是负的。但前提是你要 sample 够多次,这件事情才会发生。但有可能 sample 不够,$E_{x \sim p}[f(x)]$ 跟 $E_{x \sim q}\left[f(x) \frac{p(x)}{q(x)}\right]$ 就有可能有很大的差距。这就是 importance sampling 的问题。
|
||||
|
||||

|
||||
|
||||
@@ -73,7 +75,7 @@ $\operatorname{Var}_{x \sim p}[f(x)]$ 和 $\operatorname{Var}_{x \sim q}\left[f(
|
||||
|
||||
现在我们不用 $\theta$ 去跟环境做互动,假设有另外一个 policy $\theta'$,它就是另外一个actor。它的工作是他要去做demonstration,$\theta'$ 的工作是要去示范给$\theta$ 看。它去跟环境做互动,告诉 $\theta$ 说,它跟环境做互动会发生什么事。然后,借此来训练$\theta$。我们要训练的是 $\theta$ ,$\theta'$ 只是负责做 demo,负责跟环境做互动。
|
||||
|
||||
我们现在的 $\tau$ 是从 $\theta'$ sample 出来的,是拿 $\theta'$ 去跟环境做互动。所以 sample 出来的 $\tau$ 是从 $\theta'$ sample 出来的,这两个distribution 不一样。但没有关系,假设你本来是从 p 做 sample,但你发现你不能够从 p 做sample,所以我们不拿$\theta$ 去跟环境做互动。你可以把 p 换 q,然后在后面这边补上一个 importance weight。现在的状况就是一样,把 $\theta$ 换成 $\theta'$ 后,要补上一个importance weight $\frac{p_{\theta}(\tau)}{p_{\theta^{\prime}}(\tau)}$。这个 importance weight 就是某一个 trajectory $\tau$ 用 $\theta$ 算出来的概率除以这个 trajectory $\tau$,用 $\theta'$ 算出来的概率。这一项是很重要的,因为今天你要 learn 的是 actor $\theta$ 和 $\theta'$ 是不太一样的。$\theta'$ 会见到的情形跟 $\theta$ 见到的情形不见得是一样的,所以中间要做一个修正的项。
|
||||
我们现在的 $\tau$ 是从 $\theta'$ sample 出来的,是拿 $\theta'$ 去跟环境做互动。所以 sample 出来的 $\tau$ 是从 $\theta'$ sample 出来的,这两个distribution 不一样。但没有关系,假设你本来是从 p 做 sample,但你发现你不能够从 p 做sample,所以我们不拿$\theta$ 去跟环境做互动。你可以把 p 换 q,然后在后面这边补上一个 importance weight。现在的状况就是一样,把 $\theta$ 换成 $\theta'$ 后,要补上一个 importance weight $\frac{p_{\theta}(\tau)}{p_{\theta^{\prime}}(\tau)}$。这个 importance weight 就是某一个 trajectory $\tau$ 用 $\theta$ 算出来的概率除以这个 trajectory $\tau$,用 $\theta'$ 算出来的概率。这一项是很重要的,因为今天你要 learn 的是 actor $\theta$ 和 $\theta'$ 是不太一样的。$\theta'$ 会见到的情形跟 $\theta$ 见到的情形不见得是一样的,所以中间要做一个修正的项。
|
||||
|
||||
Q: 现在的 data 是从 $\theta'$ sample 出来的,从 $\theta$ 换成 $\theta'$ 有什么好处呢?
|
||||
|
||||
@@ -86,9 +88,9 @@ $$
|
||||
=E_{\left(s_{t}, a_{t}\right) \sim \pi_{\theta}}\left[A^{\theta}\left(s_{t}, a_{t}\right) \nabla \log p_{\theta}\left(a_{t}^{n} | s_{t}^{n}\right)\right]
|
||||
$$
|
||||
|
||||
我们用 $\theta$ 这个 actor 去 sample 出 $s_t$ 跟 $a_t$,sample 出 state 跟 action 的 pair,我们会计算这个 state 跟 action pair 它的 advantage, 就是它有多好。$A^{\theta}\left(s_{t}, a_{t}\right)$就是 accumulated 的 reward 减掉 bias,这一项就是估测出来的。它要估测的是,在 state $s_t$ 采取 action $a_t$ 是好的,还是不好的。那接下来后面会乘上$\nabla \log p_{\theta}\left(a_{t}^{n} | s_{t}^{n}\right)$,也就是说如果$A^{\theta}\left(s_{t}, a_{t}\right)$是正的,就要增加概率, 如果是负的,就要减少概率。
|
||||
我们用 $\theta$ 这个 actor 去 sample 出 $s_t$ 跟 $a_t$,sample 出 state 跟 action 的 pair,我们会计算这个 state 跟 action pair 它的 advantage, 就是它有多好。$A^{\theta}\left(s_{t}, a_{t}\right)$就是 accumulated 的 reward 减掉 bias,这一项就是估测出来的。它要估测的是,在 state $s_t$ 采取 action $a_t$ 是好的,还是不好的。那接下来后面会乘上 $\nabla \log p_{\theta}\left(a_{t}^{n} | s_{t}^{n}\right)$,也就是说如果 $A^{\theta}\left(s_{t}, a_{t}\right)$是正的,就要增加概率, 如果是负的,就要减少概率。
|
||||
|
||||
那现在用了 importance sampling 的技术把 on-policy 变成 off-policy,就从 $\theta$ 变成 $\theta'$。所以现在$s_t$、$a_t$ 是$\theta'$ ,另外一个actor 跟环境互动以后所 sample 到的data。 但是拿来训练要调整参数是 model $\theta$。因为 $\theta'$ 跟 $\theta$ 是不同的 model,所以你要做一个修正的项。这项修正的项,就是用 importance sampling 的技术,把 $s_t$、$a_t$ 用 $\theta$ sample 出来的概率除掉$s_t$、$a_t$ 用 $\theta'$ sample 出来的概率。
|
||||
那现在用了 importance sampling 的技术把 on-policy 变成 off-policy,就从 $\theta$ 变成 $\theta'$。所以现在 $s_t$、$a_t$ 是$\theta'$ ,另外一个actor 跟环境互动以后所 sample 到的data。 但是拿来训练要调整参数是 model $\theta$。因为 $\theta'$ 跟 $\theta$ 是不同的 model,所以你要做一个修正的项。这项修正的项,就是用 importance sampling 的技术,把 $s_t$、$a_t$ 用 $\theta$ sample 出来的概率除掉$s_t$、$a_t$ 用 $\theta'$ sample 出来的概率。
|
||||
|
||||
$$
|
||||
=E_{\left(s_{t}, a_{t}\right) \sim \pi_{\theta^{\prime}}}\left[\frac{P_{\theta}\left(s_{t}, a_{t}\right)}{P_{\theta^{\prime}}\left(s_{t}, a_{t}\right)} A^{\theta}\left(s_{t}, a_{t}\right) \nabla \log p_{\theta}\left(a_{t}^{n} | s_{t}^{n}\right)\right]
|
||||
@@ -118,7 +120,7 @@ $$
|
||||
|
||||
但是 $p_{\theta}(a_t|s_t)$很好算。你手上有 $\theta$ 这个参数,它就是个 network。你就把$s_t$ 带进去,$s_t$ 就是游戏画面,你把游戏画面带进去,它就会告诉你某一个 state 的 $a_t$ 概率是多少。我们其实有个 policy 的 network,把 $s_t$ 带进去,它会告诉我们每一个 $a_t$ 的概率是多少。所以 $\frac{p_{\theta}\left(a_{t} | s_{t}\right)}{p_{\theta^{\prime}}\left(a_{t} | s_{t}\right)}$ 这一项,你只要知道$\theta$ 和 $\theta'$ 的参数就可以算。
|
||||
|
||||
现在我们得到一个新的objective function。
|
||||
现在我们得到一个新的 objective function。
|
||||
|
||||
$$
|
||||
J^{\theta^{\prime}}(\theta)=E_{\left(s_{t}, a_{t}\right) \sim \pi_{\theta^{\prime}}}\left[\frac{p_{\theta}\left(a_{t} | s_{t}\right)}{p_{\theta^{\prime}}\left(a_{t} | s_{t}\right)} A^{\theta^{\prime}}\left(s_{t}, a_{t}\right)\right]
|
||||
@@ -138,8 +140,6 @@ $$
|
||||
|
||||
然后你用 $\theta'$ 去跟环境做互动,sample 出 $s_t$、$a_t$ 以后,你要去计算 $s_t$ 跟 $a_t$ 的 advantage,然后你再去把它乘上 $\frac{p_{\theta}\left(a_{t} | s_{t}\right)}{p_{\theta^{\prime}}\left(a_{t} | s_{t}\right)}$。$\frac{p_{\theta}\left(a_{t} | s_{t}\right)}{p_{\theta^{\prime}}\left(a_{t} | s_{t}\right)}$ 是好算的,$A^{\theta^{\prime}}\left(s_{t}, a_{t}\right)$ 可以从这个 sample 的结果里面去估测出来的,所以 $J^{\theta^{\prime}}(\theta)$ 是可以算的。实际上在 update 参数的时候,就是按照式(1) 来 update 参数。
|
||||
|
||||
|
||||
|
||||
## PPO
|
||||
|
||||

|
||||
@@ -168,13 +168,18 @@ A: 这边我是直接把 KL divergence 当做一个 function,input 是 $\theta
|
||||
|
||||

|
||||
|
||||
我们来看一下 `PPO1` 的 algorithm。它先 initial 一个 policy 的参数$\theta^0$。然后在每一个 iteration 里面呢,你要用参数$\theta^k$,$\theta^k$ 就是你在前一个 training 的 iteration得到的 actor 的参数,你用 $\theta^k$ 去跟环境做互动,sample 到一大堆 state-action 的pair。
|
||||
我们来看一下 `PPO1` 的 algorithm。它先 initial 一个 policy 的参数 $\theta^0$。然后在每一个 iteration 里面呢,你要用参数 $\theta^k$,$\theta^k$ 就是你在前一个 training 的 iteration得到的 actor 的参数,你用 $\theta^k$ 去跟环境做互动,sample 到一大堆 state-action 的pair。
|
||||
|
||||
然后你根据 $\theta^k$ 互动的结果,估测一下$A^{\theta^{k}}\left(s_{t}, a_{t}\right)$。然后你就 apply PPO 的 optimization 的 formulation。但跟原来的policy gradient 不一样,原来的 policy gradient 只能 update 一次参数,update 完以后,你就要重新 sample data。但是现在不用,你拿 $\theta^k$ 去跟环境做互动,sample 到这组 data 以后,你可以让 $\theta$ update 很多次,想办法去 maximize objective function。这边 $\theta$ update 很多次没有关系,因为我们已经有做 importance sampling,所以这些experience,这些 state-action 的 pair 是从 $\theta^k$ sample 出来的没有关系。$\theta$ 可以 update 很多次,它跟 $\theta^k$ 变得不太一样也没有关系,你还是可以照样训练 $\theta$。
|
||||
|
||||

|
||||
|
||||
在 PPO 的 paper 里面还有一个 `adaptive KL divergence`,这边会遇到一个问题就是 $\beta$ 要设多少,它就跟那个regularization 一样。regularization 前面也要乘一个weight,所以这个 KL divergence 前面也要乘一个 weight,但 $\beta$ 要设多少呢?所以有个动态调整 $\beta$ 的方法。在这个方法里面呢,你先设一个 KL divergence,你可以接受的最大值。然后假设你发现说你 optimize 完这个式子以后,KL divergence 的项太大,那就代表说后面这个 penalize 的 term 没有发挥作用,那就把 $\beta$ 调大。那另外你定一个 KL divergence 的最小值。如果发现 optimize 完上面这个式子以后,KL divergence 比最小值还要小,那代表后面这一项的效果太强了,你怕他只弄后面这一项,那 $\theta$ 跟 $\theta^k$ 都一样,这不是你要的,所以你这个时候你叫要减少 $\beta$。所以 $\beta$ 是可以动态调整的。这个叫做 `adaptive KL penalty`。
|
||||
在 PPO 的 paper 里面还有一个 `adaptive KL divergence`。这边会遇到一个问题就是 $\beta$ 要设多少,它就跟那个regularization 一样。regularization 前面也要乘一个 weight,所以这个 KL divergence 前面也要乘一个 weight,但 $\beta$ 要设多少呢?所以有个动态调整 $\beta$ 的方法。
|
||||
|
||||
* 在这个方法里面呢,你先设一个 KL divergence,你可以接受的最大值。然后假设你发现说你 optimize 完这个式子以后,KL divergence 的项太大,那就代表说后面这个 penalize 的 term 没有发挥作用,那就把 $\beta$ 调大。
|
||||
* 那另外你定一个 KL divergence 的最小值。如果发现 optimize 完上面这个式子以后,KL divergence 比最小值还要小,那代表后面这一项的效果太强了,你怕他只弄后面这一项,那 $\theta$ 跟 $\theta^k$ 都一样,这不是你要的,所以你这个时候你叫要减少 $\beta$。
|
||||
|
||||
所以 $\beta$ 是可以动态调整的。这个叫做 `adaptive KL penalty`。
|
||||
|
||||

|
||||
|
||||
@@ -216,7 +221,7 @@ $$
|
||||

|
||||
|
||||
如果 A 小于0 的话,取最小的以后,就得到红色的这一条线。
|
||||
这一个式子虽然看起来有点复杂,实现起来是蛮简单的,因为这个式子想要做的事情就是希望 $p_{\theta}(a_{t} | s_{t})$ 跟$p_{\theta^k}(a_{t} | s_{t})$,也就是你拿来做 demonstration 的那个model, 跟你实际上 learn 的 model,在 optimize 以后不要差距太大。那你要怎么让它做到不要差距太大呢?
|
||||
这一个式子虽然看起来有点复杂,实现起来是蛮简单的,因为这个式子想要做的事情就是希望 $p_{\theta}(a_{t} | s_{t})$ 跟$p_{\theta^k}(a_{t} | s_{t})$,也就是你拿来做 demonstration 的 model, 跟你实际上 learn 的 model,在 optimize 以后不要差距太大。那你要怎么让它做到不要差距太大呢?
|
||||
|
||||
如果 A 大于 0,也就是某一个 state-action 的pair 是好的。那我们希望增加这个 state-action pair 的概率。也就是说,我们想要让 $p_{\theta}(a_{t} | s_{t})$ 越大越好,但它跟 $p_{\theta^k}(a_{t} | s_{t})$ 的比值不可以超过 $1+\varepsilon$。如果超过 $1+\varepsilon$ 的话,就没有 benefit 了。红色的线就是我们的 objective function,我们希望 objective 越大越好,我们希望 $p_{\theta}(a_{t} | s_{t})$ 越大越好。但是$\frac{p_{\theta}\left(a_{t} | s_{t}\right)}{p_{\theta^{k}}\left(a_{t} | s_{t}\right)}$只要大过 $1+\varepsilon$,就没有 benefit 了。
|
||||
|
||||
@@ -227,7 +232,7 @@ $$
|
||||
* 假设这个 advantage 是正的,我们希望 $p_{\theta}(a_{t} | s_{t})$ 越大越好。假设这个 action 是好的,我们当然希望这个 action 被采取的概率越大越好。所以假设 $p_{\theta}(a_{t} | s_{t})$ 还比 $p_{\theta^k}(a_{t} | s_{t})$ 小,那就尽量把它挪大,但只要大到 $1+\varepsilon$ 就好。
|
||||
* 负的时候也是一样,如果某一个 state-action pair 是不好的,我们希望把 $p_{\theta}(a_{t} | s_{t})$ 减小。如果 $p_{\theta}(a_{t} | s_{t})$ 比$p_{\theta^k}(a_{t} | s_{t})$ 还大,那你就尽量把它压小,压到$\frac{p_{\theta}\left(a_{t} | s_{t}\right)}{p_{\theta^{k}}\left(a_{t} | s_{t}\right)}$是$1-\epsilon$ 的时候就停了,就不要再压得更小。
|
||||
|
||||
这样的好处就是, 你不会让 $p_{\theta}(a_{t} | s_{t})$ 跟 $p_{\theta^k}(a_{t} | s_{t})$ 差距太大。要 implement 这个东西,很简单。
|
||||
这样的好处就是, 你不会让 $p_{\theta}(a_{t} | s_{t})$ 跟 $p_{\theta^k}(a_{t} | s_{t})$ 差距太大。要实现这个东西,很简单。
|
||||
|
||||

|
||||
上图是 PPO 跟其它方法的比较。Actor-Critic 和 A2C+Trust Region 方法是 actor-critic based 的方法。PPO 是紫色线的方法,这边每张图就是某一个 RL 的任务,你会发现说在多数的 cases 里面,PPO 都是不错的,不是最好的,就是第二好的。
|
||||
|
||||
@@ -2,42 +2,42 @@
|
||||
## Double DQN
|
||||

|
||||
|
||||
接下来要讲的是 train Q-learning 的一些 tip。第一个 tip 是做 `Double DQN`。那为什么要有 Double DQN 呢?因为在实现上,你会发现 Q value 往往是被高估的。上图来自于 Double DQN 的原始 paper,它想要显示的结果就是 Q value 往往是被高估的。这边有 4 个不同的小游戏,横轴是 training 的时间,红色锯齿状一直在变的线就是 Q-function 对不同的 state estimate 出来的平均 Q value,有很多不同的 state,每个 state 你都 sample 一下,然后算它们的 Q value,把它们平均起来。红色这一条线,它在training 的过程中会改变,但它是不断上升的,为什么它不断上升,因为 Q-function 是 depend on 你的 policy 的。learn 的过程中你的 policy 越来越强,所以你得到 Q value 会越来越大。在同一个state, 你得到 expected reward 会越来越大,所以 general 而言,这个值都是上升的,但这是 Q-network 估测出来的值。
|
||||
接下来要讲的是 train Q-learning 的一些 tip。第一个 tip 是做 `Double DQN`。那为什么要有 Double DQN 呢?因为在实现上,你会发现 Q value 往往是被高估的。上图来自于 Double DQN 的原始 paper,它想要显示的结果就是 Q value 往往是被高估的。这边有 4 个不同的小游戏,横轴是 training 的时间,红色锯齿状一直在变的线就是 Q-function 对不同的 state estimate 出来的平均 Q value,有很多不同的 state,每个 state 你都 sample 一下,然后算它们的 Q value,把它们平均起来。红色这一条线,它在 training 的过程中会改变,但它是不断上升的,为什么它不断上升,因为 Q-function 是 depend on 你的 policy 的。learn 的过程中你的 policy 越来越强,所以你得到 Q value 会越来越大。在同一个 state, 你得到 expected reward 会越来越大,所以 general 而言,这个值都是上升的,但这是 Q-network 估测出来的值。
|
||||
|
||||
接下来你真地去算它,那怎么真地去算?你有那个policy,然后真的去玩那个游戏。就玩很多次,玩个一百万次。然后就去真地估说,在某一个 state, 你会得到的 Q value 到底有多少。你会得到说在某一个 state,采取某一个 action。你接下来会得到 accumulated reward 是多少。你会发现估测出来的值是远比实际的值大。在每一个游戏都是这样,都大很多。所以今天要 propose Double DQN 的方法,它可以让估测的值跟实际的值是比较接近的。我们先看它的结果,蓝色的锯齿状的线是Double DQN 的 Q-network 所估测出来的Q value,蓝色的无锯齿状的线是真正的Q value,你会发现它们是比较接近的。 用 network 估测出来的就不用管它,比较没有参考价值。用 Double DQN 得出来真正的 accumulated reward,在这 3 个case 都是比原来的DQN 高的,代表 Double DQN learn 出来那个 policy 比较强。所以它实际上得到的reward 是比较大的。虽然一般的 DQN 的 Q-network 高估了自己会得到的reward,但实际上它得到的 reward 是比较低的。
|
||||
接下来你真地去算它,那怎么真地去算?你有那个 policy,然后真的去玩那个游戏。就玩很多次,玩个一百万次。然后就去真地估说,在某一个 state, 你会得到的 Q value 到底有多少。你会得到说在某一个 state,采取某一个 action。你接下来会得到 accumulated reward 是多少。你会发现估测出来的值是远比实际的值大。在每一个游戏都是这样,都大很多。所以今天要 propose Double DQN 的方法,它可以让估测的值跟实际的值是比较接近的。我们先看它的结果,蓝色的锯齿状的线是Double DQN 的 Q-network 所估测出来的 Q value,蓝色的无锯齿状的线是真正的 Q value,你会发现它们是比较接近的。 用 network 估测出来的就不用管它,比较没有参考价值。用 Double DQN 得出来真正的 accumulated reward,在这 3 个 case 都是比原来的 DQN 高的,代表 Double DQN learn 出来那个 policy 比较强。所以它实际上得到的 reward 是比较大的。虽然一般的 DQN 的 Q-network 高估了自己会得到的 reward,但实际上它得到的 reward 是比较低的。
|
||||
|
||||

|
||||
|
||||
Q: 为什么 Q value 总是被高估了呢?
|
||||
|
||||
A: 因为实际上在做的时候,是要让左边这个式子跟右边这个 target 越接近越好。那你会发现说,target 的值很容易一不小心就被设得太高。因为在算这个 target 的时候,我们实际上在做的事情是看哪一个a 可以得到最大的Q value,就把它加上去,就变成我们的target。所以假设有某一个 action 得到的值是被高估的。
|
||||
A: 因为实际上在做的时候,是要让左边这个式子跟右边这个 target 越接近越好。那你会发现说,target 的值很容易一不小心就被设得太高。因为在算这个 target 的时候,我们实际上在做的事情是看哪一个 a 可以得到最大的 Q value,就把它加上去,就变成我们的 target。所以假设有某一个 action 得到的值是被高估的。
|
||||
|
||||
举例来说, 现在有 4 个 actions,本来其实它们得到的值都是差不多的,它们得到的reward 都是差不多的。但是在estimate 的时候,那毕竟是个network。所以estimate 的时候是有误差的。所以假设今天是第一个action它被高估了,假设绿色的东西代表是被高估的量,它被高估了,那这个target 就会选这个action。然后就会选这个高估的Q value来加上$r_t$,来当作你的target。如果第4 个action 被高估了,那就会选第4 个action 来加上$r_t$ 来当作你的target value。所以你总是会选那个Q value 被高估的,你总是会选那个reward 被高估的action 当作这个max 的结果去加上$r_t$ 当作你的target。所以你的target 总是太大。
|
||||
举例来说, 现在有 4 个 actions,本来其实它们得到的值都是差不多的,它们得到的 reward 都是差不多的。但是在estimate 的时候,那毕竟是个 network。所以 estimate 的时候是有误差的。所以假设今天是第一个 action 被高估了,假设绿色的东西代表是被高估的量,它被高估了,那这个 target 就会选这个 action。然后就会选这个高估的 Q value来加上$r_t$,来当作你的 target。如果第 4 个 action 被高估了,那就会选第 4 个 action 来加上 $r_t$ 来当作你的 target value。所以你总是会选那个 Q value 被高估的,你总是会选那个 reward 被高估的 action 当作这个 max 的结果去加上 $r_t$ 当作你的 target。所以你的 target 总是太大。
|
||||
|
||||

|
||||
Q: 怎么解决这target 总是太大的问题呢?
|
||||
|
||||
A: 在 Double DQN 里面,选 action 的 Q-function 跟算 value 的 Q-function,不是同一个。在原来的DQN 里面,你穷举所有的 a,把每一个a 都带进去, 看哪一个 a 可以给你的 Q value 最高,那你就把那个 Q value 加上$r_t$。但是在 Double DQN 里面,你有两个 Q-network,第一个 Q-network,决定哪一个 action 的 Q value 最大,你用第一个 Q-network 去带入所有的 a,去看看哪一个Q value 最大。然后你决定你的action 以后,你的 Q value 是用 $Q'$ 算出来的,这样子有什么好处呢?为什么这样就可以避免 over estimate 的问题呢?因为今天假设我们有两个 Q-function,假设第一个Q-function 它高估了它现在选出来的action a,那没关系,只要第二个Q-function $Q'$ 没有高估这个action a 的值,那你算出来的,就还是正常的值。假设反过来是 $Q'$ 高估了某一个action 的值,那也没差, 因为反正只要前面这个Q 不要选那个action 出来就没事了。这个就是 Double DQN 神奇的地方。
|
||||
A: 在 Double DQN 里面,选 action 的 Q-function 跟算 value 的 Q-function,不是同一个。在原来的DQN 里面,你穷举所有的 a,把每一个 a 都带进去, 看哪一个 a 可以给你的 Q value 最高,那你就把那个 Q value 加上 $r_t$。但是在 Double DQN 里面,你有两个 Q-network,第一个 Q-network,决定哪一个 action 的 Q value 最大,你用第一个 Q-network 去带入所有的 a,去看看哪一个 Q value 最大。然后你决定你的 action 以后,你的 Q value 是用 $Q'$ 算出来的,这样子有什么好处呢?为什么这样就可以避免 over estimate 的问题呢?因为今天假设我们有两个 Q-function,假设第一个 Q-function 它高估了它现在选出来的 action a,那没关系,只要第二个 Q-function $Q'$ 没有高估这个 action a 的值,那你算出来的,就还是正常的值。假设反过来是 $Q'$ 高估了某一个 action 的值,那也没差, 因为反正只要前面这个 Q 不要选那个 action 出来就没事了。这个就是 Double DQN 神奇的地方。
|
||||
|
||||
Q: 哪来 Q 跟 $Q'$ 呢?哪来两个 network 呢?
|
||||
|
||||
A: 在实现上,你有两个 Q-network, 一个是 target 的 Q-network,一个是真正你会 update 的 Q-network。所以在 Double DQN 里面,你的实现方法会是拿你会 update 参数的那个 Q-network 去选action,然后你拿target 的network,那个固定住不动的network 去算value。而 Double DQN 相较于原来的 DQN 的更改是最少的,它几乎没有增加任何的运算量,连新的network 都不用,因为你原来就有两个network 了。你唯一要做的事情只有,本来你在找最大的a 的时候,你在决定这个a 要放哪一个的时候,你是用$Q'$ 来算,你是用target network 来算,现在改成用另外一个会 update 的 Q-network 来算。
|
||||
A: 在实现上,你有两个 Q-network, 一个是 target 的 Q-network,一个是真正你会 update 的 Q-network。所以在 Double DQN 里面,你的实现方法会是拿你会 update 参数的那个 Q-network 去选 action,然后你拿 target 的network,那个固定住不动的 network 去算 value。而 Double DQN 相较于原来的 DQN 的更改是最少的,它几乎没有增加任何的运算量,连新的 network 都不用,因为你原来就有两个 network 了。你唯一要做的事情只有,本来你在找最大的a 的时候,你在决定这个 a 要放哪一个的时候,你是用 $Q'$ 来算,你是用 target network 来算,现在改成用另外一个会 update 的 Q-network 来算。
|
||||
|
||||
假如你今天只选一个tip 的话,正常人都是 implement Double DQN,因为很容易实现。
|
||||
假如你今天只选一个 tip 的话,正常人都是 implement Double DQN,因为很容易实现。
|
||||
|
||||
## Dueling DQN
|
||||

|
||||
第二个 tip 是 `Dueling DQN`。其实 Dueling DQN 也蛮好做的,相较于原来的DQN。它唯一的差别是改了network 的架构,Dueling DQN 唯一做的事情是改network 的架构。Q-network 就是input state,output 就是每一个action 的Q value。dueling DQN 唯一做的事情,是改了network 的架构,其它的算法,你都不要去动它。
|
||||
第二个 tip 是 `Dueling DQN`。其实 Dueling DQN 也蛮好做的,相较于原来的 DQN。它唯一的差别是改了 network 的架构,Dueling DQN 唯一做的事情是改 network 的架构。Q-network 就是 input state,output 就是每一个 action 的Q value。Dueling DQN 唯一做的事情是改了 network 的架构,其它的算法,你都不要去动它。
|
||||
|
||||
Q: Dueling DQN 是怎么改了network 的架构呢?
|
||||
Q: Dueling DQN 是怎么改了 network 的架构呢?
|
||||
|
||||
A: 本来的DQN 就是直接output Q value 的值。现在这个dueling 的DQN,就是下面这个network 的架构。它不直接output Q value 的值,它分成两条path 去运算,第一个path,它算出一个scalar,这个scalar 我们叫做$V(s)$。因为它跟input s 是有关系,所以叫做$V(s)$,$V(s)$ 是一个scalar。下面这个会output 一个vector,这个vector 叫做$A(s,a)$。下面这个vector,它是每一个action 都有一个value。然后你再把这两个东西加起来,就得到你的Q value。
|
||||
A: 本来的 DQN 就是直接 output Q value 的值。现在这个 dueling 的 DQN,就是下面这个 network 的架构。它不直接output Q value 的值,它分成两条 path 去运算,第一个 path 算出一个 scalar,这个 scalar 我们叫做 $V(s)$。因为它跟input s 是有关系,所以叫做 $V(s)$,$V(s)$ 是一个 scalar。下面这个会 output 一个 vector,这个 vector 叫做 $A(s,a)$。下面这个 vector,它是每一个 action 都有一个 value。然后你再把这两个东西加起来,就得到你的 Q value。
|
||||
|
||||

|
||||
|
||||
Q: 这么改有什么好处?
|
||||
|
||||
A : 那我们假设说,原来的$Q(s,a)$ 就是一个table。我们假设 state 是discrete 的,实际上state 不是discrete 的。那为了说明方便,我们假设就是只有4 个不同的state,只有3 个不同的action,所以$Q(s,a)$ 你可以看作是一个table。
|
||||
A : 那我们假设说,原来的 $Q(s,a)$ 就是一个 table。我们假设 state 是 discrete 的,实际上 state 不是 discrete 的。那为了说明方便,我们假设就是只有 4 个不同的state,只有 3 个不同的action,所以 $Q(s,a)$ 你可以看作是一个 table。
|
||||
|
||||
我们知道:
|
||||
$$
|
||||
@@ -46,20 +46,20 @@ $$
|
||||
|
||||
其中
|
||||
|
||||
* $V(s)$ 是对不同的state 它都有一个值。
|
||||
* $A(s,a)$ 它是对不同的state,不同的action都有一个值。
|
||||
* $V(s)$ 是对不同的 state 它都有一个值。
|
||||
* $A(s,a)$ 它是对不同的 state,不同的 action 都有一个值。
|
||||
|
||||
你把这个 V 的值加到 A 的每一个 column 就会得到Q 的值。把 2+1,2+(-1),2+0,就得到 3,1,2,以此类推。
|
||||
你把这个 V 的值加到 A 的每一个 column 就会得到 Q 的值。把 2+1,2+(-1),2+0,就得到 3,1,2,以此类推。
|
||||
|
||||
如上图所示,假设说你在train network 的时候,target 是希望这一个值变成 4,这一个值变成 0。但是你实际上能更改的并不是Q 的值,你的network 更改的是V 跟A 的值。根据network 的参数,V 跟A 的值output 以后,就直接把它们加起来,所以其实不是更动Q 的值。然后在learn network 的时候,假设你希望这边的值,这个3 增加1 变成 4,这个-1 增加1 变成 0。最后你在train network 的时候,network 可能会说,我们就不要动这个 A 的值,就动 V 的值,把 V 的值从0 变成 1。把0 变成1 有什么好处呢?你会发现说,本来你只想动这两个东西的值,那你会发现说,这个第三个值也动了,-2 变成 -1。所以有可能说你在某一个state,你明明只sample 到这2 个action,你没sample 到第三个action,但是你其实也可以更改第三个action 的Q value。这样的好处就是你不需要把所有的 state-action pair 都sample 过,你可以用比较efficient 的方式去 estimate Q value 出来。因为有时候你update 的时候,不一定是update 下面这个table。而是只update 了$V(s)$,但update $V(s)$ 的时候,只要一改所有的值就会跟着改。这是一个比较有效率的方法,去使用你的data,这个是Dueling DQN 可以带给我们的好处。
|
||||
如上图所示,假设说你在 train network 的时候,target 是希望这一个值变成 4,这一个值变成 0。但是你实际上能更改的并不是 Q 的值,你的 network 更改的是 V 跟 A 的值。根据 network 的参数,V 跟 A 的值 output 以后,就直接把它们加起来,所以其实不是更动 Q 的值。然后在 learn network 的时候,假设你希望这边的值,这个 3 增加 1 变成 4,这个 -1 增加 1 变成 0。最后你在 train network 的时候,network 可能会说,我们就不要动这个 A 的值,就动 V 的值,把 V 的值从 0 变成 1。把 0 变成 1 有什么好处呢?你会发现说,本来你只想动这两个东西的值,那你会发现说,这个第三个值也动了,-2 变成 -1。所以有可能说你在某一个 state,你明明只 sample 到这 2 个 action,你没 sample 到第三个 action,但是你其实也可以更改第三个 action 的 Q value。这样的好处就是你不需要把所有的 state-action pair 都 sample 过,你可以用比较 efficient 的方式去 estimate Q value 出来。因为有时候你 update 的时候,不一定是 update 下面这个 table。而是只 update 了 $V(s)$,但 update $V(s)$ 的时候,只要一改所有的值就会跟着改。这是一个比较有效率的方法,去使用你的 data,这个是 Dueling DQN 可以带给我们的好处。
|
||||
|
||||
那可是接下来有人就会问说会不会最后learn 出来的结果是说,反正machine 就学到 V 永远都是 0,然后反正A 就等于 Q,那你就没有得到任何 Dueling DQN 可以带给你的好处, 就变成跟原来的DQN 一模一样。为了避免这个问题,实际上你要给 A 一些constrain,让update A 其实比较麻烦,让network 倾向于会想要去用V 来解问题。
|
||||
那可是接下来有人就会问说会不会最后 learn 出来的结果是说,反正 machine 就学到 V 永远都是 0,然后反正 A 就等于 Q,那你就没有得到任何 Dueling DQN 可以带给你的好处, 就变成跟原来的 DQN 一模一样。为了避免这个问题,实际上你要给 A 一些 constrain,让 update A 其实比较麻烦,让 network 倾向于会想要去用 V 来解问题。
|
||||
|
||||
举例来说,你可以看原始的文献,它有不同的constrain 。那一个最直觉的constrain 是你必须要让这个A 的每一个column 的和都是 0,所以看我这边举的例子,我的column 的和都是 0。那如果这边column 的和都是 0,这边这个V 的值,你就可以想成是上面 Q 的每一个column 的平均值。这个平均值,加上这些值才会变成是Q 的value。所以今天假设你发现说你在update 参数的时候,你是要让整个row 一起被update。你就不会想要update 这边,因为你不会想要update A这个matrix。因为 A 这个matrix 的每一个column 的和都要是 0,所以你没有办法说,让这边的值,通通都+1,这件事是做不到的。因为它的constrain 就是你的和永远都是要 0。所以不可以都+1,这时候就会强迫network 去update V 的值,然后让你可以用比较有效率的方法,去使用你的data。
|
||||
举例来说,你可以看原始的文献,它有不同的 constrain 。那一个最直觉的 constrain 是你必须要让这个 A 的每一个column 的和都是 0,所以看我这边举的例子,我的 column 的和都是 0。那如果这边 column 的和都是 0,这边这个 V 的值,你就可以想成是上面 Q 的每一个 column 的平均值。这个平均值,加上这些值才会变成是 Q 的 value。所以今天假设你发现说你在 update 参数的时候,你是要让整个 row 一起被 update。你就不会想要 update 这边,因为你不会想要update A 这个 matrix。因为 A 这个 matrix 的每一个 column 的和都要是 0,所以你没有办法说,让这边的值,通通都+1,这件事是做不到的。因为它的 constrain 就是你的和永远都是要 0。所以不可以都 +1,这时候就会强迫 network 去update V 的值,然后让你可以用比较有效率的方法,去使用你的 data。
|
||||
|
||||

|
||||
|
||||
实现时,你要给这个 A 一个 constrain。举个例子,假设你有 3 个actions,然后在这边 output 的 vector 是7 3 2,你在把这个 A 跟这个 V 加起来之前,先加一个normalization,就好像做那个layer normalization 一样。加一个normalization,这个normalization 做的事情就是把 7+3+2 加起来等于 12,12/3 = 4。然后把这边通通减掉 4,变成 3, -1, 2。再把 3, -1, 2 加上 1.0,得到最后的Q value。这个normalization 的 step 就是 network 的其中一部分,在train 的时候,你从这边也是一路 back propagate 回来的,只是 normalization 是没有参数的,它只是一个normalization 的operation。把它可以放到network 里面,跟network 的其他部分 jointly trained,这样 A 就会有比较大的 constrain。这样network 就会给它一些benefit, 倾向于去update V 的值,这个是Dueling DQN。
|
||||
实现时,你要给这个 A 一个 constrain。举个例子,假设你有 3 个actions,然后在这边 output 的 vector 是 $[7,3,2]^{\mathrm{T}}$,你在把这个 A 跟这个 V 加起来之前,先加一个 normalization,就好像做那个 layer normalization 一样。加一个normalization,这个 normalization 做的事情就是把 7+3+2 加起来等于 12,12/3 = 4。然后把这边通通减掉 4,变成 3, -1, 2。再把 3, -1, 2 加上 1.0,得到最后的 Q value。这个 normalization 的 step 就是 network 的其中一部分,在 train 的时候,你从这边也是一路 back propagate 回来的,只是 normalization 是没有参数的,它只是一个 normalization 的operation。把它可以放到 network 里面,跟 network 的其他部分 jointly trained,这样 A 就会有比较大的 constrain。这样 network 就会给它一些 benefit, 倾向于去 update V 的值,这个是 Dueling DQN。
|
||||
|
||||
|
||||
## Prioritized Experience Replay
|
||||
@@ -71,41 +71,41 @@ $$
|
||||
## Balance between MC and TD
|
||||
|
||||

|
||||
另外一个可以做的方法是,你可以balance MC 跟TD。MC 跟 TD 的方法各自有各自的优劣。我们怎么在MC 跟TD 里面取得一个平衡呢?我们的做法是这样,在TD 里面,在某一个state $s_t$采取某一个action $a_t$ 得到 reward $r_t$,接下来跳到那一个state $s_{t+1}$。但是我们可以不要只存一个step 的data,我们存 N 个step 的data。
|
||||
另外一个可以做的方法是,你可以 balance MC 跟 TD。MC 跟 TD 的方法各自有各自的优劣。我们怎么在 MC 跟 TD 里面取得一个平衡呢?我们的做法是这样,在 TD 里面,在某一个 state $s_t$ 采取某一个 action $a_t$ 得到 reward $r_t$,接下来跳到那一个 state $s_{t+1}$。但是我们可以不要只存一个 step 的data,我们存 N 个 step 的 data。
|
||||
|
||||
我们记录在$s_t$ 采取$a_t$,得到$r_t$,会跳到什么样$s_t$。一直纪录到在第N 个step 以后,在$s_{t+N}$采取$a_{t+N}$得到 reward $r_{t+N}$,跳到$s_{t+N+1}$的这个经验,通通把它存下来。实际上你今天在做update 的时候, 在做你 Q-network learning 的时候,你的learning 的方法会是这样,你learning 的时候,要让 $Q(s_t,a_t)$ 跟你的target value 越接近越好。$\hat{Q}$ 所计算的不是$s_{t+1}$,而是$s_{t+N+1}$的。你会把 N 个step 以后的state 丢进来,去计算 N 个step 以后,你会得到的reward。要算 target value 的话,要再加上multi-step 的reward $\sum_{t^{\prime}=t}^{t+N} r_{t^{\prime}}$ ,multi-step 的 reward 是从时间 t 一直到 t+N 的 N 个reward 的和。然后希望你的 $Q(s_t,a_t)$ 和 target value 越接近越好。
|
||||
我们记录在 $s_t$ 采取 $a_t$,得到 $r_t$,会跳到什么样 $s_t$。一直纪录到在第 N 个step 以后,在 $s_{t+N}$采取 $a_{t+N}$得到 reward $r_{t+N}$,跳到 $s_{t+N+1}$ 的这个经验,通通把它存下来。实际上你今天在做 update 的时候, 在做 Q-network learning 的时候,你的 learning 的方法会是这样,你 learning 的时候,要让 $Q(s_t,a_t)$ 跟你的 target value 越接近越好。$\hat{Q}$ 所计算的不是 $s_{t+1}$,而是 $s_{t+N+1}$的。你会把 N 个step 以后的 state 丢进来,去计算 N 个 step 以后,你会得到的 reward。要算 target value 的话,要再加上 multi-step 的 reward $\sum_{t^{\prime}=t}^{t+N} r_{t^{\prime}}$ ,multi-step 的 reward 是从时间 t 一直到 t+N 的 N 个reward 的和。然后希望你的 $Q(s_t,a_t)$ 和 target value 越接近越好。
|
||||
|
||||
你会发现说这个方法就是 MC 跟 TD 的结合。因此它就有 MC 的好处跟坏处,也有 TD 的好处跟坏处。如果看它的这个好处的话,因为我们现在 sample 了比较多的step,之前是只sample 了一个step, 所以某一个step 得到的data 是real 的,接下来都是Q value 估测出来的。现在sample 比较多step,sample N 个step 才估测value,所以估测的部分所造成的影响就会比小。当然它的坏处就跟MC 的坏处一样,因为你的 r 比较多项,你把 N 项的 r 加起来,你的variance 就会比较大。但是你可以去调这个N 的值,去在variance 跟不精确的 Q 之间取得一个平衡。N 就是一个hyper parameter,你要调这个N 到底是多少,你是要多 sample 三步,还是多 sample 五步。
|
||||
你会发现说这个方法就是 MC 跟 TD 的结合。因此它就有 MC 的好处跟坏处,也有 TD 的好处跟坏处。如果看它的这个好处的话,因为我们现在 sample 了比较多的 step,之前是只 sample 了一个 step, 所以某一个 step 得到的 data 是 real 的,接下来都是 Q value 估测出来的。现在 sample 比较多 step,sample N 个 step 才估测 value,所以估测的部分所造成的影响就会比小。当然它的坏处就跟 MC 的坏处一样,因为你的 r 比较多项,你把 N 项的 r 加起来,你的 variance 就会比较大。但是你可以去调这个 N 的值,去在 variance 跟不精确的 Q 之间取得一个平衡。N 就是一个 hyper parameter,你要调这个 N 到底是多少,你是要多 sample 三步,还是多 sample 五步。
|
||||
|
||||
## Noisy Net
|
||||

|
||||
有一个技术是要improve 这个exploration 这件事,我们之前讲的Epsilon Greedy 这样的 exploration 是在action 的space 上面加noise,但是有另外一个更好的方法叫做`Noisy Net`,它是在参数的space 上面加noise。Noisy Net 的意思是说,每一次在一个episode 开始的时候,在你要跟环境互动的时候,你就把你的Q-function 拿出来,Q-function 里面其实就是一个network ,就变成你把那个network 拿出来,在network 的每一个参数上面加上一个Gaussian noise。那你就把原来的Q-function 变成$\tilde{Q}$ 。因为$\hat{Q}$ 已经用过,$\hat{Q}$ 是那个target network,我们用 $\tilde{Q}$ 来代表一个`Noisy Q-function`。我们把每一个参数都可能都加上一个Gaussian noise,就得到一个新的network 叫做$\tilde{Q}$。这边要注意在每个episode 开始的时候,开始跟环境互动之前,我们就 sample network。接下来你就会用这个固定住的 noisy network 去玩这个游戏,直到游戏结束,你才重新再去sample 新的noise。OpenAI 跟 Deep mind 又在同时间 propose 一模一样的方法,通通都publish 在ICLR 2018,两篇paper 的方法就是一样的。不一样的地方是,他们用不同的方法,去加noise。OpenAI 加的方法好像比较简单,他就直接加一个 Gaussian noise 就结束了,就你把每一个参数,每一个weight都加一个Gaussian noise 就结束了。Deep mind 做比较复杂,他们的noise 是由一组参数控制的,也就是说 network 可以自己决定说它那个noise 要加多大,但是概念就是一样的。总之就是把你的Q-function的里面的那个network 加上一些noise,把它变得有点不一样,跟原来的Q-function 不一样,然后拿去跟环境做互动。两篇paper 里面都有强调说,你这个参数虽然会加noise,但在同一个episode 里面你的参数就是固定的,你是在换episode, 玩第二场新的游戏的时候,你才会重新sample noise,在同一场游戏里面就是同一个noisy Q-network 在玩那一场游戏,这件事非常重要。为什么这件事非常重要呢?因为这是导致了Noisy Net 跟原来的Epsilon Greedy 或其它在action 做sample 方法的本质上的差异。
|
||||
有一个技术是要 improve 这个 exploration 这件事,我们之前讲的 Epsilon Greedy 这样的 exploration 是在 action 的space 上面加 noise,但是有另外一个更好的方法叫做`Noisy Net`,它是在参数的 space 上面加 noise。Noisy Net 的意思是说,每一次在一个 episode 开始的时候,在你要跟环境互动的时候,你就把你的 Q-function 拿出来,Q-function 里面其实就是一个 network ,就变成你把那个 network 拿出来,在 network 的每一个参数上面加上一个 Gaussian noise。那你就把原来的 Q-function 变成$\tilde{Q}$ 。因为$\hat{Q}$ 已经用过,$\hat{Q}$ 是那个 target network,我们用 $\tilde{Q}$ 来代表一个`Noisy Q-function`。我们把每一个参数都可能都加上一个 Gaussian noise,就得到一个新的 network 叫做 $\tilde{Q}$。这边要注意在每个episode 开始的时候,开始跟环境互动之前,我们就 sample network。接下来你就会用这个固定住的 noisy network 去玩这个游戏,直到游戏结束,你才重新再去 sample 新的 noise。OpenAI 跟 Deep mind 又在同时间 propose 一模一样的方法,通通都 publish 在 ICLR 2018,两篇 paper 的方法就是一样的。不一样的地方是,他们用不同的方法,去加noise。OpenAI 加的方法好像比较简单,他就直接加一个 Gaussian noise 就结束了,就你把每一个参数,每一个 weight都加一个 Gaussian noise 就结束了。Deep mind 做比较复杂,他们的 noise 是由一组参数控制的,也就是说 network 可以自己决定说它那个 noise 要加多大,但是概念就是一样的。总之就是把你的 Q-function 的里面的那个 network 加上一些 noise,把它变得有点不一样,跟原来的 Q-function 不一样,然后拿去跟环境做互动。两篇 paper 里面都有强调说,你这个参数虽然会加 noise,但在同一个 episode 里面你的参数就是固定的,你是在换 episode, 玩第二场新的游戏的时候,你才会重新 sample noise,在同一场游戏里面就是同一个 noisy Q-network 在玩那一场游戏,这件事非常重要。为什么这件事非常重要呢?因为这是导致了 Noisy Net 跟原来的 Epsilon Greedy 或其它在 action 做 sample 方法的本质上的差异。
|
||||
|
||||

|
||||
|
||||
有什么样本质上的差异呢?在原来sample 的方法,比如说Epsilon Greedy 里面,就算是给同样的state,你的agent 采取的action 也不一定是一样的。因为你是用sample 决定的,given 同一个state,要根据 Q-function 的network,你会得到一个action,你 sample 到random,你会采取另外一个action。所以 given 同样的state,如果你今天是用Epsilon Greedy 的方法,它得到的 action 是不一样的。但实际上你的policy 并不是这样运作的啊。在一个真实世界的policy,给同样的state,他应该会有同样的回应。而不是给同样的state,它其实有时候吃 Q-function,然后有时候又是随机的,所以这是一个不正常的action,是在真实的情况下不会出现的action。但是如果你是在Q-function 上面去加noise 的话, 就不会有这个情形。因为如果你今天在Q-function 上加 noise,在Q-function 的network 的参数上加noise,那在整个互动的过程中,在同一个episode 里面,它的network 的参数总是固定的,所以看到同样的state,或是相似的state,就会采取同样的action,那这个是比较正常的。在paper 里面有说,这个叫做 `state-dependent exploration`,也就是说你虽然会做 explore 这件事, 但是你的explore 是跟state 有关系的,看到同样的state, 你就会采取同样的exploration 的方式,而 noisy 的 action 只是随机乱试。但如果你是在参数下加noise,那在同一个episode 里面,里面你的参数是固定的。那你就是有系统地在尝试,每次会试说,在某一个state,我都向左试试看。然后再下一次在玩这个同样游戏的时候,看到同样的state,你就说我再向右试试看,你是有系统地在explore 这个环境。
|
||||
有什么样本质上的差异呢?在原来 sample 的方法,比如说 Epsilon Greedy 里面,就算是给同样的 state,你的 agent 采取的 action 也不一定是一样的。因为你是用 sample 决定的,given 同一个 state,要根据 Q-function 的 network,你会得到一个 action,你 sample 到 random,你会采取另外一个 action。所以 given 同样的 state,如果你今天是用 Epsilon Greedy 的方法,它得到的 action 是不一样的。但实际上你的 policy 并不是这样运作的啊。在一个真实世界的 policy,给同样的 state,他应该会有同样的回应。而不是给同样的 state,它其实有时候吃 Q-function,然后有时候又是随机的,所以这是一个不正常的 action,是在真实的情况下不会出现的 action。但是如果你是在 Q-function 上面去加 noise 的话, 就不会有这个情形。因为如果你今天在 Q-function 上加 noise,在 Q-function 的 network 的参数上加 noise,那在整个互动的过程中,在同一个 episode 里面,它的 network 的参数总是固定的,所以看到同样的 state,或是相似的 state,就会采取同样的 action,那这个是比较正常的。在 paper 里面有说,这个叫做 `state-dependent exploration`,也就是说你虽然会做 explore 这件事, 但是你的 explore 是跟 state 有关系的,看到同样的 state, 你就会采取同样的 exploration 的方式,而 noisy 的 action 只是随机乱试。但如果你是在参数下加 noise,那在同一个 episode 里面,里面你的参数是固定的。那你就是有系统地在尝试,每次会试说,在某一个 state,我都向左试试看。然后再下一次在玩这个同样游戏的时候,看到同样的 state,你就说我再向右试试看,你是有系统地在 explore 这个环境。
|
||||
|
||||
## Distributional Q-function
|
||||

|
||||
|
||||
还有一个技巧叫做 Distributional Q-function。我们不讲它的细节,只告诉你大致的概念。Distributional Q-function 还蛮有道理的, 但是它没有红起来。你就发现说没有太多人真的在实现的时候用这个技术,可能一个原因就是它不好实现。它的意思是什么?Q-function 到底是什么意思啊,Q-function 是 accumulated reward 的期望值,所以我们算出来的这个Q value 其实是一个期望值。因为环境是有随机性的,在某一个state 采取某一个action 的时候,我们把所有的reward 玩到游戏结束的时候所有的 reward 进行一个统计,你其实得到的是一个distribution。也许在reward 得到0 的机率很高,在-10 的概率比较低,在+10 的概率比较低,但是它是一个distribution。我们对这一个distribution 算它的mean才是这个Q value,我们算出来是 expected accumulated reward。所以这accumulated reward 是一个distribution,对它取expectation,对它取mean,你得到了Q value。但不同的distribution,它们其实可以有同样的mean。也许真正的distribution 是右边的distribution,它算出来的 mean 跟左边的 distribution 算出来的mean 其实是一样的,但它们背后所代表的distribution 其实是不一样的。假设我们只用一个 expected 的 Q value 来代表整个reward 的话,其实可能会丢失一些 information,你没有办法 model reward 的distribution。
|
||||
还有一个技巧叫做 Distributional Q-function。我们不讲它的细节,只告诉你大致的概念。Distributional Q-function 还蛮有道理的, 但是它没有红起来。你就发现说没有太多人真的在实现的时候用这个技术,可能一个原因就是它不好实现。Q-function 是 accumulated reward 的期望值,所以我们算出来的这个 Q value 其实是一个期望值。因为环境是有随机性的,在某一个 state 采取某一个 action 的时候,我们把所有的 reward 玩到游戏结束的时候所有的 reward 进行一个统计,你其实得到的是一个 distribution。也许在 reward 得到 0 的机率很高,在 -10 的概率比较低,在 +10 的概率比较低,但是它是一个 distribution。我们对这一个 distribution 算它的 mean才是这个 Q value,我们算出来是 expected accumulated reward。所以 accumulated reward 是一个 distribution,对它取 expectation,对它取 mean,你得到了 Q value。但不同的 distribution,它们其实可以有同样的 mean。也许真正的 distribution 是右边的 distribution,它算出来的 mean 跟左边的 distribution 算出来的 mean 其实是一样的,但它们背后所代表的 distribution 其实是不一样的。假设我们只用一个 expected 的 Q value 来代表整个 reward 的话,其实可能会丢失一些 information,你没有办法 model reward 的distribution。
|
||||
|
||||

|
||||
|
||||
Distributional Q-function 它想要做的事情是model distribution,怎么做呢?在原来的 Q-function 里面,假设你只能够采取 $a_1$, $a_2$, $a_3$, 3 个actions,那你就是input 一个state,output 3 个values。3 个values 分别代表3 个actions 的Q value,但是这个 Q value 是一个distribution 的期望值。所以 Distributional Q-function 的想法就是何不直接output 那个 distribution。但是要直接output 一个distribution 也不知道怎么做嘛。实际上的做法是说, 假设 distribution 的值就分布在某一个 range 里面,比如说-10 到10,那把-10 到10 中间拆成一个一个的bin,拆成一个一个的长条图。举例来说,在这个例子里面,每一个action 的 reward 的space 就拆成 5 个bin。假设reward 可以拆成5 个bin 的话,今天你的Q-function 的output 是要预测说,你在某一个 state,采取某一个action,你得到的reward,落在某一个bin 里面的概率。所以其实这边的概率的和,这些绿色的bar 的和应该是 1,它的高度代表说,在某一个state,采取某一个action 的时候,它落在某一个bin 的机率。这边绿色的代表action 1,红色的代表action 2,蓝色的代表action 3。所以今天你就可以真的用Q-function 去 estimate $a_1$ 的distribution,$a_2$ 的distribution,$a_3$ 的distribution。那实际上在做testing 的时候, 我们还是要选某一个action去执行嘛,那选哪一个action 呢?实际上在做的时候,还是选这个mean 最大的那个action 去执行。但假设我们今天可以 model distribution 的话,除了选mean 最大的以外,也许在未来你可以有更多其他的运用。举例来说,你可以考虑它的distribution 长什么样子。若distribution variance 很大,代表说采取这个action 虽然mean 可能平均而言很不错,但也许风险很高,你可以train一个network 它是可以规避风险的。就在 2 个action mean 都差不多的情况下,也许可以选一个风险比较小的 action 来执行,这是 Distributional Q-function 的好处。关于怎么train 这样的 Q-network 的细节,我们就不讲,你只要记得说 Q-network 有办法output 一个distribution 就对了。我们可以不只是估测得到的期望reward mean 的值。我们其实是可以估测一个distribution 的。
|
||||
Distributional Q-function 它想要做的事情是 model distribution,怎么做呢?在原来的 Q-function 里面,假设你只能够采取 $a_1$, $a_2$, $a_3$, 3 个 actions,那你就是 input 一个 state,output 3 个 values。3 个 values 分别代表 3 个 actions 的 Q value,但是这个 Q value 是一个 distribution 的期望值。所以 Distributional Q-function 的想法就是何不直接 output 那个 distribution。但是要直接 output 一个 distribution 也不知道怎么做。实际上的做法是说, 假设 distribution 的值就分布在某一个 range 里面,比如说 -10 到10,那把 -10 到10 中间拆成一个一个的 bin,拆成一个一个的长条图。举例来说,在这个例子里面,每一个 action 的 reward 的 space 就拆成 5 个bin。假设 reward 可以拆成 5 个 bin 的话,今天你的 Q-function 的 output 是要预测说,你在某一个 state,采取某一个 action,你得到的 reward,落在某一个 bin 里面的概率。所以其实这边的概率的和,这些绿色的 bar 的和应该是 1,它的高度代表说,在某一个 state,采取某一个 action 的时候,它落在某一个 bin 的机率。这边绿色的代表 action 1,红色的代表 action 2,蓝色的代表 action 3。所以今天你就可以真的用 Q-function 去 estimate $a_1$ 的 distribution,$a_2$ 的 distribution,$a_3$ 的 distribution。那实际上在做 testing 的时候, 我们还是要选某一个 action去执行嘛,那选哪一个 action 呢?实际上在做的时候,还是选这个 mean 最大的那个 action 去执行。但假设我们今天可以 model distribution 的话,除了选 mean 最大的以外,也许在未来你可以有更多其他的运用。举例来说,你可以考虑它的 distribution 长什么样子。若 distribution variance 很大,代表说采取这个action 虽然mean 可能平均而言很不错,但也许风险很高,你可以train一个network 它是可以规避风险的。就在 2 个action mean 都差不多的情况下,也许可以选一个风险比较小的 action 来执行,这是 Distributional Q-function 的好处。关于怎么 train 这样的 Q-network 的细节,我们就不讲,你只要记得说 Q-network 有办法 output 一个 distribution 就对了。我们可以不只是估测得到的期望 reward mean 的值。我们其实是可以估测一个 distribution 的。
|
||||
|
||||
## Rainbow
|
||||
|
||||

|
||||
|
||||
最后一个技巧叫做 rainbow 。Rainbow 就是把刚才所有的方法都综合起来就变成 rainbow 。因为刚才每一个方法,就是有一种自己的颜色,把所有的颜色通通都合起来,就变成rainbow,它把原来的DQN 也算是一种方法,故有 7 色。
|
||||
最后一个技巧叫做 rainbow,把刚才所有的方法都综合起来就变成 rainbow 。因为刚才每一个方法,就是有一种自己的颜色,把所有的颜色通通都合起来,就变成 rainbow,它把原来的 DQN 也算是一种方法,故有 7 色。
|
||||
|
||||
那我们来看看这些不同的方法。横轴是 training process,纵轴是玩了10 几个 Atari 小游戏的平均的分数的和,但它取的是median 的分数,为什么是取 median 不是直接取平均呢?因为它说每一个小游戏的分数,其实差很多。如果你取平均的话,到时候某几个游戏就dominate 你的结果,所以它取median 的值。
|
||||
那我们来看看这些不同的方法。横轴是 training process,纵轴是玩了 10 几个 Atari 小游戏的平均的分数的和,但它取的是 median 的分数,为什么是取 median 不是直接取平均呢?因为它说每一个小游戏的分数,其实差很多。如果你取平均的话,到时候某几个游戏就 dominate 你的结果,所以它取 median 的值。
|
||||
|
||||
如果你是一般的DQN,就灰色这一条线,就没有很强。那如果是你换noisy DQN,就强很多。如果这边每一个单一颜色的线是代表说只用某一个方法,那紫色这一条线是DDQN(Double DQN),DDQN 还蛮有效的。然后 Prioritized DDQN、Dueling DDQN 和 Distributional DQN 都蛮强的,它们都差不多很强的。A3C 其实是 Actor-Critic 的方法。单纯的 A3C 看起来是比DQN 强的。这边怎么没有 multi-step 的方法,multi-step 的方法就是 balance TD 跟MC,我猜是因为 A3C 本身内部就有做 multi-step 的方法,所以他可能觉得说有 implement A3C 就算是有 implement multi-step 的方法。所以可以把这个 A3C 的结果想成是 multi-step 方法的结果。其实这些方法他们本身之间是没有冲突的,所以全部都用上去就变成七彩的一个方法,就叫做rainbow,然后它很高。
|
||||
如果你是一般的 DQN,就灰色这一条线,就没有很强。那如果是你换 Noisy DQN,就强很多。如果这边每一个单一颜色的线是代表说只用某一个方法,那紫色这一条线是 DDQN(Double DQN),DDQN 还蛮有效的。然后 Prioritized DDQN、Dueling DDQN 和 Distributional DQN 都蛮强的,它们都差不多很强的。A3C 其实是 Actor-Critic 的方法。单纯的 A3C 看起来是比 DQN 强的。这边怎么没有 multi-step 的方法,multi-step 的方法就是 balance TD 跟 MC,我猜是因为 A3C 本身内部就有做 multi-step 的方法,所以他可能觉得说有 implement A3C 就算是有 implement multi-step 的方法。所以可以把这个 A3C 的结果想成是 multi-step 方法的结果。其实这些方法他们本身之间是没有冲突的,所以全部都用上去就变成七彩的一个方法,就叫做 rainbow,然后它很高。
|
||||
|
||||

|
||||
|
||||
上图是说,在rainbow 这个方法里面, 如果我们每次拿掉其中一个技术,到底差多少。因为现在是把所有的方法都加在一起,发现说进步很多,但会不会有些方法其实是没用的。所以看看说, 每一个方法哪些方法特别有用,哪些方法特别没用。这边的虚线就是拿掉某一种方法以后的结果,你会发现说,黄色的虚线,拿掉 multi-step 掉很多。Rainbow 是彩色这一条,拿掉 multi-step 会掉下来。拿掉 Prioritized Experience Replay 后也马上就掉下来。拿掉这个distribution,它也掉下来。
|
||||
上图是说,在 rainbow 这个方法里面, 如果我们每次拿掉其中一个技术,到底差多少。因为现在是把所有的方法都加在一起,发现说进步很多,但会不会有些方法其实是没用的。所以看看说, 每一个方法哪些方法特别有用,哪些方法特别没用。这边的虚线就是拿掉某一种方法以后的结果,你会发现说,黄色的虚线,拿掉 multi-step 掉很多。Rainbow 是彩色这一条,拿掉 multi-step 会掉下来。拿掉 Prioritized Experience Replay 后也马上就掉下来。拿掉这个 distribution,它也掉下来。
|
||||
|
||||
这边有一个有趣的地方是说,在开始的时候,distribution 训练的方法跟其他方法速度差不多。但是如果你拿掉distribution 的时候,你的训练不会变慢,但是 performance 最后会收敛在比较差的地方。拿掉 Noisy Net 后performance 也是差一点。拿掉Dueling 也是差一点。拿掉 Double 没什么差,所以看来全部合在一起的时候,Double 是比较没有影响的。其实在paper 里面有给一个make sense 的解释,其实当你有用 Distributional DQN的 时候,本质上就不会over estimate 你的reward。我们是为了避免over estimate reward 才加了Double DQN。那在paper 里面有讲说,如果有做 Distributional DQN,就比较不会有over estimate 的结果。 事实上他有真的算了一下发现说,其实多数的状况是 under estimate reward 的,所以会变成Double DQN 没有用。那为什么做 Distributional DQN,不会over estimate reward,反而会under estimate reward 呢?因为这个 distributional DQN 的 output 的是一个distribution 的range,output 的 range 不可能是无限宽的,你一定是设一个range, 比如说我最大output range 就是从-10 到10。假设今天得到的reward 超过10 怎么办?是100 怎么办,就当作没看到这件事。所以 reward 很极端的值,很大的值其实是会被丢掉的, 所以用 Distributional DQN 的时候,你不会有over estimate 的现象,反而会 under estimate。
|
||||
这边有一个有趣的地方是说,在开始的时候,distribution 训练的方法跟其他方法速度差不多。但是如果你拿掉distribution 的时候,你的训练不会变慢,但是 performance 最后会收敛在比较差的地方。拿掉 Noisy Net 后performance 也是差一点。拿掉 Dueling 也是差一点。拿掉 Double 没什么差,所以看来全部合在一起的时候,Double 是比较没有影响的。其实在 paper 里面有给一个 make sense 的解释,其实当你有用 Distributional DQN的 时候,本质上就不会 over estimate 你的 reward。我们是为了避免 over estimate reward 才加了 Double DQN。那在 paper 里面有讲说,如果有做 Distributional DQN,就比较不会有 over estimate 的结果。 事实上他有真的算了一下发现说,其实多数的状况是 under estimate reward 的,所以变成 Double DQN 没有用。那为什么做 Distributional DQN,不会 over estimate reward,反而会 under estimate reward 呢?因为这个 distributional DQN 的 output 的是一个 distribution 的range,output 的 range 不可能是无限宽的,你一定是设一个 range, 比如说我最大 output range 就是从-10 到10。假设今天得到的 reward 超过 10 怎么办?是100 怎么办,就当作没看到这件事。所以 reward 很极端的值,很大的值其实是会被丢掉的, 所以用 Distributional DQN 的时候,你不会有 over estimate 的现象,反而会 under estimate。
|
||||
Reference in New Issue
Block a user