Merge branch 'master' of https://github.com/datawhalechina/leedeeprl-notes
30
README.md
@@ -4,7 +4,7 @@
|
||||
|
||||
## 使用说明
|
||||
|
||||
* 第 3 章到第 10 章为李宏毅《深度强化学习》课程的部分;
|
||||
* 第 4 章到第 11 章为[李宏毅《深度强化学习》](http://speech.ee.ntu.edu.tw/~tlkagk/courses_MLDS18.html)的部分;
|
||||
* 第 1 章和第 2 章根据[《强化学习纲要》](https://github.com/zhoubolei/introRL)整理而来;
|
||||
* 第 3 章和第 12 章根据[《百度强化学习》](https://aistudio.baidu.com/aistudio/education/group/info/1335) 整理而来。
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
- bilibili:[李宏毅《深度强化学习》](https://www.bilibili.com/video/BV1MW411w79n)
|
||||
|
||||
## 内容导航
|
||||
| 章节 | 习题 | 项目 |
|
||||
|------|------|------|
|
||||
|[第一章 强化学习概述](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1) | [第一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1_questions&keywords) | |
|
||||
|[第二章 马尔科夫决策过程 (MDP)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2) | [第二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2_questions&keywords) | |
|
||||
|[第三章 表格型方法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3) | [第三章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3_questions&keywords) | |
|
||||
|[第四章 策略梯度](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4) | [第四章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4_questions&keywords) | |
|
||||
|[第五章 近端策略优化 (PPO) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5) | [第五章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5_questions&keywords) | |
|
||||
| [第六章 Q 学习 (基本概念)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6)| [第六章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6_questions&keywords) | |
|
||||
|[第七章 Q 学习 (进阶技巧)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7) | [第七章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7_questions&keywords) | [项目二 使用 DQN 实现 CartPole-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/project2) |
|
||||
|[第八章 Q 学习 (连续动作)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8) | [第八章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8_questions&keywords) | |
|
||||
|[第九章 演员-评论员算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9) | [第九章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9_questions&keywords) | |
|
||||
|[第十章 稀疏奖励](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10) | [第十章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10_questions&keywords) | |
|
||||
|[第十一章 模仿学习](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11) | [第十一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11_questions&keywords) | |
|
||||
|[第十二章 深度确定性策略梯度 (DDPG) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12) | [第十二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12_questions&keywords) | [项目三 使用 Policy-Based 方法实现 Pendulum-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/project3) |
|
||||
| 章节 | 习题 | 项目 |
|
||||
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| [第一章 强化学习概述](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1) | [第一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1_questions&keywords) | |
|
||||
| [第二章 马尔科夫决策过程 (MDP)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2) | [第二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2_questions&keywords) | |
|
||||
| [第三章 表格型方法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3) | [第三章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3_questions&keywords) | [项目一 使用 Q-learning 实现贪吃蛇](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/project1) |
|
||||
| [第四章 策略梯度](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4) | [第四章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4_questions&keywords) | |
|
||||
| [第五章 近端策略优化 (PPO) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5) | [第五章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5_questions&keywords) | |
|
||||
| [第六章 Q 学习 (基本概念)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6) | [第六章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6_questions&keywords) | |
|
||||
| [第七章 Q 学习 (进阶技巧)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7) | [第七章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7_questions&keywords) | [项目二 使用 DQN 实现 CartPole-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/project2) |
|
||||
| [第八章 Q 学习 (连续动作)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8) | [第八章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8_questions&keywords) | |
|
||||
| [第九章 演员-评论员算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9) | [第九章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9_questions&keywords) | |
|
||||
| [第十章 稀疏奖励](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10) | [第十章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10_questions&keywords) | |
|
||||
| [第十一章 模仿学习](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11) | [第十一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11_questions&keywords) | |
|
||||
| [第十二章 深度确定性策略梯度 (DDPG) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12) | [第十二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12_questions&keywords) | [项目三 使用 Policy-Based 方法实现 Pendulum-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/project3) |
|
||||
## 主要贡献者
|
||||
|
||||
| 作者 | 贡献 |
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
李宏毅老师的《深度强化学习》是强化学习领域经典的中文视频之一。李老师幽默风趣的上课风格让晦涩难懂的强化学习理论变得轻松易懂,他会通过很多有趣的例子来讲解强化学习理论。比如老师经常会用玩 Atari 游戏的例子来讲解强化学习算法。此外,为了课程的完整性,我们整理了周博磊老师的《强化学习纲要》以及李科浇老师的《百度强化学习》的部分内容作为补充。对于想入门强化学习又想看中文讲解的人来说绝对是非常推荐的。
|
||||
|
||||
## 使用说明
|
||||
* 第 3 章到第 10 章为李宏毅《深度强化学习》课程的部分;
|
||||
* 第 4 章到第 11 章为[李宏毅《深度强化学习》](http://speech.ee.ntu.edu.tw/~tlkagk/courses_MLDS18.html)的部分;
|
||||
* 第 1 章和第 2 章根据[《强化学习纲要》](https://github.com/zhoubolei/introRL)整理而来;
|
||||
* 第 3 章和第 12 章根据[《百度强化学习》](https://aistudio.baidu.com/aistudio/education/group/info/1335) 整理而来。
|
||||
|
||||
@@ -13,20 +13,20 @@
|
||||
- bilibili:[李宏毅《深度强化学习》](https://www.bilibili.com/video/BV1MW411w79n)
|
||||
|
||||
## 内容导航
|
||||
| 章节 | 习题 | 项目 |
|
||||
|------|------|------|
|
||||
|[第一章 强化学习概述](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1) | [第一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1_questions&keywords) | |
|
||||
|[第二章 马尔科夫决策过程 (MDP)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2) | [第二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2_questions&keywords) | |
|
||||
|[第三章 表格型方法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3) | [第三章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3_questions&keywords) | |
|
||||
|[第四章 策略梯度](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4) | [第四章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4_questions&keywords) | |
|
||||
|[第五章 近端策略优化 (PPO) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5) | [第五章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5_questions&keywords) | |
|
||||
| [第六章 Q 学习 (基本概念)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6)| [第六章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6_questions&keywords) | |
|
||||
|[第七章 Q 学习 (进阶技巧)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7) | [第七章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7_questions&keywords) | [项目二 使用 DQN 实现 CartPole-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/project2) |
|
||||
|[第八章 Q 学习 (连续动作)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8) | [第八章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8_questions&keywords) | |
|
||||
|[第九章 演员-评论员算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9) | [第九章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9_questions&keywords) | |
|
||||
|[第十章 稀疏奖励](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10) | [第十章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10_questions&keywords) | |
|
||||
|[第十一章 模仿学习](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11) | [第十一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11_questions&keywords) | |
|
||||
|[第十二章 深度确定性策略梯度 (DDPG) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12) | [第十二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12_questions&keywords) | [项目三 使用 Policy-Based 方法实现 Pendulum-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/project3) |
|
||||
| 章节 | 习题 | 项目 |
|
||||
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| [第一章 强化学习概述](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1) | [第一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter1/chapter1_questions&keywords) | |
|
||||
| [第二章 马尔科夫决策过程 (MDP)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2) | [第二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter2/chapter2_questions&keywords) | |
|
||||
| [第三章 表格型方法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3) | [第三章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/chapter3_questions&keywords) | [项目一 使用 Q-learning 实现贪吃蛇](https://datawhalechina.github.io/leedeeprl-notes/#/chapter3/project1) |
|
||||
| [第四章 策略梯度](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4) | [第四章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter4/chapter4_questions&keywords) | |
|
||||
| [第五章 近端策略优化 (PPO) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5) | [第五章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter5/chapter5_questions&keywords) | |
|
||||
| [第六章 Q 学习 (基本概念)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6) | [第六章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter6/chapter6_questions&keywords) | |
|
||||
| [第七章 Q 学习 (进阶技巧)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7) | [第七章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/chapter7_questions&keywords) | [项目二 使用 DQN 实现 CartPole-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter7/project2) |
|
||||
| [第八章 Q 学习 (连续动作)](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8) | [第八章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter8/chapter8_questions&keywords) | |
|
||||
| [第九章 演员-评论员算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9) | [第九章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter9/chapter9_questions&keywords) | |
|
||||
| [第十章 稀疏奖励](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10) | [第十章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter10/chapter10_questions&keywords) | |
|
||||
| [第十一章 模仿学习](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11) | [第十一章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter11/chapter11_questions&keywords) | |
|
||||
| [第十二章 深度确定性策略梯度 (DDPG) 算法](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12) | [第十二章习题](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/chapter12_questions&keywords) | [项目三 使用 Policy-Based 方法实现 Pendulum-v0](https://datawhalechina.github.io/leedeeprl-notes/#/chapter12/project3) |
|
||||
## 主要贡献者
|
||||
|
||||
| 作者 | 贡献 |
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
- 目录
|
||||
- [第一章 强化学习概述](chapter1/chapter1)
|
||||
- [第一章习题](chapter1/chapter1_questions&keywords)
|
||||
- [第一章 习题](chapter1/chapter1_questions&keywords)
|
||||
- [第二章 马尔可夫决策过程 (MDP)](chapter2/chapter2)
|
||||
- [第二章习题](chapter2/chapter2_questions&keywords)
|
||||
- [第二章 习题](chapter2/chapter2_questions&keywords)
|
||||
- [第三章 表格型方法](chapter3/chapter3)
|
||||
- [第三章习题](chapter3/chapter3_questions&keywords)
|
||||
- [第三章 习题](chapter3/chapter3_questions&keywords)
|
||||
- [项目一 使用 Q-learning 实现贪吃蛇](chapter3/project1)
|
||||
- [第四章 策略梯度](chapter4/chapter4)
|
||||
- [第四章习题](chapter4/chapter4_questions&keywords)
|
||||
- [第四章 习题](chapter4/chapter4_questions&keywords)
|
||||
- [第五章 近端策略优化 (PPO) 算法](chapter5/chapter5)
|
||||
- [第五章习题](chapter5/chapter5_questions&keywords)
|
||||
- [第五章 习题](chapter5/chapter5_questions&keywords)
|
||||
- [第六章 Q 学习 (基本概念)](chapter6/chapter6)
|
||||
- [第六章习题](chapter6/chapter6_questions&keywords)
|
||||
- [第六章 习题](chapter6/chapter6_questions&keywords)
|
||||
- [第七章 Q 学习 (进阶技巧)](chapter7/chapter7)
|
||||
- [第七章习题](chapter7/chapter7_questions&keywords)
|
||||
- [第七章 习题](chapter7/chapter7_questions&keywords)
|
||||
- [项目二 使用 DQN 实现 CartPole-v0](chapter7/project2)
|
||||
- [第八章 Q 学习 (连续动作)](chapter8/chapter8)
|
||||
- [第八章习题](chapter8/chapter8_questions&keywords)
|
||||
- [第八章 习题](chapter8/chapter8_questions&keywords)
|
||||
- [第九章 演员-评论员算法](chapter9/chapter9)
|
||||
- [第九章习题](chapter9/chapter9_questions&keywords)
|
||||
- [第九章 习题](chapter9/chapter9_questions&keywords)
|
||||
- [第十章 稀疏奖励](chapter10/chapter10)
|
||||
- [第十章习题](chapter10/chapter10_questions&keywords)
|
||||
- [第十章 习题](chapter10/chapter10_questions&keywords)
|
||||
- [第十一章 模仿学习](chapter11/chapter11)
|
||||
- [第十一章习题](chapter11/chapter11_questions&keywords)
|
||||
- [第十一章 习题](chapter11/chapter11_questions&keywords)
|
||||
- [第十二章 深度确定性策略梯度 (DDPG) 算法](chapter12/chapter12)
|
||||
- [第十二章习题](chapter12/chapter12_questions&keywords)
|
||||
- [第十二章 习题](chapter12/chapter12_questions&keywords)
|
||||
- [项目三 使用 Policy-Based 方法实现 Pendulum-v0](chapter12/project3)
|
||||
|
||||
|
||||
|
||||
@@ -137,12 +137,13 @@
|
||||
在跟环境的交互过程中,agent 会获得很多观测。在每一个观测会采取一个动作,它也会得到一个奖励。Agent 在采取当前动作的时候会依赖于它之前得到的这个历史,所以你可以把整个游戏的状态看成关于这个历史的函数。
|
||||
|
||||
Q: 状态和观测有什么关系?
|
||||
|
||||
A: `状态(state)` $s$ 是对世界的完整描述,不会隐藏世界的信息。`观测(observation)` $o$ 是对状态的部分描述,可能会遗漏一些信息。
|
||||
|
||||
在 deep RL 中,我们几乎总是用一个实值的向量、矩阵或者更高阶的张量来表示状态和观测。举个例子,我们可以用 RGB 像素值的矩阵来表示一个视觉的观测,我们可以用机器人关节的角度和速度来表示一个机器人的状态。
|
||||
|
||||

|
||||
在 Agent 的内部也有一个函数来更新这个状态。当 agent 的状态跟环境的状态等价的时候,我们就说这个环境是 full observability,就是全部可以观测。换句话说,当 agent 能够观察到环境的所有状态时,我们称这个环境是`完全可观测的(fully observed)`。
|
||||
在 agent 的内部也有一个函数来更新这个状态。当 agent 的状态跟环境的状态等价的时候,我们就说这个环境是 `full observability`,就是全部可以观测。换句话说,当 agent 能够观察到环境的所有状态时,我们称这个环境是`完全可观测的(fully observed)`。
|
||||
|
||||

|
||||
但是有一种情况是 agent 得到的观测并不能包含所有环境运作的状态,因为在这个强化学习的设定里面,环境的状态才是真正的所有状态。比如 agent 在玩这个 black jack 这个游戏,它能看到的其实是牌面上的牌。或者在玩雅达利游戏的时候,观测到的只是当前电视上面这一帧的信息,你并没有得到游戏内部里面所有的运作状态。也就是说当 agent 只能看到部分的观测,我们就称这个环境是`部分可观测的(partially observed)`。在这种情况下面,强化学习通常被建模成一个 POMDP 的问题。
|
||||
@@ -282,7 +283,7 @@ A: 针对是否需要对真实环境建模,强化学习可以分为有模型
|
||||
## Exploration and Exploitation
|
||||
|
||||

|
||||
在强化学习里面,Exploration 和 Exploitation 是两个很核心的问题。
|
||||
在强化学习里面,`Exploration` 和` Exploitation` 是两个很核心的问题。
|
||||
|
||||
* Exploration 是说我们怎么去探索这个环境,通过尝试不同的行为来得到一个最佳的策略,得到最大奖励的策略。
|
||||
|
||||
@@ -308,29 +309,44 @@ A: 针对是否需要对真实环境建模,强化学习可以分为有模型
|
||||
* Exploitation 就是说你总是采取某一种策略。比如说,你可能打街霸,你采取的策略可能是蹲在角落,然后一直触脚。这个策略很可能可以奏效,但可能遇到特定的对手就失效。
|
||||
* Exploration 就是说你可能尝试一些新的招式,有可能你会发出大招来,这样就可能一招毙命。
|
||||
|
||||
### K-armed Bandit
|
||||

|
||||
|
||||
与一般监督学习不同,强化学习任务的最终奖赏是在多步动作之后才能观察到,这里我们不妨先考虑比较简单的情形:最大化单步奖赏,即仅考虑一步操作。需注意的是,即便在这样的简化情形下,强化学习仍与监督学习有显著不同,因为机器需通过尝试来发现各个动作产生的结果,而没有训练数据告诉机器应当做哪个动作。
|
||||
|
||||
想要最大化单步奖赏需考虑两个方面:一是需知道每个动作带来的奖赏,二是要执行奖赏最大的动作。若每个动作对应的奖赏是一个确定值,那么尝试遍所有的动作便能找出奖赏最大的动作。然而,更一般的情形是,一个动作的奖赏值是来自于一个概率分布,仅通过一次尝试并不能确切地获得平均奖赏值。
|
||||
|
||||
实际上,单步强化学习任务对应了一个理论模型,即` K-臂赌博机(K-armed bandit)`。K-臂赌博机也被称为 `多臂赌博机(Multi-armed bandit) `。如上图所示,K-摇臂赌博机有 K 个摇臂,赌徒在投入一个硬币后可选择按下其中一个摇臂,每个摇臂以一定的概率吐出硬币,但这个概率赌徒并不知道。赌徒的目标是通过一定的策略最大化自己的奖赏,即获得最多的硬币。
|
||||
|
||||
* 若仅为获知每个摇臂的期望奖赏,则可采用`仅探索(exploration-only)法`:将所有的尝试机会平均分配给每个摇臂(即轮流按下每个摇臂),最后以每个摇臂各自的平均吐币概率作为其奖赏期望的近似估计。
|
||||
|
||||
* 若仅为执行奖赏最大的动作,则可采用`仅利用(exploitation-only)法`:按下目前最优的(即到目前为止平均奖赏最大的)摇臂,若有多个摇臂同为最优,则从中随机选取一个。
|
||||
|
||||
显然,仅探索法能很好地估计每个摇臂的奖赏,却会失去很多选择最优摇臂的机会;仅利用法则相反,它没有很好地估计摇臂期望奖赏,很可能经常选不到最优摇臂。因此,这两种方法都难以使最终的累积奖赏最大化。
|
||||
|
||||
事实上,探索(即估计摇臂的优劣)和利用(即选择当前最优摇臂)这两者是矛盾的,因为尝试次数(即总投币数)有限,加强了一方则会自然削弱另一方,这就是强化学习所面临的`探索-利用窘境(Exploration-Exploitation dilemma)`。显然,想要累积奖赏最大,则必须在探索与利用之间达成较好的折中。
|
||||
|
||||
## Experiment with Reinforcement Learning
|
||||

|
||||

|
||||
接下来进入一个实践环节。强化学习是一个理论跟实践结合的机器学习分支,需要去推导很多算法公式。然后去理解它算法背后的一些数学原理。另外一方面,上机实践通过实现算法,在很多实验环境里面去探索这个算法是不是可以得到预期效果也是一个非常重要的过程。
|
||||
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
我会在网页上面公布一些代码,会利用 Python 和深度学习的一些包(主要是用 PyTorch 为主),然后在[这个链接](https://github.com/cuhkrlcourse/RLexample)里面,我其实已经公布了一些 RL 相关的代码。
|
||||
|
||||

|
||||

|
||||
|
||||
你可以直接调用现有的包来实践。现在有很多深度学习的包可以用,熟练使用这里面的两三种,其实已经可以实现非常多的功能。所以你并不需要从头去去造轮子,就直接调用它里面的函数去实现你想实现的功能。
|
||||
|
||||

|
||||

|
||||
|
||||
[ OpenAI](https://openai.com/) 是一个非盈利的人工智能研究公司。Open AI 公布了非常多的学习资源以及这个算法资源,他们之所以叫 Open AI,就是他们把所有开发的算法都 open source 出来。
|
||||
|
||||
### Gym
|
||||
|
||||

|
||||

|
||||
|
||||
[OpenAI Gym](https://gym.openai.com/) 是一个环境仿真库,里面包含了很多现有的环境。针对不同的场景,我们可以选择不同的环境,
|
||||
|
||||
@@ -352,11 +368,11 @@ $python
|
||||
>>>import gym
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
强化学习的这个交互就是由 agent 跟环境进行交互。所以算法的 interface 也是用这个来表示。比如说我们现在安装了 OpenAI Gym。那我们这里就可以直接调入 Taxi-v2 的环境,就建立了这个环境。初始化这个环境过后,就可以进行交互了。Agent 得到这个观测过后,它就会输出一个 action。然后这个 action 会被这个环境拿进去执行这个 step,然后环境就会往前走一步,然后返回新的 observation 和 reward 以及一个 flag variable 就决定你这个游戏是不是结束了。几行代码就实现了强化学习里面的 framework。
|
||||
|
||||

|
||||

|
||||
在 OpenAI Gym 里面有很经典的控制类游戏。
|
||||
|
||||
* 比如说 Acrobot,就是把这个两节铁杖,然后甩了立起来。
|
||||
@@ -365,7 +381,7 @@ $python
|
||||
|
||||
大家可以点[这个链接](https://gym.openai.com/envs/#classic_control)看一看这些环境。在刚开始测试强化学习的时候,可以选择这些简单环境,因为这些环境在一两分钟之内,你就可以见到一个效果。
|
||||
|
||||

|
||||

|
||||
|
||||
这里我们看一下 CartPole 的这个环境。对于这个环境,有两个动作,Cart 往左移还是往右移。这里得到了观测:这个车当前的位置,Cart 当前的往左往右移的速度,这个杆的角度以及它的杆的最高点的速度。
|
||||
|
||||
@@ -561,6 +577,8 @@ print('平均回合奖励 = {}'.format(np.mean(episode_rewards)))
|
||||
* [强化学习:原理与Python实现](https://book.douban.com/subject/34478302/)
|
||||
* [白话强化学习与PyTorch](https://book.douban.com/subject/34809676/)
|
||||
* [OpenAI Spinning Up ](https://spinningup.openai.com/en/latest/spinningup/rl_intro.html#)
|
||||
* [神经网络与深度学习](https://nndl.github.io/)
|
||||
* [机器学习](https://book.douban.com/subject/26708119//)
|
||||
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 502 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 807 KiB After Width: | Height: | Size: 502 KiB |
|
Before Width: | Height: | Size: 508 KiB After Width: | Height: | Size: 807 KiB |
|
Before Width: | Height: | Size: 558 KiB After Width: | Height: | Size: 508 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 558 KiB |
|
Before Width: | Height: | Size: 300 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 300 KiB |
|
Before Width: | Height: | Size: 425 KiB After Width: | Height: | Size: 330 KiB |
BIN
docs/chapter1/img/1.47.png
Normal file
|
After Width: | Height: | Size: 425 KiB |
@@ -1,73 +1,70 @@
|
||||
# Sparse Reward
|
||||
实际上用 reinforcement learning learn agent 的时候,多数的时候 agent 都是没有办法得到 reward 的。那在没有办法得到 reward 的情况下,对 agent 来说它的训练是非常困难的。举例来说,假设你今天要训练一个机器手臂,然后桌上有一个螺丝钉跟螺丝起子,那你要训练它用螺丝起子把螺丝钉栓进去,那这个很难,为什么?因为你知道一开始你的 agent 是什么都不知道的,它唯一能够做不同的 action 的原因是 exploration。举例来说,你在做 Q-learning 的时候,会有一些随机性,让它去采取一些过去没有采取过的 action,那你要随机到说它把螺丝起子捡起来,再把螺丝栓进去,然后就会得到 reward 1,这件事情是永远不可能发生的。所以,不管你的 actor 做了什么事情,它得到 reward 永远都是 0,对它来说不管采取什么样的 action 都是一样糟或者是一样得好。所以,它最后什么都不会学到。如果环境中的 reward 非常的 sparse,reinforcement learning 的问题就会变得非常的困难。但是人类可以在非常 sparse 的 reward 上面去学习,我们的人生通常多数的时候,我们就只是活在那里,都没有得到什么 reward 或是 penalty。但是,人还是可以采取各种各式各样的行为。所以,一个真正厉害的 AI 应该能够在 sparse reward 的情况下也学到要怎么跟这个环境互动。
|
||||
实际上用 reinforcement learning learn agent 的时候,多数的时候 agent 都是没有办法得到 reward 的。那在没有办法得到 reward 的情况下,对 agent 来说它的训练是非常困难的。举例来说,假设你今天要训练一个机器手臂,然后桌上有一个螺丝钉跟螺丝起子,那你要训练它用螺丝起子把螺丝钉栓进去,那这个很难,为什么?因为你知道一开始你的 agent 是什么都不知道的,它唯一能够做不同的 action 的原因是 exploration。举例来说,你在做 Q-learning 的时候,会有一些随机性,让它去采取一些过去没有采取过的 action,那你要随机到说它把螺丝起子捡起来,再把螺丝栓进去,然后就会得到 reward 1,这件事情是永远不可能发生的。所以,不管你的 actor 做了什么事情,它得到 reward 永远都是 0,对它来说不管采取什么样的 action 都是一样糟或者是一样的好。所以,它最后什么都不会学到。如果环境中的 reward 非常的 sparse,reinforcement learning 的问题就会变得非常的困难。但是人类可以在非常 sparse 的 reward 上面去学习,我们的人生通常多数的时候,我们就只是活在那里,都没有得到什么 reward 或是 penalty。但是,人还是可以采取各种各式各样的行为。所以,一个真正厉害的 AI 应该能够在 sparse reward 的情况下也学到要怎么跟这个环境互动。
|
||||
|
||||
怎么解决 sparse reward 的这件事情呢?我们等一下会讲三个方向。
|
||||
## Reward Shaping
|
||||

|
||||
|
||||
第一个方向叫做 `reward shaping`,reward shaping 的意思是说环境有一个固定的 reward,它是真正的 reward,但是我们为了让 agent 学出来的结果是我们要的样子,我们刻意地设计了一些 reward 来引导我们的 agent。举例来说,如果是把小孩当成一个 agent 的话。那一个小孩,他可 以take 两个 actions,一个action 是他可以出去玩,那他出去玩的话,在下一秒钟它会得到 reward 1。但是他在月考的时候,成绩可能会很差。所以在100 个小时之后呢,他会得到 reward -100。然后,他也可以决定要念书,然后在下一个时间,因为他没有出去玩,所以他觉得很不爽,所以他得到 reward -1。但是在 100 个小时后,他可以得到 reward 100。但对一个小孩来说,他可能就会想要 take play 而不是 take study。我们计算的是 accumulated reward,但也许对小孩来说,他的 discount factor 会很大,所以他就不太在意未来的reward。而且因为他是一个小孩,他还没有很多 experience,所以他的 Q-function estimate 是非常不精准的。所以要他去 estimate 很远以后会得到的 accumulated reward,他其实是预测不出来的。所以这时候大人就要引导他,怎么引导呢?就骗他说,如果你坐下来念书我就给你吃一个棒棒糖。所以,对他来说,下一个时间点会得到的 reward 就变成是positive 的。所以他就觉得说,也许 take 这个 study 是比 play 好的。虽然这并不是真正的 reward,而是其他人骗他的reward,告诉他说你采取这个 action 是好的。Reward shaping 的概念是一样的,简单来说,就是你自己想办法 design 一些 reward,它不是环境真正的 reward。在玩 Atari 游戏里面,真的 reward 是游戏主机给你的 reward,但你自己去设计一些 reward 好引导你的 machine,做你想要它做的事情。
|
||||
第一个方向叫做 `reward shaping`。**Reward shaping 的意思是说环境有一个固定的 reward,它是真正的 reward,但是我们为了让 agent 学出来的结果是我们要的样子,我们刻意地设计了一些 reward 来引导我们的 agent。**举例来说,如果是把小孩当成一个 agent 的话。那一个小孩,他可以 take 两个 actions,一个 action 是他可以出去玩,那他出去玩的话,在下一秒钟它会得到 reward 1。但是他在月考的时候,成绩可能会很差。所以在100 个小时之后呢,他会得到 reward -100。然后,他也可以决定要念书,然后在下一个时间,因为他没有出去玩,所以他觉得很不爽,所以他得到 reward -1。但是在 100 个小时后,他可以得到 reward 100。但对一个小孩来说,他可能就会想要 take play 而不是 take study。我们计算的是 accumulated reward,但也许对小孩来说,他的 discount factor 会很大,所以他就不太在意未来的reward。而且因为他是一个小孩,他还没有很多 experience,所以他的 Q-function estimate 是非常不精准的。所以要他去 estimate 很远以后会得到的 accumulated reward,他其实是预测不出来的。所以这时候大人就要引导他,怎么引导呢?就骗他说,如果你坐下来念书我就给你吃一个棒棒糖。所以,对他来说,下一个时间点会得到的 reward 就变成是positive 的。所以他就觉得说,也许 take 这个 study 是比 play 好的。虽然这并不是真正的 reward,而是其他人骗他的reward,告诉他说你采取这个 action 是好的。Reward shaping 的概念是一样的,简单来说,就是你自己想办法 design 一些 reward,它不是环境真正的 reward。在玩 Atari 游戏里面,真的 reward 是游戏主机给你的 reward,但你自己去设计一些 reward 好引导你的 machine,做你想要它做的事情。
|
||||
|
||||

|
||||
|
||||
举例来说,这个例子是 Facebook 玩 VizDoom 的 agent。VizDoom 是一个第一人射击游戏,在这个射击游戏中,杀了敌人就得到 positive reward,被杀就得到 negative reward。他们设计了一些新的 reward,用新的 reward 来引导 agent 让他们做得更好,这不是游戏中真正的 reward。
|
||||
举例来说,这个例子是 Facebook 玩 VizDoom 的 agent。VizDoom 是一个第一人射击游戏,在这个射击游戏中,杀了敌人就得到 positive reward,被杀就得到 negative reward。他们设计了一些新的 reward,用新的 reward 来引导 agent 让他们做得更好,这不是游戏中真正的 reward。比如说掉血就扣 0.05 的分数,弹药减少就扣分,捡到补给包就加分,呆在原地就扣分,移动就加分。 活着会扣一个很小的分数,因为不这样做的话,machine 会只想活着,一直躲避敌人,这样会让 machine 好战一点。表格中的参数都是调出来的。
|
||||
|
||||
比如说掉血就扣 0.05 的分数,弹药减少就扣分,捡到补给包就加分,呆在原地就扣分,移动就加分。 活着会扣一个很小的分数,因为不这样做的话,machine 会只想活着,一直躲避敌人,这样会让 machine 好战一点。表格中的参数都是调出来的。
|
||||
|
||||
Reward shaping是有问题的,因为我们需要 domain knowledge,举例来说,机器人想要学会的事情是把蓝色的板子从这个柱子穿过去。机器人很难学会,我们可以做 Reward Shaping。一个貌似合理的说法是,蓝色的板子离柱子越近,reward 越大。但是 machine 靠近的方式会有问题,它会用蓝色的板子打柱子。而我们要把蓝色板子放在柱子上面去,才能把蓝色板子穿过柱子。 这种 reward shaping的方式是没有帮助的,那至于什么 reward shaping 有帮助,什么 reward shaping 没帮助,会变成一个 domain knowledge,你要去调的。
|
||||
Reward shaping 是有问题的,因为我们需要 domain knowledge,举例来说,机器人想要学会的事情是把蓝色的板子从这个柱子穿过去。机器人很难学会,我们可以做 reward shaping。一个貌似合理的说法是,蓝色的板子离柱子越近,reward 越大。但是 machine 靠近的方式会有问题,它会用蓝色的板子打柱子。而我们要把蓝色板子放在柱子上面去,才能把蓝色板子穿过柱子。 这种 reward shaping 的方式是没有帮助的,那至于什么 reward shaping 有帮助,什么 reward shaping 没帮助,会变成一个 domain knowledge,你要去调的。
|
||||
|
||||
## Curiosity
|
||||

|
||||
|
||||
接下来就是介绍各种你可以自己加进去,in general 看起来是有用的 reward。举例来说,一个技术是给 machine 加上 curiosity,所以叫 `curiosity driven reward`。上图是我们之前讲 Actor-Critic 的时候看过的图。我们有一个 reward function,它给你某一个s tate,给你某一个 action,它就会评断说在这个 state 采取 这个action 得到多少的 reward。那我们当然希望 total reward 越大越好。在 curiosity driven 的这种技术里面,你会加上一个新的 reward function。这个新的 reward function 叫做 `ICM(intrinsic curiosity module)`,它就是要给机器加上好奇心。ICM 会吃 3 个东西,它会吃 state $s_1$、action $a_1$ 和 state $s_2$。根据$s_1$ 、$a_1$、 $a_2$,它会 output 另外一个 reward,我们这边叫做 $r_1^i$。对 machine 来说,total reward 并不是只有 r 而已,还有 $r^i$。它不是只有把所有的 r 都加起来,它还把所有 $r^i$ 加起来当作total reward。所以,它在跟环境互动的时候,它不是只希望 r 越大越好,它还同时希望 $r^i$ 越大越好,它希望从 ICM 的 module 里面得到的 reward 越大越好。ICM 就代表了一种curiosity。
|
||||
接下来就是介绍各种你可以自己加进去,in general 看起来是有用的 reward。举例来说,一个技术是给 machine 加上 curiosity,所以叫 `curiosity driven reward`。上图是我们之前讲 Actor-Critic 的时候看过的图。我们有一个 reward function,它给你某一个 state,给你某一个 action,它就会评断说在这个 state 采取这个 action 得到多少的 reward。那我们当然希望 total reward 越大越好。在 curiosity driven 的这种技术里面,你会加上一个新的 reward function。这个新的 reward function 叫做 `ICM(intrinsic curiosity module)`,它就是要给机器加上好奇心。ICM 会吃 3 个东西,它会吃 state $s_1$、action $a_1$ 和 state $s_2$。根据 $s_1$ 、$a_1$、 $a_2$,它会 output 另外一个 reward,我们这边叫做 $r_1^i$。对 machine 来说,total reward 并不是只有 r 而已,还有 $r^i$。它不是只有把所有的 r 都加起来,它还把所有 $r^i$ 加起来当作total reward。所以,它在跟环境互动的时候,它不是只希望 r 越大越好,它还同时希望 $r^i$ 越大越好,它希望从 ICM 的 module 里面得到的 reward 越大越好。ICM 就代表了一种 curiosity。
|
||||
|
||||
|
||||

|
||||
|
||||
怎么设计这个 ICM ?这个是最原始的设计。这个设计是这样。curiosity module 就是 input 3 个东西,input 现在的 state,input 在这个 state 采取的 action,然后接 input 下一个 state $s_{t+1}$。接下来会 output 一个 reward $r^i_t$。那这个 $r^i_t$ 是怎么算出来的呢?在 ICM 里面,你有一个 network,这个 network 会 take $a_t$ 跟$s_t$,然后去 output $\hat{s}_{t+1}$,也就是这个 network 根据 $a_t$ 和 $s_t$ 去 predict $\hat{s}_{t+1}$ 。接下来再看说,这个 network 的预测 $\hat{s}_{t+1}$ 跟真实的情况 $s_{t+1}$ 像不像,越不像那得到的 reward 就越大。所以这个 reward $r_t^i$ 的意思是说,如果未来的 state 越难被预测的话,那得到的 reward 就越大。这就是鼓励 machine 去冒险,现在采取这个 action,未来会发生什么事越没有办法预测的话,这个 action 的 reward 就大。所以如果有这样子的 ICM,machine 就会倾向于采取一些风险比较大的 action,它想要去探索未知的世界,它想要去看看说,假设某一个 state 是它没有办法预测,它会特别去想要采取那个 state,这可以增加 machine exploration 的能力。
|
||||
怎么设计这个 ICM ?这个是最原始的设计。这个设计是这样,curiosity module 就是 input 3 个东西,input 现在的 state,input 在这个 state 采取的 action,然后 input 下一个 state $s_{t+1}$。接下来会 output 一个 reward $r^i_t$。那这个 $r^i_t$ 是怎么算出来的呢?在 ICM 里面,你有一个 network,这个 network 会 take $a_t$ 跟$s_t$,然后去 output $\hat{s}_{t+1}$,也就是这个 network 根据 $a_t$ 和 $s_t$ 去 predict $\hat{s}_{t+1}$ 。接下来再看说,这个 network 的预测 $\hat{s}_{t+1}$ 跟真实的情况 $s_{t+1}$ 像不像,越不像那得到的 reward 就越大。所以这个 reward $r_t^i$ 的意思是说,如果未来的 state 越难被预测的话,那得到的 reward 就越大。这就是鼓励 machine 去冒险,现在采取这个 action,未来会发生什么事越没有办法预测的话,这个 action 的 reward 就大。所以如果有这样子的 ICM,machine 就会倾向于采取一些风险比较大的 action,它想要去探索未知的世界,它想要去看看说,假设某一个 state 是它没有办法预测,它会特别去想要采取那个 state,这可以增加 machine exploration 的能力。
|
||||
|
||||
这个 network 1 其实是另外 train 出来的。Training 的时候,这个network 1,你会给它 $a_t$、 $s_t$、 $s_{t+1}$,然后让这个network 1 去学说 given $a_t, s_t$,怎么 predict $\hat{s}_{t+1}$。Apply 到 agent 互动的时候,其实要把 ICM module fix 住。其实,这一整个想法里面是有一个问题的。这个问题是某一些 state它很难被预测并不代表它就是好的,它就应该要去被尝试的。举例来说,俄罗斯轮盘的结果也是没有办法预测的,并不代表说,人应该每天去玩俄罗斯轮盘这样子。所以只是鼓励 machine 去冒险是不够的,因为如果光是只有这个 network 的架构,machine 只知道说什么东西它无法预测。如果在某一个 state 采取某一个 action,它无法预测接下来结果,它就会采取那个action,但并不代表这样的结果一定是好的。举例来说,可能在某个游戏里面,背景会有风吹草动,会有树叶飘动。那也许树叶飘动这件事情,是很难被预测的,对 machine 来说它在某一个 state 什么都不做,看着树叶飘动,然后,发现这个树叶飘动是没有办法预测的,接下来它就会一直站在那边,看树叶飘动。所以说,光是有好奇心是不够的,还要让它知道说,什么事情是真正重要的。
|
||||
这个 network 1 其实是另外 train 出来的。Training 的时候,这个 network 1,你会给它 $a_t$、 $s_t$、 $s_{t+1}$,然后让这个network 1 去学说 given $a_t, s_t$,怎么 predict $\hat{s}_{t+1}$。Apply 到 agent 互动的时候,其实要把 ICM module fix 住。其实,这一整个想法里面是有一个问题的。这个问题是某一些 state它很难被预测并不代表它就是好的,它就应该要去被尝试的。举例来说,俄罗斯轮盘的结果也是没有办法预测的,并不代表说,人应该每天去玩俄罗斯轮盘这样子。所以只是鼓励 machine 去冒险是不够的,因为如果光是只有这个 network 的架构,machine 只知道说什么东西它无法预测。如果在某一个 state 采取某一个 action,它无法预测接下来结果,它就会采取那个 action,但并不代表这样的结果一定是好的。举例来说,可能在某个游戏里面,背景会有风吹草动,会有树叶飘动。那也许树叶飘动这件事情,是很难被预测的,对 machine 来说它在某一个 state 什么都不做,看着树叶飘动,然后,发现这个树叶飘动是没有办法预测的,接下来它就会一直站在那边,看树叶飘动。所以说,光是有好奇心是不够的,还要让它知道说,什么事情是真正重要的。
|
||||
|
||||

|
||||
|
||||
怎么让 machine 知道说什么事情是真正重要的?你要加上另外一个 module,我们要 learn 一个`feature extractor`,黄色的格子代表 feature extractor,它是 input 一个 state,然后 output 一个feature vector 来代表这个state,那我们期待这个 feature extractor 可以把那种没有意义的画面,state 里面没有意义的东西把它过滤掉,比如说风吹草动、白云的飘动、树叶的飘动这种没有意义的东西直接把它过滤掉,
|
||||
怎么让 machine 知道说什么事情是真正重要的?你要加上另外一个 module,我们要 learn 一个`feature extractor`,黄色的格子代表 feature extractor,它是 input 一个 state,然后 output 一个 feature vector 来代表这个 state,那我们期待这个 feature extractor 可以把那种没有意义的画面,state 里面没有意义的东西把它过滤掉,比如说风吹草动、白云的飘动、树叶的飘动这种没有意义的东西直接把它过滤掉,
|
||||
|
||||
假设这个 feature extractor 真的可以把无关紧要的东西过滤掉以后,network 1 实际上做的事情是,给它一个 actor,给它一个state $s_t$ 的feature representation,让它预测 state $s_{t+1}$ 的feature representation。接下来我们再看说,这个预测的结果跟真正的 state $s_{t+1}$ 的 feature representation 像不像,越不像,reward 就越大。怎么 learn 这个 feature extractor 呢?让这个feature extractor 可以把无关紧要的事情滤掉呢?这边的 learn 法就是 learn 另外一个network 2。这个 network 2 是吃 $\phi(s_t)$、$\phi(s_{t+1})$ 这两个 vector 当做 input,然后接下来它要predict action a 是什么,然后它希望呢这个 action a 跟真正的 action a 越接近越好。这个network 2 会 output 一个 action,它output 说,从 state $s_t$ 跳到 state $s_{t+1}$,要采取哪一个 action 才能够做到,那希望这个 action 跟真正的 action 越接近越好。加上这个 network 2 的好处就是因为要用 $\phi(s_t)$、$\phi(s_{t+1})$ 预测action。所以,今天我们抽出来的 feature 跟预测action 这件事情是有关的。所以风吹草动等与 machine 要采取的 action 无关的东西就会被滤掉,就不会被放在抽出来的 vector representation 里面。
|
||||
假设这个 feature extractor 真的可以把无关紧要的东西过滤掉以后,network 1 实际上做的事情是,给它一个 actor,给它一个 state $s_t$ 的 feature representation,让它预测 state $s_{t+1}$ 的 feature representation。接下来我们再看说,这个预测的结果跟真正的 state $s_{t+1}$ 的 feature representation 像不像,越不像,reward 就越大。怎么 learn 这个 feature extractor 呢?让这个 feature extractor 可以把无关紧要的事情滤掉呢?这边的 learn 法就是 learn 另外一个network 2。这个 network 2 是吃 $\phi(s_t)$、$\phi(s_{t+1})$ 这两个 vector 当做 input,然后接下来它要 predict action a 是什么,然后它希望呢这个 action a 跟真正的 action a 越接近越好。这个 network 2 会 output 一个 action,它 output 说,从 state $s_t$ 跳到 state $s_{t+1}$,要采取哪一个 action 才能够做到,那希望这个 action 跟真正的 action 越接近越好。加上这个 network 2 的好处就是因为要用 $\phi(s_t)$、$\phi(s_{t+1})$ 预测 action。所以,今天我们抽出来的 feature 跟预测 action 这件事情是有关的。所以风吹草动等与 machine 要采取的 action 无关的东西就会被滤掉,就不会被放在抽出来的 vector representation 里面。
|
||||
|
||||
|
||||
|
||||
## Curriculum Learning
|
||||
|
||||

|
||||
接下来讲 `curriculum learning` ,curriculum learning 不是 reinforcement learning 所独有的概念。其实在 machine learning,尤其是 deep learning 里面,你都会用到 curriculum learning 的概念。举例来说,curriculum learning 的意思是说,你为机器的学习做规划,你给他喂 training data 的时候,是有顺序的,通常都是由简单到难。就好比说,假设你今天要交一个小朋友作微积分,他做错就打他一巴掌,这样他永远都不会做对,太难了。你要先教他九九乘法,然后才教他微积分。所以curriculum learning 的意思就是在教机器的时候,从简单的题目教到难的题目。就算不是 reinforcement learning,一般在 train deep network 的时候,你有时候也会这么做。举例来说,在 train RNN 的时候,已经有很多的文献都 report 说,你给机器先看短的 sequence,再慢慢给它长的 sequence,通常可以学得比较好。那用在reinforcement learning 里面,你就是要帮机器规划一下它的课程,从最简单的到最难的。 举例来说,在 Facebook 玩 VizDoom 的 agent 里面,Facebook 玩 VizDoom 的 agent 蛮强的。他们在参加这个 VizDoom 的比赛,机器的 VizDoom 比赛是得第一名的,他们是有为机器规划课程的。先从课程 0 一直上到课程 7。在这个课程里面,怪物的速度跟血量是不一样的。所以,在越进阶的课程里面,怪物的速度越快,然后他的血量越多。在 paper 里面也有讲说,如果直接上课程 7,machine 是学不起来的。你就是要从课程 0 一路玩上去,这样 machine 才学得起来。
|
||||
接下来讲 `curriculum learning` 。Curriculum learning 不是 reinforcement learning 所独有的概念,其实在 machine learning,尤其是 deep learning 里面,你都会用到 curriculum learning 的概念。举例来说,curriculum learning 的意思是说,你为机器的学习做规划,你给他喂 training data 的时候,是有顺序的,通常都是由简单到难。就好比说,假设你今天要交一个小朋友作微积分,他做错就打他一巴掌,这样他永远都不会做对,太难了。你要先教他九九乘法,然后才教他微积分。所以 curriculum learning 的意思就是在教机器的时候,从简单的题目教到难的题目。就算不是 reinforcement learning,一般在 train deep network 的时候,你有时候也会这么做。举例来说,在 train RNN 的时候,已经有很多的文献都 report 说,你给机器先看短的 sequence,再慢慢给它长的 sequence,通常可以学得比较好。那用在 reinforcement learning 里面,你就是要帮机器规划一下它的课程,从最简单的到最难的。
|
||||
|
||||
再举个例子,把蓝色的板子穿过柱子,怎么让机器一直从简单学到难呢?
|
||||
* 举例来说,在 Facebook 玩 VizDoom 的 agent 里面,Facebook 玩 VizDoom 的 agent 蛮强的。他们在参加这个 VizDoom 的比赛,机器的 VizDoom 比赛是得第一名的,他们是有为机器规划课程的。先从课程 0 一直上到课程 7。在这个课程里面,怪物的速度跟血量是不一样的。所以,在越进阶的课程里面,怪物的速度越快,然后他的血量越多。在 paper 里面也有讲说,如果直接上课程 7,machine 是学不起来的。你就是要从课程 0 一路玩上去,这样 machine 才学得起来。
|
||||
|
||||
如第一张图所示,也许一开始机器初始的时候,它的板子就已经在柱子上了。这个时候,机器要做的事情只有把蓝色的板子压下去,就结束了。这比较简单,它应该很快就学的会。它只有往上跟往下这两个选择嘛,往下就得到 reward,就结束了,他也不知道学的是什么。
|
||||
|
||||
如第二张图所示,这边就是把板子挪高一点,挪高一点,所以它有时候会很笨的往上拉,然后把板子拿出来了。如果它压板子学得会的话,拿板子也比较有机会学得会。假设它现在学的到说,只要板子接近柱子,它就可以把这个板子压下去的话。接下来,你再让它学更 general 的 case。
|
||||
|
||||
如第三张图所示,一开始,让板子离柱子远一点。然后,板子放到柱子上面的时候,它就会知道把板子压下去,这个就是Curriculum Learning 的概念。当然 curriculum learning 有点 ad hoc(特别),就是需要人去为机器设计它的课程。
|
||||
* 再举个例子,把蓝色的板子穿过柱子,怎么让机器一直从简单学到难呢?
|
||||
* 如第一张图所示,也许一开始机器初始的时候,它的板子就已经在柱子上了。这个时候,机器要做的事情只有把蓝色的板子压下去,就结束了。这比较简单,它应该很快就学的会。它只有往上跟往下这两个选择嘛,往下就得到 reward,就结束了,他也不知道学的是什么。
|
||||
* 如第二张图所示,这边就是把板子挪高一点,挪高一点,所以它有时候会很笨的往上拉,然后把板子拿出来了。如果它压板子学得会的话,拿板子也比较有机会学得会。假设它现在学的到说,只要板子接近柱子,它就可以把这个板子压下去的话。接下来,你再让它学更 general 的 case。
|
||||
* 如第三张图所示,一开始,让板子离柱子远一点。然后,板子放到柱子上面的时候,它就会知道把板子压下去,这个就是 curriculum learning 的概念。当然 curriculum learning 有点 ad hoc(特别),就是需要人去为机器设计它的课程。
|
||||
|
||||

|
||||
|
||||
有一个比较 general 的方法叫做 `Reverse Curriculum Generation`。你可以用一个比较通用的方法来帮机器设计课程,这个比较通用的方法是怎么样呢?假设你现在一开始有一个state $s_g$,这是你的gold state,也就是最后最理想的结果。如果拿刚才那个板子和柱子的实验作为例子的话,就把板子放到柱子里面,这样子叫做 gold state。你就已经完成了,或者你让机器去抓东西,你训练一个机器手臂抓东西,抓到东西以后叫做 gold state。接下来你根据你的 gold state 去找其他的 state,这些其他的 state 跟 gold state 是比较接近的。举例来说,如果是让机器抓东西的例子里面,你的机器手臂可能还没有抓到东西。假设这些跟 gold state 很近的 state 叫做 $s_1$。你的机械手臂还没有抓到东西,但它离 gold state 很近,那这个叫做$s_1$。至于什么叫做近,这是 case dependent,你要根据你的 task 来 design 说怎么从 $s_g$ sample 出 $s_1$。如果是机械手臂的例子,可能就比较好想。其他例子可能就比较难想。接下来呢,你再从这些 $s_1$ 开始做互动,看它能不能够达到gold state $s_g$,那每一个state,你跟环境做互动的时候,你都会得到一个reward R。
|
||||
有一个比较 general 的方法叫做 `Reverse Curriculum Generation`。你可以用一个比较通用的方法来帮机器设计课程,这个比较通用的方法是怎么样呢?假设你现在一开始有一个 state $s_g$,这是你的 gold state,也就是最后最理想的结果。如果拿刚才那个板子和柱子的实验作为例子的话,就把板子放到柱子里面,这样子叫做 gold state。你就已经完成了,或者你让机器去抓东西,你训练一个机器手臂抓东西,抓到东西以后叫做 gold state。接下来你根据你的 gold state 去找其他的 state,这些其他的 state 跟 gold state 是比较接近的。举例来说,如果是让机器抓东西的例子里面,你的机器手臂可能还没有抓到东西。假设这些跟 gold state 很近的 state 叫做 $s_1$。你的机械手臂还没有抓到东西,但它离 gold state 很近,那这个叫做$s_1$。至于什么叫做近,这是 case dependent,你要根据你的 task 来 design 说怎么从 $s_g$ sample 出 $s_1$。如果是机械手臂的例子,可能就比较好想。其他例子可能就比较难想。接下来呢,你再从这些 $s_1$ 开始做互动,看它能不能够达到 gold state $s_g$,那每一个 state,你跟环境做互动的时候,你都会得到一个 reward R。
|
||||
|
||||

|
||||
|
||||
接下来,我们把 reward 特别极端的 case 去掉,reward 特别极端的 case 的意思就是说那些 case 太简单或是太难了。如果 reward 很大,代表说这个 case 太简单了,就不用学了,因为机器已经会了,它可以得到很大的 reward。如果 reward 太小,代表这个 case 太难了,依照机器现在的能力这个课程太难了,它学不会,所以就不要学这个,所以只找一些 reward 适中的 case。那当然什么叫做适中,这个就是你要调的参数,找一些 reward 适中的 case。接下来,再根据这些 reward 适中的 case 去 sample 出更多的 state。就假设你一开始,你机械手臂在这边,可以抓的到以后。接下来,就再离远一点,看看能不能够抓得到,又抓的到以后,再离远一点,看看能不能抓得到。这是一个有用的方法,它叫做`Reverse Curriculum learning`。刚才讲的是 Curriculum learning,就是你要为机器规划它学习的顺序。而 reverse curriculum learning 是从 gold state 去反推,就是说你原来的目标是长这个样子,我们从我们的目标去反推,所以这个叫做 reverse。
|
||||
接下来,我们把 reward 特别极端的 case 去掉。Reward 特别极端的 case 的意思就是说那些 case 太简单或是太难了。如果 reward 很大,代表说这个 case 太简单了,就不用学了,因为机器已经会了,它可以得到很大的 reward。如果 reward 太小,代表这个 case 太难了,依照机器现在的能力这个课程太难了,它学不会,所以就不要学这个,所以只找一些 reward 适中的 case。那当然什么叫做适中,这个就是你要调的参数,找一些 reward 适中的 case。接下来,再根据这些 reward 适中的 case 去 sample 出更多的 state。就假设你一开始,你机械手臂在这边,可以抓的到以后。接下来,就再离远一点,看看能不能够抓得到,又抓的到以后,再离远一点,看看能不能抓得到。这是一个有用的方法,它叫做`Reverse Curriculum learning`。刚才讲的是 curriculum learning,就是你要为机器规划它学习的顺序。而 reverse curriculum learning 是从 gold state 去反推,就是说你原来的目标是长这个样子,我们从目标去反推,所以这个叫做 reverse。
|
||||
|
||||
## Hierarchical RL
|
||||
|
||||

|
||||
|
||||
那最后一个 tip 叫做 `Hierarchical Reinforcement learning`,分层的 reinforcement learning。
|
||||
所谓分层的Reinforcement learning 是说,我们有好几个 agent。然后,有一些agent 负责比较high level 的东西,它负责订目标,然后它订完目标以后,再分配给其他的 agent,去把它执行完成。这样的想法其实也是很合理的。因为我们知道说,我们人在一生之中,并不是时时刻刻都在做决定。举例来说,假设你想要写一篇paper,你会说就我先想个梗这样子,然后想完梗以后,你还要跑个实验。跑完实验以后,你还要写。写完以后呢,你还要这个去发表。每一个动作下面又还会再细分,比如说怎么跑实验呢?你要先 collect data,collect 完data 以后,你要再 label,你要弄一个network,然后又 train 不起来,要 train 很多次。然后重新 design network 架构好几次,最后才把network train 起来。
|
||||
所谓分层的 reinforcement learning 是说,我们有好几个 agent。然后,有一些 agent 负责比较 high level 的东西,它负责订目标,然后它订完目标以后,再分配给其他的 agent,去把它执行完成。这样的想法其实也是很合理的。因为我们知道说,我们人在一生之中,并不是时时刻刻都在做决定。举例来说,假设你想要写一篇 paper,你会说就我先想个梗这样子,然后想完梗以后,你还要跑个实验。跑完实验以后,你还要写。写完以后呢,你还要这个去发表。每一个动作下面又还会再细分,比如说怎么跑实验呢?你要先 collect data,collect 完 data 以后,你要再 label,你要弄一个 network,然后又 train 不起来,要 train 很多次。然后重新 design network 架构好几次,最后才把 network train 起来。
|
||||
|
||||
所以,我们要完成一个很大的 task 的时候,我们并不是从非常底层的那些 action 开始想起,我们其实是有个 plan。我们先想说,如果要完成这个最大的任务,那接下来要拆解成哪些小任务。每一个小任务要再怎么拆解成小小的任务。举例来说,叫你直接写一本书可能很困难,但叫你先把一本书拆成好几个章节,每个章节拆成好几段,每一段又拆成好几个句子,每一个句子又拆成好几个词汇,这样你可能就比较写得出来,这个就是分层的 Reinforcement learning 的概念。
|
||||
所以,我们要完成一个很大的 task 的时候,我们并不是从非常底层的那些 action 开始想起,我们其实是有个 plan。我们先想说,如果要完成这个最大的任务,那接下来要拆解成哪些小任务。每一个小任务要再怎么拆解成小小的任务。举例来说,叫你直接写一本书可能很困难,但叫你先把一本书拆成好几个章节,每个章节拆成好几段,每一段又拆成好几个句子,每一个句子又拆成好几个词汇,这样你可能就比较写得出来,这个就是分层的 reinforcement learning 的概念。
|
||||
|
||||
这边是举一个例子,就是假设校长、教授和研究生通通都是 agent。那今天假设我们的reward 就是只要进入百大就可以得到 reward。假设进入百大的话,校长就要提出愿景告诉其他的agent 说,现在你要达到什么样的目标。那校长的愿景可能就是说教授每年都要发三篇期刊。然后接下来这些agent 都是有分层的,所以上面的 agent,他的动作就是提出愿景这样。那他把他的愿景传给下一层的agent,下一层的 agent 就把这个愿景吃下去。如果他下面还有其他人的话,它就会提出新的愿景。比如说,校长要教授发期刊,但其实教授自己也是不做实验的。所以,教授也只能够叫下面的研究生做实验。所以教授就提出愿景,就做出实验的规划,然后研究生才是真的去执行这个实验的人。然后,真的把实验做出来,最后大家就可以得到reward。那现在是这样子的,在 learn 的时候,其实每一个 agent 都会 learn。那他们的整体的目标就是要达到最后的reward。那前面的这些 agent,他提出来的 actions 就是愿景这样。你如果是玩游戏的话,他提出来的就是,我现在想要产生这样的游戏画面。但是,假设他提出来的愿景是下面的 agent 达不到的,那就会被讨厌。举例来说,教授对研究生都一直逼迫研究生做一些很困难的实验,研究生都做不出来的话,研究生就会跑掉,所以他就会得到一个penalty。所以如果今天下层的 agent 没有办法达到上层 agent 所提出来的 goal 的话,上层的 agent 就会被讨厌,它就会得到一个 negative reward。所以他要避免提出那些愿景是底下的agent 所做不到的。那每一个agent 都是把上层的 agent 所提出来的愿景当作输入,然后决定他自己要产生什么输出。
|
||||
这边是举一个例子,就是假设校长、教授和研究生通通都是 agent。那今天假设我们只要进入百大就可以得到 reward。假设进入百大的话,校长就要提出愿景告诉其他的 agent 说,现在你要达到什么样的目标。那校长的愿景可能就是说教授每年都要发三篇期刊。然后接下来这些 agent 都是有分层的,所以上面的 agent,他的动作就是提出愿景这样。那他把他的愿景传给下一层的 agent,下一层的 agent 就把这个愿景吃下去。如果他下面还有其他人的话,它就会提出新的愿景。比如说,校长要教授发期刊,但其实教授自己也是不做实验的。所以,教授也只能够叫下面的研究生做实验。所以教授就提出愿景,就做出实验的规划,然后研究生才是真的去执行这个实验的人。然后,真的把实验做出来,最后大家就可以得到reward。那现在是这样子的,在 learn 的时候,其实每一个 agent 都会 learn。那他们的整体的目标就是要达到最后的reward。那前面的这些 agent,他提出来的 actions 就是愿景这样。你如果是玩游戏的话,他提出来的就是,我现在想要产生这样的游戏画面。但是,假设他提出来的愿景是下面的 agent 达不到的,那就会被讨厌。举例来说,教授对研究生都一直逼迫研究生做一些很困难的实验,研究生都做不出来的话,研究生就会跑掉,所以他就会得到一个 penalty。所以如果今天下层的 agent 没有办法达到上层 agent 所提出来的 goal 的话,上层的 agent 就会被讨厌,它就会得到一个 negative reward。所以他要避免提出那些愿景是底下的 agent 所做不到的。那每一个 agent 都是把上层的 agent 所提出来的愿景当作输入,然后决定他自己要产生什么输出。
|
||||
|
||||
但是你知道说,就算你看到上面的的愿景说,叫你做这一件事情。你最后也不一定能做成这一件事情。假设本来教授目标是要写期刊,但是不知道怎么回事,他就要变成一个YouTuber。这个paper 里面的 solution,我觉得非常有趣。给大家做一个参考,这其实本来的目标是要写期刊,但却变成 YouTuber,那怎么办呢? 把原来的愿景改成变成 YouTuber 就行了,在paper 里面就是这么做的,为什么这么做呢? 因为虽然本来的愿景是要写期刊,但是后来变成YouTuber,难道这些动作都浪费了吗? 不是,这些动作是没有被浪费的。我们就假设说,本来的愿景其实就是要成为YouTuber,那你就知道成为 YouTuber 要怎做了。这个是分层 RL,是可以做得起来的 tip。
|
||||
但是你知道说,就算你看到上面的的愿景说,叫你做这一件事情。你最后也不一定能做成这一件事情。假设本来教授目标是要写期刊,但是不知道怎么回事,他就要变成一个 YouTuber。这个 paper 里面的 solution,我觉得非常有趣。给大家做一个参考,这其实本来的目标是要写期刊,但却变成 YouTuber,那怎么办呢? 把原来的愿景改成变成 YouTuber 就行了,在 paper 里面就是这么做的,为什么这么做呢? 因为虽然本来的愿景是要写期刊,但是后来变成 YouTuber,难道这些动作都浪费了吗? 不是,这些动作是没有被浪费的。我们就假设说,本来的愿景其实就是要成为 YouTuber,那你就知道成为 YouTuber 要怎做了。这个是分层 RL,是可以做得起来的 tip。
|
||||
|
||||

|
||||
|
||||
@@ -78,4 +75,4 @@ Reward shaping是有问题的,因为我们需要 domain knowledge,举例来
|
||||
|
||||
走迷宫的例子是说粉红色的这个点代表的就是愿景。上层这个 agent,它告诉蓝色的这个 agent 说,你现在的第一个目标是先走到这个地方,蓝色的 agent 走到以后,再说你的新的目标是走到这里。蓝色的 agent 再走到以后,新的目标在这里。接下来又跑到这边,最后希望蓝色的 agent 就可以走到黄色的这个位置。
|
||||
|
||||
单摆的例子也一样,就是粉红色的这个点代表的是上层的 agent 所提出来的愿景,所以这个agent 先摆到这边,接下来,新的愿景又跑到这边,所以它又摆到这里。然后,新的愿景又跑到上面。然后又摆到上面,最后就走到黄色的位置了。这个就是 hierarchical 的 Reinforcement Learning。
|
||||
单摆的例子也一样,就是粉红色的这个点代表的是上层的 agent 所提出来的愿景,所以这个 agent 先摆到这边,接下来,新的愿景又跑到这边,所以它又摆到这里。然后,新的愿景又跑到上面。然后又摆到上面,最后就走到黄色的位置了。这个就是 hierarchical 的 reinforcement learning。
|
||||
|
||||
@@ -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,14 +54,14 @@ 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)$。
|
||||
|
||||
为了区分前面的 Q网络和策略网络以及后面的 target_Q 网络和 target_p 策略网络。前面的网络的参数是 $w$,后面的网络的参数是 $\bar{w}$。这就是为什么我们去看一些 DDPG 的文章,会发现 DDPG 会有四个网络。策略网络的 target 网络 和 Q 网络的 target 网络就是颜色比较深的这两个,它只是为了让计算 Q_target 的时候能够更稳定一点而已。因为这两个网络也是固定一段时间的参数之后再跟评估网络同步一下最新的参数。
|
||||
|
||||
这里面训练需要用到的数据就是 $s,a,r,s'$。我们只需要用到这四个数据,我们就用 Replay Memory 把这些数据存起来,然后再 sample 进来训练就好了。这个经验回放的技巧跟 DQN 是一模一样的。注意,因为 DDPG 使用了经验回放这个技巧,所以 DDPG 是一个 `off-policy` 的算法。这边我们给出 [DDPG 的 PyTorch 实现](https://github.com/datawhalechina/leedeeprl-notes/tree/master/codes/ddpg)。
|
||||
这里面训练需要用到的数据就是 $s,a,r,s'$。我们只需要用到这四个数据,我们就用 Replay Memory 把这些数据存起来,然后再 sample 进来训练就好了。这个经验回放的技巧跟 DQN 是一模一样的。注意,因为 DDPG 使用了经验回放这个技巧,所以 DDPG 是一个 `off-policy` 的算法。
|
||||
|
||||
## Exploration vs. Exploitation
|
||||
DDPG 通过 off-policy 的方式来训练一个确定性策略。因为策略是确定的,如果 agent 使用同策略来探索,在一开始的时候,它会很可能不会尝试足够多的 action 来找到有用的学习信号。为了让 DDPG 的策略更好地探索,我们在训练的时候给它们的 action 加了噪音。DDPG 的原作者推荐使用时间相关的 [OU noise](https://en.wikipedia.org/wiki/Ornstein–Uhlenbeck_process),但最近的结果表明不相关的、均值为 0 的 Gaussian noise 的效果非常好。由于后者更简单,因此我们更喜欢使用它。为了便于获得更高质量的训练数据,你可以在训练过程中把噪声变小。
|
||||
|
||||
@@ -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 对应的价值函数。
|
||||
|
||||

|
||||
|
||||
@@ -234,13 +234,13 @@ $$
|
||||
|
||||

|
||||
|
||||
我们再来看一个动态的例子。这里有很多格子,每个格子都代表了一个状态。在每个格子里面有一个初始值零。然后在每一个状态,它还有一些箭头,这个箭头就是说它在当前这个状态应该采取什么样的策略。我们这里采取一个随机的策略,不管它在哪一个状态,它上下左右的概率都是相同的。比如在某个状态,它都有上下左右 0.25 的概率采取某一个行为,所以它是一个完全随机的一个行为。
|
||||
我们再来看一个动态的例子,首先推荐斯坦福大学的一个网站:[Temporal Difference Learning Gridworld Demo](https://cs.stanford.edu/people/karpathy/reinforcejs/gridworld_td.html) ,这个网站模拟了单步更新的过程中,所有格子的一个状态价值的变化过程。
|
||||
|
||||

|
||||
这里有很多格子,每个格子都代表了一个状态。在每个格子里面有一个初始值零。然后在每一个状态,它还有一些箭头,这个箭头就是说它在当前这个状态应该采取什么样的策略。我们这里采取一个随机的策略,不管它在哪一个状态,它上下左右的概率都是相同的。比如在某个状态,它都有上下左右 0.25 的概率采取某一个行为,所以它是一个完全随机的一个行为。
|
||||
|
||||
在这样的环境里面,我们想计算它每一个状态的价值。我们也定义了它的 reward function,你可以看到有些状态上面有一个 R 的值。比如我们这边有些值是为负的,然后在这个棋盘的中间这个位置,可以看到有一个 R 的值是 1.0,为正的一个价值函数。 所以每个状态对应了一个值,然后有一些状态没有任何值,就说明它的这个 reward function,它的奖励是为零的。
|
||||
在这样的环境里面,我们想计算它每一个状态的价值。我们也定义了它的 reward function,你可以看到有些状态上面有一个 R 的值。比如我们这边有些值是为负的,我们可以看到格子里面有几个 -1 的 reward,只有一个 +1 reward 的格子。在这个棋盘的中间这个位置,可以看到有一个 R 的值是 1.0,为正的一个价值函数。 所以每个状态对应了一个值,然后有一些状态没有任何值,就说明它的这个 reward function,它的奖励是为零的。
|
||||
|
||||
所以,当我们开始做这个 policy evaluation,policy evaluation是一个不停迭代的过程。当我们初始化的时候,所有的 $v(s)$ 都是 0。我们现在迭代一次,迭代一次过后,你发现有些状态上面,值已经产生了变化。比如说那些有奖励的值,比如有些状态的值的 R 为 -1,迭代一次过后,它就会得到 -1 的这个奖励。对于中间这个绿色的,因为它的奖励为正,所以它是 + 1 的状态。
|
||||
我们开始做这个 policy evaluation,policy evaluation 是一个不停迭代的过程。当我们初始化的时候,所有的 $v(s)$ 都是 0。我们现在迭代一次,迭代一次过后,你发现有些状态上面,值已经产生了变化。比如说那些有奖励的值,比如有些状态的值的 R 为 -1,迭代一次过后,它就会得到 -1 的这个奖励。对于中间这个绿色的,因为它的奖励为正,所以它是 + 1 的状态。
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||

|
||||
|
||||
强化学习的三个重要的要素:状态、动作和奖励。强化学习智能体跟环境是一步一步交互的,就是我先观察一下状态,然后再输入动作。再观察一下状态,再输出动作,拿到这些 reward 。它是一个跟时间相关的序列决策的问题。
|
||||
**强化学习的三个重要的要素:状态、动作和奖励。**强化学习智能体跟环境是一步一步交互的,就是我先观察一下状态,然后再输入动作。再观察一下状态,再输出动作,拿到这些 reward 。它是一个跟时间相关的序列决策的问题。
|
||||
|
||||
举个例子,在 $t-1$ 时刻,我看到了熊对我招手,那我下意识的可能输出的动作就是赶紧跑路。熊看到了有人跑了,可能就觉得发现猎物,开始发动攻击。而在 $t$ 时刻的话,我如果选择装死的动作,可能熊咬了咬我那个摔了几下就发现就觉得挺无趣的,可能会走开。这个时候,我再跑路的话可能就跑路成功了,就是这样子的一个序列决策的过程。
|
||||
举个例子,在 $t-1$ 时刻,我看到了熊对我招手,那我下意识的可能输出的动作就是赶紧跑路。熊看到了有人跑了,可能就觉得发现猎物,开始发动攻击。而在 $t$ 时刻的话,我如果选择装死的动作,可能熊咬了咬我,摔了几下就发现就觉得挺无趣的,可能会走开。这个时候,我再跑路的话可能就跑路成功了,就是这样子的一个序列决策的过程。
|
||||
|
||||
当然在输出每一个动作之前,你可以选择不同的动作。比如说在 $t$ 时刻,我选择跑路的时候,熊已经追上来了,如果说 $t$ 时刻,我没有选择装死,而我是选择跑路的话,这个时候熊已经追上了,那这个时候,其实我有两种情况转移到不同的状态去,就我有一定的概率可以逃跑成功,也有很大的概率我会逃跑失败。那我们就用状态转移概率 $p\left[s_{t+1}, r_{t} \mid s_{t}, a_{t}\right]$ 来表述说在 $s_t$ 的状态选择了 $a_t$ 的动作的时候,转移到 $s_{t+1}$ ,而且拿到 $r_t$ 的概率是多少。
|
||||
|
||||
@@ -27,7 +27,7 @@ MDP 就是序列决策这样一个经典的表达方式。MDP 也是强化学习
|
||||
|
||||
如上图所示,我们把这些可能的动作和可能的状态转移的关系画成一个树状图。它们之间的关系就是从 $s_t$ 到 $a_t$ ,再到 $s_{t+1}$ ,再到 $a_{t+1}$,再到 $s_{t+2}$ 这样子的一个过程。
|
||||
|
||||
我们去跟环境交互,只能走完整的一条通路。这里面产生了一系列的一个决策的过程,就是我们跟环境交互产生了一个经验。我们会使用 P 函数(probability function)和 R 函数(reward function)来去描述环境。P 函数就是状态转移的概率,P 函数实际上反映的是环境的一个随机性。
|
||||
我们去跟环境交互,只能走完整的一条通路。这里面产生了一系列的一个决策的过程,就是我们跟环境交互产生了一个经验。我们会使用 `P 函数(probability function)`和 `R 函数(reward function)`来去描述环境。P 函数就是状态转移的概率,P 函数实际上反映的是环境的一个随机性。
|
||||
|
||||
比如,在熊发怒的情况下,我如果选择装死,假设熊看到人装死就一定会走的话,我们就称在这里面的状态转移概率就是百分之百。但如果说在熊发怒的情况下,我选择跑路而导致可能跑成功以及跑失败,出现这两种情况。那我们就可以用概率去表达一下说转移到其中一种情况的概率大概 10%,另外一种情况的概率大概是 90% 会跑失败。**如果我们知道这些状态转移概率和奖励函数的话,就说这个环境是已知的,因为我们是用这两个函数去描述环境的。**如果是已知的话,我们其实可以用动态规划去计算说,如果要逃脱熊,那么能够逃脱熊概率最大的最优策略是什么。很多强化学习的经典算法都是 model-free 的,就是环境是未知的。
|
||||
|
||||
@@ -83,7 +83,7 @@ $$
|
||||

|
||||
类似于上图,最后我们要求解的就是一张 Q 表格,它的行数是所有的状态数量,一般可以用坐标来表示表示格子的状态,也可以用 1、2、3、4、5、6、7 来表示不同的位置。Q 表格的列表示上下左右四个动作。最开始这张 Q 表格会全部初始化为零,然后 agent 会不断地去和环境交互得到不同的轨迹,当交互的次数足够多的时候,我们就可以估算出每一个状态下,每个行动的平均总收益去更新这个 Q 表格。怎么去更新 Q 表格就是接下来要引入的强化概念。
|
||||
|
||||
强化就是我们可以用下一个状态的价值来更新当前状态的价值,其实就是强化学习里面有一个 bootstrap 的概念。在强化学习里面,你可以每走一步更新一下 Q 表格,然后用下一个状态的 Q 值来更新这个状态的 Q 值,这种单步更新的方法叫做`时序差分`。
|
||||
`强化`就是我们可以用下一个状态的价值来更新当前状态的价值,其实就是强化学习里面有一个 bootstrap 的概念。在强化学习里面,你可以每走一步更新一下 Q 表格,然后用下一个状态的 Q 值来更新这个状态的 Q 值,这种单步更新的方法叫做`时序差分`。
|
||||
|
||||

|
||||
|
||||
@@ -91,21 +91,23 @@ $$
|
||||
|
||||

|
||||
|
||||
巴普洛夫效应揭示的是中性刺激(铃声)跟无条件刺激(食物)紧紧挨着反复出现的时候,条件刺激也可以引起无条件刺激引起的唾液分泌,然后形成这个条件刺激。这种中性刺激跟无条件刺激在时间上面的结合,我们就称之为强化。 强化的次数越多,条件反射就会越巩固。小狗本来不觉得铃声有价值的,经过强化之后,小狗就会慢慢地意识到铃声也是有价值的,它可能带来食物。更重要是一种条件反射巩固之后,我们再用另外一种新的刺激和条件反射去结合,还可以形成第二级条件反射,同样地还可以形成第三级条件反射。在人的身上是可以建立多级的条件反射的,举个例子,比如说一般我们遇到熊都是这样一个顺序,看到树上有熊爪,然后看到熊之后,突然熊发怒,扑过来了。经历这个过程之后,我们可能最开始看到熊才会瑟瑟发抖,后面就是看到树上有熊爪就已经有害怕的感觉了。也就说在不断的重复试验之后,下一个状态的价值,它是可以不断地去强化影响上一个状态的价值的。
|
||||
巴普洛夫效应揭示的是中性刺激(铃声)跟无条件刺激(食物)紧紧挨着反复出现的时候,条件刺激也可以引起无条件刺激引起的唾液分泌,然后形成这个条件刺激。这种中性刺激跟无条件刺激在时间上面的结合,我们就称之为强化。 强化的次数越多,条件反射就会越巩固。小狗本来不觉得铃声有价值的,经过强化之后,小狗就会慢慢地意识到铃声也是有价值的,它可能带来食物。更重要是一种条件反射巩固之后,我们再用另外一种新的刺激和条件反射去结合,还可以形成第二级条件反射,同样地还可以形成第三级条件反射。
|
||||
|
||||
在人的身上是可以建立多级的条件反射的,举个例子,比如说一般我们遇到熊都是这样一个顺序,看到树上有熊爪,然后看到熊之后,突然熊发怒,扑过来了。经历这个过程之后,我们可能最开始看到熊才会瑟瑟发抖,后面就是看到树上有熊爪就已经有害怕的感觉了。也就说在不断的重复试验之后,下一个状态的价值,它是可以不断地去强化影响上一个状态的价值的。
|
||||
|
||||

|
||||
|
||||
为了让大家更加直观感受下一个状态影响上一个状态,这里推荐斯坦福大学的一个网站:[Temporal Difference Learning Gridworld Demo](https://cs.stanford.edu/people/karpathy/reinforcejs/gridworld_td.html)。这个网站模拟了就是这种单步更新的过程中,所有格子的一个状态价值的变化过程。我们可以看到格子里面有几个 -1的 reward,只有一个 +1 reward 的那个格子。
|
||||
为了让大家更加直观感受下一个状态影响上一个状态,我们再次推荐这个网站:[Temporal Difference Learning Gridworld Demo](https://cs.stanford.edu/people/karpathy/reinforcejs/gridworld_td.html)。
|
||||
|
||||

|
||||
|
||||
玩起来是这样的,先初始化一下,然后开始时序差分的更新过程。在训练的过程中,你会看到这个小黄球在不断地试错,在探索当中会先迅速地发现有 reward 的地方。最开始的时候,只是这些有 reward 的格子 才有价值。当不断地重复走这些路线的时候,这些有价值的格子,它可以去慢慢地影响它附近的格子的价值。反复训练之后,有 reward 的这些格子周围的格子的状态就会慢慢地被强化,强化就是当它收敛到最后一个最优的状态了,就是把这些价值最终收敛到一个最优的情况之后,那个小黄球就会自动地知道,就是我一直往价值高的地方走,我就能够走到能够拿到 reward 的地方。
|
||||
我们先初始化一下,然后开始时序差分的更新过程。在训练的过程中,你会看到这个小黄球在不断地试错,在探索当中会先迅速地发现有 reward 的地方。最开始的时候,只是这些有 reward 的格子 才有价值。当不断地重复走这些路线的时候,这些有价值的格子可以去慢慢地影响它附近的格子的价值。反复训练之后,有 reward 的这些格子周围的格子的状态就会慢慢地被强化,强化就是当它收敛到最后一个最优的状态了,就是把这些价值最终收敛到一个最优的情况之后,那个小黄球就会自动地知道,就是我一直往价值高的地方走,就能够走到能够拿到 reward 的地方。
|
||||
|
||||
### Temporal Difference
|
||||
|
||||

|
||||
|
||||
这种强化方式其实在数学上面一行公式就表达出来了。这种更新的方式叫做`时序差分(Temporal Difference)`。这个公式就是说可以拿下一步的 Q 值 $Q(S_{t+_1},A_{t+1})$ 来更新我这一步的 Q 值 $Q(S_t,A_t)$ 。
|
||||
这种强化方式其实在数学上面一行公式就表达出来了,这种更新的方式叫做`时序差分(Temporal Difference)`。这个公式就是说可以拿下一步的 Q 值 $Q(S_{t+_1},A_{t+1})$ 来更新我这一步的 Q 值 $Q(S_t,A_t)$ 。
|
||||
|
||||
为了理解这个公式,如图所示,我们先把 $R_{t+1}+\gamma Q\left(S_{t+1}, A_{t+1}\right.)$ 当作是一个目标值,就是 $Q(S_t,A_t)$ 想要去逼近的一个目标值。我们想要计算的就是 $Q(S_t,A_t)$ 。因为最开始 Q 值都是随机初始化或者是初始化为零,它需要不断地去逼近它理想中真实的 Q 值,我们就叫 target 。Target 就是未来收益的总和大概有多少,而且是带衰减的那个。
|
||||
|
||||
@@ -208,8 +210,6 @@ $$
|
||||
|
||||
总结如上图所示。
|
||||
|
||||
|
||||
|
||||
## References
|
||||
|
||||
* [百面深度学习](https://book.douban.com/subject/35043939/)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# 贪吃蛇
|
||||
# 使用 Q-learning 实现贪吃蛇
|
||||
|
||||
贪吃蛇是一个起源于1976年的街机游戏 Blockade,玩家控制蛇上下左右吃到食物并将身体增长,吃到食物后移动速度逐渐加快,直到碰到墙体或者蛇的身体算游戏结束。
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
|
||||
## 任务要求
|
||||
|
||||
设计一个Q网络用于学习snake游戏,并绘制reward以及滑动平均后的reward随epiosde的变化曲线图并记录超参数写成报告。
|
||||
|
||||
|
||||
设计一个Q-learning agent用于学习snake游戏,并绘制reward以及滑动平均后的reward随episode的变化曲线图并记录超参数写成报告。
|
||||
|
||||
[参考代码](https://github.com/datawhalechina/leedeeprl-notes/tree/master/codes/snake)
|
||||
@@ -40,7 +40,7 @@
|
||||
我们把一开始的初始画面记作 $s_1$, 把第一次执行的动作记作 $a_1$,把第一次执行动作完以后得到的 reward 记作 $r_1$。不同的书会有不同的定义,有人会觉得说这边应该要叫做 $r_2$,这个都可以,你自己看得懂就好。Actor 决定一个的行为以后, 就会看到一个新的游戏画面,这边是 $s_2$。然后把这个 $s_2$ 输入给 actor,这个 actor 决定要开火,然后它可能杀了一只怪,就得到五分。这个 process 就反复地持续下去,直到今天走到某一个 timestamp 执行某一个 action,得到 reward 之后, 这个 environment 决定这个游戏结束了。比如说,如果在这个游戏里面,你是控制绿色的船去杀怪,如果你被杀死的话,游戏就结束,或是你把所有的怪都清空,游戏就结束了。
|
||||
|
||||

|
||||
一场游戏叫做一个 `Episode(回合)` 或者 `Trial(试验)`。把这个游戏里面,所有得到的 reward 都总合起来,就是 `Total reward`,我们称其为`Return(回报)`,用 R 来表示它。Actor 要想办法去 maximize 它可以得到的 reward。
|
||||
一场游戏叫做一个 `episode(回合)` 或者 `trial(试验)`。把这个游戏里面,所有得到的 reward 都总合起来,就是 `total reward`,我们称其为`return(回报)`,用 R 来表示它。Actor 要想办法去 maximize 它可以得到的 reward。
|
||||
|
||||

|
||||
首先,`environment` 是一个`function`,游戏的主机也可以把它看作是一个 function,虽然它不一定是 neural network,可能是 rule-based 的规则,但你可以把它看作是一个 function。这个 function,一开始就先吐出一个 state,也就是游戏的画面,接下来你的 actor 看到这个游戏画面 $s_1$ 以后,它吐出 $a_1$,然后 environment 把 $a_1$ 当作它的输入,然后它再吐出 $s_2$,吐出新的游戏画面。Actor 看到新的游戏画面,再采取新的行为 $a_2$,然后 environment 再看到 $a_2$,再吐出 $s_3$。这个 process 会一直持续下去,直到 environment 觉得说应该要停止为止。
|
||||
@@ -87,7 +87,7 @@ $$
|
||||

|
||||
怎么 maximize expected reward 呢?我们用的是 `gradient ascent`,因为要让它越大越好,所以是 gradient ascent。Gradient ascent 在 update 参数的时候要加。要进行 gradient ascent,我们先要计算 expected reward $\bar{R}$ 的 gradient 。我们对 $\bar{R}$ 取一个 gradient,这里面只有 $p_{\theta}(\tau)$ 是跟 $\theta$ 有关,所以 gradient 就放在 $p_{\theta}(\tau)$ 这个地方。$R(\tau)$ 这个 reward function 不需要是 differentiable,我们也可以解接下来的问题。举例来说,如果是在 GAN 里面,$R(\tau)$ 其实是一个 discriminator,它就算是没有办法微分,也无所谓,你还是可以做接下来的运算。
|
||||
|
||||
取 gradient之后,我们背一个公式,
|
||||
取 gradient之后,我们背一个公式:
|
||||
$$
|
||||
\nabla f(x)=f(x)\nabla \log f(x)
|
||||
$$
|
||||
@@ -141,8 +141,6 @@ $$
|
||||
|
||||
Update 完你的 model 以后。你要重新去收集 data,再 update model。这边要注意一下,一般 policy gradient sample 的 data 就只会用一次。你把这些 data sample 起来,然后拿去 update 参数,这些 data 就丢掉了。接着再重新 sample data,才能够去 update 参数, 等一下我们会解决这个问题。
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
接下来讲一些实现细节。实现方法是这个样子,把它想成一个分类的问题,在 classification 里面就是 input 一个 image,然后 output 决定说是 10 个 class 里面的哪一个。在做 classification 时,我们要收集一堆 training data,要有 input 跟 output 的 pair。
|
||||
@@ -168,7 +166,7 @@ $$
|
||||
|
||||

|
||||
|
||||
第一个 tip 是 add 一个 baseline。add baseline 是什么意思呢?如果 given state s 采取 action a 会给你整场游戏正面的 reward,就要增加它的概率。如果 state s 执行 action a,整场游戏得到负的 reward,就要减少这一项的概率。
|
||||
**第一个 tip 是 add 一个 baseline。** 如果 given state s 采取 action a 会给你整场游戏正面的 reward,就要增加它的概率。如果 state s 执行 action a,整场游戏得到负的 reward,就要减少这一项的概率。
|
||||
|
||||
但在很多游戏里面, reward 总是正的,就是说最低都是 0。比如说打乒乓球游戏, 你的分数就是介于 0 到 21 分之间,所以这个 R 总是正的。假设你直接套用这个式子, 在 training 的时候,告诉 model 说,不管是什么 action 你都应该要把它的概率提升。 在理想上,这么做并不一定会有问题。因为虽然说 R 总是正的,但它正的量总是有大有小,你在玩乒乓球那个游戏里面,得到的 reward 总是正的,但它是介于 0~21分之间,有时候你采取某些 action 可能是得到 0 分,采取某些 action 可能是得到 20 分。
|
||||

|
||||
@@ -195,13 +193,13 @@ $$
|
||||
|
||||
### Tip 2: Assign Suitable Credit
|
||||
|
||||
第二个 tip:给每一个 action 合适的 credit。什么意思呢,如果我们看今天下面这个式子的话,
|
||||
**第二个 tip:给每一个 action 合适的 credit。**什么意思呢,如果我们看今天下面这个式子的话,
|
||||
$$
|
||||
\nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}}\left(R\left(\tau^{n}\right)-b\right) \nabla \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right)
|
||||
$$
|
||||
我们原来会做的事情是,在某一个 state,假设你执行了某一个 action a,它得到的 reward ,它前面乘上的这一项 $R(\tau^n)-b$。
|
||||
|
||||
只要在同一个 Episode 里面,在同一场游戏里面, 所有的 state 跟 a 的 pair,它都会 weighted by 同样的 reward term,这件事情显然是不公平的,因为在同一场游戏里面 也许有些 action 是好的,有些 action 是不好的。 假设整场游戏的结果是好的, 并不代表这个游戏里面每一个行为都是对的。若是整场游戏结果不好, 但不代表游戏里面的所有行为都是错的。所以我们希望可以给每一个不同的 action 前面都乘上不同的 weight。每一个 action 的不同 weight, 它反映了每一个 action 到底是好还是不好。
|
||||
只要在同一个 episode 里面,在同一场游戏里面, 所有的 state 跟 a 的 pair,它都会 weighted by 同样的 reward term,这件事情显然是不公平的,因为在同一场游戏里面 也许有些 action 是好的,有些 action 是不好的。 假设整场游戏的结果是好的, 并不代表这个游戏里面每一个行为都是对的。若是整场游戏结果不好, 但不代表游戏里面的所有行为都是错的。所以我们希望可以给每一个不同的 action 前面都乘上不同的 weight。每一个 action 的不同 weight, 它反映了每一个 action 到底是好还是不好。
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -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 都是不错的,不是最好的,就是第二好的。
|
||||
|
||||
@@ -39,7 +39,7 @@ $$
|
||||
|
||||
怎么衡量这个 state value function $V^{\pi}(s)$ 呢?有两种不同的做法。一个是用` Monte-Carlo(MC) based` 的方法。MC based 的方法就是让 actor 去跟环境做互动,你要看 actor 好不好, 你就让 actor 去跟环境做互动,给 critic 看。然后,critic 就统计说,actor 如果看到 state $s_a$,接下来 accumulated reward 会有多大。如果它看到 state $s_b$,接下来accumulated reward 会有多大。但是实际上,你不可能把所有的state 通通都扫过。如果你是玩 Atari 游戏的话,你的 state 是 image ,你没有办法把所有的state 通通扫过。所以实际上我们的 $V^{\pi}(s)$ 是一个 network。对一个 network 来说,就算是 input state 是从来都没有看过的,它也可以想办法估测一个 value 的值。
|
||||
|
||||
怎么训练这个 network 呢?因为如果在state $s_a$,接下来的 accumulated reward 就是 $G_a$。也就是说,对这个 value function 来说,如果 input 是 state $s_a$,正确的 output 应该是$G_a$。如果 input state $s_b$,正确的output 应该是value $G_b$。所以在 training 的时候, 它就是一个 `regression problem`。Network 的 output 就是一个 value,你希望在 input $s_a$ 的时候,output value 跟 $G_a$ 越近越好,input $s_b$ 的时候,output value 跟 $G_b$ 越近越好。接下来把 network train 下去,就结束了。这是第一个方法,MC based 的方法。
|
||||
怎么训练这个 network 呢?因为如果在 state $s_a$,接下来的 accumulated reward 就是 $G_a$。也就是说,对这个 value function 来说,如果 input 是 state $s_a$,正确的 output 应该是$G_a$。如果 input state $s_b$,正确的 output 应该是value $G_b$。所以在 training 的时候, 它就是一个 `regression problem`。Network 的 output 就是一个 value,你希望在 input $s_a$ 的时候,output value 跟 $G_a$ 越近越好,input $s_b$ 的时候,output value 跟 $G_b$ 越近越好。接下来把 network train 下去,就结束了。这是第一个方法,MC based 的方法。
|
||||
|
||||

|
||||
|
||||
@@ -50,7 +50,7 @@ $$
|
||||
V^{\pi}\left(s_{t}\right)=V^{\pi}\left(s_{t+1}\right)+r_{t}
|
||||
$$
|
||||
|
||||
假设我们现在用的是某一个 policy $\pi$,在 state $s_t$,它会采取 action $a_t$,给我们 reward $r_t$ ,接下来进入$s_{t+1}$ 。state $s_{t+1}$ 的 value 跟 state $s_t$ 的 value,它们的中间差了一项 $r_t$。因为你把 $s_{t+1}$ 得到的 value 加上得到的 reward $r_t$ 就会等于 $s_t$ 得到的 value。有了这个式子以后,你在 training 的时候,你并不是直接去估测 V,而是希望你得到的结果 V 可以满足这个式子。也就是说你会是这样 train 的,你把 $s_t$ 丢到 network 里面,因为 $s_t$ 丢到 network 里面会得到 $V^{\pi}(s_t)$,把 $s_{t+1}$ 丢到你的 value network 里面会得到$V^{\pi}(s_{t+1})$,这个式子告诉我们,$V^{\pi}(s_t)$ 减 $V^{\pi}(s_{t+1})$ 的值应该是 $r_t$。然后希望它们两个相减的 loss 跟 $r_t$ 越接近,train 下去,update V 的参数,你就可以把 V function learn 出来。
|
||||
假设我们现在用的是某一个 policy $\pi$,在 state $s_t$,它会采取 action $a_t$,给我们 reward $r_t$ ,接下来进入 $s_{t+1}$ 。state $s_{t+1}$ 的 value 跟 state $s_t$ 的 value,它们的中间差了一项 $r_t$。因为你把 $s_{t+1}$ 得到的 value 加上得到的 reward $r_t$ 就会等于 $s_t$ 得到的 value。有了这个式子以后,你在 training 的时候,你并不是直接去估测 V,而是希望你得到的结果 V 可以满足这个式子。也就是说你会是这样 train 的,你把 $s_t$ 丢到 network 里面,因为 $s_t$ 丢到 network 里面会得到 $V^{\pi}(s_t)$,把 $s_{t+1}$ 丢到你的 value network 里面会得到$V^{\pi}(s_{t+1})$,这个式子告诉我们,$V^{\pi}(s_t)$ 减 $V^{\pi}(s_{t+1})$ 的值应该是 $r_t$。然后希望它们两个相减的 loss 跟 $r_t$ 越接近,train 下去,update V 的参数,你就可以把 V function learn 出来。
|
||||
|
||||

|
||||
|
||||
@@ -119,37 +119,37 @@ Q-function 有两种写法:
|
||||
|
||||
上图是文献上的结果,你去 estimate Q-function 的话,看到的结果可能会像是这个样子。这是什么意思呢?它说假设我们有 3 个 actions,3 个 actions 就是原地不动、向上、向下。
|
||||
|
||||
* 假设是在第一个state,不管是采取哪个action,最后到游戏结束的时候,得到的 expected reward 其实都差不多。因为球在这个地方,就算是你向下,接下来你其实应该还来的急救,所以今天不管是采取哪一个action,就差不了太多。
|
||||
* 假设是在第一个 state,不管是采取哪个 action,最后到游戏结束的时候,得到的 expected reward 其实都差不多。因为球在这个地方,就算是你向下,接下来你其实应该还来的急救,所以今天不管是采取哪一个action,就差不了太多。
|
||||
|
||||
* 假设在第二个state,这个乒乓球它已经反弹到很接近边缘的地方,这个时候你采取向上,你才能得到positive 的reward,才接的到球。如果你是站在原地不动或向下的话,接下来你都会miss 掉这个球。你得到的reward 就会是负的。
|
||||
* 假设在第二个s tate,这个乒乓球它已经反弹到很接近边缘的地方,这个时候你采取向上,你才能得到 positive reward,才接的到球。如果你是站在原地不动或向下的话,接下来你都会 miss 掉这个球。你得到的 reward 就会是负的。
|
||||
|
||||
* 假设在第三个state,球很近了,所以就要向上。
|
||||
* 假设在第三个 state,球很近了,所以就要向上。
|
||||
|
||||
* 假设在第四个state,球被反弹回去,这时候采取那个action就都没有差了。
|
||||
* 假设在第四个 state,球被反弹回去,这时候采取哪个 action 就都没有差了。
|
||||
|
||||
这个是 state-action value 的一个例子。
|
||||
这是 state-action value 的一个例子。
|
||||
|
||||

|
||||
|
||||
虽然表面上我们 learn 一个 Q-function,它只能拿来评估某一个 actor $\pi$ 的好坏,但只要有了这个 Q-function,我们就可以做 reinforcement learning。有了这个 Q-function,我们就可以决定要采取哪一个 action,我们就可以进行`策略改进(Policy Improvement)`。
|
||||
|
||||
它的大原则是这样,假设你有一个初始的 actor,也许一开始很烂, 随机的也没有关系。初始的 actor 叫做 $\pi$,这个 $\pi$ 跟环境互动,会 collect data。接下来你 learn 一个 $\pi$ 这个 actor 的 Q value,你去衡量一下 $\pi$ 这个actor 在某一个 state 强制采取某一个 action,接下来用 $\pi$ 这个 policy 会得到的 expected reward,那用 TD 或 MC 也是可以的。你 learn 出一个 Q-function 以后,就保证你可以找到一个新的 policy $\pi'$ ,policy $\pi'$ 一定会比原来的 policy $\pi$ 还要好。那等一下会定义说,什么叫做好。所以这边神奇的地方是,假设你有一个 Q-function 和 某一个policy $\pi$,你根据 policy $\pi$ learn 出 policy $\pi$ 的 Q-function,接下来保证你可以找到一个新的 policy $\pi'$ ,它一定会比 $\pi$ 还要好,然后你用 $\pi'$ 取代 $\pi$,再去找它的 Q-function,得到新的以后,再去找一个更好的 policy。 然后这个循环一直下去,你的 policy 就会越来越好。
|
||||
它的大原则是这样,假设你有一个初始的 actor,也许一开始很烂, 随机的也没有关系。初始的 actor 叫做 $\pi$,这个 $\pi$ 跟环境互动,会 collect data。接下来你 learn 一个 $\pi$ 这个 actor 的 Q value,你去衡量一下 $\pi$ 这个actor 在某一个 state 强制采取某一个 action,接下来用 $\pi$ 这个 policy 会得到的 expected reward,那用 TD 或 MC 也是可以的。你 learn 出一个 Q-function 以后,就保证你可以找到一个新的 policy $\pi'$ ,policy $\pi'$ 一定会比原来的 policy $\pi$ 还要好。那等一下会定义说,什么叫做好。所以这边神奇的地方是,假设你有一个 Q-function 和 某一个 policy $\pi$,你根据 policy $\pi$ learn 出 policy $\pi$ 的 Q-function,接下来保证你可以找到一个新的 policy $\pi'$ ,它一定会比 $\pi$ 还要好,然后你用 $\pi'$ 取代 $\pi$,再去找它的 Q-function,得到新的以后,再去找一个更好的 policy。这样一直循环下去,policy 就会越来越好。
|
||||
|
||||

|
||||
上图就是讲我们刚才讲的到底是什么。
|
||||
|
||||
* 首先要定义的是什么叫做比较好?我们说 $\pi'$ 一定会比 $\pi$ 还要好,什么叫做好呢?这边所谓好的意思是说,对所有可能的 state s 而言,对同一个 state s 而言,$\pi$ 的 value function 一定会小于 $\pi'$ 的 value function。也就是说我们走到同一个 state s 的时候,如果拿 $\pi$ 继续跟环境互动下去,我们得到的 reward 一定会小于用 $\pi'$ 跟环境互动下去得到的reward。所以不管在哪一个state,你用 $\pi'$ 去做 interaction,得到的 expected reward 一定会比较大。所以 $\pi'$ 是比 $\pi$ 还要好的一个policy。
|
||||
* 首先要定义的是什么叫做比较好?我们说 $\pi'$ 一定会比 $\pi$ 还要好,什么叫做好呢?这边所谓好的意思是说,对所有可能的 state s 而言,对同一个 state s 而言,$\pi$ 的 value function 一定会小于 $\pi'$ 的 value function。也就是说我们走到同一个 state s 的时候,如果拿 $\pi$ 继续跟环境互动下去,我们得到的 reward 一定会小于用 $\pi'$ 跟环境互动下去得到的reward。所以不管在哪一个 state,你用 $\pi'$ 去做 interaction,得到的 expected reward 一定会比较大。所以 $\pi'$ 是比 $\pi$ 还要好的一个 policy。
|
||||
|
||||
* 有了这个 Q-function 以后,怎么找这个 $\pi'$ 呢?事实上这个 $\pi'$ 是什么?这个$\pi'$ 就是, 如果你根据以下的这个式子去决定你的action,
|
||||
* 有了这个 Q-function 以后,怎么找这个 $\pi'$ 呢?如果你根据以下的这个式子去决定你的 action,
|
||||
|
||||
$$
|
||||
\pi^{\prime}(s)=\arg \max _{a} Q^{\pi}(s, a)
|
||||
$$
|
||||
|
||||
根据上式去决定你的action 的步骤叫做 $\pi'$ 的话,那这个 $\pi'$ 一定会比$\pi$ 还要好。这个意思是说,假设你已经 learn 出 $\pi$ 的Q-function,今天在某一个 state s,你把所有可能的 action a 都一一带入这个 Q-function,看看说那一个 a 可以让 Q-function 的 value 最大,那这一个 action,就是 $\pi'$ 会采取的 action。这边要注意一下,给定这个 state s,你的 policy $\pi$ 并不一定会采取 action a。我们是 给定某一个 state s 强制采取 action a,用 $\pi$ 继续互动下去得到的 expected reward,这个才是 Q-function 的定义。所以在 state s 里面不一定会采取 action a。假设用这一个 $\pi'$ 在 state s 采取action a 跟 $\pi$ 所谓采取 action 是不一定会一样的。然后 $\pi'$ 所采取的 action 会让他得到比较大的 reward。
|
||||
根据上式去决定你的 action 的步骤叫做 $\pi'$ 的话,那这个 $\pi'$ 一定会比 $\pi$ 还要好。这个意思是说,假设你已经 learn 出 $\pi$ 的Q-function,今天在某一个 state s,你把所有可能的 action a 都一一带入这个 Q-function,看看说那一个 a 可以让 Q-function 的 value 最大,那这个 action 就是 $\pi'$ 会采取的 action。这边要注意一下,给定这个 state s,你的 policy $\pi$ 并不一定会采取 action a,我们是给定某一个 state s 强制采取 action a,用 $\pi$ 继续互动下去得到的 expected reward,这个才是 Q-function 的定义。所以在 state s 里面不一定会采取 action a。用这一个 $\pi'$ 在 state s 采取 action a 跟 $\pi$ 采取的 action 是不一定会一样的。然后 $\pi'$ 所采取的 action 会让它得到比较大的 reward。
|
||||
|
||||
* 所以根本就没有一个 policy 叫做 $\pi'$,这个$\pi'$ 是用 Q-function 推出来的。所以没有另外一个 network 决定 $\pi'$ 怎么interaction,有 Q-function 就可以找出$\pi'$。
|
||||
* 但是这边有另外一个问题就是,在这边要解一个 arg max 的 problem。所以 a 如果是continuous 的就会有问题,如果是discrete 的,a 只有3 个选项,一个一个带进去, 看谁的 Q 最大,没有问题。但如果是 continuous 要解 arg max problem,你就会有问题,但这个是之后才会解决的。
|
||||
* 所以根本就没有一个 policy 叫做 $\pi'$,这个 $\pi'$ 是用 Q-function 推出来的。所以没有另外一个 network 决定 $\pi'$ 怎么interaction,有 Q-function 就可以找出 $\pi'$。
|
||||
* 但是这边有另外一个问题就是,在这边要解一个 arg max 的 problem。所以 a 如果是 continuous 的就会有问题,如果是 discrete 的,a 只有3 个选项,一个一个带进去, 看谁的 Q 最大,没有问题。但如果是 continuous 要解 arg max problem,你就会有问题,这个之后会解决。
|
||||
|
||||

|
||||
|
||||
@@ -167,7 +167,7 @@ $$
|
||||
Q^{\pi}(s, \pi(s)) \le \max _{a} Q^{\pi}(s, a)
|
||||
$$
|
||||
|
||||
因为这边是所有action 里面可以让 Q 最大的那个action,所以今天这一项一定会比它大。那我们知道说这一项是什么,这一项就是$Q^{\pi}(s, a)$,$a$ 就是 $\pi'(s)$。因为$\pi'(s)$ output 的 a, 就是可以让 $Q^\pi(s,a)$ 最大的那一个。所以我们得到了下面的式子:
|
||||
因为这边是所有action 里面可以让 Q 最大的那个action,所以今天这一项一定会比它大。那我们知道说这一项是什么,这一项就是$Q^{\pi}(s, a)$,$a$ 就是 $\pi'(s)$。因为 $\pi'(s)$ output 的 a, 就是可以让 $Q^\pi(s,a)$ 最大的那一个。所以我们得到了下面的式子:
|
||||
$$
|
||||
\max _{a} Q^{\pi}(s, a)=Q^{\pi}\left(s, \pi^{\prime}(s)\right)
|
||||
$$
|
||||
@@ -176,19 +176,19 @@ $$
|
||||
$$
|
||||
V^{\pi}(s) \leq Q^{\pi}\left(s, \pi^{\prime}(s)\right)
|
||||
$$
|
||||
也就是说某一个 state,如果你按照policy $\pi$,一直做下去,你得到的 reward 一定会小于等于,在这个 state s。你故意不按照 $\pi$ 所给你指示的方向,而是按照 $\pi'$ 的方向走一步,但之后只有第一步是按照 $\pi'$ 的方向走,只有在state s 这个地方,你才按照 $\pi'$ 的指示走,但接下来你就按照 $\pi$ 的指示走。虽然只有一步之差, 但是我从上面这个式子知道说,只有一步之差,你得到的 reward 一定会比完全 follow $\pi$ 得到的 reward 还要大。
|
||||
也就是说某一个 state,如果你按照 policy $\pi$,一直做下去,你得到的 reward 一定会小于等于,在这个 state s。你故意不按照 $\pi$ 所给你指示的方向,而是按照 $\pi'$ 的方向走一步,但之后只有第一步是按照 $\pi'$ 的方向走,只有在 state s 这个地方,你才按照 $\pi'$ 的指示走,但接下来你就按照 $\pi$ 的指示走。虽然只有一步之差, 但是我从上面这个式子知道说,只有一步之差,你得到的 reward 一定会比完全 follow $\pi$ 得到的 reward 还要大。
|
||||
|
||||
那接下来你想要证的东西就是:
|
||||
那接下来你想要证下面的式子:
|
||||
$$
|
||||
Q^{\pi}\left(s, \pi^{\prime}(s) \right) \le V^{\pi'}(s)
|
||||
$$
|
||||
|
||||
也就是说,只有一步之差,你会得到比较大的reward。但假设每步都是不一样的, 每步都是 follow $\pi'$ 而不是$\pi$ 的话,那你得到的reward 一定会更大。如果你要用数学式把它写出来的话,你可以这样写 $Q^{\pi}\left(s, \pi^{\prime}(s)\right)$ 这个式子,它的意思就是说,我们在state $s_t$ 采取 action $a_t$,得到 reward $r_{t+1}$,然后跳到state $s_{t+1}$,即如下式所示:
|
||||
也就是说,只有一步之差,你会得到比较大的 reward。但假设每步都是不一样的,每步都是 follow $\pi'$ 而不是 $\pi$ 的话,那你得到的 reward 一定会更大。如果你要用数学式把它写出来的话,你可以这样写 $Q^{\pi}\left(s, \pi^{\prime}(s)\right)$ 这个式子,它的意思就是说,我们在 state $s_t$ 采取 action $a_t$,得到 reward $r_{t+1}$,然后跳到 state $s_{t+1}$,即如下式所示:
|
||||
|
||||
$$
|
||||
Q^{\pi}\left(s, \pi^{\prime}(s)\right)=E\left[r_{t+1}+V^{\pi}\left(s_{t+1}\right) \mid s_{t}=s, a_{t}=\pi^{\prime}\left(s_{t}\right)\right]
|
||||
$$
|
||||
这边有一个地方写得不太好,这边应该写成$r_t$ 跟之前的notation 比较一致,但这边写成了$r_{t+1}$,其实这都是可以的。在文献上有时候有人会说 在state $s_t$ 采取action $a_t$ 得到reward $r_{t+1}$, 有人会写成$r_t$,但意思其实都是一样的。在state s,按照$\pi'$ 采取某一个action $a_t$ ,得到 reward $r_{t+1}$,然后跳到state $s_{t+1}$,$V^{\pi}\left(s_{t+1}\right)$是state $s_{t+1}$,根据$\pi$ 这个actor 所估出来的value。这边要取一个期望值,因为在同样的state 采取同样的action,你得到的reward,还有会跳到的 state 不一定是一样, 所以这边需要取一个期望值。
|
||||
这边有一个地方写得不太好,这边应该写成 $r_t$ 跟之前的记号比较一致,但这边写成了 $r_{t+1}$,其实这都是可以的。在文献上有时候有人会说 在 state $s_t$ 采取 action $a_t$ 得到 reward $r_{t+1}$, 有人会写成 $r_t$,但意思其实都是一样的。在 state s,按照 $\pi'$ 采取某一个 action $a_t$ ,得到 reward $r_{t+1}$,然后跳到 state $s_{t+1}$,$V^{\pi}\left(s_{t+1}\right)$是 state $s_{t+1}$,根据 $\pi$ 这个 actor 所估出来的 value。因为在同样的 state 采取同样的 action,你得到的 reward,还有会跳到的 state 不一定是一样, 所以这边需要取一个期望值。
|
||||
|
||||
接下来我们会得到如下的式子:
|
||||
$$
|
||||
@@ -206,7 +206,7 @@ $$
|
||||
V^{\pi}(s_{t+1}) \leq Q^{\pi}\left(s_{t+1}, \pi^{\prime}(s_{t+1})\right)
|
||||
$$
|
||||
|
||||
也就是说,现在你一直follow $\pi$,跟某一步follow $\pi'$,接下来都follow $\pi$ 比起来,某一步follow $\pi'$ 得到的reward 是比较大的。
|
||||
也就是说,现在你一直 follow $\pi$,跟某一步 follow $\pi'$,接下来都 follow $\pi$ 比起来,某一步 follow $\pi'$ 得到的 reward 是比较大的。
|
||||
|
||||
接着我们得到下式:
|
||||
$$
|
||||
@@ -294,7 +294,7 @@ $$
|
||||
|
||||

|
||||
|
||||
第三个tip是`Experience Replay(经验回放)`。 Experience Replay 会构建一个 `Replay Buffer`,Replay Buffer 又被称为 `Replay Memory`。Replay Buffer 是说现在会有某一个 policy $\pi$ 去跟环境做互动,然后它会去收集 data。我们会把所有的 data 放到一个buffer 里面,buffer 里面就存了很多data。比如说 buffer 是 5 万,这样它里面可以存 5 万笔资料,每一笔资料就是记得说,我们之前在某一个 state $s_t$,采取某一个action $a_t$,得到了 reward $r_t$。然后跳到 state $s_{t+1}$。那你用 $\pi$ 去跟环境互动很多次,把收集到的资料都放到这个 replay buffer 里面。
|
||||
第三个tip是 `Experience Replay(经验回放)`。 Experience Replay 会构建一个 `Replay Buffer`,Replay Buffer 又被称为 `Replay Memory`。Replay Buffer 是说现在会有某一个 policy $\pi$ 去跟环境做互动,然后它会去收集 data。我们会把所有的 data 放到一个buffer 里面,buffer 里面就存了很多data。比如说 buffer 是 5 万,这样它里面可以存 5 万笔资料,每一笔资料就是记得说,我们之前在某一个 state $s_t$,采取某一个action $a_t$,得到了 reward $r_t$。然后跳到 state $s_{t+1}$。那你用 $\pi$ 去跟环境互动很多次,把收集到的资料都放到这个 replay buffer 里面。
|
||||
|
||||
这边要注意是 replay buffer 里面的 experience 可能是来自于不同的 policy,你每次拿 $\pi$ 去跟环境互动的时候,你可能只互动 10000 次,然后接下来你就更新你的 $\pi$ 了。但是这个 buffer 里面可以放 5 万笔资料,所以 5 万笔资料可能是来自于不同的 policy。Buffer 只有在它装满的时候,才会把旧的资料丢掉。所以这个 buffer 里面它其实装了很多不同的 policy 的 experiences。
|
||||
|
||||
@@ -326,7 +326,7 @@ A:没关系。这并不是因为过去的 $\pi$ 跟现在的 $\pi$ 很像,
|
||||
$$
|
||||
y=r_{i}+\max _{a} \hat{Q}\left(s_{i+1}, a\right)
|
||||
$$
|
||||
其中 a 就是让 $\hat{Q}$ 的值最大的 a。因为我们在 state $s_{i+1}$会采取的action a,其实就是那个可以让 Q value 的值最大的那一个 a。接下来我们要update Q 的值,那就把它当作一个 regression problem。希望$Q(s_i,a_i)$ 跟你的target 越接近越好。然后假设已经 update 了某一个数量的次,比如说 C 次,设 C = 100, 那你就把 $\hat{Q}$ 设成 Q,这就是 DQN。我们给出 [DQN 的 PyTorch 实现](https://github.com/datawhalechina/leedeeprl-notes/tree/master/codes/dqn) 。
|
||||
其中 a 就是让 $\hat{Q}$ 的值最大的 a。因为我们在 state $s_{i+1}$会采取的action a,其实就是那个可以让 Q value 的值最大的那一个 a。接下来我们要update Q 的值,那就把它当作一个 regression problem。希望$Q(s_i,a_i)$ 跟你的target 越接近越好。然后假设已经 update 了某一个数量的次,比如说 C 次,设 C = 100, 那你就把 $\hat{Q}$ 设成 Q,这就是 DQN。
|
||||
|
||||
Q: DQN 和 Q-learning 有什么不同?
|
||||
|
||||
|
||||
@@ -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。
|
||||