绿色健康小清新

耐得住寂寞,守得住繁华

李宏毅机器学习-50-Life-long Learning

Life-long Learning

细数机器学习处理的问题,概括得讲,可以分为如下几大类:

  • 计算机视觉(CV): object classification, object detection, object segmentation, style transfer, denoising, image generation, image caption
  • 语音(Speech) : speech recogniton, speech synthesis
  • 自然语言处理(NLP): Machine translation, text classfication, emotional recogniton
  • 推荐系统: Recommendation, CRT

目前针对各个大类的不同子类问题, 都会去设计不同的网络结构,设计不同的loss, 采用不同的数据集去处理。 这使得机器学习“偏科严重”,比如前几年很火的AlphaGo, 虽然他是一个“围棋天才”,但是一旦让他去下象棋, 他就歇菜了。换句话说, 目前的人工智能,只能处理给定的任务,换一个任务就无能为力了,这距离我们所想达到的通用智能实在相差甚远。

反观人脑,在人不断成长的过程中,他可以学习各种各样的技能。不仅会下棋,还会踢球,还会辩论等等,而人的大脑只有一个(相当于自始至终只有一个网络)。 虽然随着时间的流逝,以前学习的东西会渐渐淡忘,但这丝毫不影响人脑在不断学习,胜任一个又一个任务中所表现出来的强大。

因此,我们是否可以只用一个网络结构(注意,这里的网络结构并非是固定的。也许随着任务的需要,得自行扩展网络),在不同的任务上分别训练,使得该网络能够胜任所有的任务呢? 这就是Life-long learning 所要研究的课题。

简介

Life Long Learning可以简写为LLL,又有别的名称:

  • continuons learning
  • never ending learning
  • incremental learning

其实就是机器学习了task 1,之后又学习了task 2,这时候机器同时掌握了task 1和task 2,如果机器继续学习别的task的话,就同时拥有了更多的技能,假设机器学习了很多的技能,机器就十分无敌,就可以变成天网了!这是我们理想中的机器学习形态,但是众所周知,我们现在还没有达到这种情况。

想要实现终生学习,首先要实现以下三个问题。


Knowledge Retention(知识保留)

第一个就是知识的保留,就是机器要把自己原来学过的知识进行保留,不可以学习了一个新的,就忘记旧的。但是机器又不能对这个妥协,其实就是机器不可以因为不可以忘记旧的知识,就拒绝一切新的知识。

Example – Image

我们一起来看一看机器的脑洞到底有多大,我们这里有一个三层的一个神经网络,每一层有五十个神经元,我们用这样的模型来完成下面两个任务。两个任务都是数字识别,但是可以看到的是,第一个任务是带有杂讯的数字,但是第二个是没有杂讯的

  1. 我们先用任务一的数据库对其进行导入,进行学习训练,当我们进行检验的时候发现,这个模型完任务一的准确率是百分之九十,完成任务二的准确率是百分之九十六(任务二比任务一简单,所以任务二的数字更容易识别)
  2. 当我们把上一步训练好的模型参数作为训练任务二的模型初始值的时候,我们再经过训练发现,任务一数字识别的准确率变为百分之八十,任务二数字识别的准确率变为百分之九十七,可以看到的是任务二仅仅提高了百分之一,但是任务一却忘记了。

很多人都会说机器就是会忘记掉,是无法解决的问题,但是当我们把任务一和任务二的训练数据放到一起,全部导入神经网络模型一起训练的话,我们发现任务一的准确率变为百分之八十九,而任务二的准确率是百分之九十八,意味着机器是有能力同时把两个任务都做好的,但是为什么分开训练就完蛋了呢!

这里的多任务一起学习我觉得可以参考之前在Transfer中提到的Multitask Learning(多任务学习)

Example – Question Answering

不仅是在CV中,在NLP中也有类似的例子,用模型训练一个自动问答系统,让它处理不同的任务,往往训练到下一个任务的时候他就忘记了之前的:

bAbi这样的一个copurs是一个二十种问题以及二十种问题答案的训练集。一般有两种玩法:

  1. 训练一个模型,读取所有题型数据进行训练
  2. 训练20个模型,分别解决20种题型

现在我们让一个模型每一次只训练一种问题,但是每一种问题训练完成之后,我们都让模型来回答一次固定任务的问题,检查一下准确率:

  • 右上角:20个任务依次进行训练,但每次训练结束后都回答第五种问题。我们看一下准确率折线:我们发现之前都不会的模型,在训练完问题五以后,准确率达到一个峰值,但是之后却又不会回答问题五了
  • 右下角:同上
  • 左:当每次训练结束都回答第十种问题时,发现有四次回答准确率都超过了40%,效果最好的当然是训练第十次任务的时候,但另外三次是怎么回事呢?可能是因为第十种问题和这三种问题有点相似!

这时候我们反思,是不是现有模型的参数个数不足以让模型同时学会二十种问题呢?

事实证明并不是的,因为我们同时把二十种问题的数据集全部放入网络中,之后分别检测每一种问题的准确率,我们发现其实每一种问题,机器都可以达到一定高度的准确率,这就证明机器并不是不能同时学会二十种问题的解法,只是机器没有同时学会!

“是不为也,非不能也” ——《孟子-梁惠王上》

这种情况我们称之为“catastrophic forgetting”(灾难性的忘记)就像这个人一样,学的东西统统都忘记。


Multi-task training 的两个问题

很多人说,解决catastrophic forgetting的方法已经出现了啊,就是很多任务同时进行训练!

但是这种multi task的方法在训练任务少的时候还可以,一旦训练任务过多就存在一定的弊端:

  • 首先就是storage issue(存储问题):假设我们一共又一千个任务,我们如果之前训练好了999个任务,我们想训练1000个任务的时候,我们就要把之前999个任务的数据全部放入计算机,这将造成计算机存储爆掉
  • 第二个问题就是computation issue(计算问题),仍然是训练第1000个任务的时候,我们将1000个任务的数据都放入模型中进行计算,机器要计算那么多数据,将对机器造成很大的计算压力。

以上是对multi task问题的解读,我们终生学习所想要解决的其实就是如何在不使用multi task的情况下,让模型把每一个不同的任务都学好。


Elastic Weight Consolidation (EWC,弹性权重巩固)

EWC

基本思想:在我们训练的参数中,有的参数是不重要的(这个参数无论怎么改变,之前学学过的任务都不会忘记),但是有的参数是十分重要的(就是说如果这个参数改变了,那么之前学过的任务就忘记了),θb\theta^b 反应的是这个模型中所有的参数。每一个参数θib\theta_i^b 都有一位bib_i (反应的是这个参数是否是重要的)。如果bib_i值大,就意味着这个参数是十分重要的,改变的话对之前的任务学习就会忘记了。

我们看一下在EWC中的loss function:

L(θ)=L(θ)+λibi(θiθib)2L'(\theta) = L(\theta) + \lambda\sum_ib_i(\theta_i- \theta_i^b)^2

θi\theta_i 是我们更新后的参数,θib\theta_i^b 是我们更新前的参数。我们原来的loss function仅仅是对参数θ\theta 进行更新,但是没有考虑这个参数是否是重要的。我们新的loss function就考虑了这一点,在之前的条件下,我们加入了新的一项。

  • 如果bib_i 很大的话,后一项如果括号中的变大,就会使新的损失函数瞬间变大,因此这些参数只能小幅度的改变;

  • 如果bib_i 很小的话,即使括号中的内容变大,损失函数依然不会很大,因此这些参数可以较大幅度的改变

我们举个例子来说,每一个参数的bib_i 值是不相同的:

  • 假设一个参数的bib_i 值很小,是0,就是后一项无论怎样都不会有改变,那么意味着这个参数可以随意更新,即使怎样更新都不会对之前的任务有影响
  • 假设这个参数的bib_i 值很大的话,无限大的话,后一项如果有改变,那么损失函数就会很大,就只能小幅度改变,甚至不可以更改这个参数

上式中的后面一项相当于正则项,不同于L2正则(λi=1kwi2\lambda \sum_{i=1}^k w_i^2),它是针对每一个参数θi\theta_i,限制θi\theta_i能不能远离θb\theta^b。它们两者训练出来结果的差距我们在下面会讲到!

怎么找b?

那么按照EWC的想法,我们的重点就是在于如何找到每个参数的bib_i

我们先看一下不用EWC使不同task分开训练的情况是如何的。

举一个例子来说明这个问题:上图中,左边是task1,右边是task2。图片中颜色越深的地方反应的就是loss越来越大的地方。我们先训练task1,我们使用梯度下降的方法来解决这个问题,我们把参数θ0\theta^0更新为θb\theta^b,之后我们把θb\theta^b当作task2的初始参数,进行task2的更新,更新到task2的loss function变小以后,比如图中的θ\theta^* ,我们测试这个参数对于task1的表现,发现task1的损失函数很大。

这就解释了为什么会毁灭性忘记的原因!

EWC的想法是:引入了一个参数叫做bib_i 来衡量参数θi\theta_i 的重要性,而bib_i 可以是L(θ)L(\theta)关于每个参数θ\theta的二次微分!

  • 右边上图:如果二次微分比较平坦的话,就意味着在θ1\theta_1方向(x轴)的重要性是很低的,意味着在x轴方向可以进行大得移动
  • 右边下图:如果二次微分比较忐忑,就意味着在θ2\theta_2 (y轴)方向的重要性是比较高的,所以就不能在y轴方向进行太大得移动

类似的概念我们在机器学习开始的Gradient Descent中就已经提及过了!

基于EWC的想法,我们此时更新参数就不能像之前那样直接更新为θ\theta^*

在图中表示的话,就是在x轴方向可以进行比较大得移动,但是在y轴就不要进行较大得移动。所以原本像右侧四十五度方向的移动就变为了平移,平移之后的参数θ\theta在task1中的损失函数也和之前训练时候相比差距不大,所以实现了不忘记的要求!

EWC vs L2 vs SGD

这是最初EWC论文的结果图,图中折线显示的是EWC,L2正则化,和随机梯度下降三种方法的区别。横向表示的是先训练taskA,之后再训练taskB,最后是训练taskC。纵向是使用不同的任务进行测试。

上图可以看到的是在训练A的时候,A的准确率是蛮高的,但是训练B的时候,使用SGD的情况下,A的准确率开始下降,到C的时候更是下降;但是使用EWC的情况下,是不会有什么改变的;在使用L2的时候,会有一些下降,但是下降的不大。

我们看TaskB的情况下,我们再训练TaskC的时候,使用SGD时,B的准确率还是会降低;使用EWC的时候,B的准确率几乎不变,但是使用L2正则化的方法的话,我们发现他为了记忆住TaskB的方法,选择不去学习TaskC了。

L2是一种比较保守的做法!

other

其他的方法和EWC类似,例如:Synaptic Intelligence (SI),把海森矩阵换成了曲率;**Memory Aware Synapses (MAS)**的想法也是类似的,甚至它的data不需要被标记!

Generating Data

下面我们介绍另一种方法,之前我们了解,multi-task的方法是一种可以解决一定的life long learing的方法,很多paper都是将自己的算法和multi-task的方法进行比较的。因为multi-task方法对于存储是有问题的,我们设想一种方法解决存储的问题。我们可以不存储之前task的数据,而是通过generater(生成器)去生成之前task的数据集。

举个例子就是,task1中不仅更新了参数,同时也训练一个生成器用来生成task1的数据集,之后把生成器生成的数据集放入到task2中,进行训练,以此类推。我们不再存储之前任务的数据集,我们通过数据训练一个生成器,生成这种数据集,但是这种方法存在弊端,就是现在生成器是很难生成十分高清的影像的,所以这种方法能否被广泛应用依然是问题。

贴出两篇paper供参考:


Adding New Classes

在之前的例子中,我们都是假设每一个task都是相同的神经网络架构,但是在实际问题中,很可能不同任务的神经网络架构是不相同的,那么怎么解决的呢!

这里有两篇paper用来解决这种问题:


Knowledge Transfer (知识迁移)

第二个需要解决的问题是,在训练不同任务的时候,如何将知识进行transfer。

思考一下:我们不就是想要解决很多的任务吗!那为什么不直接拿出很多的模型去训练呢?

首先:我们想让机器在学完task1之后,学习task2会更加的快,同样在学完task1,task2之后,学习task3会更快。就像我们学习完线性代数,会对学习机器学习有帮助,做到触类旁通。

其次:我们知道机器的存储是有一定极限的,我们如果存储一千个模型的话,就会对机器的存储造成影响。

那用Transfer learning是不是可以解决这个问题?

Life-Long v.s. Transfer

之前的描述,我们发现终生学习会和迁移学习有点相似的地方。没错,迁移学习和终生学习都是想让机器在学习完task1之后会对task2有帮助,做到触类旁通。

但是迁移学习会和终身学习有区别的地方在于:迁移学习只是想做到学习task1会对task2有帮助,但是学完task2是否会忘记task1却没有任何要求(这里我们不考虑Transfer中的Multitask Learning(多任务学习),因为它是直接一起学习的)。但是终身学习要求学完task2以后,不要忘记task1。

就是说,迁移学习是很容易得了芝麻丢了西瓜的,但是终身学习却不会忘记之前的情况。终身学习包括了迁移学习想做到知识的transfer,但是终身学习还想做到的是保证知识的retention。

Evaluation(衡量终生学习能力的方法)

当我们在衡量一个终身学习的能力时,我们通常会画出一个矩阵。

  • 矩阵的行表示的是依次训练某个Task
  • 矩阵的列表示的是测试某个Task

所以矩阵的第(i,j)项表示的意义就是在训练完第i个task时候,模型在第j个task的表现如何。

  • 如果i>j,矩阵的第(i,j)项所反应的就是这个模型存储学习知识的能力
  • 如果i<j,矩阵的第(i<j)项表示的是矩阵举一反三的能力,就是矩阵能否根据之前学习的task对后续的task进行优化。

下面我们介绍的是一个衡量终身学习的一些参数

  1. Accuracy(ACC):就是在模型学习完所有的task以后,对每一个task的表现的均值(下图中的红线部分)

    ACC=1Ti=1TRT,iACC = \frac{1}{T}\sum_{i=1}^TR_{T,i}

  2. Backward Transfer(BWT):就是使用模型在学习最后一个(第T个)task以后对之前第i个task的表现减去刚刚学完第i个时候的表现的差值(通常为负数,上图中的蓝色部分)。反应的是记忆能力

    BWT=1Ti=1T1RT,iRi,iBWT = \frac{1}{T}\sum_{i=1}^{T-1}R_{T,i}-R_{i,i}

    • 如果这个差值很大,就意味着模型对于之前学会的知识忘记的很多;
    • 如果这个差值很小,就意味着模型对于之前学会的知识忘记的很少;
    • 如果这个差值大于零,就意味着以后学到的知识对于之前学过的是一个促进的作用。
  3. Forward Transfer(FWT):我们以最后一个任务task T为例,这个参数反应的是机器还没有学习T,只是学习了T之前别的task时候对于T的影响。我们用机器学习之前T-1个task时候对任务taskT的表现减去初始化参数时候对taskT的表现(下图绿色部分)。用这个参数衡量机器学习之前任务对现在任务的影响。如果这个参数是正的,那么就说明这个机器是会触类旁通的。反应的是迁移能力

    FWT=1T1i=2TRi1,iR0,iFWT = \frac{1}{T-1}\sum_{i=2}^TR_{i-1,i}-R_{0,i}


Gradient Episodic Memory (GEM,梯度片段记忆)

GEM是一个更新GD的策略

👉 Gradient Episodic Memory for Continual Learning

👉 Efficient Lifelong Learning with A-GEM

我们举一个例子:GEM。假设我们有三个任务,task1,task2,task3。之前1,2都已经学习完毕,下面我们想学习task3。

我们计算出更新task3参数方向是红色虚线的方向,我们对这个gg和之前第一个任务的g1g^1,第二个任务的g2g^2g1g^1,g2g^2是通过保存的以前的一部分数据来计算之前task的梯度)做内积,发现这个内积都是正数,所以如果是按照虚线方向更新的话,对之前两个任务是没有任何影响的,我们就按照虚线方向更新参数。

但是如果像右图一般,ggg1g^1的内积是负数的话,这个gg就会对之前task1造成影响,我们就不可以这么做了。我们转换gg到实线的方向(但是注意,gg^{'} 的方向和gg方向应该是差别不大的)。

其实就是每一次更新gg都和之前的g1g^1g2g^2进行一个内积的运算,如果运算结果是正的话,我们就进行更新,如果运算结果是负的话,我们就调整一下gg,但调整后的gg'要尽可能和gg接近。之后按照调整之后的g进行更新。

但是这个方法有一定的弊端,就是我们每每训练下一个任务的时候,都要保存一些旧的数据,因为g1g^1g2g^2是每一次都要重新计算的。

这个便是GEM的结果,图中single的意思就是一个模型从第一个任务开始逐个训练到最后一个任务,independent的意思是每一个任务对应一个模型进行训练,multimodal是指所有的task的数据全部都放入到一个multimodal中。我们可以看出来,GEM是一个很棒的方法,因为GEM的BWT是正的,证明他不但没有忘记之前学过的知识,反而一定情况下做到了触类旁通。


Model Expansion(模型扩张)

我们第三个要解决得问题是,模型的扩张。在我们之前的学习中,我们都假定当前的模型是足够大的,以至于可以学好所有的task,但是在实际问题中,有时候模型并不能学好所有的知识,所以我们就需要将模型进行扩张。但是我们想要的扩张时希望可以有效率的进行扩张。其实我们不希望每进来一个新的task,模型就进行扩张,这样的结果只能时模型太大,导致存储不足。我们希望模型扩张的速度比任务添加的速度要慢

Progressive Neural Networks(渐进神经网络)

👉 Progressive Neural Networks

第一种模型扩张的例子是16年的paper所提到的Progressive Neural Networks。其实我们之前就在Transfer中介绍过了!

就是第一个task的模型我们把参数学习好以后fix住,之后再训练第二个task,我们建设一个新的模型,同时将task1的输出当作是task2的输入,同理,第三个task3时,将前两个模型的参数fix住,并且将前两个模型的输出当作时第三个模型的输入。

但是这有一个弊端,就是这样的方法是不会训练太多的任务的,因为如果训练太多的任务时候,就会对这个模型造成很大的负荷。

Expert Gate

👉 Expert Gate: Lifelong Learning with a Network of Experts

我们依旧是每一个任务对应一个模型。比如我们有三个任务,第四个来的任务和第一个很像(我们用Gate来判别新来的任务和旧的哪个任务比较像),那么我们就将第一个任务的模型作为第四个任务模型的初始化,这样就形成了一定的迁移的效果。但是这个方法依旧是一个任务对应一个模型,对于存储仍然造成很大的压力


Net2Net

👉 Net2Net: Accelerating Learning via Knowledge Transfer

👉 Towards Training Recurrent Neural Networks for Lifelong Learning

这个方法就是当我们新来的任务进来一个,原来模型的loss降不下去,或者是准确率是无法提升的,我们就需要在原有情况下在层中添加神经元。但是不能改变原来参数,所以就采用分裂原有神经元的方法,h[2]和h[3]就是分裂后的产物,都是输入是c和d,输出是f/2。

但是这样的话,这两个分裂的神经元梯度下降更新的参数都是一样的,没什么用。所以我们在这两个神经元中添加一定的噪声。就让分裂的神经元变成两个独立的神经元了。

这个方法不是每每添加一个task就加神经元,而是每当模型的loss不会降低,模型的准确率不会提高时候才添加神经元


Curriculum Learning : what is the proper learning order?

Curriculum Learning 类似于一个课程系的学习, 研究的是如何安排课程学习的先后顺序。

其实我们可以思考一下,终身学习的学习顺序会不会对学习效率造成影响呢?

我们之前是将带杂讯的作为task1,之后再将没有杂讯的作为task2,我们发现学习完task2以后,机器完全忘记了task1的知识!

但是,我们如果将没有杂讯的作为task1,将有杂讯的作为task2以后,我们发现机器不但学会了带杂讯的,反而在不带杂讯的情况下学习的很好。

我们可以思考,任务的先后次序,确实会对学习的效果起到帮助。

Taskonomy

Taskonomy 研究的是各个任务之间的关系, 即该先学哪个,后学哪个。

👉 http://taskonomy.stanford.edu/#abstract

-------------本文结束感谢您的阅读-------------
六经蕴籍胸中久,一剑十年磨在手

欢迎关注我的其它发布渠道