这篇文章和Andrychowicz在2016年发表的Learning to learn by gradient by gradient很相似,都是利用Meta-Learning来学习出一个优化算法,并且需要注意的是Meta-Learner都是基于LSTM
的循环神经网络,这也就是本论文标题的由来——将优化看成是一个模型(RNN)。
Meta-Learning的通俗解释:
少样本学习(Few-shot Learning)是Meta-Learning在监督学习领域的一个应用。元学习的关键是找到一种系统化的方法去学习在各种任务上有效的通用初始化方案,这种方案能够为基于待考虑数据上的任务提供一个良好的初始训练点,从而实现在新任务上的快速适应至收敛,即Learn-to-Learn。
参考列表:
①李宏毅Meta-Learning视频
②RNN笔记
③论文笔记1
④论文笔记2
⑤论文笔记3
Optimization as a Model for Few-Shot Learning
简介
论文中提出的基于LSTM的元学习者模型(LSTM-based),作为一个优化器的角色,能够捕获任务内的短期知识以及跨任务的长期知识,进而形成跨任务共享的基础知识,最后作用在学习者上,使其能够在每个任务上都可以快速收敛到一个较优解。
文章提出的问题以及解决方案:
对于传统基于梯度下降的优化算法而言,少样本学习是行不通的。
- 像SGD、Adam、RMSProp等一般都是为大样本训练集的任务而设定的。
- 对于分离的不同的tasks,比如不同的分类任务,传统梯度下降法会对于每个任务都设定随机化参数,而我们手上的样本很少,那么在少样本的迭代更新下,模型参数可能会到达一个很糟糕的状态。
因此必须找到一种优化算法去解决Few-shoting Learning问题。
解决方案:也就是本文的核心内容——学习一个LSTM-based Meta-Learning模型作为优化器,用它去学习出一套优化规则应用于不同的新tasks上去。
Note:
- 本文除了学习出一种通用性的学习规则之外,还可以学习出LSTM记忆细胞的初始值,有点类似于MAML。
名词解释和训练过程
名词解释
记meta-set为
D
\mathfrak{D}
D,比如Meta-Learning经典数据集Mini-Imagenet。
D
m
e
t
a
−
t
r
a
i
n
\mathfrak{D}_{meta-train}
Dmeta−train、
D
m
e
t
a
−
v
a
l
i
d
a
t
i
o
n
\mathfrak{D}_{meta-validation}
Dmeta−validation、
D
m
e
t
a
−
t
e
s
t
\mathfrak{D}_{meta-test}
Dmeta−test分别是用于训练、验证、测试(微调)的数据集,且都是
D
\mathfrak{D}
D的超集。
D
t
r
a
i
n
\mathcal{D}_{train}
Dtrain、
D
t
e
s
t
\mathcal{D}_{test}
Dtest是上述三种集合的超集,一般都分别称之为
s
u
p
p
p
r
t
−
s
e
t
suppprt-set
suppprt−set和
q
u
e
r
y
−
s
e
t
query-set
query−set。用一个完整的图来表示就是:
D
{
D
m
e
t
a
−
t
r
a
i
n
{
D
t
r
a
i
n
D
t
e
s
t
D
m
e
t
a
−
v
a
l
i
d
a
t
i
o
n
{
D
t
r
a
i
n
D
t
e
s
t
D
m
e
t
a
−
t
e
s
t
{
D
t
r
a
i
n
D
t
e
s
t
\mathfrak{D} \begin{cases} \mathfrak{D}_{meta-train}\begin{cases}\mathcal{D}_{train}\\\mathcal{D}_{test}\end{cases}\\ \mathfrak{D}_{meta-validation}\begin{cases}\mathcal{D}_{train}\\\mathcal{D}_{test}\end{cases}\\ \mathfrak{D}_{meta-test}\begin{cases}\mathcal{D}_{train}\\\mathcal{D}_{test}\end{cases} \end{cases}
D⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧Dmeta−train{DtrainDtestDmeta−validation{DtrainDtestDmeta−test{DtrainDtestNote:
-
D
m
e
t
a
−
t
r
a
i
n
\mathfrak{D}_{meta-train}
Dmeta−train用于训练,比如MAML这篇文章中的:
就是使用了 D m e t a − t r a i n \mathfrak{D}_{meta-train} Dmeta−train,其中2个更新过程分别使用了 D t r a i n \mathcal{D}_{train} Dtrain和 D t e s t \mathcal{D}_{test} Dtest。 - D m e t a − t e s t \mathfrak{D}_{meta-test} Dmeta−test用于微调,一般用于检测训练结果,集合里都是新的tasks。
- D m e t a − v a l i d a t i o n \mathfrak{D}_{meta-validation} Dmeta−validation用于调整选择一些超参数。
- k − s h o t , N − c l a s s k-shot,N-class k−shot,N−class指的是 D t r a i n \mathcal{D}_{train} Dtrain中包含 k ⋅ N k\cdot N k⋅N个样本即 N N N个类别,每个类别有 k k k张。常用于分类问题,比如 k ⋅ N k\cdot N k⋅N张图片。
- 因为小样本问题导致样本集很欠缺,所以一般我们都选择
k
=
1
k=1
k=1或者
k
=
5
k=5
k=5。下图是一个经典的
1
−
s
h
o
t
,
5
−
c
l
a
s
s
1-shot,5-class
1−shot,5−class栗子:
可以看出每一个task是如何组成的,另外 s u p p o r t − s e t support-set support−set和 q u e r y − s e t query-set query−set指的都是每一个task内部的集合。
训练过程
在Few-shot Learning中,一个task就是由
k
−
s
h
o
t
,
N
−
c
l
a
s
s
k-shot,N-class
k−shot,N−class以及query-set组成的。在Meta-Learning中,一个task称之为一个样本,而监督学习里面一个样本往往指一张图片。标准的Meta-Learning训练过程:在多个Meta-Training tasks(
D
m
e
t
a
−
t
r
a
i
n
\mathfrak{D}_{meta-train}
Dmeta−train)上进行训练,然后学到我们需要的更新规则和初始化。面对一个新的Few-shot task(
D
m
e
t
a
−
t
e
s
t
\mathfrak{D}_{meta-test}
Dmeta−test)时,我们在这个任务的support-set上面使用我们的更新规则对这个初始化参数进行优化更新(微调),在query-set上面进行性能评估。LSTM-Based Meta-Learning的训练示意图如下:
Note:
- Learner会接受来自query-set的batch个tasks的输入,然后输出的( ∇ L \nabla\mathcal{L} ∇L, L \mathcal{L} L)给Meta-Learner做更新,然后Meta-Learner会输出 θ \theta θ来对Learner做更新。
- Support-set上只更新Learner的参数,不更新Meta-Learner参数。 Query上则相反。我们可以理解Support-set上我们用当前的更新规则去试验一下效果好不好,然后在Query-set上我们在来更新修改这个更新规则。
- Meta-Learner由一个LSTM组成,其参数的学习来自于Learner在Query-set上的表现,如下图所示:
核心内容
这篇文章的核心:
- 通过LSTM-based Meta-Learning学习一个通用化的用于学习Learner参数的梯度规则。
- 以及LSTM初始参数 c 0 c_0 c0的学习。
在一个Learner上标准的梯度更新为:
θ
t
=
θ
t
−
1
−
α
t
⋅
∇
θ
t
−
1
L
t
(1)
\theta_t=\theta_{t-1}-\alpha_t\cdot\nabla_{\theta_{t-1}}\mathcal{L}_t\tag{1}
θt=θt−1−αt⋅∇θt−1Lt(1)而LSTM的记忆细胞输出公式为:
c
t
=
f
t
⊙
c
t
−
1
+
i
t
⊙
c
t
~
(2)
c_t=f_t\odot c_{t-1}+i_t\odot \tilde{c_t}\tag{2}
ct=ft⊙ct−1+it⊙ct~(2)因此,当
f
t
=
1
,
c
t
−
1
=
θ
t
−
1
,
i
t
=
α
t
,
c
t
~
=
−
∇
θ
t
−
1
L
t
f_t=1,c_{t-1}=\theta_{t-1},i_t=\alpha_t,\tilde{c_t}=-\nabla_{\theta_{t-1}}\mathcal{L}_t
ft=1,ct−1=θt−1,it=αt,ct~=−∇θt−1Lt的时候,则梯度更新规则就可以用LSTM的记忆细胞来表示了,即
c
t
=
θ
t
c_t=\theta_t
ct=θt。
这里需要注意的是学习率
α
t
\alpha_t
αt(输入门)和遗忘门的值,你大可把他们两当做常数看待,但是最佳的选择是通过学习的方式动态调整这两个值,如下图所示:
怎么去学习呢,就是把
i
t
、
f
t
i_t、f_t
it、ft参数化表示:
i
t
=
σ
(
W
I
⋅
[
∇
θ
t
−
1
L
t
,
L
t
,
θ
t
−
1
,
i
t
−
1
]
+
b
I
)
f
t
=
σ
(
W
F
⋅
[
∇
θ
t
−
1
L
t
,
L
t
,
θ
t
−
1
,
f
t
−
1
]
+
b
F
)
i_t=\sigma(W_I\cdot[\nabla_{\theta_{t-1}}\mathcal{L}_t,\mathcal{L}_t,\theta_{t-1},i_{t-1}]+b_I)\\ f_t=\sigma(W_F\cdot[\nabla_{\theta_{t-1}}\mathcal{L}_t,\mathcal{L}_t,\theta_{t-1},f_{t-1}]+b_F)
it=σ(WI⋅[∇θt−1Lt,Lt,θt−1,it−1]+bI)ft=σ(WF⋅[∇θt−1Lt,Lt,θt−1,ft−1]+bF)Note:
- 表达的意思就是学习率或者 f t f_t ft都是 ∇ θ t − 1 L t , L t , θ t − 1 , i t − 1 , f t − 1 \nabla_{\theta_{t-1}}\mathcal{L}_t,\mathcal{L}_t,\theta_{t-1},i_{t-1},f_{t-1} ∇θt−1Lt,Lt,θt−1,it−1,ft−1的函数,由于其值是动态变化的,因此Meta-Learner可以进行调节。
- 对于 f t f_t ft,一般来说都是 f t = 1 f_t=1 ft=1,但是能如果参数陷入局部最优,那么我们可能会想要去忘掉之前的内容,这就需要遗忘门 f t f_t ft去调节值,而不是只能等于1.
LSTM内部的初始值,比如记忆细胞
c
0
c_0
c0,是可以通过训练得到的,因此在LSTM-based的架构下:把
θ
0
=
c
0
\theta_0=c_0
θ0=c0当作是参数,也可以被学出来。这种通过Meta-Learning学习初始化参数的方法有点类似于MAML。但和MAML明显不同的是,MAML是显式的去学习这个初始化参数,而LSTM-based是基于LSTM可学习细胞初始值的特性而学习的。可以想象,一个好的初始化值对于之后优化的速度是大有裨益的。
参数共享和预处理
这一节其实在更早的时候由Andrychowicz发表的Learning to learn by gradient descent by gradient descent中有了介绍说明。
参数共享
一般我们的 θ \theta θ维度都是很大的,那么如果给每个维度的参数 θ i \theta_i θi都配一个LSTM去学习的话,那么LSTM的参数量可是非常巨大了。因此作者提出不管参数有多少维度,都只使用一个LSTM,即共享LSTM,由于每个维度对应的 ( ∇ θ i L , L ) (\nabla_{\theta_i}\mathcal{L},\mathcal{L}) (∇θiL,L)都是不一样的,那么即便是同一个LSTM,那么输出的结果也是不一样的,那么问题就不大。这样做的另一个好处是,这样的LSTM学出来的更新规则使得每个维度的参数当共享一套更新规则,回想SGD、Adam、RMSProp的每个参数也都是共享一套更新规则的。
预处理
由于共享LSTM,而每个维度的大小可能大不一样,因此需要做个预处理,将他们的大小进行类似标准化的处理:
x
→
{
(
log
(
∣
x
∣
)
p
,
s
g
n
(
x
)
)
i
f
∣
x
∣
≥
e
−
p
(
−
1
,
e
p
x
)
o
t
h
e
r
w
i
s
e
x\to\begin{cases} (\frac{\log(|x|)}{p},sgn(x))\quad if\,|x|\ge e^{-p}\\ (-1,e^px)\quad \mathbf{otherwise} \end{cases}
x→{(plog(∣x∣),sgn(x))if∣x∣≥e−p(−1,epx)otherwise意思就是,对参数的每个维度的值
x
x
x进行判定,从而获取
(
∇
θ
i
L
,
L
)
(\nabla_{\theta_i}\mathcal{L},\mathcal{L})
(∇θiL,L)的值。
梯度独立性假设
实际我们在做的时候是这样的:
如上图所示,因为
∇
θ
L
\nabla_\theta\mathcal{L}
∇θL和
θ
\theta
θ一定是有依赖的,所以你在做backward的时候,除了主线做梯度回传以外,红框虚线处
也会有梯度回传。但实际上LSTM的记忆细胞和输入是没有关系的,因此这里作者也做了个假设:假设红色虚线这里的依赖关系是不存在的,不去管他少改一点代码量,这样假设也符合LSTM的特征。
做梯度独立性假设,即删掉虚线之后:
模型初始化
作者给了LSTM的初始化的一个小技巧,为了使初始LSTM的输出更像标准的梯度下降,即较小的学习率以及遗忘门 f t ≈ 1 f_t\approx1 ft≈1,可以将遗忘门的bias设置较大,使得输出溢出,这样就能保证 f t = 1 f_t=1 ft=1,此外将输入门的bias设置小一点,那么输出的学习率就不会太大。
实验
对比实验
从对比实验的结果来看,LSTM-Based优化算法
超过
了一些基线算法,并且和当时已经在Few-shot Learning取得最佳效果的Matching Network FCE几乎持平
。
可视化
上图可视化了遗忘门和输入门网络中4层卷积层以及末尾全连接层输出的情况:
- 遗忘门的情况可以理解,几乎输出维持在常数1,意味着Meta-Learner学到的值就是1。而输入门的情况不太好去解释。
- 不同的曲线代表着不同的tasks上的随机选取的参数值,因此我们可以知道Meta-Learner学到的不只是一种固定的参数,而是针对不同task而不同的策略。也就是说,不同的task,Meta-Learner学到的东西都是不同的,这对于Meta-Learner的意义在于元学者本身具有的通用性。
总结与展望
-
伪代码如下:
①显然上述代码是预训练的伪代码,并不包括在 D m e t a − t e s t \mathfrak{D}_{meta-test} Dmeta−test上进行微调的过程,但大致也差不多。②Meta-Learner的初始参数是随机初始化的,而Learner的初始化参数是可以学习的,因为 c 0 c_0 c0可以当作LSTM的内部的参数来学习。③Meta-Learner的训练是通过Adam优化算法来实现的。
-
本文的意义在于:在Few-shot Learning领域,找到了一种LSTM-based的Meta-Learning方法,它可以在少量样本下学到一种通用性的更新规则去update学习者的参数;除此之外,它也可以给于Learner一个较好的初始化参数 θ 0 \theta_0 θ0,从而有一个较快的收敛速度。
-
上图是李宏毅教授在视频中提出的一个理想结构,可以看出来这个结构是Learning to Learn by gradient by gradient这篇论文以及本论文的合体。在前者那篇论文中,是没有红色框的,它只是将绿色框的输出和 θ \theta θ做简单相加来实现梯度下降规则。而在本论文中,是只有红色框而没有蓝色框的