小样本论文笔记1:Metric Based - [2] Matching Networks for One Shot Learning
0. 前言
- 相关资料:
- 论文基本信息:
- 领域:小样本学习
- 作者单位:DeepMind
- 发表期刊和时间:NIPS2016
- 评价:获得Andrej Karpath点赞过,成为之后相关研究中经常被对比的参照。
- 以下笔记基本翻译了一下Andrej Karpathy的笔记内容。
1. 解决什么问题?中心思想?
- 解决啥问题
- 这是一篇关于小样本学习(one-shot learning)的文章,我们可以通过非常少的训练样本来学习一个类别。比如小孩子认识一个长颈鹿,只需要一张照片,而不用成千上百张。(按我的理解,小样本学习其实学习的是分类的能力,仅根据几张图片(A集合)就能够将测试图片b准确归类到A集合中的其中一种类别中)或者说是主要在于解决:基于小样本去学习归类(或者别的任务),并且这个训练好的模型不需要经过调整,也可以用在对训练过程中未出现过的类别进行归类。
- 中心思想
- 训练一个端到端的类似于nearest neighbor的分类器。
2. 用了什么方法?
2.1 预备知识
- 什么是LSTM,参考如何简单的理解LSTM——其实没有那么复杂. 随着距离的增加,RNN无法有效的利用历史信息。LSTM作为一种特殊的RNN,能够学习长的依赖关系。 LSTM是为了避免长依赖问题而精心设计的。记住较长的历史信息实际上是他们的默认行为,而不是他们努力学习的东西。LSTM有选择性的忘记或新增一些信息。
- Attention机制是什么,参考
2.2 模型结构
- 对支撑集(下图中左侧四张狗子)用双向 LSTM 网络
g
θ
g_{\theta}
gθ 编码,对测试图片
x
^
\hat x
x^(下图中右下角一个狗子)用已经迭代了k步的
f
θ
f_{\theta}
fθ 编码成向量,然后用
y ^ = ∑ i = 1 k a ( x ^ , x i ) y i \hat{y}=\sum_{i=1}^{k} a\left(\hat{x}, x_{i}\right) y_{i} y^=i=1∑ka(x^,xi)yi
计算测试样本 x ^ \hat x x^ 的标签 y ^ \hat y y^. 这与最近邻计算很像。原文并没提及,但猜测 y i y_i yi应该是一个one-hot向量。 这里的a类似attention模型中的核函数,用来度量 x ^ \hat x x^ 和训练样本 x i x_i xi 的匹配度,之后通过 y i y_i yi 对于测试样本 label 的计算就类似于加权求和:
a ( x ^ , x i ) = e c ( f ( x ^ ) , g ( x i ) ) / ∑ j = 1 k e c ( f ( x ^ ) , g ( x j ) ) a\left(\hat{x}, x_{i}\right)=e^{c\left(f(\hat{x}), g\left(x_{i}\right)\right)} / \sum_{j=1}^{k} e^{c\left(f(\hat{x}), g\left(x_{j}\right)\right)} a(x^,xi)=ec(f(x^),g(xi))/j=1∑kec(f(x^),g(xj))
在这里,公式f定义了如何对测试样本编码成向量,公式 g g g 定义了如何对训练样本编码。从 c ( ) c() c() 是 c o s cos cos 距离用来计算两者之间的匹配度,之后将他们做了一个 softmax 归一化。Andrej Karpethy猜测余弦距离是通过先正则化两个输入向量得到L2范数,然后用点积操作实现的。Andrej 猜测作者曾尝试跳过正则化操作但好像效果不好放弃了。
2.3 对训练集编码( g θ g_{\theta} gθ)
- g的结构是一个双向LSTM,这个双向LSTM的输入序列是S中的各个样本
(
x
0
,
x
1
,
x
2
.
.
.
)
(x_0, x_1, x_2...)
(x0,x1,x2...),
g
′
(
x
i
)
g'(x_i)
g′(xi)是一个神经网络(如VGG、Inception model)。定义基于支撑集S,对样本
x
i
x_i
xi 的编码为:
g ( x i , S ) = h i → + h i ‾ + g ′ ( x i ) g\left(x_{i}, S\right)=\overrightarrow{h_{i}}+\overline{h_{i}}+g^{\prime}\left(x_{i}\right) g(xi,S)=hi+hi+g′(xi)
这里:
h ⃗ i , c ⃗ i = LSTM ( g ′ ( x i ) , h ⃗ i − 1 , c ⃗ i − 1 ) h ← i , c ˉ i = LSTM ( g ′ ( x i ) , h ← i + 1 , c ˉ i + 1 ) \begin{array}{l} \vec{h}_{i}, \vec{c}_{i}=\operatorname{LSTM}\left(g^{\prime}\left(x_{i}\right), \vec{h}_{i-1}, \vec{c}_{i-1}\right) \\ \overleftarrow{h}_{i}, \bar{c}_{i}=\operatorname{LSTM}\left(g^{\prime}\left(x_{i}\right), \stackrel{\leftarrow}{h}_{i+1}, \bar{c}_{i+1}\right) \end{array} hi,ci=LSTM(g′(xi),hi−1,ci−1)hi,cˉi=LSTM(g′(xi),h←i+1,cˉi+1)
h i {h}_{i} hi 和 c i c_i ci 都为LSTM的输出. 作者在本篇文章中未提及如何将无序的参考集样本排序,可以参考作者另一篇文章Order Matters: Sequence to Sequence for Sets.,这里将原本无序的支撑集样本进行了排序。 - 关于为啥要用LSTM,这个知乎作者给出了个人理解: 将各个类别的样本作为序列输入到LSTM中,是为了模型纵观所有的样本去自动选择合适的特征去度量,例如如果我们的目标是识别人脸,那么就需要构建一个距离函数去强化合适的特征(如发色,脸型等);而如果我们的目标是识别姿势,那么就需要构建一个捕获姿势相似度的距离函数,这里需要参考一下度量学习(Metric Learning)。
- 对测试集编码 ( f θ f_{\theta} fθ)
-
f
θ
f_{\theta}
fθ 是一个迭代了K步(注意这里的k是k steps,上文中的k是k个样本)的 LSTM,并且在对测试集编码的过程中考虑了所有训练样本(
g
(
x
i
)
g(x_i)
g(xi) ),最后f的编码结果为最后一步LSTM输出的隐状态。同样,作者让该网络像基于训练样本的函数一样更改它对于测试样例的编码。
f ( x ^ , S ) = attLSTM ( f ′ ( x ^ ) , g ( S ) , K ) h ^ k , c k = LSTM ( f ′ ( x ^ ) , [ h k − 1 , r k − 1 ] , c k − 1 ) h k = h ^ k + f ′ ( x ^ ) r k − 1 = ∑ i = 1 ∣ S ∣ a ( h k − 1 , g ( x i ) ) g ( x i ) a ( h k − 1 , g ( x i ) ) = softmax ( h k − 1 T g ( x i ) ) \begin{aligned} f(\hat{x}, S) &=\operatorname{attLSTM}\left(f^{\prime}(\hat{x}), g(S), K\right) \\ \hat{h}_{k}, c_{k} &=\operatorname{LSTM}\left(f^{\prime}(\hat{x}),\left[h_{k-1}, r_{k-1}\right], c_{k-1}\right) \\ h_{k} &=\hat{h}_{k}+f^{\prime}(\hat{x}) \\ r_{k-1} &=\sum_{i=1}^{|S|} a\left(h_{k-1}, g\left(x_{i}\right)\right) g\left(x_{i}\right) \\ a\left(h_{k-1}, g\left(x_{i}\right)\right) &=\operatorname{softmax}\left(h_{k-1}^{T} g\left(x_{i}\right)\right) \end{aligned} f(x^,S)h^k,ckhkrk−1a(hk−1,g(xi))=attLSTM(f′(x^),g(S),K)=LSTM(f′(x^),[hk−1,rk−1],ck−1)=h^k+f′(x^)=i=1∑∣S∣a(hk−1,g(xi))g(xi)=softmax(hk−1Tg(xi))
在公式(5)中可能作者有个笔误:r的下标应该是k而不是k-1。
在LSTM的每一步中,输入 f ′ ( x ^ ) f'(\hat x) f′(x^) 都是固定的,是对测试样本自身的一个编码(参考上文的 g ′ g' g′ )。在这里的 LSTM 相当于不断地对测试样本自身进行 k 次迭代编码,如果是 RNN 的话我想可以理解成对自己的输出进行编码,拉长了看就是个 neural network,但是用 LSTM 会遗忘一些东西,为什么要遗忘一些东西呢?这里想的不是很透彻。有两种猜测是:1.为了和对训练样本的的编码结构一致。2.也许遗忘一些东西会相当于dropout?
2.4 训练过程
- 给定一个有k个样本的支撑集 S = ( x i , y i ) i = 1 k S={(x_i,y_i)}^k_{i=1} S=(xi,yi)i=1k,对测试样本 x ^ \hat x x^分类( x ^ \hat x x^类别与S中的某个或几个类别相同),类别是 C S ( x ^ ) C_S(\hat x) CS(x^)。定义 S → C S ( x ^ ) S \rightarrow C_{S}(\hat{x}) S→CS(x^)这一映射为 P ( y ^ ∣ x ^ , S ) P(\hat{y} \mid \hat{x}, S) P(y^∣x^,S),这里的P的参数是通过神经网络学习到的,映射方式就是最后学到的模型。因此,在测试过程中:给定一个新的支撑集 S ′ S' S′,我们可以用之前学到的模型对每个测试样本 x ^ \hat x x^ 得到他们可能的label y ^ \hat y y^ 。
- 比如,在训练时给定一张暹罗猫的图片和一张柯基的图片作为 S S S,对于一张新的哈士奇的图片模型可以将其分类为狗;在测试时拿来一张熊二的图片和一张兔八哥的图片,又拿来一张小熊维尼的图片问机器这个新图片是属于哪一类的,机器就会告诉你这个是熊(跟那个熊二是一个类的)
- 训练策略
作者称“one-shot learning is much easier if you train the network to do one-shot learning” ,所以保持测试和训练一模一样的规则:给定N类k个样本(k=1或5),预测新的测试样例为N类中的一类。
每一次训练都经历如下俩步骤:- 1.从训练集中建立一个任务T,如 选择5个类别,每一类标签含有最多5个样本(总共有5-25个样本)
- 2.为了形成一个“episode”, 采样一个标签集合L(如猫,狗), 然后使用 L 来采样支撑集 S 和一个批次的样例 B 计算损失。
原文采样细节不详,并没有说如何采样。
3. 实验和效果
- Task:N-way k-shot learning task. 对于N个类别,每一个类别给定k个样本,并且这些样本以及类别都是之前再训练过程中没有见过的,判断一个新的样本的类别。 作者选择了几个对比模型:Baselines\MANN\Siamese Network,详见论文。
- 在Omniglot上的实验:
Omniglot 是一个类似 MNIST 的数据集,一共有1623个characters,每个里面有20个样本。
- 在ImageNet上的实验
- Andrej Karpathy对表中数值有质疑,MANN的数值82.8%和94.9%无法在MANN原文中找到,并且5-way 5-shot结果是88.4%而不是这里的94.9%。有可能遗漏了啥?
- Siamese Net的结果也是找不到的,但Table2中的结果One-shot 20-way应该是92.0%,而不是这里的88.1%。
- Lake等人发布的Omniglot结果并没有放上来。人类在1-shot 20-way分类上精度为95.5%,Omniglot是95.2%,而匹配网络是93.8%(嗯哼?似乎发现了什么)。
- 但是总体来说,这个方法确实非常的通用,并且不需要任何假设,非常简单的一个方法。
- 作者还新定义了一个数据集 miniImageNet
- 一共有100个类别,每个类有600个样本。其中80个类用于训练20个类用于测试。
- 一共有100个类别,每个类有600个样本。其中80个类用于训练20个类用于测试。
- 作者还在 One-Shot Language Modeling 上做了实验,但是对于这个实验的结果论文中只是粗略的说了一下,所以在这里就不展开了。
4. 有什么启发和问题?总结
- “Good paper, effectively develops a differentiable nearest neighbor trained end-to-end. It’s something new, I like it!” --by Andrej Karpathy
- 大佬说好应该就是很好吧。以下是大佬的担忧:
- 作者没有提到采样顺序,这对结果会有很大的影响。
- 训练样本增加时,这种方法会变得非常缓慢,一旦这个数字很大,就可以切换到参数化方法。
- 在训练过程中,该方法使用了特定数量的例子,例如5-25,这也是在测试时必须使用的数量。如果我们想让训练集的规模在线增长,会发生什么呢?看来我们需要重新训练网络,因为编码器LSTM的训练数据不是“习惯于”看到输入更多的例子?除非你反复地对训练数据进行子抽样,进行多次推断并求平均值,或者类似的事情。如果我们不使用FCE,它仍然可能是注意机制LSTM仍然不能“习惯于”出席更多的例子,但这有多重要还不清楚。一个有趣的实验是不使用FCE,尝试使用100或1000个训练示例,而只训练多达25个(有和没有FCE)。围绕这一点的讨论将会很有趣。
- 不清楚Omniglot实验发生了什么,关于算法[11],[21]的结果不正确,并且排除了与Lake等人[14]结果的比较。
- 一个缺失的Baseline还包括一个Exemplar SVM,一种比用一个CNN和最近邻编码更强大的方法。
- 个人感受
- 对LSTM和Attention机制的了解较为浅显,公式的理解也不够透彻。
- 大概懂了这篇文章做小样本学习的思路。