分享

从遗忘问题到预训练轻量化微调

 汉无为 2022-05-30 发布于湖北

所谓的遗忘,在心理学上,是指本来记得的东西,现在在重现的时候发现无法重现或者重现出现偏差的这种现象,所谓的“人工智能”,也会存在和人类似的毛病,那么这个毛病在预训练模型里面如何出现,又如何解决,本文来给出我的讨论。

背景

模型一旦完成了训练,多半不会动这个模型内的参数了,然而随着预训练模型的出现,逐步形成了“pre-train”到“fine-tuning”的两阶段训练模式以后,问题却出现了,我们指望着这个花大力气训好的预训练模型能用在很多领域,并且能充分用到他的知识,事实上我们也获益匪浅,然而值得注意的是,一旦我们又继续开始训练了,而且继续训练的内容和预训练任务差异比较大的时候,参数更新以后,就很可能会把一些原有学到的内容给忘记,甚至我们没想过去验证,问题并非不存在,只是没关注罢了。

然而,已经有不少人有注意到这个问题了,19年有一篇文章[1]内部比较完善地展示了这种遗忘的现象,虽然用的都是CV领域,但是这足够引起我们的思考了。

遗忘的机理

上面其实背景已经讲了不少了,这里,我们来聊预训练模型的遗忘问题是怎么回事。

首先,我们都知道,预训练模型是通过对海量知识的学习得到的,内部的参数本质所代表的就是训练语料对应的语言信息设置逻辑知识信息,值得注意的是,代表各种信息被存储的本质,就是预训练模型中的参数。

然后,预训练模型目前的主要使用方法,依旧是预训练+微调的模式,而微调,注定是要动原来训练的好好的预训练模型的,这里动的,就是预训练模型里面的参数,如果变化的波动足够大,那遗忘,甚至灾难性遗忘就很容易发生了,有的时候,大家可以试试学习率大一些跑跑,会发现学几代以后loss就会骤变,这个其实就是重现遗忘最简单的方式。

但是,值得强调的是,虽然参数一定程度代表了知识,但是他太底层了,参数的修改不见得就代表了知识的丢失,知识可能可以通过别的参数代表,这也是为什么,在很多情况下,fine-tuning我们并没有看到很大的负影响,大部分效果还是非常优秀。

了解了,遗忘的核心本质就是动了,或者说过度变化预训练模型里面的参数,导致了这种遗忘,那么,是否有方式可以解决呢。答案是肯定的。

遗忘的解决方案

NLP领域,说到遗忘,基本都会引这篇文章[2](非常推荐精读这篇文章),这篇文章算是说明了遗忘存在的本质,并且综述了一些比较常见的解决方案,主要分为3点,到了现在的视角,这篇文章的讨论依旧可靠。根据这篇文章的描述,解决遗忘问题可以概括为三个思路:

  • Replay。重播,就是在新任务中,把老的内容复习一遍,能让模型保留住。
  • Regularization-based。通过一些类似正则化的手段,在损失函数上做工作来保持,这点思路其实和蒸馏的思想非常接近,要求在进行下一步训练的时候,模型和原模型之间的差距不会很大。
  • Parameter isolation。参数孤立化,就是把要训练的模块独立出原有的模型,要进行新的任务,就弄个新的模块来,训练就训练这个模块,原有部分就不更新参数了。

如果把问题缩小到预训练模型的问题,重播的方式虽然很简单,但是问题在于预训练模型之前的任务很难重现,也很难控制,毕竟数据和任务都太重了,而正则化的方式,目前其实已经有不少,而且用起来也很方便,从损失函数层面控制起来修改量不会很大,然而,从统计学角度,这种训练最终其实会让预测结果产生偏移,这种训练对最优解并非是新任务的最优解,而且更有甚者,会因为太过关注原本的模型而在效果上被拖累。

所以我其实想说,对预训练模型最优的方式,其实就是那个第三种,Parameter isolation,而且目前其实已经有比较多的研究了,非常推荐大家去尝试,即lightweight finetuning,庞大的预训练模型的微调,参数更新的成本非常高,而如果能够造一个比较小的模块,微调阶段就训练这个,那成本有很大程度的下降,而且,还不会出现非常严重的遗忘问题,虽说出发点本身是为了解决遗忘,但是训练的效率,确实是有不小的提升的。

轻量化微调

轻量化微调,想简单聊聊的论文有4篇。

首先是比较基本的adapter[3],这个模型其实比较简单,一张图就能理解了,就是在Transformer layer中增加了两个全连接层,训练阶段就训这个全连接层即可,而别的attention部分可以不懂,这种训练很简单,而且训练的参数量也很少。

第二篇,想聊的是LoRA[4],它的本质和Adapter相比,就是把上下游的串行改成了并行的关系,看图大家就明白了。如下面图所示,左边的是预训练模型,而右边的就是适配的部分,并行和串行两者来看,并行的似乎可控空间更大。

第三篇,就是prefix-tuning[5]了,这篇文章是在LoRA的基础上做了更加激进的做法,这种做法和后来的prompt其实挺接近的,也是看下图,可以看到,其实就是直接在预训练模型之前加上一串predix,这种方式的使用可以说是对预训练模型底层的理解非常熟悉了。

第四篇,可以说是以为集前面大成之作了,他强的点在于,能够把前面提的3篇论文综合起来,进行了总结和梳理,归结起来就是这样的:

这样画图,大家就能看到上述3篇论文的特点,并且尝试推导出了新的更为合理的优化方式。

本质上我只是想聊的是轻量化微调的常见方式和核心的研究工作吧,详情大家可以直接去看论文,参考文献就在文末。

轻量化微调的讨论

轻量化微调,本质上是给预训练模型加上一些插件,这些插件是可训练的,而且可训练的这部分在更新参数的过程,预训练模型可以纹丝不动,而且经过实验看来,相比常规的finetuning,对最终的效果影响非常小,可以说是灵活度拉满,每次新来一个任务,加一个插件直接训,训完了就是新模型了,这其实某种程度上看,就是迁移学习的方法了,[6]已经非常直白的说这事了,很低的迁移成本和训练成本,而且灾难性遗忘能很大程度上解决,毕竟,预训练模型的参数都没变对吧。但是,预训练模型的参数不变,意味着就是没有遗忘吗?答案似乎是否定的。

预训练模型的参数不变,不代表没有遗忘,其根源在于,预训练模型预测得到的内容,需要像经过adapter进行转化,或者经过LoRA那样的拼接稀释,这种情况下,终究还是可能有损失的。然而到底是损失还是伤害,我们似乎并不太好说出,因为,最终还是测试集说了算,至少我们经过了目前已知的最大努力,给预训练模型做好了“保鲜”了。

参考文献

[1] An Empirical Study of Example Forgetting during Deep Neural Network Learning
[2] A continual learning survey: Defying forgetting in classification tasks
[3] Parameter-Efficient Transfer Learning for NLP adapters
[4] LoRA: Low-Rank Adaptation of Large Language Models
[5] Prefix-Tuning: Optimizing Continuous Prompts for Generation
[6] Towards a Unified View of Parameter-Efficient Transfer Learning

图片


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多