21 KiB
模仿学习
模仿学习(imitation learning,IL)讨论的问题是:假设我们连奖励都没有,那要怎么办呢?模仿学习又叫做示范学习(learning from demonstration),学徒学习(apprenticeship learning),观察学习(learning by watching)。在模仿学习里面,你有一些专家的示范,那机器也可以跟环境互动,但它没有办法从环境里面得到任何的奖励,它只能看着专家的示范来学习什么是好,什么是不好。其实,多数的情况,我们都没有办法真的从环境里面得到非常明确的奖励。举例来说,如果是棋类游戏或者是电玩,你有非常明确的奖励。但是其实多数的任务,都是没有奖励的。以聊天机器人为例,机器跟人聊天,聊得怎么样算是好,聊得怎么样算是不好,你无法给出明确的奖励。所以很多任务是根本就没有办法给出奖励的。
虽然没有办法给出奖励,但是收集专家的示范是可以做到的。举例来说,在自动驾驶汽车里面,虽然你没有办法给出自动驾驶汽车的奖励,但你可以收集很多人类开车的纪录。在聊天机器人里面,你可能没有办法定义什么叫做好的对话,什么叫做不好的对话。但是收集很多人的对话当作范例,这一件事情也是可行的。
所以模仿学习的使用性非常高。假设你不知道该怎么定义奖励,你就可以收集到专家的示范。如果你可以收集到一些范例的话,你可以收集到一些很厉害的智能体(比如人)跟环境实际上的互动的话,那你就可以考虑模仿学习这个技术。在模仿学习里面,我们介绍两个方法。第一个叫做行为克隆(behavior cloning,BC),第二个叫做逆强化学习(inverse reinforcement learning,IRL) 或者叫做逆最优控制(inverse optimal control)。
行为克隆
其实行为克隆跟监督学习是一模一样的。如下图所示,以自动驾驶汽车为例,你可以收集到人开自动驾驶汽车的所有资料,比如说可以通过行车记录器进行收集。看到下图的观测的时候,人会决定向前。机器就采取跟人一样的行为,也向前,就结束了。这个就叫做行为克隆,专家做什么,机器就做一模一样的事。
怎么让机器学会跟专家一模一样的行为呢?我们可以把它当作一个监督学习的问题,去收集很多行车记录器,然后再收集人在具体情境下会采取什么样的行为(训练数据)。你知道说人在状态s_1 会采取动作$a_1$,人在状态s_2 会采取动作$a_2$。人在状态, s_3 会采取动作$a_3$。接下来,你就学习一个网络。这个网络就是演员,它输入s_i 的时候,你就希望它的输出 是$a_i$,就这样结束了。它就是一个的监督学习的问题。
行为克隆虽然非常简单,但它的问题是如果你只收集专家的资料,你可能看过的观测会是非常有限的。举例来说,如下图所示,假设你要学习一部自动驾驶汽车,自动驾驶汽车就是要过这个弯道。如果是专家的话,它就是把车顺着这个红线就开过去了。但假设智能体很笨,它开着开着就撞墙了,它永远不知道撞墙这种状况要怎么处理。因为训练数据里面从来没有撞过墙,所以它根本就不知道撞墙这一种情况要怎么处理。打电玩也是一样,让人去玩马里奥(Mario),那专家可能非常强,它从来不会跳不上水管,所以机器根本不知道跳不上水管时要怎么处理。
所以光是做行为克隆是不够的,只观察专家的行为是不够的,需要一个招数,这个招数叫作数据集聚合(dataset aggregation,DAgger)。
我们会希望收集更多样性的数据,而不是只收集专家所看到的观测。我们会希望能够收集专家在各种极端的情况下,它会采取什么样的行为。如下图所示,以自动驾驶汽车为例的话,假设一开始,我们有演员 $\pi_1$,并且让 $\pi_1$去开这个车,但车上坐了一个专家。这个专家会不断地告诉机器说,如果在这个情境里面,我会怎么样开。所以 \pi_1 自己开自己的,但是专家会不断地表示它的想法。比如说,一开始的时候,专家可能说往前走。在拐弯的时候,专家可能就会说往右转。但 \pi_1 是不管专家的指令的,所以它会继续去撞墙。虽然专家说往右转,但是不管它怎么下指令都是没有用的,\pi_1 会自己做自己的事情,因为我们要做的记录的是说,专家在 \pi_1 看到这种观测的情况下,它会做什么样的反应。这个方法显然是有一些问题的,因为你每开一次自动驾驶汽车就会牺牲一个人。那你用这个方法,你牺牲一个专家以后,你就会知道,人类在这样子的状态下,在快要撞墙的时候,会采取什么样的行为。再把这个数据拿去训练新的 $\pi_2$。这个过程就反复继续下去,这个方法就叫做数据集聚合。
行为克隆还有一个问题:机器会完全模仿专家的行为,不管专家的行为是否有道理,就算没有道理,没有什么用的,就算这是专家本身的习惯,机器也会硬把它记下来。如果机器确实可以记住所有专家的行为,也许还好。因为如果专家这么做,有些行为是多余的。但是没有问题,假设机器的行为可以完全仿造专家行为,也就算了,它就是跟专家一样得好,只是做一些多余的事。但问题是机器是一个网络,网络的容量是有限的。就算给网络训练数据,它在训练数据上得到的正确率往往也不是 100%,它有些事情是学不起来的。这个时候,什么该学,什么不该学就变得很重要。
举例来说,如下图所示,在学习中文的时候,老师有语音、行为和知识,但其实只有语音部分是重要的,知识的部分是不重要的。也许机器只能够学一件事,也许它就只学到了语音,那没有问题。如果它只学到了手势,这样子就有问题了。所以让机器学习什么东西是需要模仿,什么东西是不需要模仿,这件事情是重要的。而单纯的行为克隆就没有把这件事情学进来,因为机器只是复制专家所有的行为而已,它不知道哪些行为是重要,是对接下来有影响的,哪些行为是不重要的,是对接下来是没有影响的。
行为克隆还有一个问题:在做行为克隆的时候,训练数据跟测试数据是不匹配的。我们可以用数据集聚合的方法来缓解这个问题。在训练跟测试的时候,数据分布其实是不一样的。因为在强化学习里面,动作会影响到接下来所看到的状态。我们是先有状态$s_1$,然后采取动作$a_1$,动作a_1 其实会决定接下来你看到什么样的状态$s_2$。所以在强化学习里面有一个很重要的特征,就是你采取了动作会影响你接下来所看到的状态,也就是会影响状态的分布。如果做了行为克隆的话,我们只能观察到专家$\hat{\pi}$的一堆状态跟动作的对$(s,a)$。
然后我们希望可以学习一个 $\pi^*$,我们希望 \pi^* 跟 \hat{\pi} 越接近越好。如果 \pi^* 可以跟 \hat{\pi} 一模一样的话,训练的时候看到的状态跟测试的时候所看到的状态会是一样的。因为虽然动作会影响我们看到的状态,但假设两个策略一模一样, 在同一个状态都会采取同样的动作,那你接下来所看到的状态都会是一样的。但问题就是你很难让学习出来的策略跟专家的策略一模一样。专家可是一个人,网络要跟人一模一样,有点困难。
如果 \pi^* 跟 \hat{\pi} 有一点误差。这个误差在一般监督学习问题里面,每一个样本(example)都是独立的,也许还好。但对强化学习的问题来说,可能在某个地方就是失之毫厘,差之千里。可能在某个地方,也许机器没有办法完全复制专家的行为,它复制的差了一点点,也许最后得到的结果就会差很多这样。所以行为克隆并不能够完全解决模仿学习这件事情,我们就有另外一个比较好的做法叫做逆强化学习。
逆强化学习
为什么叫逆强化学习,因为原来的强化学习里面,有一个环境和一个奖励函数。根据环境和奖励函数,通过强化学习这个技术,你会找到一个演员,你会学习出一个最优演员。但逆强化学习刚好是相反的,你没有奖励函数,你只有一堆专家的示范。但你还是有环境的。逆强化学习的做法是说假设我们现在有一堆专家的示范,我们用 \hat{\tau} 来代表专家的示范。如果是在玩电玩的话,每一个 \tau 就是一个很会玩电玩的人玩一场游戏的纪录,如果是自动驾驶汽车的话,就是人开自动驾驶汽车的纪录。这一边就是专家的示范,每一个 \tau 是一个轨迹。
把所有专家示范收集起来,然后,使用逆强化学习这个技术。使用逆强化学习技术的时候,机器是可以跟环境互动的。但它得不到奖励。它的奖励必须要从专家那边推出来,有了环境和专家示范以后,去反推出奖励函数长什么样子。之前强化学习是由奖励函数反推出什么样的动作、演员是最好的。逆强化学习是反过来,我们有专家的示范,我们相信它是不错的,我就反推说,专家是因为什么样的奖励函数才会采取这些行为。你有了奖励函数以后,接下来,你就可以套用一般的强化学习的方法去找出最优演员。所以逆强化学习是先找出奖励函数,找出奖励函数以后,再去用强化学习找出最优演员。
把这个奖励函数学习出来,相较于原来的强化学习有什么样好处。一个可能的好处是也许奖励函数是比较简单的。也许,虽然这个专家的行为非常复杂,但也许简单的奖励函数就可以导致非常复杂的行为。一个例子就是也许人类本身的奖励函数就只有活着这样,每多活一秒,你就加一分。但人类有非常复杂的行为,但是这些复杂的行为,都只是围绕着要从这个奖励函数里面得到分数而已。有时候很简单的奖励函数也许可以推导出非常复杂的行为。
逆强化学习实际上是怎么做的呢?如下图所示,首先,我们有一个专家$\hat{\pi}$,这个专家去跟环境互动,给我们很多轨迹:{\hat{\tau_1},$\hat{\tau_2}$,$\hat{\tau_N}$}。如果是玩游戏的话,就让某一个电玩高手,去玩 N 场游戏。把 N 场游戏的状态跟动作的序列都记录下来。接下来,你有一个演员 $\pi$,一开始演员很烂,这个演员也去跟环境互动。它也去玩了 N 场游戏,它也有 N 场游戏的纪录。接下来,我们要反推出奖励函数。怎么推出奖励函数呢?原则就是专家永远是最棒的,是先射箭,再画靶的概念。
专家去玩一玩游戏,得到这一些游戏的纪录,演员也去玩一玩游戏,得到这些游戏的纪录。接下来,你要定一个奖励函数,这个奖励函数的原则就是专家得到的分数要比演员得到的分数高(先射箭,再画靶),所以我们就学习出一个奖励函数。你就找出一个奖励函数。这个奖励函数会使专家所得到的奖励大过于演员所得到的奖励。你有了新的奖励函数以后,就可以套用一般强化学习的方法去学习一个演员,这个演员会针对奖励函数去最大化它的奖励。它也会采取一大堆的动作。但是这个演员虽然可以最大化这个奖励函数,采取一大堆的行为,得到一大堆游戏的纪录。
但接下来,我们就改奖励函数。这个演员就会很生气,它已经可以在这个奖励函数得到高分。但是它得到高分以后,我们就改奖励函数,仍然让专家可以得到比演员更高的分数。这个就是逆强化学习。有了新的奖励函数以后,根据这个新的奖励函数,你就可以得到新的演员,新的演员再去跟环境做一下互动,它跟环境做互动以后, 你又会重新定义奖励函数,让专家得到的奖励比演员大。
怎么让专家得到的奖励大过演员呢?如下图所示,其实我们在学习的时候,奖励函数也许就是神经网络。这个神经网络就是输入 $\tau$,输出就是应该要给这个 \tau 多少的分数。或者说,你假设觉得输入整个 \tau 太难了。因为 \tau 是 s 和 a 的一个很强的序列。也许它就是输入一个 s 和 a 的对,然后输出一个实数。把整个 \tau 会得到的实数都加起来就得到 $R(\tau)$。在训练的时候,对于 $\left{\hat{\tau}{1}, \hat{\tau}{2}, \cdots, \hat{\tau}{N}\right}$,我们希望它输出的 R 越大越好。对于 $\left{\tau{1}, \tau_{2}, \cdots, \tau_{N}\right}$,我们就希望 R 的值越小越好。
什么叫做一个最好的奖励函数。最后你学习出来的奖励函数应该就是专家和演员在这个奖励函数都会得到一样高的分数。最终奖励函数没有办法分辨出谁应该会得到比较高的分数。通常在训练的时候,你会迭代地去做。最早的逆强化学习对奖励函数有些限制,它是假设奖励函数是线性的(linear) 。如果奖励函数是线性的话,你可以证明这个算法会收敛(converge)。但是如果不是线性的,你就没有办法证明说它会收敛。
逆强化学习的框架如下图所示,其实我们只要把逆强化学习中的演员看成生成器,把奖励函数看成判别器,它就是 GAN。所以逆强化学习会不会收敛这个问题就等于是问说 GAN 会不会收敛。如果你已经实现过,你会知道不一定会收敛。但除非你对 R 下一个非常严格的限制,如果 R 是一个一般的网络的话,你就会有很大的麻烦。
我们可以把逆强化学习跟 GAN 比较一下。 如下图所示,GAN 里面,我们有一堆很好的图、一个生成器和一个判别器。一开始生成器不知道要产生什么样的图,它就乱画。判别器的工作就是给画的图打分,专家画的图就是高分,生成器画的图就是低分。生成器会想办法去骗过判别器,生成器会希望判别器 也会给它画的图高分。整个过程跟逆强化学习是一模一样的。画的图就是专家的示范。生成器就是 演员,生成器画很多图,演员 会去跟环境互动,产生很多轨迹。这些轨迹 跟环境互动的记录,游戏的纪录其实就是等于 GAN 里面的这些图。然后你学习一个奖励函数。奖励函数就是判别器。奖励函数要给专家的示范高分,给演员互动的结果低分。 接下来,演员会想办法,从这个已经学习出来的奖励函数里面得到高分,然后迭代地去循环。跟 GAN 其实是一模一样的,我们只是换个说法而已。
逆强化学习有很多的应用,比如可以用开来自动驾驶汽车,有人用这个技术来学开自动驾驶汽车的不同风格。每个人在开车的时候会有不同风格,举例来说,能不能够压到线,能不能够倒退,要不要遵守交通规则等等。每个人的风格是不同的,然后用逆强化学习可以让自动驾驶汽车学会各种不同的开车风格。
下图是文献上真实的例子。在这个例子里面,逆强化学习有一个有趣的地方,通常你不需要太多的训练数据,因为训练数据往往都是个位数。因为逆强化学习只是一种示范,只是一种范例,实际上机器可以去跟环境互动非常多次。所以在逆强化学习的文献, 往往会看到说只用几笔数据就训练出一些有趣的结果。 比如说,在这个例子里面是要让自动驾驶汽车学会在停车场里面停。这边的示范是这样,蓝色是终点,自动驾驶汽车要开到蓝色终点停车。给机器只看一行的四个示范,然后让它去学怎么样开车,最后它就可以学出,在红色的终点位置,如果它要停车的话,它会这样开。给机器看不同的示范,最后它学出来开车的风格就会不太一样。举例来说,上图第二行是不守规矩的开车方式,因为它会开到道路之外,这边,它会穿过其它的车,然后从这边开进去。所以机器就会学到说,不一定要走在道路上,它可以走非道路的地方。上图第三行是倒退来停车,机器也会学会说,它可以倒退,
这种技术也可以拿来训练机器人。你可以让机器人,做一些你想要它做的动作,过去如果你要训练机器人,做你想要它做的动作,其实是比较麻烦的。怎么麻烦呢?过去如果你要操控机器的手臂,你要花很多力气去写程序才让机器做一件很简单的事看。假设你有模仿学习的技术,你可以让人做一下示范,然后机器就跟着人的示范来进行学习,比如学会摆盘子,拉着机器人的手去摆盘子,机器自己动。让机器学会倒水,人只教它 20 次,杯子每次放的位置不太一样。用这种方法来教机械手臂。
第三人称视角模仿学习
其实还有很多相关的研究,如下图所示,举例来说,你在教机械手臂的时候,要注意就是也许机器看到的视野跟人看到的视野是不太一样的。在刚才那个例子里面,人跟机器的动作是一样的。但是在未来的世界里面,也许机器是看着人的行为学的。刚才是人拉着,假设你要让机器学会打高尔夫球,在刚才的例子里面就是人拉着机器人手臂去打高尔夫球,但是在未来有没有可能机器就是看着人打高尔夫球,它自己就学会打高尔夫球了呢?但这个时候,要注意的事情是机器的视野跟它真正去采取这个行为的时候的视野是不一样的。机器必须了解到当它是第三人的视角的时候,看到另外一个人在打高尔夫球,跟它实际上自己去打高尔夫球的时候,看到的视野显然是不一样的。但它怎么把它是第三人的时间所观察到的经验把它泛化到它是第一人称视角的时候所采取的行为,这就需要用到第三人称视角模仿学习(third person imitation learning)的技术。
这个怎么做呢?它的技术其实也是不只是用到模仿学习,它用到了领域对抗训练(domain-adversarial Training)。我们在讲领域对抗训练的时候,我们有讲说这也是一个 GAN 的技术。如下图 所示,我们希望有一个提取器,有两个不同领域(domain)的图像,通过特征提取器以后,没有办法分辨出它来自哪一个领域。其实第一人称视角和第三人称视角,模仿学习用的技术其实也是一样的,希望学习一个特征提取器,机器在第三人称的时候跟它在第一人称的时候看到的视野其实是一样的,就是把最重要的东西抽出来就好了。
序列生成和聊天机器人
在讲序列生成对抗网络(sequence GAN)的时候,我们有讲过句子生成(sentence generation)跟聊天机器人。那其实句子生成或聊天机器人 也可以想成是模仿学习。 如下图所示,机器在模仿人写的句子,你在写句子的时候,你写下去的每一个字都想成是一个动作,所有的字合起来就是一个回合。举例来说,句子生成里面,你会给机器看很多人类写的文字。你要让机器学会写诗,那你就要给它看唐诗三百首。人类写的文字其实就是专家的示范。每一个词汇其实就是一个动作。你让机器做句子生成的时候,其实就是在模仿专家的轨迹。聊天机器人也是一样,在聊天机器人 里面你会收集到很多人互动对话的纪录,那些就是专家的示范。
如果我们单纯用最大似然(maximum likelihood)这个技术来最大化会得到似然(likelihood),这个其实就是行为克隆。行为克隆就是看到一个状态,接下来预测我们会得到什么样的动作,有一个标准答案(ground truth)告诉机器说什么样的动作是最好的。在做似然的时候也是一样,给定句子已经产生的部分。接下来机器要预测说接下来要写哪一个字才是最好的。所以,其实最大似然在做序列生成(sequence generation)的时候,它对应到模仿学习里面就是行为克隆。只有最大似然是不够的,我们想要用序列生成对抗网络。其实序列生成对抗网络就是对应到逆强化学习,逆强化学习就是一种 GAN 的技术。你把逆强化学习的技术放在句子生成,放到聊天机器人里面,其实就是序列生成对抗网络跟它的种种的变形。










