博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
8.9 元学习网络结构讲解
阅读量:3950 次
发布时间:2019-05-24

本文共 10477 字,大约阅读时间需要 34 分钟。

文章目录

文章目录

Meta Learning 网络基本方法

image-20210307174540219

我们有一个更疯狂的想法,能不能直接learn一个function,这个function既做了Learning,又做了Prediction。给它Training Data,它就learn好了;给它Testing Data,它就给出Testing Data的答案!

快速学习是区分人类智能和机器的一个关键特性,人类可以有效的利用先验知识和经验去快速学习新的技术。元学习就是来解决这样的问题。

比起基于一个单一的任务训练的学习器(它的目标是泛化到来自一个相似数据分布的没看见过的数据上),元学习器基于相似任务的分布进行训练,它的目标是学习一个策略,可以泛化到来自相似任务分布的相似的新的任务上。

元学习器是可以灵活应对它正要面临的问题的一种学习器,需要有一个表现力强的、通用的模型结构,以便在不同的领域学习一系列不同的策略。

元学习器

现在实现猫狗图像分类,训练过程为:

img

现在,训练图像是一只🐈,表示图像是一只猫的标签是 🔺。最大的这些 △ 表示我们的神经网络,里面的 ■ 表示参数和梯度,标有 L 的四边形表示损失函数,标有 O 的四边形表示优化器。

在我们的训练过程中,具体而言,可以学习到两点:

在这里插入图片描述

  • 神经网络的初始参数(图中的蓝色■);
  • 优化器的参数(粉色的★)。

我会介绍将这两点结合的情况,不过这里的每一点本身也非常有趣,而且可获得到简化、加速以及一些不错的理论结果。

现在,我们有两个部分需要训练:

  • 用「模型(M)」这个词来指代我们之前的神经网络,现在也可以将其理解为一个低级网络。有时,人们也会用「优化对象(optimizee)」或者「学习器(learner)」来称呼它。该模型的权重在图中用 ■ 表示。
  • 用「优化器(O)」或者「元学习器」来指代用于更新低级网络(即上述模型)权重的高级模型。优化器的权重在图中用 ★ 表示。

如何学习这些元参数?

事实上,我们可以将训练过程中的元损失的梯度反向传播到初始的模型权重和/或优化器的参数。

现在,我们有了两个嵌套的训练过程:优化器/元学习器上的元训练过程,其中(元)前向传输包含模型的多个训练步:我们之前见过的前馈、反向传播以及优化步骤。

现在我们来看看元训练的步骤:

在这里插入图片描述

元 训 练 步 ( 训 练 优 化 器 O ) 包 含 3 个 模 型 ( M ) 的 训 练 步 。 元训练步(训练优化器 O)包含 3 个模型(M)的训练步。 O3M

在这里,元训练过程中的单个步骤是横向表示的。它包含模型训练过程中的两个步骤(在元前馈和元反向传播的方格中纵向表示),模型的训练过程和我们之前看到的训练过程完全一样。

可以看到,元前向传输的输入是在模型训练过程中依次使用的一列样本/标签(或一列批次)。

在这里插入图片描述

元训练步中的输入是一列样本(🐈、🐕)及其对应的标签(🔺、🔻)。

我们应该如何使用元损失来训练元学习器呢?在训练模型时,我们可以直接将模型的预测和目标标签做比较,得到误差值。

在训练元学习器时,我们可以用元损失来度量元学习器在目标任务——训练模型——上的表现。

一个可行的方法是在一些训练数据上计算模型的损失:损失越低,模型就越好。最后,我们可以计算出元损失,或者直接将模型训练过程中已经计算得到的损失结合在一起(例如,把它们直接加起来)。

我们还需要一个元优化器来更新优化器的权重,在这里,问题就变得很「meta」了:我们可以用另一个元学习器来优化当前的元学习器……不过最终,我们需要人为选择一个优化器,例如 SGD 或者 ADAM(不能像「turtles all the way down」一样(注:turtles all the way down 这里大概是说,「不能一个模型套一个模型,这样无限的套下去」)。

这里给出一些备注,它们对于我们现在要讨论的实现而言非常重要:

  • 二阶导数:将元损失通过模型的梯度进行反向传播时,需要计算导数的导数,也就是二阶导数(在最后一个动画中的元反向传播部分,这是用绿色的 ▲ 穿过绿色的 ■ 来表示的)。我们可以使用 TensorFlow 或 PyTorch 等现代框架来计算二阶导数,不过在实践中,我们通常不考虑二阶导数,而只是通过模型权重进行反向传播(元反向传播图中的黄色 ■),以降低复杂度。
  • 坐标共享:如今,深度学习模型中的参数数量非常多(在 NLP 任务中,很容易就有将近 3000 万 ~2亿个参数)。当前的 GPU 内存无法将这么多参数作为单独输入传输给优化器。我们经常采用的方法是「坐标共享」(coordinate sharing),这表示我们为一个参数设计一个优化器,然后将其复制到所有的参数上(具体而言,将它的权重沿着模型参数的输入维度进行共享)。在这个方法中,元学习器的参数数量和模型中的参数数量之间并没有函数关系。如果元学习器是一个记忆网络,如 RNN,我们依然可以令模型中的每个参数都具有单独的隐藏状态,以保留每个参数的单独变化情况。

人脸验证

Face Verification就用到了这样的技术!

image-20210307174706633

Face Verification和Face Identification听起来有点像,但其实是不同的Task!

Face Verification是给你一张人脸,让你判断是不是某个人,这是一个是非题。比如在手机上,它就是判断:这是“我”的主人吗?

Face Identification是给你一张人脸,让你判断是一组人中的哪一个?比如公司的门禁系统,通过刷脸打卡,然后以此来判断你有没有来上班,也就是说通过刷脸判断是公司里的哪一个员工。

我们在手机买来的时候,就会让我们眨眼睛,扭下头什么的来收集你的信息,这些信息就是Training Data,然后用这些Training Data进行Few-shot Learning。然后在Testing的时候,看到一个脸,就判断“这是不是手机的主人?”。

image-20210307174834165

如上,我们需要搜集一些训练任务:训练的时候你有一张人脸,测试的时候有另一张人脸,然后判断测试中的人脸和训练中的人脸是不是同一个人。

  • train是一张三玖,test是另一张三玖,这个测试的结果就是Yes。在我们的Network中(具体架构接下来会说),就是吃这一张训练的图片(三玖)和一张测试的图片(三玖),然后判断测试的图片是不是三玖,这里当然是Yes。
  • train是一张三玖,test是一张一花,然后判断测试的图片是不是三玖,这里显然是No。
  • train是一张一花,test是一张三玖,然后判断测试的图片是不是一花,这里显然也是No。

在测试的时候,我们要注意一个问题:train(support set)test(query set)不能出现之前task中出现过的图片。

测试的时候,看图中,train是一张四宫辉夜,test是另外一张图片,然后判断这张图片是不是四宫辉夜,这里显然是Yes。我们让Network做的就是吃一张训练的图片和一张测试的图片,然后告诉你Yes还是No。

Siamese Network(孪生网络)

Siamese的中文意思是暹罗人,这有点奇怪!但其实它还有另外一个意思:连体。因此Siamese Network可以称为孪生网路。

实际上,这个Network最简单的一种做法就是Siamese Network。

上图,就是两个CNN(这两个CNN通常参数是一样的,但如果训练资料和测试资料有很大差别,也可以不一样),训练的图和测试的图通过CNN得到两个embedding vector,然后计算这两个embedding vector的相似度 (比如说计算它们的Euclidean Distance或者Cosine Similarity等),得到一个score,这个score越大,就代表这个network的输出是Yes,越小输出就是No。

训练的时候:

  • 如果train和test是同一个人,output的score就越大越好
  • 如果train和test是不同的人,output的score就越小越好

image-20210307175155672

Siamese Network - 直观的解释

image-20210307175228075

你可以把Siamese Network单纯的当做是一个Binary classification,输入是两张图片,输出是这两张图片一样吗?还是不一样?

在Training Set中,每一个task就是训练时的一笔资料,而每一个task有两张图片,它们的标注就是这两张图片是一样的吗?还是不一样?一样就算是一类,不一样就不算是一类。

在Testing Set中,就是判断这两张图片是一样的吗?还是不一样?

那么Siamese Network内部的设计有什么意义呢?

image-20210307175331471

如果我们单纯的通过pixel计算两张图片的相似度,会发现同一个人的两张图片相差会非常的大!因为同一个人可能一张图片往左看,一张图片往右看。

因此通过CNN我们将图片投影到一个公共空间上,就算一张图片往左看,一张图片往右看,但是在这个公共空间上是非常接近的。而且我们希望同一个人的不同图片在这个空间中越近越好,不同人的图片越远越好。

看到这,你可能会想:我们用PCA和Auto-Encoder不是也能做吗?

仔细想一下,我们在做PCA和Auto-Encoder的时候,并不知道test的任务是什么呀!它们会保留图片中大部分的资讯,而且它们不知道什么样的资讯是重要的,什么样的资讯是不重要的。在这个例子中(右图),一花的图和右上三玖的图背景都是浅灰色,右下三玖的图是深灰色,对于Auto-Encoder来说,一花和右上三玖可能是一样的,因为它们的背景是一样的。

但是在Siamese Network中,因为要让右上三玖跟右下三玖拉近,右上三玖跟一花拉远。那么它就会学到可能头发的颜色很重要,但是背景的颜色可能不重要,可以忽略它。

那么问题来了,怎么计算两个点在公共空间中的距离呢?

image-20210307175551076

方法如下:

  • SphereFace: Deep Hypersphere Embedding for Face Recognition
  • Additive Margin Softmax for Face Verification
  • ArcFace: Additive Angular Margin Loss for Deep Face Recognition

我们这里不细说了!

上图中还有一个概念:Triplet loss

Triplet有三的意思嘛,意思就是输入三个资料。就是说在一个task中,train的数据集给它两个训练资料:一个是目标的脸,一个不是目标的脸。然后进行训练,这样子效果可能会更好。

Triplet loss 具体请看

N-way Few/One-shot Learning

我们上面说的都是Face Verification,它就是单纯的回答Yes or No,也就是一个二分类问题。但如果此时要做的是Face Identification,一个多分类的问题,又该怎么办呢?

举例:

我们此时要做一个5-ways 1-shot(有5个class,每个class只有一个example):

image-20210307175732527

上面的5个class就是:一花,二乃,三玖,四叶,五月

不得不说老师的脑洞是真的大。。。我全都要不香吗!?花泽香菜,竹达彩奈,伊藤美来,佐仓绫音,水濑祈,啧啧啧,无法舍弃!

言归正传,每个姐妹各一张图片作为training data吃下去,测试的图片是一张三玖,希望可以判断出测试的图片是training data中五个姐妹中的哪一个。这又如何做呢?

Prototypical Network(原型网络)

👉

它和Siamese Network非常的像!

image-20210307175833849

  • 通过CNN将Training Data中和Testing Data的每个图片变为vector
  • 然后再计算Testing Data的vector和每个Training Data的vector的相似度,就是图中的黄色块。
  • 将所有的相似度通过Softmax得到预测的结果
  • loss function就和一般的分类问题一样,比如用cross-entropy。将预测的结果和真实的结果进行比较,得到loss,然后minimize它

我们上面说的是one-shot,如果是few-shot呢?

也很简单!看下图:

image-20210307180008924

将每个class的图片求vector,然后相加求平均就可以了!然后求Testing Data中图片的vector和哪一个class的平均vector最像,那么就是哪一个class!

上图凭我们的直觉就能看出来,Testing Data属于 c 2 c_2 c2

Prototypical networks 计算公式 : 分类器 h h h,该架构基于在学习特征空间中与类均值 μ k \mu_{k} μk 的距离的分类概率:

h ( x , S train  ; w ) = p ^ ( x ) p ^ k ( x ) = e − d ( ϕ ( x ; w ϕ ) , μ k ) ∑ j e − d ( ϕ ( x ; w ϕ ) , μ j ) μ k = ∑ ( x i , y i ) ∈ S train  ϕ ( x i ; w ϕ ) I [ y i = k ] ∑ ( x i , y i ) ∈ S train  I [ y i = k ] \begin{aligned} h\left(x, S_{\text {train }} ; \mathbf{w}\right)&=\hat{\mathbf{p}}(x) \\ \hat{p}_{k}(x)&=\frac{e^{-d\left(\phi\left(x ; \mathbf{w}_{\phi}\right), \mu_{k}\right)}}{\sum_{j} e^{-d\left(\phi\left(x ; \mathbf{w}_{\phi}\right), \mu_{j}\right)}} \\ \mu_{k}&=\frac{\sum_{\left(x_{i}, y_{i}\right) \in S_{\text {train }}} \phi\left(x_{i} ; \mathbf{w}_{\phi}\right) \mathbf{I}\left[y_{i}=k\right]}{\sum_{\left(x_{i}, y_{i}\right) \in S_{\text {train }}} \mathbf{I}\left[y_{i}=k\right]} \end{aligned} h(x,Strain ;w)p^k(x)μk=p^(x)=jed(ϕ(x;wϕ),μj)ed(ϕ(x;wϕ),μk)=(xi,yi)Strain I[yi=k](xi,yi)Strain ϕ(xi;wϕ)I[yi=k]
这里 p ^ k \hat{p}_{k} p^k是概率向量 p ^ \hat{\mathbf{p}} p^的组成部分,而 d d d是一个距离度量(欧氏距离)。这里需要学习的唯一参数是特征提取器 w ϕ \mathbf{w}_{\phi} wϕ的参数。类均值 μ k \mu_{k} μk 的估计意味着可以看作是发生在 h h h内部的 S train S_{\text {train}} Strain的“学习”的简单形式。

Matching Network(匹配网络)

👉

还有一种很像的做法叫做Matching Network

image-20210307180137679

不同的做法是前面我们将Training Data中每个class的数据分别进行处理,而这种Model是假设Training Data中就算是不同class的图片也是有某种关系的,所以我们直接用一个Bidirectional LSTM来处理,然后每个class分别得到一个vector。

Matching Network还有一个不一样的地方,它在计算出相似度之后,其实有通过一个类似于Multiple hop的过程。

Matching Network :使用了记忆方法

Matching networks计算方法:

Vinyals等人认为,当面对一个分类问题和相关的训练集时,人们希望关注那些对那些特定类别区分有用的特征。因此,在使用特征提取器独立嵌入所有训练和测试点后,提出分别使用双向长短期记忆网络(lstm)和注意lstm创建训练和测试示例的上下文嵌入。这些上下文嵌入可以被看作是强调与所讨论的特定类相关的特性。最后的类概率是使用软最近邻机制计算的。更具体地说,

h ( x , S t r a i n ; w ) = p ^ ( x ) p ^ k ( x ) = ∑ ( x i , y i ) ∈ S train  e − d ( f ( x ) , g ( x i ) ) I [ y i = k ] ∑ ( x i , y i ) ∈ S train  e − d ( f ( x ) , g ( x i ) ) f ( x ) = AttLSTM ⁡ ( ϕ ( x ; w ϕ ) , { g ( x i ) } i = 1 N ; w f ) { g ( x i ) } i = 1 N = BiLSTM ⁡ ( { ϕ ( x i ; w ϕ ) } i = 1 N ; w g ) . \begin{array}{r} h\left(x, S_{\mathrm{train}} ; \mathbf{w}\right)=\hat{\mathbf{p}}(x) \\ \hat{p}_{k}(x)=\frac{\sum_{\left(x_{i}, y_{i}\right) \in S_{\text {train }}} e^{-d\left(f(x), g\left(x_{i}\right)\right)} \mathbf{I}\left[y_{i}=k\right]}{\sum_{\left(x_{i}, y_{i}\right) \in S_{\text {train }}} e^{-d\left(f(x), g\left(x_{i}\right)\right)}} \\ f(x)=\operatorname{AttLSTM}\left(\phi\left(x ; \mathbf{w}_{\phi}\right),\left\{g\left(x_{i}\right)\right\}_{i=1}^{N} ; \mathbf{w}_{f}\right) \\ \left\{g\left(x_{i}\right)\right\}_{i=1}^{N}=\operatorname{BiLSTM}\left(\left\{\phi\left(x_{i} ; \mathbf{w}_{\phi}\right)\right\}_{i=1}^{N} ; \mathbf{w}_{g}\right) . \end{array} h(x,Strain;w)=p^(x)p^k(x)=(xi,yi)Strain ed(f(x),g(xi))(xi,yi)Strain ed(f(x),g(xi))I[yi=k]f(x)=AttLSTM(ϕ(x;wϕ),{
g(xi)}
i=1N
;wf)
{
g(xi)}
i=1N
=BiLSTM({
ϕ(xi;wϕ)}
i=1N
;wg)
.
这里, d d d是距离度量。有三组参数需要学习: w ϕ , w g \mathbf{w}_{\phi}, \mathbf{w}_{g} wϕwg,和 w f \mathbf{w}_{f} wf

  • 👉

有趣的是,是先有的Matching Network再有的Prototypical Network。

Relation Network(关系网络)

👉

其实道理差不多:

image-20210307180500150

input训练资料和测试资料,然后接下来当做分类问题来做。

但它也有一个不一样的地方:先从训练资料和测试资料中抽取embedding vector,上图中,左边的五种不同颜色的vector就是从训练资料中抽取出来的,而右边的黄色vector就是从测试资料中抽取的,放在训练资料的vector后面形成一个新的vector。本来我们是直接算训练资料和测试资料vector的相似度,但Relation Network是另外再用一个network来算相似度,input就是通过连接新生成的vector,这个network也是在整个model中一起学出来的。

假想数据的Few-shot learning

👉

通常我们的训练资料都比较少,我们其实可以通过一张图片来进行幻想从而生成更多的图片。

上图中,我们输入一个三玖的图片,它是面无表情的,但是也许可以幻想出三玖害羞的样子,生气的样子以及卖萌的样子!

上图中,我们的Testing Data是一张图片,Training Data是五个class,每个class一张图片。但是我们可以通过一个Generator来生成更多的图片,然后丢进Network中进行接下来的训练。

在训练的时候,我们的Network和Generator是一起train的!

Meta Learning - Train+Test as RNN

上面我们说了一个疯狂的想法,将训练资料和测试资料一起给Network,然后给出测试资料结果。这是能实现的,我们上面也给出了几种方法。

但上面的几种Network都要设计一下Network的架构才能达到我们想要的目标。现在说的是能不能用一个general network来完成这件事情呢?

LSTM

我们可以用一个LSTM来解决这个问题。

就当做是一个sequence,LSTM依次读取training data,最后读取testing data,然后输出答案!

  • 训练资料:每张图片经过一个CNN得到embedding vector,每张图片的类别也可以用one-hot vector来表示,然后这两个vector做concatenate丢进LSTM中。
  • 测试资料:图片经过一个CNN得到embedding vector,类别并不知道,可以用一个zero vector来表示,然后这两个vector做concatenate丢进LSTM中。

很遗憾,看似很有道理,但并不work!

因此有人也修改了network的架构:

  • MANN:Nerual Turing Machine
  • SNAIL:Using Attention

这里我们并不细讲!

MANN & SNAIL

MANN:全名为Memory Augmented Neural Networks,翻译成中文就是:记忆增强神经网络。

神经图灵机具有增强记忆功能,提供了快速编码和检索新信息的能力,因此可以潜在地消除传统模型的缺点。mann 使用神经图灵机作为网络,实现了快速学习和提取元知识的能力,使用少样本就能获取高准确率,从而解决one-shot问题。

具体实现可见:👉

记忆增强图神经网络:捕获长期依赖关系。

  • 为了对用户的短期和长期兴趣进行建模,使用记忆增强图神经网络来获取物品的短期上下文信息和长期依赖关系。
  • 为了有效地融合短期和长期利益,在GNN框架中加入了一种门控机制来自适应地结合这两种隐藏表征。
  • 为了明确地建模项目共现模式,使用一个双线性函数来捕获项目之间的特征相关性。

具体实现可见:👉

SNAIL:全名为A Simple Neural Attentive Meta-Learner,翻译成中文就是:一个简单的神经注意力元学习器。SNAIL中文意思是蜗牛,看上图右下角的架构,可能看起来有点像蜗牛吧?

👉

👉

它的做法其实差不多,是将训练资料和测试资料丢进时序卷积网络(TCN)中,它不是单纯的卷积网络。之后再结合完成元学习。

时序卷积和注意力互相可以互补:前者提供整合全局信息的方法,代价是受限于 context 的大小,后者可以基于不确定的可能无限大的 context 提供精准的提取。因此,SNAIL 的构建使用二者的组合:使用时序卷积去处理用注意力机制提取过的内容。通过整合 TC 和 attention,SNAIL 可以基于它过去的经验产出高带宽的处理方法且不再有经验数量的限制。

self-attention:当丢进 X t − 2 X_{t-2} Xt2 时,会attent X t − 3 X_{t-3} Xt3的资料;当丢进 X t − 1 X_{t-1} Xt1 时 ,会attent X t − 2 X_{t-2} Xt2 X t − 3 X_{t-3} Xt3 的资料;当测试资料 X t X_{t} Xt丢进去的时候,会attent之前所有的训练资料。

想想测试资料attent这一步是不是和之前讲的Prototypical Network和Matching Network的计算相似度差不多呢?

也就是说我们原本是想要用general network来解决这个问题,但是最终发现还是要改一下network的架构才能做到和前面Siamese Network,Prototypical Network类似的想法!

实验结果

image-20210307181519477

上图是使用SNAIL与其它六种方式(表格下方)在Omniglot上的结果进行了对比;

下图是使用SNAIL与其它五种方式(表格左方)在Mini-ImageNet上的结果进行了对比。

结果看起来真的是蛮厉害的!

参考资料

李宏毅2020人类语言处理

转载地址:http://fdyzi.baihongyu.com/

你可能感兴趣的文章
XDR-从文件空间解码整数
查看>>
XDR-.x文件的简单使用
查看>>
XDR-枚举的试用
查看>>
使用CppSQLite3访问SQLite数据库
查看>>
第一个boost程序---timer的使用
查看>>
使用boost asio库实现字节数可控的CS通信
查看>>
linux下串口编程
查看>>
boot asio 非阻塞同步编程---非阻塞的accept和receive。
查看>>
利用ADOX、ADO操纵MDB文件(ACCESS)
查看>>
使用ADO操作MDB,关注数据类型
查看>>
使用windows自带Zip命令压缩文件
查看>>
windows获得文件大小
查看>>
Host 'ETCV3' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
查看>>
OCILIB在VS2008中的使用
查看>>
OCILIB VC2008 效率测试
查看>>
PL/SQL设置NUMBER显示为字符串
查看>>
linux ftp 脚本 -- 使用程序执行脚本
查看>>
MFC CListBox的使用
查看>>
VS2008向MFC 对话框 添加托盘图标(显示和消失)
查看>>
redhat中vsftp开机自启动
查看>>