本节仍然是为了系列笔记的完整性而做,主要介绍迁移学习的概念,以及BERT出现之前NLP领域两个重要的预训练模型ULMFit和ELMo
本节完全来自于Sebastian Ruder博士论文的第三章。原文一共有90页,本文作为转记,完全覆盖原文的所有内容有些困难,所以只能有所取舍——例如原文引用了大量相关工作,本文由于篇幅的限制,只能通通略去,因此强烈建议有兴趣的朋友也阅读原文,顺藤摸瓜
在经典的有监督学习中,如果要为某个任务或某个领域 A A A训练模型,一般会假设我们对此任务/领域有足够数据,而且也只能预期模型在同样的任务/领域上能够取得不错的效果——也就是说,前提假设是数据都是独立同分布(i.i.d.)的。如果任务或者领域变了,就要重新收集数据,重新从头训练模型。如果新的任务/领域没有足够数据,传统的有监督学习方法就不再适用,这时就需要迁移学习的帮忙,因为这种方法可以把相关任务/领域(称为源任务/源领域)的知识提取出来,应用在目标任务/目标领域上。通常情况下,我们假设对目标任务/领域,有少量有标签数据,或者大量无标签数据
为了更简洁的描述,可以引入一些符号定义和例子。记领域为 D \mathcal{D} D,由特征空间 X \mathcal{X} X和该特征空间上的边缘概率分布 P ( X ) P(X) P(X)组成,其中 X = { x 1 , … , x n } ∈ X X = \{x_1, \ldots, x_n\} \in \mathcal{X} X={x1,…,xn}∈X。以文档分类问题为例,如果使用词袋模型, X \mathcal{X} X就是所有文档表示组成的空间, x i x_i xi是第 i i i个文档的向量表示, X X X是一个随机变量,表示用来训练的文档样本集合。即 D \mathcal{D} D可以表示为一个元组
D = { X , P ( X ) } \mathcal{D} = \{\mathcal{X}, P(X)\} D={X,P(X)}
对给定的领域 D \mathcal{D} D,任务 T \mathcal{T} T包含一个标签空间 Y \mathcal{Y} Y、一个先验分布 P ( Y ) P(Y) P(Y)和一个条件概率 P ( Y ∣ X ) P(Y|X) P(Y∣X),其中条件概率通常从训练数据中学到。仍以分档分类问题为例,此时 Y \mathcal{Y} Y是所有可能的标签组成的集合,即 { T r u e , F a l s e } \mathtt{\{True, False\}} {True,False}。所以 T \mathcal{T} T也可以表示为一个元组
T = { Y , P ( Y ) , P ( Y ∣ X ) } \mathcal{T} = \{\mathcal{Y}, P(Y), P(Y|X)\} T={Y,P(Y),P(Y∣X)}
使用上面的记号,并以 S S S表示“源端”, T T T表示“目标端”,则迁移学习可以分为五大应用场景,分别为
在[PanJialin2009]的基础上,NLP领域迁移学习的分类可如下图所示。其中跨语言学习部分可参考本专栏前面的内容,本文主要介绍剩余三类迁移学习,即多任务学习、顺序学习和领域适配
机器学习的目的通常是为某个确定任务训练模型,但是如果聚焦于某个任务,多少会顾此失彼,忽略某些可以帮助我们在其他方面做得更好的信息。如果可以在相关的任务之间共享一些表示方法,就可以让模型有更好的泛化能力,这种方法称为多任务学习,也被称为联合学习(joint learning)、L2L(learning to learn)等。通常情况下,如果优化问题有多个损失函数,则就在做多任务学习了
在深度学习语境下,多任务学习可以通过隐藏层的硬参数共享/软参数共享来达到
尽管常见的多任务学习在实施时是引入多个损失函数一起优化,但即便在常见的,只优化一个损失函数的场景下,也有机会通过辅助任务来提升模型效果。常见的辅助任务可以分为如下四类:
统计的。这类辅助任务是要预测输入数据底层的统计信息,例如对序列标注任务,同时预测词汇的频率,使得模型不会在常见词和罕见词之间共享表示信息
选择性无监督的(selective unsupervised)。例如对情感分析任务,预测句子是否包含某个领域无关的正向/负向情感词
有监督的。例如使用与主任务相关的任务、对抗训练、反向训练(例如机器翻译,英法翻译系统同时用法英数据训练)、对输出进行预测、用未来信息预测当前信息等(还有一个quantization smoothing,没太明白)。NLP各领域里,典型的辅助任务选取有如下实例
无监督的。例如引入一些通用任务(如语言模型)来进行表示学习,或者学习序列模型的初始状态
假设有两个相关的任务 A A A和 B B B,两者依赖于一个共同的隐藏层表示 F F F,多任务学习的有效性可以从如下几方面来阐述
在顺序迁移学习场景下,源端任务和目标端任务不同,训练分别按顺序进行,而不是像多任务学习那样多个模型联合优化。顺序迁移学习的目标是将训好的模型(模型由源端任务训练得到)所拥有的知识转移到目标模型上,以提高目标模型的性能,其在以下三个场景会比较有效
顺序迁移学习一般包含两个阶段
当顺序迁移学习应用于多个任务时,称作终生学习,也被称作学习如何学习(learning to learn)或元学习(meta-learning)。终生学习中,源任务和目标任务不再泾渭分明,而是顺序学习 T T T个任务。终生学习模型通常包含两个成分
终生学习可以看做是一种在线的多任务学习,其在NLP里最常用的两个领域是信息提取和情感分析。
此外,原文将元学习看做是终生学习的一种手段,其中,元学习最常用的策略是使用一个独立的控制器来控制基模型的学习过程,例如Wolf2018使用一个高层LSTM来更新语言模型的权重。另一种策略是进行“元优化”,以学习模型参数为目标,其生成的初始化参数可以让模型在下游任务上的微调更容易。这类工作的开山鼻祖是模型不可知论元学习(Model-Agnostic Meta-Learning, MAML),有人将其用在低资源机器翻译上(Gu2018)。元学习的基本思路是通过反复模拟适配场景来学习一个好的初始化参数。由于在大数据集上微调的代价太大,所以元学习基本都用在少样本学习(few-shot learning)场景
(本小节引用文献相对细碎,建议直接阅读原文)
机器学习领域通常假设训练数据和测试数据独立同分布,但是当模型被应用于真实环境下时,这样的假设就无法成立了,所以需要领域适配。领域适配不需要模型在所有任务上普遍表现得好,只需要对特定任务发挥出色就可以。与顺序迁移学习不同,领域适配通常要用在大量无标签样本上,所以需要的是无监督方法。具体地,这些方法可以分为三类
基于表示的方法试图修改数据的底层表示,或是要基于领域相似度找出在源领域和目标领域都存在的特征,或是要在两个领域的共享低维空间中表示数据
可以通过让两个领域的特征分布尽量相似来尝试进行领域适配(只需要丢掉在目标数据中不存在的特征就可以)。最常见的分布相似性度量方法是KL散度(Kullback-Leibler divergence): D K L ( P S ∣ ∣ P T ) = E x ∼ P S [ log P S ( x ) − log P T ( x ) ] D_{\rm KL}(P_S||P_T) = \mathbb{E}_{ {\bf x}\sim P_S}[\log P_S({\bf x}) -\log P_T({\bf x})] DKL(PS∣∣PT)=Ex∼PS[logPS(x)−logPT(x)],其余还有JS散度(Jensen-Shannon divergence)、Rényi散度、MMD(Maximum Mean Discrepancy)、Wasserstein距离和 A \mathcal{A} A距离等
可以通过某些方法度量目标数据各样本与已有训练集中各样本的相似度。如果利用相似度对训练数据给出权重,影响其对损失函数的贡献,则这种方法为数据加权;如果设定阈值,淘汰掉一批不相关的数据,则这种方法为数据选择。机器翻译领域中常用数据选择的方法,例如通过语言模型打分进行筛选(原文中大量的方法都出现在统计翻译时代)
自标注技术是半监督学习的一种,核心思路是在有标签数据上训练模型,然后让这个模型给未标注数据打上“伪”标签,然后用带有真伪标签的数据混合,训练更好的模型。在混合时,对带有伪标签的数据,通常使用一个阈值选择置信度比较高的。在此基础上,还有一些其他自标注技术,例如
本节最后一个小节讲述了多源领域适配,不过引用的工作更加琐碎,这里就不介绍了
前文对迁移学习作了一个简单的介绍,其中在顺序迁移学习部分,提到这种迁移学习方法大致可以分为两步,即预训练和微调。自2013年Mikolov提出word2vec开始至2018年以前,基于神经网络的NLP方法所使用的的预训练“模型”基本上都是基于词向量的。词向量使得人们可以不再仅以0-1独热向量表示词语,而是可以获得词语的稠密表示,且可以通过一些向量运算发现词之间的关系。但是词向量模型的产生结果通常是一组独立于上下文的词向量,表示能力不够强。在2018年初,ULMFiT和ELMo两种基于LSTM的预训练模型相继问世,不仅在词的基础上引入了上下文信息,还通过多层结构同时引入了语法和语义信息。2018年底BERT的问世更是使NLP的预训练模型进入了一个新的时代,其与其子孙直至本文写作之日(2020年6月)仍繁荣不衰。由于BERT基于Transformer结构和自注意力机制,本系列文章尚未涉及,因此本文先介绍这之前两种经典的预训练模型ULMFiT和ELMo
ULMFiT(Universal Language Model Fine-tuning)也是由Ruder提出,试图将CV领域里比较成熟的迁移学习技术引入NLP。在这之前,NLP领域已经有一些基于语言模型的预训练工作,但是这些工作需要大量领域相关文档微调,而且语言模型容易在小数据集上过拟合,在对分类问题微调时又容易灾难性遗忘。ULMFiT就是为了解决这样的问题而诞生
ULMFiT使用的是一个有三个隐藏层的双向AWD-LSTM,分三步解决具体问题:
示意图如下图所示
在目标领域上微调语言模型时,原文引入了如下技术
分层微调(discriminative fine-tuning, discr)。动机是网络的不同层捕捉的信息类型不同,因此被微调的程度也应不同,这种方法可以通过对不同层设置不同学习率来实现。设顶层学习率为 η ( L ) \eta^{(L)} η(L),实践表明各底层遵循 η ( l − 1 ) = η ( l ) / 2.6 \eta^{(l-1)} = \eta^{(l)} / 2.6 η(l−1)=η(l)/2.6的设置效果较好
斜三角学习率(slanted triangular learning rates, STLR)。目的是让模型快速收敛到合适区域,然后缓慢微调。学习率调整策略具体为
c u t = ⌊ T ⋅ c u t _ f r a c ⌋ p = { t / c u t i f t < c u t 1 − t − c u t c u t ⋅ ( 1 / c u t _ f r a c − 1 ) o t h e r w i s e η t = η m a x ⋅ 1 + p ⋅ ( r a t i o − 1 ) r a t i o \begin{aligned} cut &= \lfloor T \cdot cut\_frac \rfloor \\ p &= \begin{cases} t/cut & {\rm if\ }t < cut \\ 1 - \frac{t-cut}{cut \cdot (1/cut\_frac - 1)} & {\rm otherwise}\end{cases} \\ \eta_t &= \eta_{max} \cdot \frac{1 + p\cdot (ratio - 1)}{ratio} \end{aligned} cutpηt=⌊T⋅cut_frac⌋={t/cut1−cut⋅(1/cut_frac−1)t−cutif t<cutotherwise=ηmax⋅ratio1+p⋅(ratio−1)
各参数的意义为:
原文采用的配置是 c u t _ f r a c = 0.1 , r a t i o = 32 , η m a x = 0.01 cut\_frac = 0.1,\ ratio=32,\ \eta_{max} = 0.01 cut_frac=0.1, ratio=32, ηmax=0.01
在目标领域上微调分类模型时,除了上述两种技巧,还额外使用了如下方法
原文通过一系列实验,得出如下结论
ELMo这一名字是Embeddings from Language Models的缩写,从名字可以看出ELMo是通过训练语言模型而得到词向量。不过这里所说的语言模型并非传统的、根据上文信息推断下一个词的语言模型,而是双向的语言模型,这样可以更好地捕捉单词的上下文信息。
对于给定的标识符 t k t_k tk,使用 L L L层双向语言模型可以得到 2 L + 1 2L+1 2L+1个向量表示
R k = { x k L M , h → k , j L M , h ← k , j L M ∣ j = 1 , … , L } = { h k , j L M ∣ j = 0 , … , L } \begin{aligned} R_k &= \{\boldsymbol{x}_{k}^{\rm LM}, \overrightarrow{\boldsymbol{h}}_{k,j}^{\rm LM}, \overleftarrow{\boldsymbol{h}}_{k,j}^{\rm LM} | j = 1, \ldots, L \} \\ &= \{\boldsymbol{h}_{k,j}^{\rm LM}|j=0, \ldots, L\} \end{aligned} Rk={xkLM,hk,jLM,hk,jLM∣j=1,…,L}={hk,jLM∣j=0,…,L}
其中 h k , 0 L M \boldsymbol{h}_{k,0}^{\rm LM} hk,0LM是嵌入层, h k , j L M = [ h → k , j L M ; h ← k , j L M ] \boldsymbol{h}_{k,j}^{\rm LM} = \left[\overrightarrow{\boldsymbol{h}}_{k,j}^{\rm LM};\overleftarrow{\boldsymbol{h}}_{k,j}^{\rm LM}\right] hk,jLM=[hk,jLM;hk,jLM]是每个双向LSTM隐藏层隐藏状态拼接后的结果。ELMo会把得到的这些表示组合成一个向量以传递给下游任务,即
E L M o k t a s k = E ( R k ; Θ t a s k ) = γ t a s k ∑ j = 0 L s j t a s k h k , j L M \boldsymbol{ELMo}_k^{\rm task} = E\left(R_k; \Theta^{\rm task}\right) = \gamma^{\rm task}\sum_{j=0}^L s_j^{\rm task}\boldsymbol{h}_{k,j}^{\rm LM} ELMoktask=E(Rk;Θtask)=γtaskj=0∑Lsjtaskhk,jLM
其中 s t a s k \boldsymbol{s}^{\rm task} stask是使用softmax归一化的权重,意义是控制各层向量的贡献比例,在下游任务中训练; γ t a s k \gamma^{\rm task} γtask是一个缩放因子,使得ELMo得到的向量尺度可以与下游任务相吻合。原文建议在每个隐藏层先做一个层归一化操作,然后再训练权重值。此外,加入适量的dropout,以及尝试加入L2正则化对ELMo的效果都有提升作用
得到ELMo的词向量表示以后,下游任务对输入序列的每个标识符 t k t_k tk不再只使用独立于语境的词向量 x k \boldsymbol{x}_k xk,而是将其与ELMo词向量 E L M o k t a s k \boldsymbol{ELMo}_k^{\rm task} ELMoktask拼接。对于某些任务,将隐藏层向量与ELMo词向量拼接也有好处。由于大多数NLP任务所使用的神经网络结构其底层都是相同的,因此ELMo词向量的适用领域非常广泛。此外实验表明,在下游任务上微调ELMo,语言模型的效果会显著提升
具体地,ELMo的体系结构为
网络使用残差连接,正向反向LSTM共享输入(词嵌入矩阵)和输出(softmax)
实验表明,ELMo词向量中低层的部分更多捕获了单词的语法信息,高层部分更多捕获了单词的语义信息
本节来自于Ruder论文的7.2节。原文即对比了上面提到的2018年上半年明星模型ELMo和下半年明星模型、开创NLP预训练模型新纪元的BERT,因此感觉结论更广泛,更有实效性
对于预训练模型,通常有两种使用方法:
原文将ELMo和BERT应用在了若干任务中,包括命名实体识别、情感分析、自然语言推理、同义句识别(paraphrase detection)和语义相似度检测,对比的基线模型使用了Skip-thoughts提取句子向量作为特征。两者效果均显著超越极限模型,对于ELMo,EX效果好于FT,但是对BERT则相反(不过BERT做EX的效果仍然优于ELMo做EX的效果)。对此,原文作了若干分析
(这里没有记录全部结论)
高速公路网络[Srivastava2015]有点像LSTM门机制和残差网络的组合体,简单说就是学习一个线性变换 T ( x , W T ) = σ ( W T T x + b T ) T(\boldsymbol{x}, \boldsymbol{W}_T) = \sigma(\boldsymbol{W}_T^\mathsf{T}\boldsymbol{x} +\boldsymbol{b}_T) T(x,WT)=σ(WTTx+bT),使得输出由两部分组成,一部分是隐藏层变换后的状态,一部分是原始输入。即 y = h ⊙ T ( x , W T ) + x ⊙ ( 1 − T ( x , W T ) ) \boldsymbol{y} = \boldsymbol{h}\odot T(\boldsymbol{x}, \boldsymbol{W}_T) + \boldsymbol{x} \odot (\boldsymbol{1}-T(\boldsymbol{x}, \boldsymbol{W}_T)) y=h⊙T(x,WT)+x⊙(1−T(x,WT)) ↩︎