赞
踩
细数机器学习处理的问题,概括得讲,可以分为如下几大类:
目前针对各个大类的不同子类问题, 都会去设计不同的网络结构,设计不同的loss, 采用不同的数据集去处理。 这使得机器学习“偏科严重”,比如前几年很火的AlphaGo, 虽然他是一个“围棋天才”,但是一旦让他去下象棋, 他就歇菜了。换句话说, 目前的人工智能,只能处理给定的任务,换一个任务就无能为力了,这距离我们所想达到的通用智能实在相差甚远。
反观人脑,在人不断成长的过程中,他可以学习各种各样的技能。不仅会下棋,还会踢球,还会辩论等等,而人的大脑只有一个(相当于自始至终只有一个网络)。 虽然随着时间的流逝,以前学习的东西会渐渐淡忘,但这丝毫不影响人脑在不断学习,胜任一个又一个任务中所表现出来的强大。
因此,我们是否可以只用一个网络结构(注意,这里的网络结构并非是固定的。也许随着任务的需要,得自行扩展网络),在不同的任务上分别训练,使得该网络能够胜任所有的任务呢? 这就是Life-long learning 所要研究的课题。
Life Long Learning可以简写为LLL,又有别的名称:
其实就是机器学习了task 1,之后又学习了task 2,这时候机器同时掌握了task 1和task 2,如果机器继续学习别的task的话,就同时拥有了更多的技能,假设机器学习了很多的技能,机器就十分无敌,就可以变成天网了!这是我们理想中的机器学习形态,但是众所周知,我们现在还没有达到这种情况。
想要实现终生学习,首先要实现以下三个问题。
第一个就是知识的保留,就是机器要把自己原来学过的知识进行保留,不可以学习了一个新的,就忘记旧的。但是机器又不能对这个妥协,其实就是机器不可以因为不可以忘记旧的知识,就拒绝一切新的知识。
我们一起来看一看机器的脑洞到底有多大,我们这里有一个三层的一个神经网络,每一层有五十个神经元,我们用这样的模型来完成下面两个任务。两个任务都是数字识别,但是可以看到的是,第一个任务是带有杂讯的数字,但是第二个是没有杂讯的。
很多人都会说机器就是会忘记掉,是无法解决的问题,但是当我们把任务一和任务二的训练数据放到一起,全部导入神经网络模型一起训练的话,我们发现任务一的准确率变为百分之八十九,而任务二的准确率是百分之九十八,意味着机器是有能力同时把两个任务都做好的,但是为什么分开训练就完蛋了呢!
这里的多任务一起学习我觉得可以参考之前在Transfer中提到的Multitask Learning(多任务学习)
不仅是在CV中,在NLP中也有类似的例子,用模型训练一个自动问答系统,让它处理不同的任务,往往训练到下一个任务的时候他就忘记了之前的:
bAbi这样的一个copurs是一个二十种问题以及二十种问题答案的训练集。一般有两种玩法:
现在我们让一个模型每一次只训练一种问题,但是每一种问题训练完成之后,我们都让模型来回答一次固定任务的问题,检查一下准确率:
这时候我们反思,是不是现有模型的参数个数不足以让模型同时学会二十种问题呢?
事实证明并不是的,因为我们同时把二十种问题的数据集全部放入网络中,之后分别检测每一种问题的准确率,我们发现其实每一种问题,机器都可以达到一定高度的准确率,这就证明机器并不是不能同时学会二十种问题的解法,只是机器没有同时学会!
“是不为也,非不能也” ——《孟子-梁惠王上》
这种情况我们称之为“catastrophic forgetting”(灾难性的忘记)就像这个人一样,学的东西统统都忘记。
很多人说,解决catastrophic forgetting的方法已经出现了啊,就是很多任务同时进行训练!
但是这种multi task的方法在训练任务少的时候还可以,一旦训练任务过多就存在一定的弊端:
storage issue(存储问题)
:假设我们一共又一千个任务,我们如果之前训练好了999个任务,我们想训练1000个任务的时候,我们就要把之前999个任务的数据全部放入计算机,这将造成计算机存储爆掉computation issue(计算问题)
,仍然是训练第1000个任务的时候,我们将1000个任务的数据都放入模型中进行计算,机器要计算那么多数据,将对机器造成很大的计算压力。以上是对multi task问题的解读,我们终生学习所想要解决的其实就是如何在不使用multi task的情况下,让模型把每一个不同的任务都学好。
基本思想:在我们训练的参数中,有的参数是不重要的(这个参数无论怎么改变,之前学学过的任务都不会忘记),但是有的参数是十分重要的(就是说如果这个参数改变了,那么之前学过的任务就忘记了), θ b \theta^b θb 反应的是这个模型中所有的参数。每一个参数 θ i b \theta_i^b θib 都有一位 b i b_i bi (反应的是这个参数是否是重要的)。如果 b i b_i bi值大,就意味着这个参数是十分重要的,改变的话对之前的任务学习就会忘记了。
我们看一下在EWC中的loss function:
L
′
(
θ
)
=
L
(
θ
)
+
λ
∑
i
b
i
(
θ
i
−
θ
i
b
)
2
L'(\theta) = L(\theta) + \lambda\sum_ib_i(\theta_i- \theta_i^b)^2
L′(θ)=L(θ)+λi∑bi(θi−θib)2
θ
i
\theta_i
θi 是我们更新后的参数,
θ
i
b
\theta_i^b
θib 是我们更新前的参数。我们原来的loss function仅仅是对参数
θ
\theta
θ 进行更新,但是没有考虑这个参数是否是重要的。我们新的loss function就考虑了这一点,在之前的条件下,我们加入了新的一项。
如果 b i b_i bi 很大的话,后一项如果括号中的变大,就会使新的损失函数瞬间变大,因此这些参数只能小幅度的改变;
如果 b i b_i bi 很小的话,即使括号中的内容变大,损失函数依然不会很大,因此这些参数可以较大幅度的改变
我们举个例子来说,每一个参数的 b i b_i bi 值是不相同的:
上式中的后面一项相当于正则项,不同于L2正则( λ ∑ i = 1 k w i 2 \lambda \sum_{i=1}^k w_i^2 λ∑i=1kwi2),它是针对每一个参数 θ i \theta_i θi,限制 θ i \theta_i θi能不能远离 θ b \theta^b θb。它们两者训练出来结果的差距我们在下面会讲到!
那么按照EWC的想法,我们的重点就是在于如何找到每个参数的 b i b_i bi?
我们先看一下不用EWC使不同task分开训练的情况是如何的。
举一个例子来说明这个问题:上图中,左边是task1,右边是task2。图片中颜色越深的地方反应的就是loss越来越大的地方。我们先训练task1,我们使用梯度下降的方法来解决这个问题,我们把参数 θ 0 \theta^0 θ0更新为 θ b \theta^b θb,之后我们把 θ b \theta^b θb当作task2的初始参数,进行task2的更新,更新到task2的loss function变小以后,比如图中的 θ ∗ \theta^* θ∗ ,我们测试这个参数对于task1的表现,发现task1的损失函数很大。
这就解释了为什么会毁灭性忘记的原因!
EWC的想法是:引入了一个参数叫做 b i b_i bi 来衡量参数 θ i \theta_i θi 的重要性,而 b i b_i bi 可以是 L ( θ ) L(\theta) L(θ)关于每个参数 θ \theta θ的二次微分!
类似的概念我们在机器学习开始的Gradient Descent中就已经提及过了!
基于EWC的想法,我们此时更新参数就不能像之前那样直接更新为 θ ∗ \theta^* θ∗ 。
在图中表示的话,就是在x轴方向可以进行比较大得移动,但是在y轴就不要进行较大得移动。所以原本像右侧四十五度方向的移动就变为了平移,平移之后的参数 θ \theta θ在task1中的损失函数也和之前训练时候相比差距不大,所以实现了不忘记的要求!
这是最初EWC论文的结果图,图中折线显示的是EWC,L2正则化,和随机梯度下降三种方法的区别。横向表示的是先训练taskA,之后再训练taskB,最后是训练taskC。纵向是使用不同的任务进行测试。
上图可以看到的是在训练A的时候,A的准确率是蛮高的,但是训练B的时候,使用SGD的情况下,A的准确率开始下降,到C的时候更是下降;但是使用EWC的情况下,是不会有什么改变的;在使用L2的时候,会有一些下降,但是下降的不大。
我们看TaskB的情况下,我们再训练TaskC的时候,使用SGD时,B的准确率还是会降低;使用EWC的时候,B的准确率几乎不变,但是使用L2正则化的方法的话,我们发现他为了记忆住TaskB的方法,选择不去学习TaskC了。
L2是一种比较保守的做法!
其他的方法和EWC类似,例如:Synaptic Intelligence (SI),把海森矩阵换成了曲率;**Memory Aware Synapses (MAS)**的想法也是类似的,甚至它的data不需要被标记!
- 本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。