目录
元学习介绍
元学习的主旨是让机器学会学习(learn to learn),对于一个机器学习模型,我们希望利用这个模型在不同的任务上学习,让模型能够具有更高效的学习基础,从而在面对后续任务时,获得更优秀的学习效果。
一般来说,元学习中的机器学习模型,可以从语音,图像到文字等任务,该模型不会局限于单一的任务,元学习的目标只是让模型具备更好的学习基础。简单可以理解为,不同任务的模型架构一致,但其参数在不同任务上学习后最终也是各自不同的。
Meta Learning 不同于 Life-Long Learning ,Life-Long Learning 中使用同一个模型,该模型可学习到处理各种任务的知识。对于Meta Learning,不同任务对应不同的参数,但机器会在学习过程中积累学习技巧,以便于后续任务的学习。
提到元学习,需要认识到其一个分支问题 Few-shot Learning,Few-shot Learning 即为:少样本学习。面对少样本的任务,我们依然希望模型可以做出分类,一种解决办法是对少量的样本集进行数据增强,扩充样本,以图像分类任务为例,我们可以用对抗生成网络去生成样本,也可以用基本的数字图像操作扩充样本;另一种解决方法即使用元学习去处理。
再次回忆上面描述的内容,元学习需要让机器学会学习,而目前常见的元学习方法分为两个分支:
- 基于相似度对比的方法:对于一个新任务,我们需要对模型的计算结果进行相似度判断,从而实现在新任务上的分辨,我们可以看出:该过程的目标不在于泛化到某个测试集,而是让机器具备更通用的先验知识,能够分辨事物的异同。这类方法更常用于 Few-shot Learning 问题;
- 获得一个优秀的初始参数:我们在不同任务上进行学习,获得一个适当的参数,以这个参数作为模型的初始参数,于是在面对新任务时,该参数能更容易更新到新任务下的局部最优解。这条分支分在处理下游任务时,通常分为有微调和不微调。
比如现在的NLP范式:大规模数据上预训练(即meta learning)+下游任务的微调(基于fine-tuning的判别式学习)或者直接应用。
基于相似度对比的方法即为度量学习(Metric Learning);
元学习还有一个不太明显的分支,事实上,这个分支其实已经被广泛使用:学习到具有良好泛化性的特征表达,以便于后续任务的迁移学习。比如过去的静态词向量Glove,Word2vec就是具有良好泛化性的特征表达(embedding);
总之,元学习是一种思想,只要可以泛化到多任务的策略或者模型都可以称为元学习。
相似度对比的应用:Few-shot Learning
问题概述
现在讨论 Few-shot Learning 问题,少样本学习问题不只有训练集,少样本学习中还有 support set,和 query 输入。以动物图像分类为例,假设有以下训练集:
现在输入一张非训练集内类别的图像作为 query,要根据 support set 中的图像(support set 中的样本极少,故称为少样本学习),利用模型进行分类,输入需要的信息如下:
少样本学习是元学习的一个应用,元学习的主旨是学会学习,即可以利用模型分辨事物的异同,而不是像我们所熟悉的有监督学习中那样关注具体的分类。
有监督学习具有两个特点:
- 测试集里的样本是模型从来没有见过的;
- 测试集里的样本是归属于训练集中某个类别的。
对于少样本学习,则有:
- query 样本是模型从未见过的;
- query 样本是属于完全陌生的一个类别,但该类别在 support set 中可以索引到;
关于 support set,包含两个元素:
k
k
k-way:support set 内样本的类别数;
n
n
n-shot:每个类别有
n
n
n个样本。
比如这是一个 4-way 2-shot 的 support set。
回到如何处理少样本学习问题,最常见的想法就是学习一个相似度函数
s
i
m
(
q
u
e
r
y
,
s
u
p
p
o
r
t
s
e
t
i
)
sim(query,supportset_{i})
sim(query,supportseti),计算出 query 与 support set 内第
i
i
i 类样本的相似度,通过取最相似的一类作为结果。比如以下情况,模型将 query 分类到结果"Otter":
上述过程描述如下:
- 首先,我们在训练集上学习相似度函数(比如神经网络模型),注意该函数不注重于具体的分类,而是注重于两个样本之间的相似度计算,即学会分辨事物异同;
- 然后将相似度函数用于 support set 和 query,通过索引最大相似度的类别得到分类结果。
此处补充两个关于少样本学习常用的数据集:Omniglot 和 Mini-ImageNet;
Omniglot是一个多类少样本的数据集,分为50个大类的字母,每个字母又分为很多类字符,每个字符由20个不同的人手写保存,手写保存的数据均为一张105×105的图片。Mini-ImageNet 则包含100类对象,每类有600张图像。
孪生网络SiameseNetwork
孪生网络是一种学习方法,孪生网络可以迫使神经网络学会分辨事物的异同,孪生网络有两种实现方法,一种是学习成对相似度(Learning Pairwise Similarity Scores),另一种是利用三元组损失函数(Triplet Loss)学习。
Learning Pairwise Similarity Scores
下面介绍第一种实现方法 “Learning Pairwise Similarity Scores”;现有以下数据集作为原始训练集:
下面要重新构造数据集进行训练,构造正样本组合和负样本组合。我们从训练集的同一类中随机取两个样本作为一个正样本组合,标记为1,表示这两个样本是很相似的;反之,我们从训练集的两个不同类中随机各取一个样本作为负样本组合,标记为0,表示这两个样本是很不相似的;
构造数据如下:
我们定义一个卷积神经网络模型CNN(记作函数
f
f
f)用于提取特征,用
x
x
x表示输入样本,则输出特征信息展开至向量(Flatten操作)表示为
f
(
x
)
f(x)
f(x):
训练框架为:
比如取一个样本组合,由于该组合都是Tiger类,故标记为1,通过卷积网络提取特征得到
h
1
,
h
2
h_{1},h_{2}
h1,h2,然后计算两者的相似度:
z
=
∣
h
1
−
h
2
∣
z=|h_{1}-h_{2}|
z=∣h1−h2∣
s
i
m
(
x
1
,
x
2
)
=
s
i
g
m
o
i
d
(
N
N
(
z
)
)
sim(x_{1},x_{2})=sigmoid(NN(z))
sim(x1,x2)=sigmoid(NN(z))得到的结果
s
i
m
(
x
1
,
x
2
)
sim(x_{1},x_{2})
sim(x1,x2)为输入数据
x
1
,
x
2
x_{1},x_{2}
x1,x2之间的相似度,值在0到1之间;我们使用二元交叉熵损失函数(BCELoss)计算该相似度与标签之间的损失;
利用损失函数进行反向传播计算卷积网络模型 f f f中各个参数的梯度,并更新模型参数。
训练结束后,我们就能得到一个具备分辨事物异同能力的卷积网络,于是我们将该CNN用于 support set 中每一类样本和 query 比较,通过索引最大相似度的类别得到分类结果。
Triplet Loss
另一种孪生网络的实现方法基于三元组损失(Triplet Loss),三元组损失函数依赖三个样本:anchor,positive,negative:
如上图所示,我们随机从数据集中选择某一类,取该类的一个样本作为anchor(标记为
x
a
x^{a}
xa),在该类下再取一个样本作为positive(标记为
x
+
x^{+}
x+),最后随机取一个其他类,并取该其他类下的一个样本作为negative(标记为
x
−
x^{-}
x−)。
现在同样使用卷积网络
f
f
f提取特征信息,使用同一个卷积网络分别对三个样本前向计算:
分别计算特征之间的距离:
d
+
=
∣
∣
f
(
x
+
)
−
f
(
x
a
)
∣
∣
2
2
d^{+}=||f(x^{+})-f(x^{a})||^{2}_{2}
d+=∣∣f(x+)−f(xa)∣∣22
d
−
=
∣
∣
f
(
x
−
)
−
f
(
x
a
)
∣
∣
2
2
d^{-}=||f(x^{-})-f(x^{a})||^{2}_{2}
d−=∣∣f(x−)−f(xa)∣∣22简单地考虑一个二维特征空间,我们可以发现特征间的距离有以下关系:
很明显,我们希望
d
+
d^{+}
d+更小,而
d
−
d^{-}
d−更大,如果设置一个边界值
α
>
0
\alpha>0
α>0,当存在
d
−
≥
d
+
+
α
d^{-}\geq d^{+}+\alpha
d−≥d++α时,可以设置损失为0,否则损失为
d
+
+
α
−
d
−
d^{+}+\alpha-d^{-}
d++α−d−,因此,三元组损失为:
l
o
s
s
(
x
a
,
x
+
,
x
−
)
=
m
a
x
(
0
,
d
+
+
α
−
d
−
)
loss(x^{a},x^{+},x^{-})=max(0,d^{+}+\alpha-d^{-})
loss(xa,x+,x−)=max(0,d++α−d−)因此,我们根据最小化损失去更新卷积网络
f
f
f即可得到一个能够分辨事物异同的模型。
预训练与微调
这是一个效果较好的方法,并且操作简单,我们利用模型在大规模数据集上训练,再放置到小数据集上微调;下面先回顾一些数学基础。
余弦相似度是衡量向量相似程度的方法,假设有两个单位向量
x
x
x和
w
w
w,我们可以将其内积作为相似度:
c
o
s
θ
=
x
T
w
cos\theta=x^{T}w
cosθ=xTw内积的物理意义如下,结果越大,说明两个向量越相似:
如果两个向量不是单位向量,我们可以进行归一化再内积:
c
o
s
θ
=
x
T
w
∣
∣
x
∣
∣
2
∣
∣
w
∣
∣
2
cos\theta=\frac{x^{T}w}{||x||_{2}||w||_{2}}
cosθ=∣∣x∣∣2∣∣w∣∣2xTw下面继续了解softmax函数,用于将向量映射成为概率分布,假设输入向量为:
ϕ
=
[
ϕ
1
,
ϕ
2
,
ϕ
3
,
.
.
.
,
ϕ
k
]
∈
R
k
\phi=[\phi_{1},\phi_{2},\phi_{3},...,\phi_{k}]\in R^{k}
ϕ=[ϕ1,ϕ2,ϕ3,...,ϕk]∈Rk
然后我们对每个元素进行指数变换,再进行归一化即可得到softmax输出的概率分布 p p p: p = n o r m a l i z e ( [ e ϕ 1 , e ϕ 2 , e ϕ 3 , . . . , e ϕ k ] ) ∈ R k p=normalize([e^{\phi_{1}},e^{\phi_{2}},e^{\phi_{3}},...,e^{\phi_{k}}])\in R^{k} p=normalize([eϕ1,eϕ2,eϕ3,...,eϕk])∈Rksoftmax函数常用于模型输出作为分类器。
softmax可以将得分高的元素概率值变大,得分低的元素概率值变小,但不同于max函数生硬地将得分低的元素直接映射成0,故有soft的意义,softmax函数的变换对比如下所示:
现在回到 Few-shot Learning 问题,通常我们在大规模数据集上预训练一个CNN模型,这个预训练过程可以是传统的有监督学习,也可以使用孪生网络方法;
当得到训练后的模型,我们就可以将其迁移到少样本数据上,下面先介绍不进行微调的计算过程。
对于一个 3-way 2-shot 的少样本数据,可以使用预训练后的CNN模型
f
f
f进行如下计算:
注意要对 query 也进行同样的操作:
上面的normalize和softmax中的一样,可以将向量的模压缩成1;同时,我们根据support set的结果构造矩阵
M
M
M:
M
=
[
μ
1
,
μ
2
,
μ
3
]
T
M=[\mu_{1},\mu_{2},\mu_{3}]^{T}
M=[μ1,μ2,μ3]T然后便可以进行预测:
p
=
s
o
f
t
m
a
x
(
M
q
)
=
s
o
f
t
m
a
x
(
[
μ
1
T
q
,
μ
2
T
q
,
μ
3
T
q
]
T
)
p=softmax(Mq)=softmax([\mu_{1}^{T}q,\mu_{2}^{T}q,\mu_{3}^{T}q]^{T})
p=softmax(Mq)=softmax([μ1Tq,μ2Tq,μ3Tq]T)根据
p
p
p最大的元素索引类别即为分类结果。
下面介绍进行微调(Fine-Tuning)的处理方法。实验表明,如果在预训练的基础上使用微调,往往可以带来更好的效果。
假设 ( x j , y j ) (x_{j},y_{j}) (xj,yj)是support set中的一个样本, x x x为数据, y y y为标签; f ( x j ) f(x_{j}) f(xj)是经过CNN计算得到的特征信息,我们在分类器上预测为: p j = s o f t m a x ( W f ( x j ) + b ) p_{j}=softmax(Wf(x_{j})+b) pj=softmax(Wf(xj)+b)如果我们令 W = M , b = 0 W=M,b=0 W=M,b=0,这就是上面提到的没有微调的方法。
如果现在我们进行微调,即在这个基础上根据support set再次训练: m i n ∑ j C r o s s E n t r o p y ( y j , p j ) min\sum_{j}CrossEntropy(y_{j},p_{j}) minj∑CrossEntropy(yj,pj)其中, j j j代表support set的第 j j j个样本,根据该目标更新输出层的参数 ( W , b ) (W,b) (W,b),也可以考虑更新前面的CNN模型参数,这就是微调。
参数初始方法
现在介绍元学习分支的第二种:参数初始化。我们在不同任务上进行学习,获得一个适当的参数,以这个参数作为模型的初始参数,于是在面对新任务时,该参数能更容易更新到新任务下的局部最优解。关于具体的参数初始化策略,又可以分为MAML和Reptile。
MAML源自论文"Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks",指的是一种适用于各种模型的元学习方法;
继MAML之后,论文"On First-Order Meta-Learning Algorithms"提出方法Reptile。
MAML
MAML可以帮助模型从不同的任务中学习到一个良好的参数作为模型的初始化参数。在过去的机器学习模型训练中,我们会借助某个分布随机初始化参数,MAML使得我们可以基于各类任务的训练,让模型具有一个良好的初始化参数。
回顾传统的模型训练框架:
随机初始化参数
ϕ
\phi
ϕ经过多次epoch更新后得到参数
θ
^
\widehat{\theta}
θ
,现在我们让初始模型(参数为
ϕ
\phi
ϕ)分别在不同的任务上学习,对于第
n
n
n个任务,我们将更新后的参数记为
θ
^
n
\widehat{\theta}^{n}
θ
n,并计算模型(参数为
θ
^
n
\widehat{\theta}^{n}
θ
n)在对应数据上的损失
l
n
(
θ
^
n
)
l^{n}(\widehat{\theta}^{n})
ln(θ
n)。
对于所有任务,我们可以得到综合的损失: L ( ϕ ) = ∑ n = 1 N l n ( θ ^ n ) L(\phi)=\sum_{n=1}^{N}l^{n}(\widehat{\theta}^{n}) L(ϕ)=n=1∑Nln(θ n)因此,可以得到MAML的初始化参数更新方法: ϕ = ϕ − l r ▽ ϕ L ( ϕ ) \phi=\phi-lr\triangledown_{\phi}L(\phi) ϕ=ϕ−lr▽ϕL(ϕ)其中, l r lr lr为学习率。
考虑实际的训练时间要求,通常我们仅让模型在各个任务上仅训练1个epoch,所以对于第 i i i个任务有: θ ^ i = ϕ − ε ▽ ϕ l i ( ϕ ) \widehat{\theta}^{i}=\phi-\varepsilon\triangledown_{\phi}l^{i}(\phi) θ i=ϕ−ε▽ϕli(ϕ)其中, ε \varepsilon ε为某个任务下的学习率。可见, θ ^ i \widehat{\theta}^{i} θ i与 ϕ \phi ϕ相关,因此,我们确实可以计算 L ( ϕ ) L(\phi) L(ϕ)关于 ϕ \phi ϕ的梯度,从而更新 ϕ \phi ϕ。
现在思考MAML与预训练(pre-training)的区别,预训练关注的是模型在当前任务上的表现,而MAML关注的是找到一个参数,让它更容易在各种任务下都能快速学习到良好的表现,注意"快速"二字,实现"快速"其实来自于前面提到的策略:我们仅让模型在各个任务上仅训练1个epoch后就结束当前任务。
用 “损失-模型参数” 的关系可视化有:
左图代表pre-training方法,右图代表MAML方法。
对于pre-training,模型先在任务1上训练,得到局部最优解 ϕ \phi ϕ,然后迁移到任务2上,参数收敛到 θ ^ 2 \widehat{\theta}^{2} θ 2,很明显,这不是一个好的局部最优解,因为对应的损失还是较大。
但如果我们采用MAML,同时考虑了任务1和任务2,得到一个参数 ϕ \phi ϕ,虽然该参数此时不能让任务1和任务2都处在较低的损失值上,但通过训练,该参数总是能很容易地收敛到各个任务对应的局部最优解上,且这个解不会太差。因此,就实现了learn to learn。
Reptile
除了MAML,2018年提出的Reptile也是一种获取优质初始参数
ϕ
\phi
ϕ的方法。Reptile可以用下图进行说明:
首先,我们随机初始化参数
ϕ
0
\phi^{0}
ϕ0,取任务
m
m
m进行训练,上图假设每个任务迭代4个epoch,得到参数
θ
^
m
\widehat{\theta}^{m}
θ
m,然后更新参数:
ϕ
1
=
ϕ
0
+
ϵ
(
θ
^
m
−
ϕ
0
)
\phi^{1}=\phi^{0}+\epsilon(\widehat{\theta}^{m}-\phi^{0})
ϕ1=ϕ0+ϵ(θ
m−ϕ0)其中,
ϵ
\epsilon
ϵ为更新参数的学习率。然后,在
ϕ
1
\phi^{1}
ϕ1的基础上,取任务n进行训练,得到参数
θ
^
n
\widehat{\theta}^{n}
θ
n,同样的操作更新参数:
ϕ
2
=
ϕ
1
+
ϵ
(
θ
^
n
−
ϕ
1
)
\phi^{2}=\phi^{1}+\epsilon(\widehat{\theta}^{n}-\phi^{1})
ϕ2=ϕ1+ϵ(θ
n−ϕ1)很明显,Reptile并不是预训练,如果我们设置
ϵ
=
1
\epsilon=1
ϵ=1时,Reptile就退化成为pre-training。
小结:Reptile和MAML都是用于获取初始参数的方法,获取一个良好的初始参数可以帮助机器学会学习,为后续任务的训练带来更优表现。
meta learning与few-shot learning的关系
首先,few-shot learning的背景是:基于少量样本训练一个模型。通常,在使用常规训练策略的情况下,少量样本会导致模型过拟合,所以要探索其他学习策略。few-shot learning的目标任务是单任务。
meta learning面对的任务是多任务,meta learning需要学到多个任务中最好的模型参数,本质是让模型能更快速适应新任务:在multi-task下学习tasks’ meta knowledge。
至此可发现,meta learning与few-shot learning具有一个共同点:需要在某个任务上快速适应(fast adapt),快速适应指的是在少量样本下就适应到该任务。因此,few-shot learning可以使用meta learning来处理。
对于few-shot learning,为了克服只有少量样本的缺陷,可以利用meta learning的多任务假设,如果假设有多个任务并且多个任务是相似的,则可以弥补少量样本的单任务学习(虽然没有目标任务上的大量训练样本,但可以使用大量相似任务(每个任务都是少量样本)作为补偿),比如:我们在这些多任务上进行基于度量的学习,从而强化模型对目标任务(少样本单任务)的感知能力。