斯坦福-CS330-深度多任务与元学习笔记-全-
斯坦福 CS330 深度多任务与元学习笔记(全)
1:什么是多任务学习?🤖


概述
在本节课中,我们将学习课程的目标与安排,并初步探讨多任务学习与元学习的基本概念及其重要性。
课程介绍与安排
我的名字是Chelsea,是这门课程的主讲教师。我们还有七位非常出色的助教。欢迎大家来到这门课程。
课程网站是获取信息的第一站,上面有大量信息,请仔细阅读。如有疑问,请先在网站上查找,然后可以在Ed讨论区提问。Ed与Canvas关联,你也可以联系助教邮箱。我们鼓励在Ed上公开提问,这样其他有相同问题的同学也能看到。如果你不希望问题被公开,可以在Ed上私密发帖或直接邮件联系助教,例如提交OAE信件。
答疑时间已公布在课程网站上,Zoom链接在Canvas上。答疑将于周三开始。
你将学到什么?
本课程主要有三个学习目标:
- 学习现代深度学习方法在多任务学习和跨任务学习方面的基础知识。
- 获得实际经验,在PyTorch中实现和应用这些方法,理解它们在实践中的运作方式。
- 了解构建这类方法背后的科学和工程过程,鼓励大家挑战现有知识,并学习开发此类算法的过程。
课程内容概览
我们将涵盖广泛的主题:
- 从多任务学习和迁移学习的基础开始。
- 深入三类元学习算法:黑盒方法、基于优化的方法和度量学习。
- 探讨更高级的元学习主题,如元学习中的过拟合、无监督元学习和贝叶斯元学习方法。
- 学习其他少样本学习和适应方法,包括无监督预训练、领域适应和领域泛化。
课程将强调深度学习技术,并研究多个真实应用案例,例如YouTube推荐系统中的多任务学习、用于土地覆盖分类和教育的元学习,以及大语言模型中的少样本学习。
与之前开课相比,本课程新增了上述内容,并移除了所有强化学习相关的讲座和作业。这是因为我们将在春季学期开设一门新的深度强化学习课程。移除强化学习内容也使没有相关背景的同学更容易入门。如果你对将课程思想应用于强化学习感兴趣,仍然可以在最终项目中探索,并得到助教的支持。
课程形式与要求
- 讲座:所有讲座均为线下进行,同时直播和录制,录像可在Canvas上观看。季度末将有两场嘉宾讲座。鼓励大家在讲座中提问,可以通过举手或在Zoom聊天区输入问题,会有助教监控聊天并确保问题得到解答。
- 答疑:混合线下和远程形式,主要为线下,但会为SCPD学生提供两个远程选项。
- 先修要求:主要要求是具备足够的机器学习背景(如CS229或同等课程)。所有作业都需要使用PyTorch训练神经网络。如果你确实不喜欢PyTorch,可以使用其他框架,但所有起始代码和主要支持都基于PyTorch。我们将在本周四下午4:30在本教室举行PyTorch复习课,也会直播和录制。
- 作业:
- 作业0是热身,确保你熟悉PyTorch和多任务学习基础。
- 作业1将涉及黑盒元学习,以及如何设置数据以使少样本学习更有效。
- 作业2将涵盖基于梯度的元学习和度量学习,涉及少样本字符识别问题。
- 作业3将专注于自然语言处理和语言模型的预训练模型微调。
- 作业4是可选的,涵盖课程中更多概念性内容。前四个作业基于实现,最后一个作业更像一篇小论文。
- 评分:课程评分50%基于作业,50%基于项目。作业0占5%,其余三个作业各占15%。作业4可以用来替换之前一个作业的部分分数或项目部分分数,系统会自动选择对你最有利的方式计分。
- 灵活性政策:为提供灵活性,我们提供总共6个“迟交日”,每项作业最多可使用2个,无需说明理由。如有特殊情况,可联系我们寻求额外安排。
- 合作政策:请阅读课程网站和荣誉准则。作业允许讨论,但需注明合作者,并应独立完成解答,不得参考其他同学的解答或网络上的答案。
- 期末项目:项目是自选的研究级项目,可以1-3人组队。鼓励将校内研究用作项目主题(只要与课程内容相关)。也可以与其他课程共享项目,但期望会稍高。迟交日政策与作业相同,但海报展示环节不接受迟交,因为这是现场活动。海报展示将于12月7日(课程最后一天)举行,代替当天的讲座。
项目与初步步骤
项目主题非常开放,只要与课程内容相关即可。我们正在向更广泛的斯坦福AI社区征集想法,下周一会发布项目想法列表。你也可以参考往年课程的项目标题和公开链接获取灵感。



作业0已发布,一周后截止。所有作业截止时间为太平洋时间晚上11:59。鼓励开始组建项目小组,可以在Ed上发帖寻找队友,我们也乐意帮助大家建立联系。
关于是否组队,各有利弊。好处是可以做更多事情,互补专业知识,合作更有趣。缺点是某种程度上需要依赖队友,需要确保彼此兼容可靠。一般推荐组队,但不是必须的,也欢迎单独完成。
为什么研究多任务学习与元学习?🤔
个人视角:从机器人到通用智能
我实验室的很多研究都在思考如何让智能体在现实世界中学习多种技能。这里的“智能体”指的是真实的机器人,让它们学习诸如将积木放入形状分类盒、观看人类演示后模仿完成任务、甚至使用工具等技能。
机器人之所以有趣,是因为它们能教我们关于智能的知识。它们需要面对现实世界的复杂性,必须在各种任务、物体和环境中进行泛化,还需要某种常识理解。此外,监督信号也不总是明确的。




除了帮助我们理解智能,如果能建造出真正有用的机器人,它们可以在社会许多方面提供帮助,例如从事危险、繁琐或人们不愿做的工作。
在我博士初期,我研究了一个机器人通过试错学习将玩具飞机轮子插入对应孔洞的项目。虽然有趣,但机器人当时是“闭着眼睛”的,没有使用视觉。后续项目中,我们让机器人“睁开眼睛”,学习一个从摄像头图像直接映射到关节扭矩的神经网络策略。它不仅能将积木插入红色孔洞,还能应对立方体在不同位置的情况。这很酷,但关键在于,我们拥有的是一个能让机器人学习多种任务的强化学习算法。只需改变奖励函数,它就能学会其他任务,比如用玩具锤撬起钉子、拧上瓶盖,甚至用锅铲将物体舀入碗中。
大约在2016-2017年,深度强化学习在Atari游戏、围棋、模拟行走等领域取得了令人兴奋的进展。然而,这里存在一个普遍问题:我们训练机器人完成某项特定任务(例如用特定锅铲舀起特定物体放入特定碗中)后,如果换一个锅铲或环境,机器人就无法成功。这是一个巨大的问题,因为这意味着如果我们想把机器人投入现实世界,它并没有学到通用的东西。
你可能会说,也许我们可以给机器人更多锅铲,用更多数据训练它。但问题是,训练这些系统通常需要反复尝试任务,每次尝试后都需要人工将环境重置回初始状态。这看起来效率低下,且难以扩展。以这种方式收集大量数据是不切实际的。
这就引出了为什么多任务学习和元学习很重要:我们正在训练系统做一件非常狭隘的事情,这需要详细的监督和大量人力。如果我们想做另一件事,又需要从头开始投入大量人力。这不仅是强化学习和机器人学的问题,在语音识别或物体检测等领域,系统虽然训练数据更多样,但仍然是针对单一任务从头开始学习,需要大量监督和工程。

我将所有这些系统称为“专家”系统——我们训练机器学习系统做一件事。而在许多情况下,更有用的是那些不是在单一任务上训练,而是在许多不同任务上训练的系统。例如,人类不是从第一天起就被训练使用锅铲舀东西,而是更广泛地学习世界知识。从这个意义上说,人类是“通才”。我对如何构建更通用的机器学习系统这个问题很感兴趣。
再比如AlphaGo,它是围棋冠军,但这也是一个“专家”系统的例子。这有点像从第一天起就训练一个婴儿下围棋,而不教他世界上的其他事情。事实上,即使是训练机器人捡起围棋棋子并摆好,也超出了当前AI系统的能力。

超越机器人:深度学习的动机
如果你上过机器学习课程,可能不需要太多动机来解释为什么关注深度学习。历史上,计算机视觉等方法需要手动设计特征,然后在这些特征上训练分类器。而现代方法则是训练一个端到端的单一神经网络。前者有其好处(如可解释性),但后者通常效果更好,并且允许我们处理非结构化输入(如图像像素、语言、传感器读数),无需大量领域知识来设计特征。
在ImageNet基准测试中,自AlexNet(第一个端到端方法)出现后,性能有了显著提升。在自然语言处理领域,谷歌神经机器翻译系统相比之前的短语系统,在翻译任务上取得了60%到87%的改进。现在谷歌翻译等系统就使用这类模型。
为什么关注深度多任务与元学习?
在深度学习中,我们看到,如果拥有大型多样化的数据集和大型模型,就能在之前提到的任务上实现良好的泛化(如图像识别、机器翻译)。然而,在很多场景下,你一开始并没有大型多样化的数据集:
- 医疗影像:存在隐私问题。
- 机器人学:没有现成的“机器人维基百科”。
- 个性化教育或稀有语言翻译:没有现成的大型数据集,收集成本高昂。
在这些场景下,上述“秘诀”开始失效,为每种新情况(每种罕见疾病、每个机器人、每个人、每种语言)从头学习是不切实际的。


此外,还有场景是虽然你有一个大数据集,但数据分布非常偏斜,存在长尾分布。这些“边缘情况”对现代机器学习系统构成了主要挑战(例如,我认为这就是为什么我们今天还没有完全自动驾驶汽车的原因)。多任务学习和元学习本身不能解决这个问题,但有迹象表明,如果能利用大数据中的先验知识并将其迁移到尾部情况,或许能更好地处理这类分布。

再者,如果你希望系统快速学习新事物(例如,关于一个新用户或新环境),这也是一个数据稀少的场景。多任务学习和元学习的思想可能很有用。
少样本学习测试
我给大家做个小测试:学习区分两位画家(Brock和Czanne)的画作。训练集是左边的六幅画(三幅Brock,三幅Czanne)。现在请判断测试图片(一幅画)属于哪位画家。

大多数人答对了,这是Brock的画。这是一个少样本学习的例子:你只用了一个非常小的训练集(六个数据点)就泛化到了新数据点。你是怎么做到的?如果从头开始训练一个卷积神经网络,它可能无法得出正确答案。但你能做到,可能是因为你以前学过如何看图像、识别模式,你所有的先前经验使你能够用少量数据学习新任务,而不是从零开始。
少样本学习是指训练数据集只有很少数据点的情况。如果你能利用先验经验而不是从头开始,就应该能实现少样本学习。
为什么现在研究?
这些想法并不新鲜。早在20世纪90年代甚至更早,就有论文讨论并行训练任务、少样本学习、元学习规则等。然而,尽管存在已久,它们仍在AI系统中扮演重要角色。
元学习在拥有大数据集时也有助于泛化吗?
一般来说,这些方法在数据量少时效果最显著,因为那里利用先前经验最有用。如果你有一个非常大的数据集,仅从头训练可能就表现很好。但如果存在分布偏移,先验知识可能仍有帮助。总的来说,对于标准的独立同分布问题且数据量大时,先验经验的作用会小得多。
现代应用案例
- DeepMind的Flamingo模型:训练单一模型执行多种视觉和语言任务(如物体识别、算术、计数),并能以少样本方式快速适应新任务。
- 教育应用(元学习):在一门入门CS课程中,利用元学习对大量学生编程作业提供反馈。通过利用以往课程的数据进行元学习,系统能够适应新课程的新问题,为成千上万份作业提供反馈,并实际部署。
- 机器翻译:同时翻译102种语言的多任务学习系统,超越了仅针对语言对训练的强基线。
- YouTube推荐系统:多任务学习用于多目标优化。
- 通用智能体:训练单一模型执行从对话、玩Atari游戏到控制模拟和真实机器人的广泛任务。
- 机器人学:让机器人利用先前任务的经验,对新物体执行任务(如将物体放入新容器)。
挑战与开放性问题
尽管有这些成功案例,仍存在许多开放性问题与挑战,例如:如何量化一个数据集对另一个数据集的有用性?这也使得该领域的研究同样令人兴奋。

让深度学习更普及
深度学习在拥有大数据集时效果很好(如ImageNet有120万图像,英法翻译数据集有4000万配对句子)。但许多我们关心的问题没有这么多数据(如糖尿病视网膜病变检测只有3.5万图像,癫痫治疗数据不足1小时,早期机器人任务数据不足15分钟)。如果我们能从其他更大的数据集中提取先验信息,或许就能开始更好地解决数据量少的任务,从而使这项技术对没有大量数据或资金收集数据的人们更加普及。
如何量化一个任务的数据对学习新任务的有用性?
这是一个开放性问题,尚未解决。有一些工作试图关联两个任务之间的相似性(更准确说是方向性相似性),以及数据估值的一般性研究。
如果有很多小数据集呢?
绝对可以。例如,作业中将使用的Omniglot数据集,每个字符大约20个例子,但有超过1200个字符。这类系统在这种情况下可以表现得很好。
能否使用生成模型创建合成数据集?
有一些相关研究,但通常存在“没有免费午餐”的问题:如果你从数据中学习生成数据,并没有创造超出原始数据的新信息。但如果能将领域知识注入生成模型,可能会有所帮助。这是一个有趣但棘手的问题。
任务与多任务学习的定义 📚
什么是任务?
非正式地,我们可以将一个机器学习任务视为:接收一个数据集和一个损失函数作为输入,并试图产生一个模型。不同的任务可以在许多方面有所不同,直观地说,可以是不同的物体、不同的人、不同的目标函数、不同的光照条件、不同的词语、不同的语言等。
因此,多任务学习涵盖的“任务”可能非常多样,它们可能沿着许多不同的轴线变化。多任务学习不仅仅指英语单词“task”意义上的不同任务,也可能意味着处理不同的物体。如果你想构建一个能处理许多不同物体的系统,并跨物体进行训练,这仍然符合机器学习任务的更技术性定义。
关键假设:共享结构
这些系统有一个关键假设:你训练的任务之间需要存在一些共享的结构。如果它们彼此完全独立,那么一起训练或利用共享结构就不会带来任何好处。如果没有共享结构,你最好使用单任务学习。
好消息是,许多任务确实存在共享结构。例如,拧开罐子、瓶盖甚至使用胡椒研磨器,这些任务都涉及相似的动作。即使任务看似无关,物理定律是所有真实数据的基础,因此已经存在大量共同结构。人们都是有意图的生物,英语语法规则是所有英语语言数据的基础,语言都是为了相似的目的而发展,因此即使跨语言也存在许多共享结构。实际上,很少有情况下的任务是统计意义上完全独立的。因此,模型可以利用这些共享结构来做得更好。

问题定义
本课程将涵盖的问题定义主要有两类:
- 多任务学习问题:学习一组任务,并试图比独立学习这些任务更快或更熟练。在这里,训练和测试时看到的是同一组任务,不涉及处理新任务。
- 迁移学习/元学习问题:给定先前任务的数据,目标是更快或更熟练地学习一个新任务。元学习算法也旨在解决这个问题。
本课程将关注任何试图解决这两个问题陈述之一或全部的方法。
多任务学习可以简化为单任务学习吗?
有人可能会问:多任务学习可以简化为单任务学习吗?对于每个任务 i,你有一个数据集 D_i 和一个损失函数 L_i。你可以将损失函数求和,合并数据集,从而创建一个单一的数据集和损失函数,然后你就有了一个单任务学习问题。从某种意义上说,这可以简化为单任务学习,跨任务聚合数据并训练单一模型是多任务学习的一种可行方法。
然而,本课程将更侧重于迁移学习问题(学习新任务),因为它更具挑战性,不能简单地简化为单任务学习。不过,我们也会在周三有一节关于多任务学习的讲座,讨论诸如如何告诉模型我们想做哪个任务,或者如果简单聚合数据训练无效该怎么办等问题。

总结 🎯
本节课我们一起学习了课程的目标、安排和评分政策,探讨了研究多任务学习与元学习的动机——从构建通用机器人智能体,到处理数据稀缺、长尾分布和快速适应新任务的现实挑战。我们通过实例看到了这些方法在视觉语言模型、教育、翻译等领域的成功应用,也认识到其中存在的开放性问题。最后,我们初步定义了“任务”的概念,并区分了多任务学习与迁移学习/元学习两类核心问题。下节课我们将更正式地深入这些主题。



提醒:作业0已发布,下周一截止。如果你想为期末项目组队,请开始组建小组。
2:多任务学习基础 I 🧠


在本节课中,我们将要学习多任务学习的基础知识。我们将从定义“任务”开始,探讨如何构建一个能够同时处理多个任务的神经网络模型,并讨论其中的关键设计选择,例如如何让模型知道当前是哪个任务、如何权衡不同任务的重要性,以及如何优化模型。最后,我们会通过一个来自谷歌的真实案例研究,看看这些理论是如何在实践中应用的。
任务的定义与多任务学习问题
上一讲我们介绍了课程概览,本节中我们来看看如何形式化地定义一个“任务”。
在深度学习的背景下,一个任务 通常由三部分组成:
- 输入
x的分布P(x)。 - 给定输入
x时输出y的条件分布P(y|x)。 - 一个衡量模型在该任务上表现的损失函数
L。
因此,一个任务 T_i 可以表示为:
T_i = { P_i(x), P_i(y|x), L_i }
我们通常无法直接访问这些真实的数据分布,只能获得从这些分布中采样得到的数据集 D_i(例如训练集和测试集)。
从单任务学习到多任务学习
在单任务监督学习中,我们有一个数据集 D = {(x, y)},目标是找到模型参数 θ 以最小化损失函数 L(θ)。在多任务学习中,我们的目标变为同时解决一组任务 {T_1, T_2, ..., T_T}。
以下是多任务学习问题的几个例子:
- 多任务分类:任务共享相同的损失函数(如交叉熵损失),但输入和输出的分布不同。例如,识别不同语言的笔迹,每个语言是一个独立的任务。
- 多标签学习:输入分布
P(x)相同,但输出分布P(y|x)不同。例如,在同一张图像上预测深度、关键点和表面法线。 - 混合任务:任务间损失函数也可能不同。例如,一些任务的标签是连续的(使用均方误差损失),另一些是离散的(使用交叉熵损失)。
多任务学习模型架构
既然我们要让一个模型处理多个任务,首先需要告诉模型当前正在执行哪个任务。这是通过任务描述符 z_i 来实现的。
任务描述符
任务描述符 z_i 是标识任务 i 的信息,会被输入到网络中。模型因此变为预测 P(y | x, z_i)。z_i 可以有多种形式:
- 独热编码:最简单的形式,例如
[1, 0, 0]表示任务1。 - 自然语言描述:例如,“给我摘要”、“告诉我论文长度”。
- 任务元数据:例如,在个性化任务中,可以是用户属性。
模型条件化与参数共享
如何将 z_i 整合到网络中,直接决定了参数在任务间是共享还是独享。这是多任务学习的核心设计选择。
两种极端情况:
- 完全不共享(任务独享):为每个任务训练完全独立的网络,通过
z_i像开关一样选择使用哪个网络。这等价于没有共享参数。# 伪代码示意 if z_i == [1,0,0]: output = network_1(x) elif z_i == [0,1,0]: output = network_2(x) - 完全共享:使用单一网络,简单地将
z_i与某一层的激活值拼接(Concatenation)或相加(Addition)。此时几乎所有参数都被所有任务共享。
更常见的架构选择:
在实践中,我们通常介于两者之间。以下是两种主流方法:
- 多头部架构:网络底层是共享的,用于提取通用特征;顶层则分为多个独立的“头部”,每个头部专门负责一个任务。这是一种硬性参数划分。
- 乘性条件化:比加性条件化更强大。它通过将
z_i的表示与网络激活值进行逐元素相乘来实现条件化。这种方式可以学习一种“门控”机制,动态地决定哪些特征或网络路径对当前任务更重要,从而能更灵活地模拟从完全共享到完全独立的各种情况。
加性与乘性条件化的关系:
值得注意的是,拼接(Concatenation)和加性(Addition)条件化在本质上是等价的。考虑一个全连接层,将拼接后的向量 [x, z] 乘以权重矩阵 W:
W * [x; z] = W_x * x + W_z * z
其中 W_x 和 W_z 是权重矩阵 W 的分块。这正是加性条件化的形式。因此,这两种方式具有相同的表达能力。
目标函数与优化
上一节我们介绍了模型如何接收任务信息,本节中我们来看看如何定义和优化多任务学习的目标。
基础目标函数
最直接的多任务目标函数是各个任务损失函数的求和:
L(θ) = Σ_{i=1}^{T} w_i * L_i(θ)
其中 L_i 是任务 i 的损失,w_i 是任务 i 的权重。
任务权重的选择
如何设置权重 w_i 是一个重要的设计选择,它影响了模型对不同任务的关注度。以下是一些常见策略:
- 均匀权重:
w_i = 1。这是最简单的基线。 - 手动调整:根据任务的重要性、数据量多少或损失函数的量级来手动设置。
- 动态调整:权重在训练过程中可以变化,以应对优化挑战(例如某个任务收敛过慢)。
- 极小化极大(Minimax)优化:一种自动平衡任务的策略。在每一步,选择当前损失最大的任务进行优化。这确保了所有任务最终都能达到相对均衡的性能,在公平性要求高的场景中特别有用(例如,不同用户群体的体验)。其目标可形式化为:
min_θ max_i L_i(θ)
优化过程
多任务学习的优化通常采用小批量随机梯度下降的变体:
- 采样一批任务:从所有任务中均匀采样一个子集(例如,如果任务不多,可以每次都用所有任务)。
- 为每个采样任务采样数据:对每个被选中的任务,从其数据集中采样一个小批量数据。
- 计算损失与梯度:计算这批任务和数据的总体损失,然后反向传播计算梯度。
- 更新参数:使用优化器(如SGD、Adam)更新模型参数。
这个过程确保了即使不同任务的数据量差异很大,每个任务在优化过程中被采样的频率也是均匀的。
实践挑战与设计指南
在构建多任务学习系统时,我们会遇到几个关键挑战,它们直接指导我们的设计选择。
1. 负迁移
负迁移 是指多任务学习的性能反而比单独训练每个任务更差。这通常是由于任务间存在干扰,或者模型容量不足导致的。
- 应对策略:如果观察到负迁移,应尝试减少参数共享。例如,采用多头部架构,或增加任务特定参数的比例。
2. 过拟合与正则化不足
相反,如果模型在单个任务上过拟合,而多任务学习作为一种正则化手段可能效果不佳。
- 应对策略:尝试增加参数共享,让任务间通过共享表示相互约束,提升泛化能力。
3. 任务相似性与分组
如何预先知道哪些任务一起训练会有正面效果(正迁移)?这是一个难题,因为它依赖于数据、模型和优化器。
- 现状:没有通用的先验度量。一种实践方法是进行单次多任务训练,通过分析梯度相似性等指标,事后评估任务间的兼容性,并据此调整任务分组。
软参数共享
除了“共享”与“不共享”的硬性选择,还存在软参数共享。即为每个任务维护独立的参数,但同时添加一个约束项(如L2正则化)来鼓励这些参数彼此相似。这提供了更大的灵活性,但引入了额外的超参数和内存开销。预训练+微调 也可以看作是一种时序上的软共享。
案例研究:YouTube视频推荐系统
现在,让我们通过一个来自谷歌的真实案例,看看多任务学习如何解决工业级问题。该系统的目标是为用户推荐YouTube侧边栏的视频。
问题建模:
- 输入:查询视频特征、候选视频特征、用户特征、上下文特征。
- 输出/任务:预测用户对候选视频的多种参与度和满意度指标。
- 参与度:点击率、观看时长等。
- 满意度:点赞率、调查评分等。
- 挑战:不同指标的数据稀疏性和量级不同,且需要平衡短期参与和长期满意度。
模型演进:
- 基线 - 多头部模型:共享底层网络,不同预测头对应不同指标。但发现当任务相关性低时,性能会受损。
- 改进 - 多门控混合专家模型:
- 在共享层之上,引入多个“专家”网络(小型子网络)。
- 为每个任务学习一个“门控网络”,该网络根据输入计算权重,软选择要组合哪些专家。
- 公式化表示,对于任务
k和输入x,输出为:
y_k(x) = Σ_{e=1}^{E} g_k(x)_e * f_e(x)
其中f_e是第e个专家,g_k(x)是任务k的门控网络输出的权重向量(通过softmax获得)。 - 优势:模型可以自动学习让不同专家专注于不同任务(专业化),同时允许有用的专家被多个任务复用(共享),实现了灵活的软共享。
结果:相比共享底层的基线模型,MMoE模型在满意度指标上提升了3%,在参与度指标上提升了0.45%,效果显著,并成功部署于生产系统。
总结 🎯
本节课中我们一起学习了多任务学习的基础。我们首先形式化地定义了任务,并介绍了如何通过任务描述符 z_i 让模型感知当前任务。我们深入探讨了模型架构的核心选择——参数共享,比较了加性/乘性条件化以及多头部等设计。接着,我们研究了目标函数,讨论了如何通过设置任务权重或采用极小化极大策略来平衡不同任务。最后,我们分析了实践中面临的负迁移、过拟合等挑战,并给出了相应的设计指南,最终通过YouTube推荐系统的案例看到了这些理论的成功应用。

记住关键点:观察到的迁移性质(正/负)是指导你调整参数共享程度(更多还是更少)的重要信号。下一讲,我们将开始学习迁移学习,并逐步深入到元学习的主题。
3:迁移学习与元学习入门 🎯


在本节课中,我们将要学习迁移学习与元学习的基本概念。我们将从迁移学习的定义和经典方法(微调)开始,探讨其背后的设计选择与常见实践。随后,我们将引入元学习的概念,从概率图模型和机制化两个视角来理解其核心思想,即如何通过学习多个任务来优化快速学习新任务的能力。
课程安排与公告 📢
在开始之前,有一些课程安排需要说明。
作业零的截止时间是今晚11点59分。
作业一现已发布,截止时间为下周三。
我们将在今天发布一些项目相关的资源。
以下是即将发布的资源列表:
- 项目创意:如果你不确定做什么项目,这些创意会很有帮助。
- 往年项目示例:这些示例可以让你了解过去这门课的学生都做了哪些项目。
- 兴趣与合作者匹配表:如果你希望找到有相似兴趣的同学合作项目,可以填写这个表单。我们会发布表单的回复,帮助你建立联系。

这个表单是可选的,主要是为了帮助你寻找合作者。
另一个重要的公告是关于AI代码补全工具的使用政策。
目前,对于在课程项目中使用这类工具,我们没有严格的规定。
我们认为在项目中使用这些工具是可以接受的。
但是,在完成作业时,不允许使用这些工具,因为你应该真正理解自己编写的代码,而不是让AI替你完成作业。
最后,你们的反馈对我们改进课程体验非常重要。
从本周开始,我们将进行“高分辨率反馈”活动。
每周会随机抽取一部分同学填写反馈表,告诉我们课程的进展等情况。
我们不会每周都让所有同学填写,以减轻大家的负担,同时也能在整个课程期间持续收集反馈。
另外,我们已经确定了课程后期的客座讲师。
我们很高兴邀请到Ho和Percy来做客座讲座。
Ho在谷歌工作,在迁移学习和深度学习理解方面做了很多出色的工作。
Percy在斯坦福大学,他在基础模型、自然语言处理和理解涌现的少样本学习方面做了大量工作。
我很期待在课程后期看到这些讲座。
以上就是所有的课程安排。所有信息都会发布在课程网站上,项目资源会发布在Ed上。

上节课回顾 🔄


上一讲我们讨论了多任务学习。
我们将任务定义为一组数据生成分布,从中采样出训练集和测试集,每个任务还有一个对应的损失函数。
我们可以将学习一个任务看作是以数据集为输入,预测一组模型参数的过程。
我们讨论了多任务学习,即训练一个以任务描述符Z为条件的神经网络,根据该任务描述符对输入进行预测。
我们讨论了如何通过不同方式对Z进行条件化,来影响参数共享的程度。
如果你观察到负迁移,可能需要考虑减少信息共享,并设计相应的架构和条件化方式。
反之,如果观察到过拟合,你可能需要尝试增加参数共享。
最后,我们讨论了多任务学习的目标函数,以及如果对标签进行归一化,那么直接相加损失并优化是一个很好的选择,但你也可能希望通过调整任务权重来影响任务的优先级。
以上是对上节课的简要回顾。
本节课计划 📋
今天的计划是,我们先讨论迁移学习及其问题定义。
然后,我们将开始讨论元学习的问题定义,以及我们如何理解元学习的本质。
这部分内容将涉及作业一的开始,周三的讲座将涵盖完成作业一所需的其他内容。
今天的学习目标包括:
- 思考如何将知识从一个任务迁移到另一个任务。
- 理解多个任务具有某种“共享结构”意味着什么(这是我们上周一直在讨论的一个有些模糊的概念)。
- 理解什么是元学习。
迁移学习 🚚
在之前的讲座中,我们讨论了如何同时解决多个任务。
而在迁移学习中,情况有所不同。
在迁移学习中,我们的目标通常是在解决了一个或多个源任务之后,去解决一个特定的目标任务。
我们的目标是,在尝试解决目标任务B时,能够迁移一些在任务A中学到的知识。
这里一个常见的假设是,在尝试解决任务B时,通常无法访问任务A的数据。
因此,你基本上希望将关于任务A的所有信息或知识压缩到一些参数中,然后在处理任务B时使用这些压缩的知识。
需要指出的是,迁移学习可以被视为多任务学习的一种有效解决方案。
因为如果你想学习两个任务,可以先学习任务一,然后将其迁移以更有效地学习任务二,这样你就得到了任务一和任务二的解决方案。
然而,由于上述常见假设(无法在迁移过程中访问源任务数据),多任务学习通常不被认为是迁移学习的有效解决方案,因为你无法同时访问两个任务的数据集。
迁移学习的适用场景 💡
现在我已经介绍了这两种问题定义,我想知道你们对于在哪些场景下迁移学习可能比多任务学习更有意义有什么想法。
以下是一些适用场景:
- 源任务数据量巨大:你不想在解决任务B时保留这些数据并重新训练,而是希望将知识压缩并迁移。
- 目标任务数据稀缺:迁移学习在这种情况下很有用。
- 任务间共享结构多:这也是使用迁移学习的好场景。
- 已有预训练模型可用:如果你已经学习了任务A,或者可以直接从网上下载别人训练好的模型权重,那么你甚至不需要自己解决任务A,可以直接使用这些权重来解决任务B。
- 任务未知或需快速适应:你可能处于一个不知道所有任务的前期场景,或者需要快速适应新任务(例如在手机上针对特定用户进行适配)。
这些都是非常好的例子。
微调:迁移学习的核心方法 ⚙️
我们将讨论微调,这基本上是迁移学习的首选方法。
微调的工作原理是,我们取在任务A上训练好的权重(用θ表示),用这些权重初始化一个神经网络,然后在目标任务上以这些权重为起点运行梯度下降。
如果 D_train 是新任务的训练数据,那么你将计算梯度,并在初始化的θ处应用该梯度。图中只展示了一步梯度下降,但在实践中通常会进行多步。

这个过程的结果是,你将得到一组参数φ,希望这些参数在任务B上的表现比随机初始化θ要好得多。
实际上,如果比较随机初始化参数与使用对目标任务有效的数据集进行预初始化的参数,我们可以看到性能要好得多。
例如,有一个实验显示,在ImageNet上预训练的神经网络,相比于随机初始化,在Pascal和SUN这两个图像识别数据集上,性能有显著提升(大约16%到17%)。
这非常酷,本质上,它利用了ImageNet数据集中存在的丰富信息,在迁移到这些新任务时发挥了作用。

微调的设计选择与常见实践 🛠️
现在我们来谈谈微调中的各种设计选择。
很多这些设计选择都围绕着如何不破坏模型中已有的先验知识,并平衡先验知识与新数据集的知识。
一个常见情况是:你有一个在ImageNet上预训练的网络,输出层是1000维(对应1000个类别)。而你的目标任务可能只有两个标签(例如白板笔和白板擦)。
在这种情况下,你需要重新初始化最后一层,因为无法直接使用原来的输出层。你可以选择只使用其中两个类别的输出,或者在这些特征之上重新初始化一个新的网络层。
这里出现的问题是:如果你反向传播梯度通过整个网络,而新初始化的权重矩阵是随机的,那么你基本上是在用一些随机数乘以梯度,然后将这些梯度应用到网络的其余部分。这可能会破坏前面层中非常有价值的信息。
因此,有一些常见的做法:
- 使用较小的学习率:尤其是对于网络的早期层,因为你不想让来自网络的梯度破坏这些特征。
- 冻结早期层:只训练网络后面的部分。
- 从后往前逐步解冻:先只训练最后几层,然后逐渐解冻并训练更前面的层。
- 重新初始化最后一层:正如我们讨论过的。
如何在这些设计选择中做出决定?通常可以在目标任务上运行交叉验证来搜索这些设计选择和超参数。
另外值得一提的是,你选择的微调架构也会影响迁移性能。例如,具有残差连接的残差网络通常对微调更有效,因为它们在整个网络中提供了一种“高速公路”,使得梯度更容易传播到所有层。
打破常规认知的新研究 🔬

尽管有上述常见实践,但关于微调的知识并非一成不变。我想介绍两篇新论文(以机器学习标准来看,上周发表的论文也算“新”),它们打破了一些常规认知。

第一篇论文发现,对于无监督预训练方法,你并不一定需要一个非常多样化的数据集。
实验表明,在目标任务数据本身上进行无监督预训练,得到的性能与在大型多样化语料库上预训练的性能非常接近。
这打破了常规认知,因为常规认为我们需要非常多样化的预训练数据集。
需要注意的是,这预计只适用于无监督预训练的情况,对于有监督预训练则不然。
第二篇论文(由本课程的助教Yunho等人合著)探讨了是否只有最后一层对微调特别重要。
他们发现,在某些情况下(例如处理低层图像损坏时),微调网络的第一层比微调整个网络或仅微调最后一层效果更好。
甚至在某些情况下,微调中间层是最佳选择。
这表明我们并未完全理解微调,并且最佳策略可能因源任务和目标任务之间的差异类型而异。
尽管存在这些新发现,在实践中,如果你想使用微调,一个可靠且通常有效的默认策略是:先训练网络的最后一层(或最后几层),然后再微调整个网络。
这样做的原因正是为了避免破坏早期的特征。
数据量对微调性能的影响 📊
最后,我们看看微调性能如何随目标任务数据量的变化而变化。
随着目标任务数据量的增加,验证错误率会降低,这符合预期。
蓝线表示从头开始训练,绿线和橙线表示不同的预训练模型。
需要注意的是,如果只有100个目标任务数据点,性能远不如有更多数据时好。
当数据量非常少(例如只有100个示例)时,性能会变得很差。
而这正是元学习可以派上用场的地方。
从迁移学习到元学习 🧠
在迁移学习中,我们讨论了如何初始化模型,并希望这种初始化对目标任务有帮助。
元学习背后的关键直觉是:与其希望它有帮助,不如我们显式地优化可迁移性。
这意味着,如果我们不仅有一个源任务,而是有一组源任务,我们能否优化快速学习这些任务的能力,从而也能快速学习新任务?
你可以这样想:如果我们已经学会了如何快速学习一组任务,那么我们应该也能快速学习新任务。
从机制化的角度看,你可以想象一个深度神经网络,它以数据集为输入,并对新数据点进行预测。你希望使用这种形式的元数据集来优化这个深度神经网络,这样当你给它一个新任务的数据集时,它就能给出该任务的参数。
从概率角度看,如果我们有一组源任务,我们可以尝试从中提取共享的知识或结构,以一种能让我们高效学习新任务的方式。然后,当我们遇到新任务时,就利用这些先验知识来推断目标任务的参数。
元学习的概率图模型视角 📈
为了理解任务共享结构意味着什么,让我们从概率图模型(贝叶斯网络)的视角来看元学习。
首先,我们为单任务学习建立一个图模型。
我们有参数φ、输入x和标签y。y依赖于x和φ,因此有箭头从φ和x指向y。
如果我们有多个数据点,可以使用“板表示法”,用一个板(plate)圈住这些变量,并标注索引i,表示板内的结构对每个数据点i进行复制。
对于多任务学习(或元学习),我们会有多个任务。
我们用索引j表示任务,并添加一个外层的板。φ_j是任务j的参数。
这些参数共享某种结构,具体表现为它们都依赖于一个共享的潜在变量θ。
θ代表了任务间的共享信息,它是未被观察到的(潜在的)。
如果任务间没有依赖关系(即没有θ),那么它们就不共享任何结构。
如果存在对共享结构θ的依赖,那么它们确实共享一些信息。
关键点:如果我们以θ为条件,那么任务特定的参数φ_i之间就变得独立了。这意味着,一旦我们掌握了关于θ的信息,就能降低对φ_i的不确定性(熵)。
因此,如果我们能识别出关于θ的信息,并且这种依赖关系存在,那么学习φ_i应该会更快,因为我们需要从数据中揭示的信息量更少了。
极端情况是,如果给定θ时φ的熵为零,那么我们就完全知道了φ,甚至不需要任何额外数据就能解决任务。
思考练习:
- 正弦曲线任务族:每个任务是不同振幅和相位的正弦曲线。那么θ对应的是正弦曲线函数族本身(除了具体的振幅和相位)。
- 机器翻译任务族:每个任务是在两种语言之间进行翻译。那么θ可能对应的是所有语言共享的语法结构、词性等抽象概念,而不是特定语言的词汇或语序。
在实践中,θ可以对应许多不同的东西。选择符号θ的部分原因是,它可以表示微调的初始化参数,你可以将其视为先验知识或共享结构的体现。
元学习的机制化视角与问题定义 🎯
现在让我们转向元学习的机制化视角。
假设我们的目标是图像分类,并且有一个只有5个示例的极小数据集。
我们的目标是利用这个训练数据对新示例进行分类。
如果我们想从头开始解决这个任务,效果不会好。因此,我们希望利用其他任务的信息。
具体来说,我们可以从其他图像类别中获取数据,并将其构建成多个任务,每个任务都有自己的训练集和测试集。
例如,一个任务可能是分类鸟类、钢琴、蘑菇和另一种狗。
另一个任务可能是分类风景、体操运动员和旋转木马。
我们可以构建许多这样的任务,使用一组训练图像类别。
我们希望以某种方式构建它们,使我们能够学会如何快速学习每个任务,这样当我们看到新图像类别的示例时,也能学会该任务的分类器。
你可以将顶部的过程视为元训练过程,我们在此学习如何学习这些任务。
底部的过程视为元测试过程,我们在此尝试学习一个新任务。
这个例子是图像分类,但你可以用任何其他类型的机器学习任务来替换。
更正式地说,元学习的目标是:给定一组任务的数据,尝试更快、更熟练或更稳定地解决一个新的测试任务。
在本课程中,我们看到的许多用例都是为了尝试用更少的示例更快地学习,但原则上,这些思想也可以用于优化学习过程的其他方面,如性能或稳定性。

这里一个非常关键的假设是:我们有一组训练任务,并且我们假设测试任务与训练任务来自相同的分布。
具体来说,存在一个更广泛的任务分布。我们需要假设训练任务和测试任务都从这个分布中抽取,这样当我们有足够多的训练任务样本时,我们自然可以期望能够泛化并学习该分布中的一个新测试任务。
这类似于机器学习中的标准假设,即我们假设训练集和测试集来自相同的数据分布。
和之前一样,我们可能希望这些任务共享结构。如果任务分布是完全随机的,那么我们就不期望能够学习新任务。

总结 📝
本节课中,我们一起学习了迁移学习与元学习的基础知识。
在迁移学习部分,我们了解到其目标是在解决源任务后解决目标任务,核心方法是微调。我们探讨了微调的各种设计选择(如学习率调整、层冻结策略)以及如何平衡先验知识与新数据。研究显示,关于微调的最佳实践仍在发展中,但先训练最后几层再微调整个网络是一个可靠的起点。
在元学习部分,我们刚刚入门。我们从概率图模型的视角理解了任务间“共享结构”的概念,它体现为一个共享的潜在变量θ,能降低学习新任务参数的不确定性。从机制化视角,元学习的目标是利用一组训练任务,优化快速学习新测试任务的能力,其关键假设是训练任务与测试任务来自同一分布。

下节课我们将深入探讨元学习的核心方法。
4:黑盒元学习 🧠


在本节课中,我们将学习元学习的基础问题设定,并深入探讨一种核心方法——黑盒元学习。我们将了解如何设计一个能够“学会学习”的神经网络,使其仅用少量数据就能快速适应新任务。
课程回顾:元学习问题设定
上一讲我们介绍了元学习的核心思想。我们的目标是:给定一组来自某些任务的数据,我们希望模型能够利用这些经验,在面对新任务时,用更少的数据达到更高的准确率或效率。
一个关键假设是,所有任务(包括训练任务和测试任务)都来自同一个任务分布。这类似于传统机器学习中的独立同分布假设,是保证算法能够泛化的基础。
任务可以对应多种形式:
- 在作业一中,任务对应识别不同语言的手写数字。
- 其他例子包括:针对不同学生的作业提供反馈、对世界不同区域的物种进行分类,或让机器人执行不同的操作。
一个自然的问题是:我们需要多少任务才能快速学习新任务?虽然没有确切的答案,但通常任务越多越好。在元学习中,我们将任务视为数据点,更多的任务意味着更多的“元训练”数据。


元学习的两种视角
周一我们讨论了元学习的两种视角:
- 机制视角:将元学习视为训练一个神经网络,该网络能够读取输入数据集并给出对新数据点的预测。你可以将其看作是在实现一个学习过程。
- 概率视角:思考如何从训练任务中提取先验知识,并在测试时施加该先验,以便用更少的数据进行学习。
在接下来的几讲中,我们将主要关注机制视角,因为它更便于思考如何实际实现这些算法。
小样本学习与术语
我们来看一个小样本分类的例子。目标是在给定极少量训练数据(例如,每类仅一个样本)的情况下,对新的测试样本进行分类。

在这个框架下,我们引入一些标准术语:
- 支持集:对应一个任务中的训练数据集,为学习过程提供“支持”。
- 查询集:对应一个任务中的测试数据集,用于在基于支持集学习后“查询”模型的预测。
- N-way K-shot 学习:
N:分类任务中的类别数(例如,5-way 表示在5个类别间分类)。K:每个类别提供的样本数(例如,1-shot 表示每类只有一个样本)。
对于上图的例子,这是一个 5-way 1-shot 分类问题。
将元学习视为监督学习
我们可以将元学习重新表述为一个监督学习问题。
在标准监督学习中,我们学习一个函数 f: X -> Y,将输入映射到输出。
在元学习中,我们的输入变得不同:
- 输入:一个任务的支持集
D_train和一个新的测试输入x_test。 - 输出:测试输入
x_test的预测标签y_test。
因此,元学习函数 F 的形式是:y_test = F(D_train, x_test)。这个函数 F 封装了“从数据集中学习并预测新样本”的整个过程。
如何学习这个函数 F?我们使用一个数据集的集合进行训练。每个数据集对应一个任务,并且包含足够多的样本,以便我们能从中采样出支持集和查询集。
黑盒元学习方法 🎯
现在,我们进入核心:如何设计和优化函数 F。黑盒元学习将 F 直接表示为一个神经网络(如循环神经网络RNN)。我们以 Omniglot 数据集(包含50种手写文字,共1623个字符,每个字符仅20个样本)为例,说明其工作流程。
版本一:输出网络参数(超网络)
以下是元训练过程的关键步骤:
- 采样任务:从训练任务中采样一个任务(例如,一种字母表),并采样N个字符作为分类类别。
- 构建支持集与查询集:为每个字符采样多个图像,并随机划分为支持集(用于训练)和查询集(用于评估)。关键:需要随机分配样本标签(如0,1,2),以防止网络简单地记忆映射。
- 前向传播(学习):
- 将支持集
(x, y)序列输入一个RNN。 - RNN输出一组参数
φ_i(即“学会”的参数)。 - 使用另一个网络(参数由
φ_i定义)对查询集样本x_test进行预测,得到y_hat。
- 将支持集
- 计算损失与反向传播:
- 计算预测
y_hat与真实标签y_test之间的损失(如交叉熵)。 - 关键:通过整个计算图(从损失,经过预测网络,回到RNN输出的参数
φ_i,再回到RNN的权重)进行反向传播。 - 更新的是RNN的权重
θ(即元参数),而不更新任务特定参数φ_i。φ_i被视为RNN的激活值,在每次前向传播时被重新计算。
- 计算预测
- 循环:重复步骤1-4,采样不同任务进行训练。
元测试过程则简单得多:给定一个新任务的支持集,我们将其输入训练好的RNN,并传入测试样本,RNN会通过前向传播直接输出预测结果。此过程没有参数更新。
缺点:直接输出整个预测网络的参数 φ_i 可能维度极高,计算效率低。
版本二:输出上下文向量(更实用)
一个更实用的变体是让RNN输出一个低维的上下文向量(隐藏状态)h_i,而不是全部参数。
- 前向传播:支持集序列输入RNN,最终隐藏状态
h_i编码了任务信息。 - 预测:将测试样本
x_test和上下文向量h_i一起输入一个共享的预测网络g(其参数θ_g也是元参数的一部分)来得到预测。 - 训练:同样通过查询集损失反向传播,更新RNN的参数和共享预测网络
g的参数θ_g。
这个版本更高效,且上下文向量 h_i 可以直观地理解为从数据中推断出的任务描述符。
架构选择 🏗️
选择合适的架构来实现函数 F 很重要:
- 循环神经网络:早期常用,能处理变长序列,但顺序敏感性不符合数据集的无序性。
- Deep Sets 架构:
- 将每个样本独立通过一个前馈网络得到嵌入。
- 然后对嵌入进行聚合(如求和、平均),得到一个与输入顺序无关的集合表示。
- 理论证明,这类架构可以表示任何置换不变函数,表达能力很强。
- Transformer:利用自注意力机制,能更好地建模样本间的关系,是现代更流行的选择。
- 外部记忆机制(如神经图灵机):概念有趣,但实践中未必比上述方法更优。
在Omniglot等数据集上,这些方法能在少样本设置下取得很高准确率(如5-way 1-shot >99%),但在更复杂的图像数据集(如MiniImageNet)上,性能仍有提升空间。
与大语言模型的联系 🤖
像GPT-3这样的大语言模型可以被视为一种黑盒元学习者,其少样本学习能力是涌现出来的。
- 工作原理:将各种任务(翻译、问答、数学等)都格式化为文本。模型的“支持集”是输入提示(包含任务描述和少量示例),“查询集”是模型需要补全或回答的文本。
- 训练:在大量互联网文本数据上,通过标准语言建模目标(预测下一个词)进行训练。
- 上下文学习:在推理时,通过提供不同的提示(少样本示例),模型能适应不同任务,这类似于元测试过程。
研究表明,这种涌现的少样本学习能力需要:
- 数据特性:时间上的相关性(突发性主题)和词语的动态含义。
- 模型特性:足够的模型容量(参数量)。Transformer架构通常比RNN更好,且模型越大,少样本性能往往越强。
总结与作业 📝
本节课我们一起学习了黑盒元学习的核心思想:
- 我们将元学习框架化为一个可学习的函数
F,它接收支持集和查询输入,输出查询预测。 - 通过使用神经网络(如RNN、Transformer)来实现
F,并利用元训练任务的数据对其进行端到端的优化。 - 我们探讨了两种实现方式:输出完整参数(超网络)和输出上下文向量,后者更常用。
- 我们还看到了黑盒元学习思想与大语言模型涌现的上下文学习能力之间的联系。
优点:表达能力强,可应用于多种问题(监督学习、强化学习)。
缺点:优化可能较困难,数据效率可能低于融入更多归纳偏置的元学习方法(我们将在下节课讨论)。

在作业一中,你将亲自在Omniglot数据集上实现数据预处理和一个黑盒元学习器,并观察其少样本学习性能。
5:基于优化的元学习 🧠


在本节课中,我们将要学习基于优化的元学习方法。我们将回顾元学习的基本问题设置,并深入探讨如何将一个优化过程嵌入到另一个优化过程中,这种方法被称为基于优化的元学习。我们将学习其核心算法、数学原理、实现细节,并将其与之前讨论的黑盒元学习方法进行比较。
课程回顾与引言
上一讲我们介绍了元学习的问题框架和黑盒元学习方法。本节中,我们来看看另一种强大的元学习范式——基于优化的元学习。
元学习的目标是:给定一组训练任务,我们希望学习一种方法,使其在面对新任务时,能够利用少量样本(小样本)快速且高效地学习。我们之前使用了一个五分类的小样本学习作为运行示例。
在黑盒方法中,我们使用一个大型神经网络(如循环神经网络)来接收训练数据,并直接输出针对该任务的模型参数。这种方法虽然表达能力强,但优化起来可能具有挑战性。
基于优化的元学习核心思想
本节中,我们将探讨如何利用我们对机器学习已有的知识,来构建这个从训练数据到任务参数的函数。核心思想是:将这个函数 F 本身视为一个优化过程,特别是基于梯度的优化过程。
具体来说,我们将用梯度下降优化过程来替代之前图中的RNN。关键想法是:我们将梯度下降这个“内循环”优化过程,嵌入到一个更广泛的“外循环”元学习过程中。
那么,元参数是什么?在本方法中,我们主要优化的是神经网络的初始参数。目标是找到一组初始参数 θ,使得在每个任务上,仅用少量样本运行几步梯度下降后,就能得到在该任务上表现良好的任务特定参数 φ_i。
为什么这行得通?回想一下我们之前讨论的微调。使用预训练参数初始化的微调,通常比从头开始学习效果更好。基于优化的元学习可以看作是在优化一组预训练参数,使其在小样本场景下也能表现优异,而不仅仅是传统的监督预训练。
算法目标与形式化
让我们形式化这个目标。在测试时,我们希望对一个新任务的小训练集进行微调。为简化,我们先考虑内循环只进行一次梯度下降步的情况。
对于任务 i,其任务特定参数 φ_i 通过以下方式获得:
φ_i = θ - α * ∇_θ L(θ, D_i_train)
其中:
θ是元参数(初始参数)。α是内循环学习率。L是损失函数。D_i_train是任务i的支持集(训练集)。
然后,我们在该任务的查询集(测试集)D_i_test 上评估 φ_i 的性能。元学习的目标是优化 θ,使得所有任务上这个“一步微调”后的参数在新样本上泛化能力都好。
元目标函数可以写为:
min_θ Σ_i L( φ_i, D_i_test ) = Σ_i L( θ - α * ∇_θ L(θ, D_i_train), D_i_test )
当然,内循环可以包含多个梯度步,公式会变长,但概念是相同的。
算法步骤详解
以下是基于优化的元学习(以MAML算法为例)的具体步骤,我们以三类别单样本分类问题为例说明:
- 采样任务:从任务分布中采样一个任务
T_i(例如,对应三个不同的字符分类)。 - 采样数据:为该任务采样支持集
D_train和查询集D_test(例如,每个字符一张图)。 - 内循环适应:从当前元参数
θ开始,在支持集D_train上执行一步(或多步)梯度下降,得到任务特定参数φ_i。
φ_i = θ - α * ∇_θ L(θ, D_train) - 外循环元更新:使用参数
φ_i在查询集D_test上计算损失。然后,通过反向传播,计算该损失对元参数θ的梯度,并更新θ。
θ = θ - β * ∇_θ Σ_i L(φ_i, D_test)
其中β是外循环学习率。 - 重复步骤1-4。
注意:在步骤3的内循环中,我们只将图像输入网络,标签用于计算损失梯度。这与黑盒方法中将图像和标签拼接后输入网络有所不同。
在元测试时,过程很简单:给定新任务及其支持集,我们直接从学习到的元参数 θ 开始,运行与内循环相同次数的梯度下降步进行微调,得到最终模型用于预测。
由于该算法不依赖于特定的模型架构,只要模型能用梯度下降优化即可,因此被称为 “模型无关的元学习”。
数学推导:元梯度与二阶导数
现在我们来深入看看元梯度计算中的数学细节。计算外循环损失 L(φ_i, D_test) 对 θ 的梯度时,我们需要用到链式法则,这会引入二阶导数。
∇_θ L(φ_i, D_test) = (∇_{φ_i} L(φ_i, D_test)) * (dφ_i / dθ)
其中 dφ_i / dθ = I - α * ∇_θ^2 L(θ, D_train)。这里出现了海森矩阵 H = ∇_θ^2 L,即二阶导数。
直接计算和存储海森矩阵(规模为参数数量的平方)在深度学习中是极其昂贵的。幸运的是,我们只需要计算海森向量积,这可以通过以下方式高效近似计算:
H * v ≈ (∇_θ L(θ + r*v, D_train) - ∇_θ L(θ, D_train)) / r
其中 r 是一个小标量,v 是向量 ∇_{φ_i} L。
实际上,像PyTorch这样的框架可以精确且高效地计算海森向量积,而无需显式构造海森矩阵。这意味着计算元梯度只需要几次额外的反向传播,复杂度可控。
如果内循环有 K 步,则需要计算 K 次这类梯度,会涉及海森矩阵的连乘,但不会出现三阶或更高阶导数。内存和计算开销会随内循环步数线性增长。
与黑盒方法的比较
上一节我们介绍了基于优化方法的数学基础,本节我们来对比一下基于优化和黑盒这两种元学习思路。
从概念上看,两者可以统一为一个框架:一个以前馈方式处理支持集和查询输入,并输出预测的计算图。
- 在黑盒方法中,这个计算图是一个大型神经网络(如RNN)。
- 在基于优化的方法中,这个计算图内部显式地包含了梯度下降步骤。
这种视角表明,我们可以混合搭配计算图的组件,例如学习初始化参数的同时,用一个学习到的网络来“扭曲”梯度更新方向(尽管实践中直接使用梯度通常更简单有效)。
实践性能对比:
研究表明,基于优化的方法(如MAML)在分布外泛化上通常优于黑盒方法(如SNAIL、Meta Networks)。例如,在字符被扭曲或缩放的Omniglot任务上,MAML的性能下降更缓慢。这是因为基于优化的方法在测试时本质上就是微调,即使任务稍有变化,微调过程本身也具有合理的归纳偏置。
表达能力:
理论上,只要神经网络足够深,单步梯度下降的MAML函数可以近似任意从训练数据到预测的函数。黑盒方法可能用更小的网络就能获得高表达能力。
挑战、技巧与案例研究
基于优化的元学习并非没有挑战。下面我们来看看主要的挑战和一些实用的解决方案。
挑战一:双层优化的不稳定性
内循环和外循环都是优化过程,可能训练不稳定。
- 解决方案:除了学习初始参数
θ,也学习内循环的学习率α(甚至每层不同),这通常能使外循环优化更稳定。也可以引入上下文变量来增加元优化器的表达能力。
挑战二:长内循环的计算与内存开销
内循环步数多时,反向传播的计算和内存成本高。
- 解决方案:
- 一阶近似:在元梯度计算中忽略二阶项(即假设
dφ_i / dθ ≈ I)。这在许多简单问题上效果出奇地好,但并非总是有效。 - 仅优化最后一层:内循环只调整分类头(最后一层)的权重。这大大降低了计算量,并且在特征学习很重要的任务(如图像分类)上效果很好。
- 隐函数定理:更高级的数学工具,允许不通过展开优化路径来求元梯度。
- 一阶近似:在元梯度计算中忽略二阶项(即假设
案例研究:土地覆盖分类
这是一个现实世界的应用。目标是对卫星图像进行土地分类(如森林、农田)。标注成本高,且不同地区地貌差异大。
- 元学习设置:将每个地理区域视为一个任务。元训练使用多个有标签的区域。
- 目标:对于一个新区域,仅需标注少量样本,就能快速获得一个准确的分类模型。
- 结果:与随机初始化和传统预训练+微调相比,MAML能在给定少量目标区域样本时,取得更高的分类准确率,展示了其在小样本迁移上的优势。
总结与下节预告
本节课中我们一起学习了基于优化的元学习方法。我们了解了其核心思想是通过双层优化来学习一组良好的模型初始参数,使得在小样本任务上能通过几步梯度下降快速适应。我们推导了其算法步骤和元梯度计算,分析了它与黑盒方法的优劣,并探讨了实际应用中的挑战与解决方案。
优点:具有合理的归纳偏置(测试时就是微调),分布外泛化能力强,模型无关,理论表达能力强。
缺点:通常需要二阶优化,计算和内存开销相对较大。

下节课我们将讨论最后一类元学习方法:非参数小样本学习。下周我们将进入无监督预训练主题,再下周则会探讨更高级的元学习话题。
6:非参数小样本学习 🎯


在本节课中,我们将要学习元学习的第三类主要方法:非参数小样本学习。我们将探讨如何通过学习一个有效的嵌入空间,然后在该空间中使用简单的最近邻方法进行预测,从而构建高效的小样本分类器。我们还会通过一个教育领域的实际案例,了解这类方法如何被部署应用。最后,我们将对比之前学过的三类元学习方法,并讨论它们各自的优缺点。
课程回顾与引入
上一节我们介绍了基于优化的元学习方法,它通过将梯度下降的结构嵌入到内循环学习过程中,提供了良好的归纳偏置。然而,这类方法通常需要进行二阶优化,计算开销较大。
本节中,我们将探讨一种新的思路:将非参数学习过程嵌入到元学习的内循环中。具体来说,我们将关注像最近邻这样的算法。你可能会想,最近邻算法并不强大,为什么我们要用它?原因在于,在小样本场景下,我们恰好处于低数据状态。此时,非参数的机器学习方法(如最近邻)计算效率高且非常简单。然而,在元训练阶段,我们通常拥有大量任务,我们希望从数据中学习到好的表示,因此元训练过程本身仍然是参数化的。
所以,今天这类方法的核心思想是:使用参数化的元学习器,来产生有效的非参数学习器。
核心思想:学习如何比较样本
假设我们想解决经典的小样本图像分类问题。如果我们想使用最近邻方法,我们会将测试数据点与训练集中的每个样本进行比较,然后输出最相似训练样本的标签。这很简单。
但关键问题是:我们如何进行比较?在什么空间中进行比较?使用什么距离度量?
一个直观的想法是在原始像素空间中使用L2距离。但事实证明,对于图像等数据,L2距离效果很差。例如,一张猫的图片在L2距离上可能更接近一张纹理相似的沙发图片,而不是另一张猫的图片,这与我们的感知不符。
那么,我们应该使用什么距离度量呢?一个核心思路是:我们可以利用元训练数据来学习如何比较样本。距离函数的选择将是参数化的(即需要学习),但一旦我们有了这个距离函数或嵌入空间,后续的最近邻比较过程就是完全非参数的。
方法一:孪生网络
以下是实现上述思想的第一种具体方法。
孪生网络是一种简单的神经网络架构。它有两个输入,这两个输入通过参数完全相同的两个神经网络进行处理,因此得名“孪生”。
- 训练过程:我们将两张图像输入网络,网络会比较这两张图像的表征,并输出一个值,表示这两张图像是否属于同一类别。这是一个简单的二分类问题(相同类别标签为1,不同类别标签为0)。我们可以利用所有可用的元训练数据来训练这个网络。
- 测试过程:训练完成后,这个孪生网络就成为了我们的相似性度量或距离函数。对于一个新的测试图像,我们将其与支持集中的每个样本配对输入网络,计算它们属于同一类别的概率,然后选择概率最高的支持集样本的标签作为预测结果。
优点:概念简单,易于实现。
缺点:元训练(二分类)和元测试(N分类)的目标存在不匹配。此外,对于单样本学习,如果支持集中每个类别只有一个样本,这种方法本质上就是在比较测试样本与单个样本,可能不够鲁棒。
方法二:匹配网络
为了克服孪生网络中训练与测试目标不匹配的问题,匹配网络被提出。它的核心思想是让元训练过程直接模拟元测试时的行为。
在元测试时,匹配网络的行为可以近似表示为:对于测试样本 $ x_{test} $,其预测标签 $ \hat{y}_{test} $ 由支持集中所有样本“投票”决定,每个样本的投票权重是其与测试样本的相似度。
$$
\hat{y}{test} = \sum a(\hat{x}_{test}, x_k) \cdot y_k
$$
其中,$ a $ 是一个可学习的注意力函数(相似度函数),通常由神经网络实现。这样,整个预测过程(包括嵌入和相似度比较)是端到端可微的。
算法流程与之前的元学习框架类似:
- 采样一个任务。
- 采样支持集和查询集。
- 直接使用上述公式为查询集样本生成预测,无需显式计算任务参数。
- 计算预测损失(如交叉熵),并更新元参数 $ \theta $。
匹配网络通常使用双向LSTM(或现代的双向Transformer)来编码支持集样本,这使得每个样本的编码能考虑到支持集中其他样本的信息,从而获得更好的上下文感知表征。
方法三:原型网络
当每个类别有多个样本时,匹配网络中每个样本独立“投票”的方式可能存在缺陷。例如,一个错误标签的样本如果与测试样本非常相似,可能会压倒其他正确样本的投票。
原型网络通过聚合类别信息来解决这个问题。它为每个类别计算一个原型(通常是该类所有样本嵌入的均值),然后在元测试时,比较测试样本与各个类别原型的距离,而非与每个独立样本的距离。
原型计算:
对于类别 $ n $,其原型 $ c_n $ 为:
$$
c_n = \frac{1}{|S_n|} \sum_{(x_i, y_i) \in S_n} f_\theta(x_i)
$$
其中 $ S_n $ 是属于类别 $ n $ 的支持集样本,$ f_\theta $ 是嵌入函数。
预测:
测试样本 $ x $ 属于类别 $ n $ 的概率通过 softmax 函数基于负距离计算:
$$
p(y = n | x) = \frac{\exp(-d(f_\theta(x), c_n))}{\sum_{n'} \exp(-d(f_\theta(x), c_{n'}))}
$$
其中 $ d $ 可以是欧氏距离或余弦距离等。
优点:
- 更鲁棒:通过平均,减少了异常样本的影响。
- 计算高效:只需要计算测试样本到每个类别原型的距离,计算量与类别数成正比,而非样本总数。
- 端到端训练:整个系统(嵌入函数 $ f_\theta $)可以通过元训练目标进行优化。
变体与扩展:
- 关系网络:不直接使用固定距离公式,而是学习一个关系模块来输出相似度分数。
- 混合原型:对于难以用单个原型表示的复杂类别(如猫的多个品种),可以为每个类别学习多个原型。
实际案例研究:教育领域的代码反馈系统
现在,我们来看一个原型网络在实际中的应用案例:为大规模在线编程课程的学生代码提供自动反馈。
问题:课程有超过12,000名学生,手动为每位学生的诊断性代码练习提供反馈需要超过8个月。我们需要一个能快速适应新题目和新评分标准的自动反馈系统。
元学习框架:
- 任务定义:每个题目的每个评分标准项(如“错误地插入了字符”)定义为一个独立的任务。
- 输入:学生的Python代码(文本序列)。
- 输出:预测该代码是否触发了当前评分标准项(二分类)。
- 目标:给定一个新题目和它的评分标准,仅需少量已标注的学生代码样本,就能快速对该题目的所有学生代码给出准确反馈。
使用原型网络:
我们使用基于Transformer的预训练模型(CodeBERT)作为嵌入函数 $ f_\theta $,将学生代码编码为向量。对于每个任务(评分项),我们使用支持集中的正例和负例代码分别计算原型,然后对查询代码进行分类。
提升性能的关键技巧:
- 任务增强:除了真实的评分任务,还构造了自监督任务(如预测代码的编译错误、掩码语言建模)来增加元训练数据。
- 融入辅助信息:将题目文本和评分项描述作为辅助信息,与代码一起输入编码器,让模型知道当前的任务是什么。
- 使用预训练模型:使用在大规模无监督代码数据上预训练的CodeBERT初始化编码器,提供更好的起点。
部署结果:
- 在离线测试中,该系统比监督学习方法准确率高8-17%,在某些情况下甚至超过了人类助教的评分准确率。
- 在真实课程中部署,为约15,000份学生代码提供了反馈。学生对该AI反馈的同意率和有用性评分与人类反馈相当,且未发现明显的性别或国籍偏见。


这个案例表明,非参数元学习方法(如原型网络)在计算效率、易于优化和实际效果方面,非常适合此类小样本分类问题。
三类元学习方法的比较
我们已经介绍了三类主要的元学习方法:黑盒元学习、基于优化的元学习以及非参数元学习。以下是它们的高层对比:
概念框架:
三者都可以纳入同一个计算图视角:输入支持集和查询样本,输出查询预测。区别在于内循环的实现方式:
- 黑盒:用一个神经网络直接映射。
- 基于优化:嵌入梯度下降过程。
- 非参数:嵌入最近邻或原型比较过程。
关键属性:
- 表达能力:模型能够表示的学习算法的范围。
- 黑盒方法:完全表达,但可能难以优化。
- 基于优化的方法:表达能力强(特别是使用深度模型时)。
- 非参数方法:表达能力强,取决于嵌入函数。
- 一致性:随着任务内数据增多,学习器的性能是否能单调提升(即表现得更像标准学习器)。
- 黑盒方法:不一致。
- 基于优化的方法:一致(退化为梯度下降)。
- 非参数方法:条件一致(如果嵌入函数没有过度压缩信息)。
优缺点总结:
- 黑盒元学习:
- 优点:可与各种学习问题结合,非常灵活。
- 缺点:优化困难,数据效率低。
- 基于优化的元学习:
- 优点:有良好的归纳偏置,能较好处理不同数量的支持样本。
- 缺点:涉及二阶优化,计算和内存开销大。
- 非参数元学习:
- 优点:完全前馈,计算速度快,易于优化。
- 缺点:难以推广到变化的支持集数量(K),难以扩展到非常大的K(计算复杂度O(NK)),且仅限于分类问题。
选择建议:
- 如果是监督分类问题,非参数方法(如原型网络)通常是首选,因为它们快速、简单且有效。
- 对于非分类问题(如回归、强化学习),应考虑另外两类。其中,基于优化的方法通常是更通用的选择。
- 黑盒方法在强化学习等没有良好内循环优化方法的领域,或者拥有海量数据(如GPT-3)的场景下可能更有优势。
值得注意的是,许多算法是这些类别的混合体,实际选择应基于具体问题、计算约束和数据情况。
其他应用示例
最后,我们快速浏览几个元学习在其他领域的创造性应用:
- 单样本模仿学习:任务对应操作不同物体。给定一段人类演示视频(单样本),机器人通过基于优化的元学习(如MAML,并学习内循环损失函数)快速学会执行该任务。
- 分子属性预测:任务对应预测不同分子的特性。使用基于优化的元学习(如MAML),配合图神经网络作为基模型,在小样本实验数据上预测分子活性,效果优于微调或最近邻方法。
- 小样本运动预测:任务对应不同行人或车辆轨迹。使用黑盒与优化混合的方法(学习内循环更新规则),根据过去几帧运动预测未来轨迹,效果优于多任务学习。
一个重要的启示是:内循环和外循环的数据不必相同。内循环训练数据可以有噪声标签、弱监督或来自不同领域(域偏移),只要外循环测试目标是定义良好的机器学习目标,元学习过程就能被驱动去学习适应这些挑战的学习程序。
总结
本节课中,我们一起学习了元学习的第三类方法——非参数小样本学习。我们深入探讨了其核心思想:学习一个嵌入空间,然后在该空间中使用简单的最近邻规则进行预测。我们介绍了三种具体方法:孪生网络、匹配网络和原型网络,并通过一个教育领域的代码反馈案例看到了原型网络的实际应用价值。最后,我们系统比较了黑盒、基于优化和非参数这三类元学习方法的核心属性、优缺点和适用场景,帮助大家根据实际问题做出合适的选择。

这是关于元学习核心算法的最后一讲。下一讲我们将探讨无监督预训练方法,以及它们与元学习之间的联系。
7:无监督预训练与对比学习 🧠


概述
在本节课中,我们将要学习一种强大的无监督表示学习方法——对比学习。我们将探讨其核心思想、实现方式、关键设计选择,并了解它如何与之前学过的元学习方法相联系。
从元学习到无监督预训练
上一节我们介绍了多种元学习方法,它们都假设我们能够访问大量带标签的训练任务。然而,在实际应用中,我们可能无法获得如此丰富的任务数据。
因此,本周我们将探讨另一种场景:我们只有一个大型无标签数据集。我们的目标是通过在这些无标签数据上进行预训练,得到一个模型,使得该模型在少量有标签数据上微调后,能在新任务上表现良好。
今天,我们将专注于实现这一目标的一类方法:对比学习。

对比学习的核心思想 🎯
对比学习的关键目标是学习一个从输入到向量表示的映射,使得语义相似的样本具有相似的表示,而语义不同的样本则具有不同的表示。
例如,我们希望两张“狗”的图片在表示空间中的距离,比一张“狗”的图片和一张“椅子”的图片之间的距离更近。
当然,如果我们有类别标签,可以直接利用标签来训练这种相似性。但在无监督设置下,我们需要其他方式来定义“相似性”。
以下是几种常见的定义“正样本对”的方式:
- 图像块:同一张图像中相邻的块可能来自同一物体,因此它们的表示应该相似。
- 数据增强:对一张图像进行裁剪、翻转等增强操作,生成的新图像应与原图有相似的表示。
- 时序邻近:在视频中,时间上邻近的帧很可能内容相关,因此它们的表示应该相似。
核心思想是:利用我们直觉上认为应该相似的样本,鼓励它们的表示接近,从而学习到一个有意义的表示空间,以便迁移到下游任务。
如何实现对比学习?
那么,如何在实践中实现上述直觉呢?

假设我们想训练模型,使上方的两张相似图像表示接近,下方的两张不同图像表示远离。一个朴素的想法是直接最小化相似样本表示之间的距离:
L_naive = ||f_θ(x) - f_θ(x^+)||²
但这里存在一个退化解:模型可能简单地将所有输入映射到同一个常数向量,这样损失直接变为0,但表示空间毫无意义。
因此,对比学习不仅要拉近相似样本,还要推开不相似样本。这就是“对比”一词的由来。
以下是实现对比学习时两个关键的设计选择:
- 损失函数的设计:如何量化“拉近”和“推开”。
- 正负样本的选择:如何定义哪些样本是相似的(正样本),哪些是不相似的(负样本)。
对比损失函数
首先,我们引入一些术语:
- 锚点:作为比较基准的样本。
- 正样本:与锚点相似的样本。
- 负样本:与锚点不相似的样本。
我们的目标是:拉近锚点与正样本的距离,拉远锚点与负样本的距离。
三元组损失
最简单的对比损失是三元组损失。它不仅最小化锚点与正样本的距离,还最大化锚点与负样本的距离:
L_triplet = ||f_θ(x) - f_θ(x^+)||² - ||f_θ(x) - f_θ(x^-)||²
直接优化这个损失可能导致模型将负样本无限推远。为了解决这个问题,我们引入间隔损失:
L_triplet = max(||f_θ(x) - f_θ(x^+)||² - ||f_θ(x) - f_θ(x^-)||² + α, 0)
其中,α 是一个超参数,称为间隔。只有当负样本与锚点的距离比正样本近至少 α 时,才会产生损失。这防止了无限制的推远。
多负样本的对比损失
三元组损失每次只对比一个负样本。在实践中,我们通常希望锚点能与多个负样本进行对比。这引出了另一种更常见的损失形式,它看起来像一个多分类的Softmax损失。
我们希望锚点 x 与正样本 x^+ 的相似度,远高于它与所有负样本 {x^-_i} 的相似度。用距离的负值作为“相似度得分”,我们可以这样计算锚点选择正样本的概率:
P(x^+ is positive | x) = exp(-d(z, z^+)) / [exp(-d(z, z^+)) + Σ_i exp(-d(z, z^-_i))]

其中,z = f_θ(x), z^+ = f_θ(x^+), z^-_i = f_θ(x^-_i),d(·,·) 是距离函数(如欧氏距离或负余弦相似度)。

我们的损失函数就是最小化这个概率的负对数似然:
L_contrastive = -log [ exp(-d(z, z^+)) / (exp(-d(z, z^+)) + Σ_i exp(-d(z, z^-_i)) ) ]
直观理解是:我们正在训练一个分类器,给定一个锚点,从一堆候选样本中正确识别出那个唯一的正样本。
SimCLR 算法实例 🖼️
让我们通过一个具体的算法——SimCLR,来理解对比学习如何运作。该算法的输入是一个大型无标签数据集 {x}。
以下是算法的步骤:
- 采样小批量:从数据集中采样
N个样本,构成一个小批量。 - 生成增强视图:对每个样本应用两次随机数据增强(如裁剪、翻转、颜色扰动),得到
2N个增强后的图像:{x̃_i}和{x̃‘_i}。 - 编码表示:使用编码网络
f_θ将所有增强图像映射到表示空间,得到{z_i}和{z‘_i}。 - 定义正负样本:
- 正样本对:来自同一原始图像的两个增强视图
(z_i, z‘_i)。 - 负样本:来自不同原始图像的任何其他增强视图。
- 正样本对:来自同一原始图像的两个增强视图
- 计算对比损失:对于每个正样本对
(z_i, z‘_i),将其视为锚点和正样本,将小批量中所有其他2(N-1)个表示视为负样本,代入上述多负样本对比损失进行计算。对所有正样本对取平均得到总损失。 - 优化:通过梯度下降优化编码网络参数
θ,以最小化总损失。
训练完成后,我们得到编码器 f_θ,它可以为任何输入图像生成有用的表示。我们可以冻结这个编码器,在其表示上训练一个简单的分类器,或者对整个网络进行微调,以适应特定的下游任务。
对比学习的性能与挑战 ⚡
对比学习(如SimCLR)在图像分类等任务上取得了显著成功。例如,在ImageNet数据集上,仅使用1%的标签进行微调,就能达到超过85%的top-5准确率,远超从零开始的监督训练。
然而,对比学习也面临一些挑战:
- 需要大批次训练:为了获得足够多的负样本以进行有效的对比,SimCLR等算法需要非常大的批次大小(如4096),这对计算资源要求很高。
- 原因:对比损失中的求和项在log函数内部。根据詹森不等式,用小批次估计会得到原始损失的一个下界,优化这个下界可能无法优化原始目标。大批次能提供更好的估计。
- 解决方案:有研究提出如MoCo等方法,通过动量编码器和队列机制存储历史负样本,从而能用较小的批次进行训练。
- 依赖数据增强:算法的效果很大程度上取决于定义正样本对的数据增强策略。对于图像以外的领域(如文本、传感器数据),设计有效的增强方式可能很困难。
- 解决方案:有研究工作尝试通过对抗学习的方式自动学习最优的数据增强策略。
对比学习的广泛应用 🌐
对比学习的思想非常通用,不仅限于图像增强:
- 时序对比学习:在视频中,将时间上邻近的帧作为正样本,时间上远离的帧作为负样本。这已被用于机器人技能学习等领域。
- 跨模态对比学习:例如,在CLIP模型中,将图像与其对应的文本描述作为正样本对,将不匹配的图像-文本对作为负样本。这学习到了一个强大的多模态表示空间,甚至能实现高质量的零样本分类。
对比学习与元学习的关系 🔗
你可能已经注意到,对比学习的损失函数与我们在非参数化元学习(如原型网络)中见过的损失函数非常相似。
实际上,我们可以将对比学习框架重新解释为一个元学习过程:
- 将每个原始图像及其增强视图视为一个“类别”。
- 从这个“类别”中采样两个增强视图作为支持集和查询集。
- 构建一个N-way分类任务,目标是在N个“类别”中识别出查询样本所属的类别。
在这种视角下,像SimCLR这样的对比学习算法,与使用原型网络在增强生成的任务上进行元训练,在数学形式和实际性能上都非常接近。主要区别在于批次内样本对比的细节和效率。
这揭示了无监督对比学习与少样本元学习之间深刻而紧密的联系。
总结
本节课我们一起学习了对比学习。我们了解了它的核心思想是学习一个表示空间,使得语义相似的样本靠近,语义不同的样本远离。我们探讨了两种主要的损失函数(三元组损失和多负样本对比损失),并通过SimCLR算法深入了解了其实现细节。我们还讨论了对比学习的性能、挑战(如大批次需求)以及其广泛的应用场景。最后,我们揭示了对比学习与之前学过的元学习方法之间有趣而紧密的联系。

下节课,我们将探讨另一类重要的无监督预训练方法:基于重构的方法。
8:用于小样本学习的无监督预训练 🧠


在本节课中,我们将要学习基于重构的无监督预训练方法。我们将从简单的自编码器开始,探讨其局限性,然后深入讲解更强大的掩码自编码器(如BERT)和自回归模型(如GPT)。我们还将了解如何高效地对这些大型预训练模型进行微调,以适应特定的下游任务。
课程回顾:无监督学习与对比学习
上一讲中,我们讨论了无监督学习的整体框架和对比学习方法。本节中,我们将重点转向另一类强大的无监督预训练方法:基于重构的方法。
无监督学习的基本流程如下:
- 我们拥有一个大型、多样化的未标记数据集。
- 首先进行无监督预训练(灰色箭头),得到一个预训练模型。
- 然后,通常使用一个较小的有标签数据集对模型进行微调,使其适应特定任务。
对比学习的基本思想是:相似的样本应该具有相似的表示。这可以通过构建正样本对(如来自同一类、同一图像的不同增强版本、视频中相邻帧)来实现。为了避免所有表示坍缩到同一个点,我们还需要负样本进行对比。一个经典的实现是三元组损失:
L = max(0, d(a, p) - d(a, n) + margin)
其中 a 是锚点样本,p 是正样本,n 是负样本。
更通用的形式是 N路分类损失(如InfoNCE损失),它将对比学习视为一个分类问题,即从一批样本中正确识别出正样本对。
基于重构的无监督目标
与对比学习不同,基于重构的方法不涉及在多个样本之间进行比较。其核心直觉是:一个好的数据表示,应该能让我们从该表示中重构出原始数据。
一个简单的流程是:
- 输入
x(如图像)通过一个编码器得到表示r。 - 表示
r通过一个解码器得到重构输出x_hat。 - 我们定义一个损失函数来衡量
x和x_hat的差异(如图像常用L2距离)。 - 端到端地训练编码器和解码器。
然而,这里存在一个明显的问题:如果表示 r 的维度与输入 x 相同,编码器和解码器可以简单地学习恒等映射(即 r = x, x_hat = r),这样损失为零,但学到的表示毫无意义。
为了解决这个问题,常见的做法是引入瓶颈。最直观的方式是让表示 r 的维度远低于输入 x 的维度。这样,编码器被迫将高维输入压缩到一个低维空间,理想情况下,这个低维空间会编码输入的高级、有意义的特征。
训练好这种“瓶颈自编码器”后,如何进行小样本学习呢?方法很简单:
- 丢弃解码器。
- 在编码器产生的表示
r之上,初始化一个新的预测头(如一个线性分类器或小型MLP)。 - 冻结编码器的参数,仅使用少量标注数据训练这个预测头。
这种方法的优点是简单、通用,且无需像对比学习那样精心设计正负样本对。但其主要缺点是:设计一个能迫使编码器学习到可泛化高级特征的瓶颈机制非常困难。很多时候,模型学到的表示更像是输入的“哈希值”,记住了重构所需的具体细节,而非易于适应新任务的概念性摘要。
为了鼓励编码器提取更高级的特征,除了维度瓶颈,我们还可以尝试其他类型的瓶颈,如添加噪声的信息瓶颈、限制非零维度的稀疏性瓶颈,或限制解码器能力的容量瓶颈。然而,目前实践中更常见的策略是:不再专注于设计复杂的瓶颈,而是直接让预训练任务变得更难。这就引出了我们下一节的主题。
掩码自编码器
掩码自编码器的核心思想是:通过让模型预测被随机掩盖的部分输入,来构建一个更具挑战性的预训练任务。这样,模型必须理解数据的整体结构和上下文,而不是简单地记忆或复制。
以下是训练掩码自编码器的一般流程:
- 对于一个训练样本
x,我们应用一个掩码函数,生成被掩盖的版本x_tilde和目标y(通常y就是被掩盖的部分)。 - 模型
f_theta以x_tilde为输入,预测被掩盖的部分y_hat。 - 计算损失
L(y, y_hat)。
与普通自编码器相比,我们多了一个可调节的“旋钮”:掩码策略。
以下是两个经典实例:
1. BERT(语言模型)
- 输入:文本序列(如两个句子)。
- 掩码策略:随机掩盖约15%的词元(token)。其中80%替换为特殊的
[MASK]标记,10%替换为随机词元,10%保持不变。这种混合策略有助于模型在微调时(没有[MASK]标记)也能产生良好的表示。 - 模型:Transformer 编码器。
- 损失:在被掩盖的位置上,计算模型预测分布与真实词元one-hot分布之间的交叉熵损失。
2. MAE(视觉模型)
- 输入:图像被分割成一系列图像块(patch)。
- 掩码策略:随机掩盖高达75%的图像块(仅将可见块输入编码器)。
- 模型:编码器处理可见块,解码器根据编码器输出和掩码位置占位符,重构被掩盖的块。
- 损失:在被掩盖块的位置计算像素级损失(如MSE)。
掩码自编码器非常强大,在图像分类等任务上,其性能甚至可以超过从零开始的监督学习。与对比学习相比,掩码模型在直接使用冻结表示时可能稍逊一筹,但在进行模型微调后往往表现更佳,这体现了“表示质量”与“可微调性”之间的一种权衡。
Transformer 架构简介
掩码自编码器的成功,很大程度上得益于 Transformer 架构的通用性和强大能力。Transformer 是一种与模态无关的序列模型,可广泛应用于语言、图像、分子等各种数据。
以下是 Transformer 编码器(以视觉Transformer为例)的高层工作流程:
- 序列化:将输入(如图像块)转换为一个序列。
- 嵌入与位置编码:将每个序列元素映射为嵌入向量,并加上位置编码(这是关键,因为Transformer本身是置换不变的)。
- Transformer 块堆叠:序列经过多个相同的Transformer块处理。每个块主要包含:
- 层归一化
- 多头自注意力机制:这是不同序列元素间交互的唯一场所。
- 残差连接
- 层归一化
- 前馈网络:独立应用于每个序列位置。
- 残差连接
- 输出:取序列开头特殊
[CLS]标记的表示,或所有位置的表示,用于下游任务。
自注意力机制是Transformer的核心。对于输入序列 X,我们通过三个不同的可学习矩阵 W_Q, W_K, W_V 将其投影为查询(Query)、键(Key)、值(Value):
Q = X W_Q, K = X W_K, V = X W_V
注意力矩阵 A 计算为:
A = softmax(Q K^T / sqrt(d_k)) V
其中 softmax 按行进行。这可以理解为:每个位置的输出,是所有位置值的加权和,权重由该位置与所有位置的查询-键相似度决定。
高效微调策略
得到大型预训练模型后,如何对其进行微调以适应新任务?我们面临两个问题:1) 不想完全覆盖预训练模型的知识;2) 不想为每个新任务存储一份完整的模型副本。
一种流行的高效微调方法是 LoRA。其核心思想是:对预训练权重矩阵 W_0 的更新应该是低秩的。即,微调后的权重 W = W_0 + A B^T,其中 A 和 B 是低秩矩阵(秩 r << min(d_in, d_out))。在微调时,我们冻结 W_0,只训练 A 和 B。
这大大减少了需要训练和存储的参数数量。研究表明,在某些情况下,使用LoRA等轻量微调方法,即使模型规模小得多,也能获得优于GPT-3等大型模型进行上下文学习的小样本性能。
自回归模型
自回归模型是掩码自编码器的一个特例,它简化了掩码策略:总是预测序列的下一个元素。
- 训练:给定序列
[x1, x2, ..., xT],我们构造训练样本:用[BOS]预测x1,用[BOS, x1]预测x2,依此类推。损失计算在每一个预测步骤上。 - 优势:
- 无需设计掩码策略。
- 能完全利用每个训练样本(每个位置都参与损失计算)。
- 训练和推理效率高(得益于因果注意力掩码,可以缓存之前步骤的计算结果)。
- 是一个显式的生成模型,可以采样新数据。
- 劣势:由于只能看到上文,其表示能力可能弱于双向的掩码模型。
GPT系列、视觉自回归模型等都是此类的代表。它们也可以通过多模态数据微调,构建出像Flamingo这样的强大模型,实现少样本的图像-语言任务。
总结
本节课中,我们一起学习了基于重构的无监督预训练方法:
- 我们从自编码器的基本直觉出发,即好的表示应能重构输入,并讨论了其瓶颈设计的挑战。
- 我们深入探讨了掩码自编码器,它通过预测被掩盖的输入部分来构建更具挑战性的任务,在视觉和语言领域都取得了顶尖性能。
- 我们简要介绍了支撑这些模型的 Transformer 架构,特别是其自注意力机制。
- 我们了解了如何通过 LoRA 等高效微调技术,使大型预训练模型适应新任务。
- 最后,我们讨论了自回归模型作为掩码自编码器的一个特例,及其在效率和生成能力上的优势。

对比学习与基于重构的方法各有千秋:对比学习通常能产生更高质量的冻结表示,而基于重构的方法(尤其是掩码模型)在模型微调后可能潜力更大。理解这些方法的原理和权衡,将帮助我们为特定任务选择合适的预训练和微调策略。
9:高级元学习主题(任务构建)📚


在本节课中,我们将探讨元学习中的高级主题,特别是任务构建。我们将了解不当的任务构建如何导致记忆化问题,以及如何利用无标签数据自动构建任务来提升元学习性能。
课程回顾与术语澄清 🔄
上一节我们介绍了元学习的基础算法。本节中,我们来看看元学习中的一些高级挑战和机遇。
首先,我们回顾一下课程中使用的核心术语。在元学习中,我们通常有:
- 元训练任务集:用于训练元学习器的任务集合。
- 元测试任务集:用于评估元学习器泛化能力的、全新的任务集合。
- 支持集:每个任务中用于“学习”的少量带标签数据(训练数据)。
- 查询集:每个任务中用于评估该任务学习效果的带标签数据(测试数据)。
一个需要澄清的常见混淆点是:在元训练过程中,我们实际上是在每个任务的“查询集”上进行优化,但这并非最终评估。真正的泛化能力是在全新的、未见过的元测试任务上衡量的。
我们已学习过的元学习方法主要有三类:
- 黑盒元学习:核心思想是将学习器参数化为一个神经网络。该网络作为元学习的内循环,从少量示例中学习(也称为上下文学习)。其优点是表达能力强,但优化可能具有挑战性。
- 公式/代码描述:
f_θ(D_train, x_test) -> y_pred,其中f_θ是元学习器网络,θ是元参数。
- 公式/代码描述:
- 基于优化的元学习:将梯度下降过程嵌入到元学习框架中。它利用了优化结构,但通常需要进行二阶优化。
- 非参数元学习:为所有示例创建嵌入,然后通过最近邻等非参数方法进行比较和预测。它易于优化且计算速度快,但主要适用于分类问题。
在所有这些设置中,我们通常需要大量带标签数据来构建任务集。
第一部分:元学习中的记忆化问题 🧠
现在让我们深入探讨本节课的第一个核心主题:记忆化。这是一个在特定任务构建方式下出现的问题。
记忆化是如何发生的?
为了理解这个问题,我们先进行一个思维实验。考虑一个黑盒元学习器,其输入是训练数据集 D_train 和一个测试输入 x_test,输出是预测标签。
思维实验一:如果在输入中加入任务的独热编码标识符,元训练和元测试时会发生什么?
- 在元训练时,网络可能会发现依赖简单的任务标识符比从复杂的训练数据中推断任务更容易,因此它可能忽略训练数据,直接记忆标识符与任务输出的映射。
- 在元测试时,如果遇到一个全新的任务标识符(一个未见过的独热编码),由于网络过度依赖标识符,它将无法执行新任务,导致泛化失败。
思维实验二:如果输入的不是独热编码,而是一段描述任务的自然语言段落呢?
- 这取决于网络认为从段落中理解任务更容易,还是从训练数据中推断更容易。它可能选择依赖其中之一。泛化能力则取决于它是否学习了足够通用的语言表示,以理解对新任务的描述。
这两个实验揭示的关键问题是:模型可以在不查看支持集(训练数据) 的情况下最小化元损失。这意味着它可能没有学会一个依赖于训练数据的学习过程,而只是记忆了一个从输入到输出的静态映射。
任务互斥性的重要性
在我们之前看到的少样本分类问题中,任务通常是这样构建的:对于每个任务,我们随机采样一些图像类别,并随机分配标签(例如,在任务1中“钢琴”是类别4,在任务2中“钢琴”是类别2)。这确保了任务之间是互斥的:不存在一个单一的神经网络能同时解决所有任务,因为相同的图像类别在不同任务中被赋予了不同的标签。因此,模型必须查看支持集才能知道当前任务的标签分配规则。
然而,如果我们在所有任务中为相同的图像类别分配一致的标签(例如,“钢琴”在所有任务中都是类别1),那么任务就变成了非互斥的。一个单一的静态分类器就可以解决所有元训练任务,模型因此可能学会忽略支持集,仅根据测试输入 x_test 直接进行分类。这时就发生了记忆化。
以下是记忆化可能成为实际问题的场景示例:
- 机器人任务:如果不同任务对应操作不同的物体(如关门、敲钉子),系统可能仅通过初始图像识别物体就知道该执行什么动作,而无需从少量演示数据中学习。
- 姿态预测任务:预测图像中物体的方向。如果元训练任务只包含有限物体,网络可能记忆这些物体的标准朝向。当遇到新物体时,由于它没有学会从支持集中推断新物体的朝向,泛化性能会下降。
解决记忆化:通过正则化控制信息流
我们可以将记忆化问题形式化。当任务非互斥时,存在多个能最小化元损失的解决方案:
- 理想方案:元参数
θ中不存储特定任务信息,所有任务特定信息都从支持集D_train中获取。 - 记忆化方案:元参数
θ中记忆了所有任务的解决方案,完全忽略支持集D_train。
我们的目标是鼓励模型选择第一个方案。从信息论角度看,我们希望最大化预测 y 与支持集 D_train 之间的互信息,同时最小化元参数 θ 中所含的信息。直接优化互信息很困难,因此一个实用的方法是最小化 θ 中的信息,但需与最小化元损失进行平衡。
一种有效的技术是向元参数 θ 添加噪声,这相当于施加了一种信息瓶颈正则化。具体做法是在元目标函数中加入一项,鼓励 θ 的分布接近某个先验分布(如标准高斯分布):
L_meta(θ) + β * KL( q(θ) || p(θ) )
其中 q(θ) 是以当前 θ 为均值的高斯分布,p(θ) 是先验分布。添加噪声使得依赖 θ 中记忆的信息变得困难,从而促使模型更多地从支持集 D_train 中获取信息。
这种权重噪声正则化在元学习设置中效果显著。例如,在去除标签打乱的“非互斥Omniglot”数据集上,使用MAML算法的性能很低,但加入此正则化后性能大幅恢复。在姿态预测任务上,该方法也能显著降低预测误差。
第二部分:无监督任务构建 🏗️
上一节我们讨论了任务构建不当带来的问题。本节中,我们来看看任务构建的一个积极方向:如何从无标签数据中自动构建任务,以扩充任务集并提升元学习性能。
这与上周讨论的无监督预训练有相似之处,但关键区别在于:我们不是仅仅预训练一个表示然后进行微调,而是显式地进行元学习,优化少样本学习能力。
无监督元学习通用流程
通用流程包含三个步骤:
- 给定一个无标签数据集。
- 从该数据集中提出/构建任务。
- 在这些构建的任务上运行元学习算法。
核心挑战和关键在于第二步:如何构建任务?我们通常希望构建的任务具备两个特性:
- 多样性:能够覆盖在元测试时可能遇到的未知任务分布。
- 结构性:任务本身应具有一定的内在规律或模式,使得元学习器能够从少量样本中学会。
以下是几种针对不同数据类型的任务构建方法:
方法一:基于聚类的任务构建(用于图像)
对于图像数据,可以在无监督学习得到的嵌入空间中进行聚类来构建分类任务。
- 获取嵌入:使用无监督方法(如对比学习、自动编码器)将图像映射到低维嵌入空间。
- 聚类:在嵌入空间中对所有数据进行聚类。
- 构建N-way分类任务:随机采样N个聚类,每个聚类代表一个“类别”。从每个聚类中采样图像作为支持集和查询集,构建一个N-way分类任务。
通过这种方式,我们可以创建大量多样且具有结构性的任务(例如,区分圆形物体和方形物体、区分不同颜色的物体等)。随后,可以在这些任务上运行MAML或原型网络等元学习算法。实验表明,这种方法在Mini-ImageNet等数据集上的少样本分类性能显著优于仅使用无监督表示后直接进行简单分类的方法。
方法二:基于图像增强的任务构建
受对比学习启发,我们可以利用图像领域知识,通过数据增强来构建任务。
- 构建思路:随机采样一批图像并分配临时标签。对每张图像应用一系列保持语义不变的增强变换(如裁剪、翻转、颜色抖动)。原始图像作为支持集,增强后的图像作为查询集,且它们共享同一标签。
- 优势:充分利用了图像变换的领域知识。在Omniglot数据集上,这种方法能达到接近全监督基线的性能。
方法三:基于掩码语言建模的任务构建(用于文本)
对于文本数据,可以采用类似BERT预训练中的掩码语言建模方式来构建分类任务。
- 采样单词:随机采样N个不同的单词。
- 分配标签:为每个单词分配一个唯一的ID(1到N)。
- 构建句子:从语料库中找出包含这些单词的句子,并将单词掩码(替换为
[MASK])。 - 构建分类任务:任务目标是预测被掩码的单词是N个候选单词中的哪一个。包含掩码单词的句子作为输入,单词ID作为标签。由此可以构建支持集和查询集。
这种方法允许我们在没有任何人工标注的情况下,创建大量的文本分类任务进行元学习。研究表明,将这种无监督构建的任务与已有的有监督任务结合(半监督元学习),可以在多个文本分类基准上取得比仅使用有监督任务或多任务学习更好的少样本学习性能。
总结 📝
本节课我们一起学习了元学习中关于任务构建的两个重要方面:
- 记忆化问题:当元训练任务构建不当(例如,任务非互斥)时,元学习器可能绕过学习过程,直接记忆静态映射,导致对新任务的泛化能力差。我们探讨了通过添加噪声/信息瓶颈正则化来控制信息流,从而缓解此问题。
- 无监督任务构建:为了利用大量无标签数据,我们可以自动构建元学习任务。我们介绍了多种方法:
- 对图像数据,可通过聚类或数据增强来构建分类任务。
- 对文本数据,可通过掩码语言建模来构建分类任务。
- 在这些自动构建的任务上进行元学习,可以显著提升模型在少样本场景下的性能,特别是在与有监督任务结合的半监督设置中。

理解任务构建的挑战与方法,对于设计和应用强大的元学习系统至关重要。
10:大规模元优化 🚀


在本节课中,我们将探讨元学习在大规模场景下面临的挑战,并介绍两种应对这些挑战的核心方法:截断反向传播和基于梯度的优化方法。我们将了解为什么传统的元学习方法难以扩展,以及如何通过新的技术手段来克服这些限制。
概述:为何需要大规模元优化?
我们可以将学习方法视为一个光谱,一端是手工设计的先验知识,另一端是数据驱动的先验知识。整个领域的发展趋势是不断向更数据驱动的一端移动。例如,从直接建模图像形成,到手写特征提取,再到端到端地学习特征本身(如微调预训练模型)。这种转变的原因是,数据驱动的方法更具可扩展性:投入更多真实数据,模型就能更好地编码真实先验,并在下游任务中表现更佳。
元学习的核心理念是,它比端到端的网络微调更加数据驱动,因为我们直接学习的是学习算法本身。然而,一个关键问题是:现有的元学习方法(如MAML或原型网络)真的能随着数据量的增加而有效扩展吗?答案往往是否定的。今天的讲座将探讨其原因,以及如何在保持元学习框架的同时解决这个问题。
传统元学习方法的局限性
我们之前学过的元学习方法,无论是基于优化的(如MAML)、基于黑盒模型的,还是基于非参数方法的,都可以概括为以下模式:构建一个任务学习计算图,然后通过整个计算图进行反向传播。这是一种通用方法,其优点是自动微分(Autograd)为我们完成了所有工作。
但这种方法的核心问题是:内存成本随着计算图的大小而线性增长。在某些学习场景中,我们希望拥有更大的计算图(例如,更深的网络、更多的梯度步数、包含二阶优化),这时直接反向传播就变得不可行。
大规模元优化的应用场景
当我们考虑更大的计算图时,我们可以将更多有趣的组件作为元参数进行优化,而不仅仅是初始参数。以下是一些例子:
- 学习率: 我们可以将学习率作为元参数进行优化。
- 优化器: 优化器本身(如一个神经网络)可以作为元参数来学习。
- 损失函数: 我们可以学习一个可微的损失函数,使其能更好地驱动模型优化以获得高精度。
- 数据集/数据增强: 我们可以直接优化合成数据或数据增强策略,使得在这些数据上训练能获得更好的下游性能。
- 神经网络架构: 通过神经架构搜索(NAS),我们可以学习网络的结构参数。
这些应用都面临一个共同的核心问题:为了计算元梯度(从最终验证损失到元参数),我们需要反向传播通过一个非常长的计算链,而直接反向传播在内存上无法承受。
方法一:截断反向传播
截断反向传播是一种简单直接的解决方案。其核心思想是:在展开的计算图中,我们只保留最近T个时间步的计算节点进行反向传播,更早的节点则被“分离”,梯度流在此处被截断。
以下是其工作原理的简要说明:
- 在前向传播过程中,我们像往常一样构建计算图。
- 当进行反向传播时,对于超过
T步之前的计算节点,我们调用.detach()方法,阻止梯度继续向前流动。 - 这样,我们只需要在内存中保存最近
T步的计算状态。
优点:
- 实现简单: 主要技巧就是在适当的时候分离变量。
- 内存可控: 通过选择
T,可以在内存成本和梯度准确性之间进行权衡。
缺点:
- 有偏估计: 得到的梯度不是真实的元梯度,因为它忽略了长程依赖关系。
- 忽略长期影响: 无法学习那些需要在很长的训练步数后才能体现出益处的元参数。
方法二:基于梯度的优化(进化策略)
这种方法完全避免了反向传播的需要,因为它根本不使用梯度信息。我们将重点介绍进化策略。
进化策略的灵感来源于生物进化,其工作流程如下:
- 初始化: 初始化一个参数分布(例如高斯分布),包含均值
mu和方差sigma。 - 采样: 从该分布中采样
N组候选参数。 - 评估: 在内部循环中,使用每一组候选参数执行完整的训练过程(例如,用特定的学习率训练一个网络很多个epoch),并评估其最终性能(如验证集准确率)。
- 选择: 选择性能最好的前
k组候选参数。 - 更新: 用这
k组精英参数的均值和方差来更新参数分布mu和sigma。 - 迭代: 重复步骤2-5,直到分布收敛到高性能区域。
优点:
- 内存成本恒定: 内存消耗与内部循环的步数无关,只与采样数量
N和参数维度有关。 - 高度可并行: 对
N个候选参数的评估是完全独立的,非常适合分布式计算。 - 兼容非可微操作: 内部循环可以包含采样、离散决策等不可微操作。
缺点:
- 高维空间效率低: 当元参数空间维度很高时(例如直接优化神经网络初始权重),随机采样很难探索到好的区域,收敛非常缓慢。
- 可能陷入局部最优: 需要通过调整探索策略(如方差)来缓解。
其他方法简介
除了上述两种主要方法,还有其他一些技术:
- 隐式微分: 利用内部优化收敛到最优解这一假设,通过对最优性条件进行微分来计算元梯度,无需存储中间状态。但假设可能不总是成立。
- 前向模式微分: 与反向传播(反向模式)不同,前向模式微分在计算过程中同步计算梯度,无需存储所有中间状态,但计算成本可能更高。
总结
本节课我们一起学习了大规模元优化。我们首先探讨了为什么传统的元学习方法在面临大规模计算图(如深层网络、多步训练、复杂内部优化器)时会失效,主要是因为内存限制。接着,我们介绍了两类主要的解决方案:
- 截断反向传播: 通过有选择地忽略长程梯度流来降低内存开销,实现简单但会引入偏差。
- 进化策略: 一种基于梯度的优化方法,通过采样、评估和选择来更新元参数,内存效率高且可并行,但在高维空间中效率较低。

理解这些方法的适用场景和权衡,对于设计和应用能够处理现实世界复杂任务的大规模元学习算法至关重要。
11:变分推断与生成模型 🧠


在本节课中,我们将学习一种贝叶斯视角下的元学习方法。今天的课程内容与之前有所不同,我们不会过多讨论元学习本身,而是将重点放在变分推断上。这是一种进行近似贝叶斯推断的方法。学习变分推断非常重要,因为它为理解贝叶斯元学习算法提供了关键的背景知识,并且在元学习之外也有广泛的应用。我们将在周三深入探讨贝叶斯元学习,今天则先打好基础,学习如何使用更复杂的分布类别进行贝叶斯推断。
课程大纲 📋
今天的计划如下:
- 首先,我们将介绍一类称为隐变量模型的概率模型。
- 接着,我们将探讨如何使用变分推断来训练这些隐变量模型。
- 然后,我们会讨论摊销变分推断,以解决非摊销变分推断的一个关键缺陷。
- 最后,我们将介绍几个隐变量模型的例子。
本节课的目标是理解隐变量模型(包括在深度学习场景中)的工作原理,并掌握如何使用变分推断来训练这些模型。这些知识对于完成可选作业也很有帮助,其中一道题目就与贝叶斯元学习相关。
概率模型回顾 📊
在概率建模中,我们的目标是建模某个分布。例如,我们可能有一个分布 P(X),我们拥有来自该分布的样本数据点。我们希望构建一个概率模型,能够生成这些数据点或评估这些数据点的似然。例如,我们可以尝试用高斯模型来拟合这些数据点,从而生成类似的新数据点,或者对数据点的分布进行建模。
类似地,我们可能想要建模一个条件概率分布 P(Y|X),即给定一个变量 X 来预测另一个随机变量 Y 的分布。在本课程中,我们已经见过条件概率模型的例子,例如,给定输入预测标签的分布。最常见的情况是输出离散分类分布的概率值,或者输出高斯分布的均值和方差。因此,我们通常输出的是概率分布的值,逻辑回归就是这样的例子。
当然,分布不一定是分类分布或高斯分布,虽然它们在文献中极为常见。我们可能希望构建更复杂、表达能力更强的分布。
当我们想要训练一个概率模型时,我们会形式化我们的模型,例如 P_θ(X) 或 P_θ(Y|X),并假设我们拥有来自该分布的数据。通常,我们会制定一个最大似然目标,目标是找到使数据似然最大化的模型。这可以说是对我们已观测数据的最佳拟合。
对于分类分布和高斯分布,这种目标非常容易评估和求导,这也是我们经常使用它们的原因之一。这个最大似然目标对应于我们常用的交叉熵损失和均方误差损失。
本节课的真正目标是超越分类或高斯分布,尝试建模和训练更复杂的分布。
为何需要更复杂的分布? 🤔
我们为什么需要训练更复杂的模型呢?原因可能包括:
- 生成复杂数据:我们可能不想生成一个简单的标签,而是想生成图像、文本或视频。例如,我们可能希望生成一段描述为“日出时在公园骑马”的高清视频,并且我们不只是想要一个视频,而是希望得到一系列符合该描述的视频。
- 表示不确定性:我们可能希望表示标签的不确定性。这种不确定性可能源于数据有限或部分可观测性。真实的标签分布可能不是单峰的,而是多峰的,这很难用高斯分布或分类分布来捕捉。
- 表示函数的不确定性:在元学习中,我们通常表示的是函数的点估计。但有些情况下,我们可能希望完整地表示任务特定参数的分布。例如,在小样本学习问题中可能存在模糊性。假设我们有一个小的训练数据集,包含一些正例和负例。对于一个新样本,分类器应该关注面部表情还是是否戴帽子?这种模糊性可能意味着我们不应该只输出一个分类器,而是输出多个可能解释数据的分类器。这种对模糊性的推理能力在安全关键场景、主动学习以及元强化学习中都非常重要。
以上几点是我们可能需要训练更复杂分布的一些动机。接下来,我们将具体探讨如何实现这一点。
隐变量模型示例 🎯
让我们从几个隐变量模型的例子开始,有些例子你可能已经见过。
假设你有一些看起来像这样的数据点,你想拟合一个模型。如果只拟合一个高斯分布,效果可能不会很好。相反,你可以使用一种称为混合模型的方法。你尝试拟合几个不同的成分,每个成分都是混合模型的一个组成部分。这就是高斯混合模型的一个例子。在底层,你并不知道哪些数据点对应哪个混合成分,但通过建模过程,你希望同时建模混合成分和每个混合成分的参数。
从数学上讲,你可以这样写:P(X) = Σ_Z P(Z) * P(X|Z)。在高斯混合模型这个特定情况下,P(Z) 是一个分类分布,而 P(X|Z) 是一个条件高斯分布。
你可能也想用类似混合模型的方式来建模一个条件分布。为此,你基本上可以取相同的高斯混合模型,并将所有变量都条件化于你正在条件化的变量上。这样,P(Z) 就变成了 P(Z|X),而你的条件高斯分布不仅条件化于 Z,也条件化于变量 X。这被称为混合密度网络。
例如,如果你想根据论文标题回归预测论文的长度,你不仅仅是输出你认为的平均长度,而是输出多个高斯分布的均值、方差以及对应的权重。因此,这种模型能更丰富地表示你对标签的认知。
现在,让我们看看更一般的情况。
通用隐变量模型 🏗️
一般来说,隐变量模型的目标是建模一个相当复杂的分布。我们通过首先定义一个隐变量 Z 来实现这一点。之所以称为“隐”变量,是因为我们只观测到 X,而观测不到 Z。然后,我们从该隐变量中采样,这通常是一个相对简单的分布,例如高斯分布。接着,我们将该变量的样本传入一个神经网络,该网络也会输出一个相当简单的分布(例如高斯分布),但这个条件高斯分布的参数会相当复杂。
通过组合这个简单分布和那个简单分布,我们可以构建出一个更复杂的分布。本质上,我们是在用神经网络转换来自高斯分布的样本,从而得到来自这个更复杂分布的样本。
其通用形式是这个相当简单的方程:P(X) = ∫ P(X|Z) * P(Z) dZ。在这两种情况下,P(Z) 将是一个简单分布,P(X|Z) 也将是一个简单分布类。关键思想是,我们可以通过组合两个更简单的分布来表示这个更复杂的分布。
需要指出的是,虽然 P(X|Z) 是一个简单分布类,但函数本身可以非常复杂,可以由神经网络表示。分布类实际上受输出分布的限制,例如高斯分布,而你的神经网络将输出该高斯分布的均值和方差。
通过这种设置,你基本上可以表示任何任意的分布 P(X)。这为你提供了相当大的表达能力。另外,图中只有一个神经网络,即 P(X|Z)。通常 P(Z) 是一个高斯分布,你甚至不需要学习其参数,可以将其设置为标准正态分布。这样做不会损失一般性,因为神经网络可以很容易地将其转换为自己想要的任何形式。
训练隐变量模型的挑战 🚧
现在,我们面临如何训练这些模型的问题。我们知道似然函数 P(X) = ∫ P(X|Z) * P(Z) dZ。如果我们想训练这些模型,我们可以将这个 P(X) 代入我们的目标方程。因此,我们的目标将是数据点对数似然的和或平均,即 Σ_i log( ∫ P(X_i|Z) * P(Z) dZ )。
不幸的是,通常你需要采样大量的 Z 才能准确估计这个积分。一般来说,这个积分并不容易处理。如果我们每次计算梯度都需要采样大量不同的 Z,那么优化将变得非常困难。
这就是训练隐变量模型的各种技术出现的原因,它们都试图在不评估积分的情况下估计这个目标的梯度。
在深度学习文献中,有几种不同类型的隐变量模型,它们基本上都归结为训练这类模型的不同方法。你可能听说过生成对抗网络、变分自编码器、标准化流模型和扩散模型。所有这些模型都是不同隐变量模型的例子,它们通常都有某种隐变量(通常是高斯隐变量),然后通过神经网络转换到示例空间。
有一类生成模型不使用隐变量,那就是自回归模型。但基本上我知道的其他所有模型都使用某种形式的隐变量。这些不同的隐变量模型之间的区别在于它们的训练方式,它们在优化能力、评估样本似然等方面各有优缺点。
在本节课以及周三的课程中,我们将主要关注使用变分推断的方法,因为这种方法有许多优点,并且在元学习的参数隐变量模型中使用最多。
变分推断:核心思想 💡
现在,让我们谈谈如何实际训练这些模型。我们将首先制定一个对数似然目标的下界,使我们能够摆脱计算那个烦人的积分。然后,我们将检查这个下界的紧密度。接着,我们将转向摊销变分推断,这是在深度隐变量模型中一个重要的实际步骤。最后,我们将讨论如何优化我们得到的下界。
我们想要优化这个目标,我们将制定一个略有不同的目标,称为期望对数似然。这个期望对数似然看起来很像原来的目标,但我们现在用关于隐变量 Z 给定输入 X 的期望代替了积分。这里的直觉是,我们不需要考虑所有可能的 Z 值,只需要考虑对于给定 X_i 最可能的那些 Z 值。当然,对于给定的 X_i,可能不止一个 Z 值,因此我们将使用 Z 给定 X 的分布,这通常被称为后验分布。
一旦我们考虑了这些可能的 Z 值,然后最大化该 Z 和我们的样本 X 的联合似然,这个目标就变得更容易优化了,因为我们可以使用样本来估计那个期望。
但问题仍然存在:我们如何实际估计 Z 给定 X_i?这不是我们事先给定的。我们将尝试用一个相当简单的东西来估计这个分布,我们称之为 Q_i。基本上,对于每个数据点,我们将尝试估计我们认为的隐变量是什么,这将由这个 Q 变量表示。这个估计不会完美,但一旦我们有了这个估计,它将有助于优化目标。
证据下界推导 📝
关于用类似 Q_i 的东西来近似 Z 给定 X_i 的好处是,一旦我们有了这个估计,我们就可以制定目标的一个下界。这个下界并不难推导。
我们希望对 P(X_i) 或 log P(X_i) 制定一个下界。如前所述,这等于 log( ∫ P(X_i|Z) * P(Z) dZ )。现在的问题是,这个 Q_i 如何发挥作用?你可以做的是,在你的表达式中乘以 Q_i(Z) / Q_i(Z)。这样做是可以的,因为这总是等于一。一旦我们有了这个,我们就可以将其表述为一个期望:log( E_{Z~Q_i} [ P(X_i|Z) * P(Z) / Q_i(Z) ] )。这比我们之前的形式要好得多,因为我们知道如何从 Q_i 中采样。
到目前为止,这只是代数运算,我们还没有做任何近似。值得注意的是,这对于任何 Q_i 都成立,我们没有对 Q_i 的好坏做任何假设。
从这里开始,我们可以利用琴生不等式。琴生不等式指出,对于凹函数(如对数函数),有 log(E[Y]) >= E[log(Y)]。利用琴生不等式,我们现在可以制定一个下界。通过交换期望和对数的顺序,我们得到一个下界。因为这些是对数内的乘积,我们可以将其写为对数的和:E_{Z~Q_i} [ log P(X_i|Z) + log P(Z) - log Q_i(Z) ]。
这个目标现在被称为证据下界。一旦我们最大化这个目标,也就最大化了我们原来的目标,即对数似然。
熵与KL散度 🔄
在深入探讨之前,理解一些量如熵和KL散度会很有帮助。
熵定义为负的期望对数概率:H(P) = -E_{x~P} [log P(x)]。熵衡量的是一个变量的随机性。例如,一个公平的硬币抛掷(伯努利变量,概率为0.5)具有更高的熵。熵也可以看作是变量在其自身分布下的期望对数概率的大小。
KL散度衡量两个分布 P 和 Q 之间的差异:KL(Q||P) = E_{z~Q} [log Q(z) - log P(z)]。当 Q = P 时,KL散度为零;当它们差异越大时,KL散度越大。另一种看待方式是,它衡量的是在 Q 分布下 P 的期望对数概率(加上 Q 的熵)。
现在,回到我们的证据下界目标。它主要有两项。第一项(前两项)试图为给定的 Z 使 P(X, Z) 变高。第二项试图最大化 Q(Z) 的熵,即使分布尽可能宽。总的来说,这个目标一方面最大化概率,另一方面试图使分布尽可能宽以匹配底层分布。
下界的紧密度与优化 🎯
我们推导出了优化隐变量模型的目标。我们仍然有 P(Z) 项(可以是高斯分布),以及将 Z 映射到 X_i 的神经网络。此外,我们还引入了第三个东西,即这个试图近似后验 P(Z|X_i) 的分布 Q_i。
接下来的问题是:我们给这个目标设定了一个下界,这个下界到底有多紧?在什么情况下是紧的?这部分与 Q_i 的选择有关。直觉上,我们希望 Q_i 尽可能接近 P(Z|X_i)。
如果我们计算 Q_i 和 P(Z|X_i) 之间的KL散度,并利用贝叶斯规则,我们可以推导出它实际上对应于什么。结果发现,KL(Q_i || P(Z|X_i)) = -L_i + log P(X_i)。这意味着,如果我们设 Q_i(Z) = P(Z|X_i),使得KL散度为零,那么 L_i 就等于对数概率 log P(X_i)。也就是说,当 Q(Z) 和 P(Z|X) 之间的KL散度为0时,下界是紧的,证据下界恰好等于对数似然。
此外,因为KL散度总是非负的,这也提供了推导 P(X_i) 下界的另一种方式。所以,如果我们优化 Q_i 以最小化这个KL散度,我们就能使下界变得更紧。这证明了同时优化证据下界关于模型参数 θ 和变分分布 Q_i 是合理的。
因此,我们的优化目标看起来是这样的:我们有一个单一目标 L_i,我们将同时关于模型参数 θ 和变分分布 Q_i 最大化它。
优化算法步骤 🔄
一旦我们有了这个目标,算法步骤如下:
- 采样:采样一个示例
X_i或一个小批量的示例。 - 计算关于 θ 的梯度:
θ只出现在log P_θ(X_i|Z)项中。为了评估这个梯度,我们需要一个X_i和一个Z。我们从Q_i中采样一个(或多个)Z,然后使用这些Z来计算log P_θ(X_i|Z)的梯度。在实践中,通常只采样一个Z也能工作得很好。 - 更新 Q_i:如果
Q_i是一个高斯分布,我们设Q_i为具有均值μ_i和方差σ_i的高斯分布。然后我们计算损失函数关于μ_i和σ_i的梯度,并用其来更新μ_i和σ_i。
摊销变分推断 🏃
这里有一个小问题:在深度学习中,我们通常有大量样本。这意味着为每个示例单独拟合一个 Q_i 可能不太实际。那么,当我们有这种模型时,参数总数是多少?我们会有所有的 θ 参数,然后对于每个示例,我们会有 μ_i 和 σ_i 的维度参数。这是一个相当庞大的参数数量。
为了解决这个问题,我们可以训练一个神经网络来预测给定 X_i 的 Z。这样,我们不仅有一个预测 X 给定 Z 的神经网络,还会有第二个网络,通常称为推断网络,它给出给定 X 的 Z 的分布。这个神经网络以 X 作为输入,输出一个均值和一个方差,因此 Q 再次成为一个高斯分布,但是一个条件高斯分布,由该均值和方差参数化。
这就是摊销变分推断。之所以称为“摊销”,是因为我们本质上是在使用这个神经网络来分摊推断过程,而不是为每个数据点单独进行推断。
它的工作方式是我们再次制定完全相同的目标,只是将 Q_i(Z) 替换为 Q_φ(Z|X_i)。这在边界内是可行的,因为我们提到过这对于任何 Q 值都有效,Q 可以条件化于 X_i。算法看起来和之前一样,只是现在我们从条件于 X_i 的这个条件分布中采样 Z,并且我们更新的是推断网络的参数 φ,而不是每个单独的 Q_i。
重参数化技巧 🎲
现在还有一个问题需要解决:我们如何计算关于 φ 的梯度?问题在于,在我们的目标中,φ 出现在两个地方:出现在熵项中,也出现在期望项中。熵项有闭式解,不难计算。但期望项更困难,因为这里你必须通过采样过程对 φ 进行微分。
这就是重参数化技巧发挥作用的地方。具体来说,Q_φ(Z|X) 被定义为一个高斯分布。我们在这个期望中采样一个 Z,并且我们希望能够通过这个采样过程进行微分。
重参数化技巧的妙处在于,我们可以将采样过程重写为:Z = μ_φ(X) + ε * σ_φ(X),其中 ε 是从标准正态分布中采样的一个值。这个方程应该相当简单:来自高斯分布的样本等于均值加上噪声乘以标准差。
这个方程真正酷的地方在于,ε 完全独立于 φ,而 μ 和 σ 是由 φ 参数化的。这意味着我们可以通过这种方式生成样本:我们从 ε 生成一个样本,然后将其代入这个方程。然后,我们可以通过这个方程对 φ 进行微分,以便通过采样过程更新 φ。

更具体地说,为了估计关于 φ 的梯度,我们首先从标准正态分布中采样(一个样本通常也足够),然后梯度将
12:贝叶斯元学习 🧠


课程概述
在本节课中,我们将学习贝叶斯元学习算法。我们将探讨为何需要贝叶斯元学习,介绍不同类型的贝叶斯元学习算法(包括黑盒方法和基于优化的方法),并讨论如何评估这些算法,这与我们之前见过的典型少样本学习评估方法有所不同。
贝叶斯元学习动机
上一讲我们讨论了元学习算法的理想属性,如表达能力和一致性。然而,我们尚未深入探讨的一个关键属性是不确定性推理的能力。这正是贝叶斯元学习算法的核心。
不确定性推理对于主动学习、需要校准不确定性估计的场景以及强化学习设置都至关重要。从贝叶斯的角度来看,这些方法也提供了更原则性的框架,因为它们旨在最大化某个图模型下的似然。
回顾:任务结构与图模型
在我们深入讨论元学习算法之前,我们曾提到训练和测试任务应共享某种程度的结构。这可以理解为对某些潜在信息 θ 的统计依赖。
我们提出了一个图模型,其中包含任务特定参数 φᵢ、共享潜在信息 θ,以及我们可观察的数据(包括支持集 X_train, Y_train 和查询集 X_test, Y_test)。
如果我们以共享信息 θ 为条件,那么任务参数之间就变得独立。因此,给定 θ 后,φᵢ 的分布熵会降低,不确定性减少。
以下是几个思考练习:
- 何时学习更快? 如果你能识别元参数 θ(例如通过元学习算法),并且新任务与元训练期间看到的任务来自同一分布,那么共享结构将有助于你推断 φᵢ。
- 任务完全独立会怎样? 如果任务之间完全独立且没有共享结构,那么以 θ 为条件并不会减少 φ 的不确定性。
- 熵为零的情况? 如果以 θ 为条件后熵为零,意味着数据告诉了你关于任务特定参数的一切。在这种情况下,你实际上不需要任何支持集数据来推断参数,这更像是记忆,而非学习。
为何需要不确定性?
到目前为止,我们见过的所有算法都以完全确定的方式给出任务特定参数,即它们给出的是 φᵢ 的退化分布(单一参数向量)。但在某些情况下,我们确实需要生成多个假设。
例如,少样本学习问题可能存在模糊性。支持集可能本质上不清楚应该关注哪些属性。如果我们能学习生成关于底层函数的多个假设,这可以告诉我们是否需要更多标签,或者是否应该因为不确定而避免对新示例做出预测。这在安全关键设置、主动学习和探索设置中非常重要。
算法一:输出 Y 的分布(V0)
我们可以考虑的第一个简单算法是:让元学习器输出 Y_test 的分布参数,然后使用最大似然进行优化。
- 在分类设置中,我们已经这样做了(输出每个类别的概率)。
- 在回归问题中,可以输出均值和方差,或者使用混合密度网络。
- 一旦选择了 Y_test 的分布类别,就可以用最大似然进行优化,这对应于元学习算法的外部损失。
优点:非常简单,事实上我们已经这样做了,并且可以结合多种不同的元学习算法。
缺点:
- 它允许你对标签的不确定性进行推理,但不允许对底层函数的不确定性进行推理。
- 你只能捕获有限的 Y_test 分布类别。参数化复杂的分布非常困难。
- 用最大似然训练的神经网络往往给出校准很差的不确定性估计(例如,过于自信)。
如何衡量校准?
衡量神经网络校准程度有几种方法。一个直观的方法是使用可靠性图。
- X轴:神经网络输出的置信度(例如,0.9)。
- Y轴:具有该特定置信度的所有数据点的实际准确率。
- 理想情况:一条对角线。例如,90%的置信度对应90%的准确率。越接近对角线,校准估计越好。
不确定性的类型
有两种主要的不确定性:
- 偶然不确定性:数据本身固有的噪声,也称为数据不确定性。
- 认知不确定性:模型自身知识不足导致的不确定性,也称为模型不确定性。估计这种不确定性更难,但更有价值。
从输出 Y 分布到输出 Φ 分布
一个自然的问题是:我们能否让元学习器输出 φ 的分布(给定训练数据),然后用最大似然训练它?
答案是否定的。因为要进行最大似然估计,我们需要 φ 的真实值。我们只能访问真实标签,而无法访问真实的 φ。因此,我们需要比最大似然更复杂的算法。
贝叶斯元学习工具箱
为了创建这些算法,我们可以依赖概率深度学习工具箱。
- 潜变量模型与变分推断:这是本节课的重点。
- 贝叶斯集成:不显式表示分布,而是表示来自该分布的多个样本(粒子)。通常训练多个独立的模型。
- 贝叶斯神经网络:直接形成神经网络参数上的分布(通常是高斯分布)。
- 其他:标准化流、基于能量的模型、生成对抗网络等(本节课不深入讨论)。
变分推断回顾
上周一,我们讨论了使用潜变量表示分布。关键思想是:
- 有一个简单的潜变量 z 的分布。
- 通过一个网络将其转换到观察到的变量 x。
- 我们推导出对数似然的下界(证据下界,ELBO),并通过重参数化技巧进行优化。
应用于元学习
我们可以将变分推断的思想应用于元学习:
- 观察变量:特定任务的数据 Dᵢ。
- 潜变量:任务特定参数 φᵢ。
- 推断网络 Q:近似后验
Q(φᵢ | ...)。我们可以选择让其以训练数据 Dᵢ_train 为条件。这看起来很像黑盒元学习——一个以训练数据集为输入并输出分布参数(均值和方差)的神经网络。 - 先验 P(φᵢ | θ):可以学习,元参数 θ 可以出现在这里。
- 似然项:使用查询集数据评估
P(Y_test | φᵢ, X_test)。
最终的优化目标(对任务求和)是最大化这个ELBO。
优点:
- 可以表示 Y_test 上的非高斯分布。
- 给出了函数空间上的分布,而不仅仅是标签上的分布。
- 测试时,你会使用 Q 来推断 φᵢ 的分布,然后使用 P 进行预测。
缺点:
- 由于重参数化技巧和KL散度计算的限制,通常只能表示 φᵢ 上的高斯分布。
基于优化的贝叶斯元学习方法
接下来,我们看看如何将变分推断应用于基于优化的元学习方法(如MAML)。我们将探讨三种方法。
方法一:将梯度下降作为推断网络
在黑盒方法中,Q 是一个神经网络。在这里,我们可以重新定义 Q,使其包含一个梯度下降过程。
- Q 的定义:从初始均值
μ_θ和方差σ_θ开始,对训练数据 Dᵢ_train 的损失运行梯度下降,以得到最终的μ_φᵢ和σ_φᵢ。 - 训练:使用相同的ELBO目标,只是 Q 的形式变了。
- 测试:通过运行梯度下降来进行推断,这可能对分布外任务更鲁棒。
优点:简单,是黑盒方法的直接修改。
缺点:仍然将 P(φᵢ | θ) 建模为高斯分布。
方法二:集成方法
如果我们想要 φᵢ 上的分布,可以简单地训练一个MAML模型的集成。
- 基本方法:独立训练 M 个不同的MAML模型。
- 挑战:独立训练可能导致参数非常相似。
- 改进:使用** Stein 变分梯度下降** 等方法,在内部循环优化中主动推动不同集成成员(粒子)的参数彼此远离,以增加多样性。
优点:
- 实现相对简单。
- 集成是估计认知不确定性最有效的方法之一。
- 可以表示非高斯分布。
缺点:
- 需要维护 M 个模型实例,成本较高。
方法三:结合 MAP 估计与变分推断
这种方法旨在以比维护多个模型实例更低成本的方式获得非高斯后验。
核心直觉:学习一个先验 θ,使得如果我们对参数添加噪声然后运行梯度下降,会落入分布的不同模式中(例如,对应不同属性的分类器)。
流程:
- 有一个元参数 θ 上的分布(例如高斯)。
- 为了从给定支持集的后验中采样 φᵢ:
- 首先从
P(θ)中采样一个 θ‘(添加噪声)。 - 然后,将
P(φᵢ | θ’, D_train)近似为从 θ‘ 开始,对D_train运行梯度下降得到的 MAP 估计。 - 重复此过程以获得多个样本。
- 首先从
优点:
- 测试时简单(添加噪声,运行梯度下降)。
- 只需训练一个元模型实例。
- 可以得到非高斯后验。
缺点:
- 训练过程更复杂。
贝叶斯元学习算法总结
| 方法 | 描述 | 优点 | 缺点 |
|---|---|---|---|
| V0 | 直接输出 Y_test 的分布。 | 简单,易于实现。 | 无法推理函数空间的不确定性;分布类别有限;校准差。 |
| 黑盒变分法 | 使用摊销变分推断对 φ 建模。 | 可表示 Y 上的非高斯分布;给出函数分布。 | φ 上的分布通常限于高斯形式。 |
| 优化法(梯度下降Q) | 将梯度下降作为推断网络 Q。 | 简单;测试时更鲁棒。 | φ 上的分布限于高斯形式。 |
| 集成法 | 训练多个模型实例(如MAML集成)。 | 简单有效;可表示非高斯分布;不确定性估计好。 | 需要多个模型实例,成本高。 |
| 混合法(采样+优化) | 结合先验采样与梯度下降MAP估计。 | 测试时简单;单模型实例;非高斯后验。 | 训练过程更复杂。 |
如何评估贝叶斯元学习算法?
使用标准基准(如 Mini-ImageNet)可以检查你的贝叶斯元学习算法是否破坏了原有性能,但它们并非评估贝叶斯特性的最佳指标。
更好的评估涉及以下方面:
- 可视化模糊问题:在一维或二维的模糊回归或分类任务上可视化算法生成的函数,直观理解其行为。
- 模糊生成任务:评估在给定单个视角下生成物体多视角的能力,比较生成样本的质量和多样性。
- 综合指标:在故意设计模糊的任务上,同时考察:
- 准确率
- 模式覆盖:算法是否学到了所有可能的合理分类器?
- 负对数似然
- 可靠性图:评估预测置信度的校准情况。
- 主动学习性能:在允许主动查询额外数据点的设置下,观察算法降低错误率或提升准确率的速度。良好的不确定性估计应能更快地提升性能。
课程总结
本节课我们一起学习了贝叶斯元学习算法。我们首先探讨了在元学习中推理不确定性的动机。然后,我们介绍了几类主要的贝叶斯元学习算法:从简单的输出标签分布方法,到使用变分推断的黑盒方法,再到三种基于优化的方法(将梯度下降作为推断网络、集成方法以及结合采样与优化的混合方法)。最后,我们讨论了如何超越传统准确率指标,从不确定性校准、分布覆盖和主动学习等多个维度来全面评估这些算法。

下周,我们将讨论领域自适应与领域泛化,这是多任务与元学习问题设置中一个非常有趣的特例。
13:领域自适应 🎯


在本节课中,我们将要学习领域自适应。这是一种特殊的迁移学习问题,其核心目标是在拥有源领域数据的情况下,利用目标领域的(通常是无标签的)数据,来提升模型在目标领域上的性能。我们将探讨领域自适应的定义、几种核心算法,并理解它们各自的适用场景。
什么是领域自适应? 🤔
在本课程中,我们已经介绍了几种不同的问题设定。从多任务学习开始,我们的目标是同时解决多个任务。接着是迁移学习,我们希望利用解决某个源任务的经验来帮助解决一个新的目标任务。我们还学习了元学习,其目标是在解决一系列先前任务后,能够更快、更高效地解决新任务。
今天,我们将讨论领域自适应和领域泛化。这两个问题看起来与迁移学习和元学习非常相似,但在某种意义上,它们是这些问题的特例。
具体来说,领域自适应的目标是:我们希望在源领域的数据上进行训练后,能够在目标领域上表现良好。我们可能拥有多个源领域的数据,但在本讲中,我们主要关注单个源领域的情况。
这与迁移学习看起来几乎完全相同,但有一个关键假设:我们假设在训练期间可以访问一些来自目标领域的数据。这被称为转导学习,即我们可以访问一些测试数据。
领域自适应有几种不同的形式,基本上对应于对目标领域数据的不同访问权限:
- 无监督领域自适应:我们假设可以访问来自目标领域的无标签数据。
- 半监督领域自适应:我们假设可以访问来自目标领域的无标签和有标签数据,通常有标签数据远少于无标签数据。
- 监督领域自适应:我们假设可以访问少量有标签的目标领域数据。
本节课我们将主要关注无监督领域自适应。对于有监督的领域自适应,仅通过微调和之前讨论的迁移学习技术就能做得很好。而无监督领域自适应则不同,因为只有目标领域的无标签数据,微调并不适用。
核心假设与定义 📝
我们将做出几个相当常见的假设,这也是领域自适应与标准迁移学习设置的不同之处。
第一个假设是:源领域和目标领域仅在 P(x) 上不同,或者说仅在输入的分布上不同。因此,这意味着给定输入 x 时,输出 y 的条件分布 P(y|x) 在源领域和目标领域中是相同的。
第二个相关假设是:我们假设存在一个单一的假设(或函数),它能够在源领域和目标领域上都实现低误差。
在许多方面,你可以将领域视为任务的一个特例。当我们引入“任务”这个概念时,我们认为它对应于一个数据生成分布 P(x)、P(y|x) 以及该任务的损失函数。而一个领域则是这样一个特例:不同领域之间只有 P(x) 不同,而 P(y|x) 和损失函数在各个领域间是相同的。本质上,领域是任务的一种特殊情况,它对应于 x 的不同分布。
通过做出“仅在 x 上不同”的假设,以及“在训练期间可以访问一些无标签目标领域数据”的假设,我们将能够比专为多任务学习或迁移学习设计的方法做得更好,因为我们可以假设 P(y|x) 保持不变。
领域自适应的实例 🌍
让我们看几个例子,这可能会让领域自适应的概念更具体。
- 医学影像诊断:你的目标是从组织细胞切片中检测或分类肿瘤。你在一个医院的图像上训练了一个分类器。现在你想在另一个医院部署同一个模型。但另一家医院可能有不同的图像采集技术或不同的患者群体。因此,源医院和目标医院的图像可能看起来有些不同。然而,医生仍然可以查看这些图像并判断是否有肿瘤,因此仍然存在一个可以从图像预测肿瘤的单一函数。但这两个不同领域之间存在分布偏移。
- 土地利用分类:你想对土地利用方式进行分类。你在北美训练了一个非常好的模型,并希望能在南美等另一个大陆部署该模型。建筑物、植物在该区域的外观、天气条件、污染情况在源区域和目标区域之间可能不同。这本质上是同一个任务,但图像的分布不同,因此
P(x)发生了变化。 - 文本分类/生成:我们想在维基百科上训练一个模型,然后将其部署在 arXiv 或 PubMed 的论文上。由于词汇使用和句子结构的不同,在源领域训练的模型可能无法很好地迁移到目标领域。
我们的目标是能够利用来自目标领域的无标签数据来提高在该目标领域上的性能。
领域也可以是不同的人或用户、不同的时间点、不同的机构(如来自不同学校、公司或大学的数据)。
与迁移学习的区别 🔄
领域自适应与典型迁移学习问题的一个关键区别是:我们在训练期间可以访问目标领域数据。例如,如果我们想将文本分类器迁移到 arXiv,我们可能已经可以访问 arXiv 上的无标签数据。这意味着我们不必立即部署模型,我们可以获取 arXiv 的无标签数据,将其与可能带有标签的维基百科训练数据结合起来,训练一个我们认为在 arXiv 上应该表现更好的模型。
当然,有些场景下这个假设不现实,但也有许多场景下你确实已经可以访问无标签数据。
如果可以直接在目标领域的有标签数据上训练,为什么还需要领域自适应?
如果你可以访问大量有标签的目标领域数据,那么你可能不需要领域自适应,也不一定需要使用任何源数据,因为你可以直接在目标数据上训练。而当你只有少量有标签数据、或少量有标签数据加大量无标签数据、或只有无标签数据时,领域自适应就非常有用了。
算法一:重要性加权 📊
上一节我们介绍了领域自适应的核心问题定义。本节中,我们来看看第一种算法:重要性加权。这种方法的核心思想是:通过调整源领域样本的权重,让模型更关注那些在目标领域中更可能出现、但在源领域中较少出现的样本。
首先,考虑一个简单的领域自适应问题。源领域是蓝色分布,目标领域是绿色分布。这是一个二分类问题。如果只在源数据上训练分类器,它可能会忽略那些在源分布下概率低、但在目标分布下概率高的数据点,从而在目标分布上表现不佳。
我们的目标是最小化模型在目标分布上的期望损失。虽然我们无法直接从目标分布采样,但我们可以从源分布采样。通过数学推导,我们可以将目标分布上的期望损失,重写为源分布上的期望损失,但每个样本的损失需要乘以一个重要性权重:w(x) = P_target(x) / P_source(x)。
这个权重公式与我们的直觉一致:对于在目标分布下可能性高、在源分布下可能性低的样本,我们会增加其权重;反之则降低权重。
关键问题:如何计算这个重要性权重 w(x)?直接估计 P_target(x) 和 P_source(x) 的密度非常困难。幸运的是,我们可以利用贝叶斯定理,将这个比率转化为一个我们可以用判别式模型估计的形式:
w(x) ∝ P(domain=target | x) / P(domain=source | x)
这意味着,我们可以训练一个二分类器来预测一个样本 x 是来自目标领域还是源领域。然后,用这个分类器的输出来估计重要性权重。
以下是该算法的步骤:
- 训练领域分类器:训练一个二分类器,仅根据输入
x来预测样本来自目标分布还是源分布。 - 重新加权或重采样数据:根据上述公式计算的重要性权重,对源领域的训练样本进行重新加权或重采样。
- 优化模型:在重新加权或重采样后的数据上,优化你的主模型(例如分类器)的损失函数。
该方法的局限性:它做了一个重要假设——源分布的支撑集必须覆盖目标分布的支撑集。也就是说,对于目标分布中概率非零的输入,其在源分布下的概率也必须非零。如果源数据没有覆盖目标数据(例如,源医院和目标医院的图像差异极大),这种方法可能效果不佳。
算法二:领域对抗训练 ⚔️
上一节的重要性加权方法要求源领域覆盖目标领域。本节我们来看第二种算法:领域对抗训练。当源领域和目标领域没有重叠时,这种方法更为适用。
考虑另一个例子:源分布和目标分布都是二分类问题,但它们的形状和位置不同,没有直接重叠。例如,源数据是手写数字数据集MNIST,目标数据是街景门牌号数据集SVHN。直接训练的分类器在目标域上效果不佳。
这种方法的思路是:对齐特征空间。我们学习一个特征编码器,将输入映射到一个特征空间。我们的目标是让源领域和目标领域样本在特征空间中的分布尽可能相似,以至于无法区分它们来自哪个领域。这样,在源领域特征上训练的分类器,就能在目标领域特征上表现良好。
具体实现时,我们引入一个领域分类器,它根据特征来预测样本的领域。同时,我们训练特征编码器,不仅要能帮助主任务(如分类)取得好效果,还要能“欺骗”这个领域分类器,让它无法准确判断特征的来源。这通过一个梯度反转层来实现:在反向传播时,领域分类器的损失梯度在传入特征编码器之前会被取反。
以下是该算法的概要:
- 更新领域分类器:最大化其区分源特征和目标特征的能力。
- 更新特征编码器和主任务分类器:最小化主任务(如分类)的损失,同时(通过梯度反转)最大化领域分类器的损失(即增加领域混淆)。
设计选择与注意事项:
- 编码器:可以使用共享的编码器,也可以为源和目标使用独立的编码器。独立编码器更灵活,但可能增加训练难度。
- 损失函数:除了最大化领域分类器损失,另一种选择是优化领域分类器的输出概率,使其接近50/50的猜测。
- 迭代训练:需要交替更新领域分类器和特征编码器,以确保领域分类器始终能跟上特征的最新变化。
该方法的优缺点:
- 优点:实现相对简单,效果不错;不要求源分布覆盖目标分布。
- 缺点:涉及对抗性优化,可能训练不稳定;需要仔细调整领域混淆损失和主任务损失的权重;要求两个领域的数据分布存在某种可对齐的“形状”或结构。
算法三:基于循环一致性的领域映射 🌀
上一节我们学习了在特征空间对齐分布的方法。本节我们来看第三种算法:基于循环一致性的领域映射。这种方法不是对齐特征,而是学习一个在原始输入空间 X 上进行领域转换的映射。
核心思想是:如果我们能学会将源领域的样本转换成看起来像来自目标领域的样本(反之亦然),那么我们就可以:
- 将带标签的源数据转换成目标风格,然后在转换后的数据上训练一个分类器,并直接用于目标领域。
- 或者,训练一个源领域上的分类器,将目标测试样本转换成源风格,然后用源分类器对其进行分类。
这引出了一个关键问题:如何在没有成对数据的情况下学习这种跨领域映射?我们可以使用生成对抗网络。训练一个生成器 F 将源样本转换为目标风格,另一个生成器 G 将目标样本转换为源风格。每个生成器都配有一个判别器,确保其生成样本看起来像来自目标领域。
然而,仅使用GAN目标会导致模式崩溃或无约束的映射(例如,将所有的狗都映射到狐狸)。为了解决这个问题,我们引入循环一致性损失:将一个源样本 x_s 通过 F 映射到目标域,再通过 G 映射回源域,应该得到与原始 x_s 非常接近的图像。对目标样本也施加类似的约束。这鼓励了映射是双向一致的。
因此,完整的目标函数包括:
F的GAN损失(生成目标风格图像)。G的GAN损失(生成源风格图像)。- 循环一致性损失:
|| G(F(x_s)) - x_s ||和|| F(G(x_t)) - x_t ||。
该方法的优缺点:
- 优点:概念直观,可解释性强(可以看到生成的图像);是一种完全无监督的映射方法,甚至不需要源领域的标签。
- 缺点:同样涉及对抗性优化和生成建模,可能需要更大的模型;要求两个领域间存在清晰的、可对齐的语义结构;数据集的类别分布需要大致匹配,否则可能学到错误的映射。
总结与融合 🏁
本节课我们一起学习了三种主流的无监督领域自适应方法:
- 重要性加权:通过重新加权源数据来匹配目标分布。它假设源分布覆盖目标分布,适用于样本选择偏差等问题。
- 领域对抗训练:在特征空间对齐源和目标分布,使它们不可区分。它不要求分布重叠,但要求分布存在可对齐的结构。
- 循环一致性映射:学习在输入空间进行领域转换的生成模型。它直观且可解释,但训练更复杂,也需要分布间存在语义对齐。
在实际应用中,这些方法可以结合使用。例如,将领域对抗训练与循环一致性映射相结合,可以在一些任务上取得比单一方法更好的性能。

选择哪种方法取决于具体问题:数据的性质、计算资源以及对可解释性的需求。理解这些算法的核心假设和局限性,是成功应用它们的关键。
14:领域泛化 🎯


在本节课中,我们将要学习一个重要的概念——领域泛化。我们将了解其问题定义、核心挑战,并学习两种主流的解决思路:基于显式正则化的方法和基于数据增强的方法。
概述
大家好,欢迎来到本次讲座。我是徐华,是Charles实验室的博士后。今天我将为大家讲解领域泛化。
在开始之前,我们先回顾一下课程安排。项目里程碑提交日期是本周三,而可选的作业4截止日期是下周一。
今天的课程计划如下:我将首先介绍领域泛化这一新概念,包括问题陈述和形式化定义。然后,我将介绍两类主要的算法:第一类是通过添加显式正则化来解决领域泛化问题;第二类是利用数据增强来处理这个问题。
本节课的目标是:
- 理解领域泛化背后的直觉和问题形式化。
- 熟悉主流的领域泛化方法,包括基于正则化的方法和基于数据增强的方法。
回顾:领域自适应
首先,让我们回顾一下上一讲学到的领域自适应。
在领域自适中,我们的目标是利用来自源领域的训练数据,使模型在目标领域上表现良好。这是一种迁移学习的形式,但我们在训练过程中可以访问目标领域的数据(尽管是无标签的),因此它是一种直推式学习。我们基本上拥有源领域数据和未标记的目标领域数据,并希望模型在目标领域上表现良好。
领域自适应有两个常见假设:
- 源领域和目标领域仅在数据的边缘分布上不同。这意味着条件分布
P(y|x)在源领域和目标领域之间是相同的。 - 存在一个单一的假设(模型),在源领域和目标领域上都有较低的误差。
我们还需要回顾一下,领域是任务的一个特例。一个任务由三个组成部分构成:
P(X):特征的边缘分布。P(Y|X):条件分布(即决策函数)。- 损失函数
L。
在我们在多任务学习或元学习中学习的任务中,这三个组成部分都可以在不同任务间变化。但在领域中,只有 P(X) 可以在不同领域间变化。
为什么需要领域泛化?
那么,我们是否总能访问目标领域的未标记数据呢?然而,在一些现实世界的应用中,由于以下两个原因,我们无法总是访问目标领域数据:
- 实时部署需求:有时我们需要进行实时部署,没有足够的时间来收集足够的目标领域数据并进行自适应(无论是领域自适应还是收集标签数据进行元学习或小样本学习自适应)。
- 隐私政策限制:获取目标数据可能受到隐私政策的限制。
我将为每个原因提供一个例子:
- 实时部署的例子:假设我们想训练一个自动驾驶系统,让模型在三种类型的道路上训练。然后我们想将这个模型部署到一条新的道路上,例如夜间道路。在这种情况下,我们需要进行实时部署,没有足够的时间收集足够的数据。
- 隐私问题的例子:有许多关于隐私的政策,例如欧洲的《通用数据保护条例》。在这种情况下,我们不能在不同机构、医院或其他实体之间共享数据。例如,如果我们想建立一个疾病预测模型,我们在三家医院(例如医院1、2、3)上训练了这个模型,然后我们想将这个模型部署到一家新医院。在这种情况下,由于隐私问题,我们无法访问新医院的训练数据。
基于这两点,我将首先阐述为什么需要领域泛化,并给出一些正式的问题形式化。
领域泛化:问题定义
在领域泛化中,假设我们有一堆源领域。例如,有三个领域:剪贴画、油画和素描。我们希望在每个领域上识别不同的物体。
我们将训练一个模型,得到一个神经网络,这被视为一个训练好的模型。然后,我们将把这个模型部署到一些未见过的目标领域。这里是一个真实图像的领域。
我们希望从这些源领域中泛化出一些共同知识,使模型在这个目标领域上表现良好。
数学上,领域泛化问题可以形式化为:给定一堆源领域 {P_1(X), ..., P_N(X)},我们的目标是在目标领域 P_T(X, Y) 上表现良好,而无需访问其数据。
同样,也有两个常见假设:
- 所有领域仅在数据的边缘分布上不同。这意味着条件分布
P(y|X)在所有领域(包括源领域和目标领域)中都是相同的,只有P(X)会变化。 - 存在一个单一的假设(模型),在所有领域上都有较低的误差。这保证了我们可以学习一个在不同领域上都能表现良好的模型。
是的,这也是任务的一个特例,因此领域泛化问题也成立。
与其他概念的比较
基于这个定义,我将尝试将我们之前在许多讲座中学到的元学习与领域泛化进行比较。
在元学习中,它是一种迁移学习,我们希望利用许多源任务的知识。给定任务1到N的数据,我们希望在一个新任务T上更快、更熟练、更稳健地学习。
在领域泛化中,这是我们之前学习的元学习的一个特例。给定领域D1到DN的数据,我们的目标是在新领域DT上表现良好。
但是,领域泛化和元学习之间存在两种差异:
- 变化的内容不同:在领域泛化中,只有
P_i(X)在不同任务间变化。但在元学习中,任务的三个组成部分(P(X),P(Y|X),L)都可以变化。 - 目标不同:在领域泛化中,我们希望直接泛化到新领域,而不是进行任何形式的自适应。
第二个比较是和我们上一讲学到的领域自适应进行比较。
在领域自适中:
- 我们可以访问所有源领域的标签数据,并且可以使用目标领域的未标记数据。
- 我们的目标是使模型在目标领域上表现良好。
- 通常只有一个源领域(尽管人们也可以使用更多),但可以仅依赖一个源领域来实现成功的领域自适应。
- 为领域自适应训练的模型只针对特定的目标领域进行专门化。这意味着我们只关心我们能访问的特定目标领域的性能,而不是考虑更一般情况下的问题。
领域自适应是一种迁移学习设置。
在领域泛化中,情况则有所不同:
- 给定一组源领域
{P_1(X,Y), ..., P_n(X,Y)}的标签数据,我们的目标是使模型在(一批)目标领域上表现良好。 - 我们无法在训练过程中访问测试数据。这是第一个区别。
- 领域泛化通常需要多于一个源领域。当你有一堆源领域时,你可以捕捉这些源领域背后的共同知识,然后将这些共同知识泛化,以提升目标领域的性能。
- 第三个区别是,这些模型可以应用于所有领域,包括源领域、目标领域,甚至我们未曾见过的领域。
这就是为什么我们需要学习一些泛化性强的知识,并能泛化到一系列领域。
是的,这是领域自适应和领域泛化之间的关键区别。在本讲座中,我们想强调的是,领域泛化是一种归纳式学习设置。
现实世界应用
基于这个定义和一些比较,我想向大家展示一些领域泛化的现实世界应用。
- 可持续性与野生动物识别:我们希望识别不同地点的不同动物。这里我们使用 iWildCam 数据集,有245个地点。我们想从这些地点训练一个模型,并将模型泛化到新的地点。
- 组织病理学图像分类:这个例子大家可能比较熟悉,因为在上次讲座中我们也看到了这个例子的自适应版本。我们的目标是对组织图像进行分类,判断它是正常的还是肿瘤。基本上,我们从一批医院学习一个模型,然后将这个模型应用到新医院(例如医院4和医院5)。而在领域自适中,我们可能只有两家医院,并希望从这两家医院学习一些共同知识。
- 分子属性预测:分子预测在药物发现领域非常重要。我们希望预测给定小分子的毒性。我们在不同规模力场下训练模型,然后旨在泛化一些共同知识,使其在未见过的力场上工作。
- 代码补全:这也是非常重要的应用,例如在编程语言领域。我们有一堆代码库,然后训练一个模型来预测源代码上下文中的下一个标记,然后我们旨在将这个模型泛化到一些测试分布上。
好的,这就是关于什么是领域泛化的基本介绍,进行了一些比较,并给出了一些应用。接下来,我将介绍一些关于领域泛化的具体算法。第一类算法旨在添加一些显式正则化器来处理这个问题。
方法一:基于显式正则化的方法
在深入具体算法之前,让我们重新思考一个问题:如何学习这种可泛化的表示?
为了回答这个问题,一个很自然的方式是思考另一个问题:为什么机器学习模型无法泛化?
这里有一个非常简单的例子。我们的目标是分类狗和猫。有两个领域:领域1是水域,领域2是草地。实际上我们有四个组:水中的狗、水中的猫、草地上的狗、草地上的猫。其中,水中的狗和草地上的猫是两个多数群体。而水中的猫和草地上的狗是少数群体。
基于此,我们在这两个源领域上训练一个模型,然后部署这个训练好的模型到一个新领域,例如森林中的狗。我们的问题是:这是一只狗吗?
人类可以很容易地认出这是一只狗。但对计算机来说,这非常困难。通常计算机很容易识别,但在这个情况下很难识别它是一只狗。计算机会做出错误的预测。为什么会发生这种情况?
训练数据中存在一些虚假相关性。我们可以看到,在训练数据中,狗通常在水里,而猫通常在草地上。然后,当它看到与草地相似的环境时,草地的信息就成了虚假信息。这意味着这些模型会错误地将猫的信息与草地的信息关联起来。因此,当计算机看到相似的环境时,它会做出错误的预测。
所以我们的目标是消除这种虚假信息。为此,我们旨在训练一个新的网络来学习一些领域不变的特征。
这是我想在这里提到的另一个概念:领域不变性。我们希望学习通过神经网络得到的一批特征,这些特征在不同领域间不发生变化。这样,我们就可以学习到领域不变的信息,例如,我们可以将动物与标签关联起来。计算机就能做出正确的预测。
好的,这就是关于领域不变性的一些内容。基于这个定义,我将详细介绍基于正则化的方法。
基于正则化方法的核心思想是:我们想使用一个正则化器来对齐不同领域间的表示,从而学习领域不变的表示。
让我们回到这个例子。我们有两个领域和两个类别来分类猫和狗。在这种情况下,我们可以得到表示。例如,对于领域1,我们可以得到由两种信息组成的表示:第一种是动物信息,第二种是水域信息。我们只覆盖了这些图像中的一些主要信息。类似地,我们可以得到领域2的表示:也是动物和草地。
我们希望对齐这两种表示,强制它们变得非常相似。实现这一目标的最简单方法是设置一个损失函数。最终,这个新网络只能学习动物信息,因为动物信息在不同领域间是共享的。
好的,基于这个例子,我将从数学上定义一些通用的损失函数。
这是基于正则化方法的典型损失函数:
总损失 = 标签分类损失 + λ * 正则化损失
第一项是标签分类损失,例如,在这个例子中,我们分类狗和猫。然后我们将对所有训练样本的损失进行平均。
然后,我们将定义一个显式的正则化项来学习领域不变的表示。这是这些基于正则化方法的关键部分。那么,如何定义这个正则化项呢?
算法示例:领域对抗训练
在我们深入介绍具体算法之前,我将首先回顾一下我们在上一讲中学到的领域自适应中的领域对抗训练。
其核心思想是:预测必须基于那些无法区分领域的特征。
例如,给定一个输入图像 X,我们将其输入到特征提取器 F_θ 中得到特征 Z。然后我们有两个分支:
- 第一个分支是标签预测器
G。我们旨在进行准确的标签预测。在领域自适中,我们只有源领域的标签,所以只有源领域的数据会进入这个分支。 - 第二个分支是领域分类器
D。我们旨在使模型无法根据这些特征预测该图像的领域。在这种情况下,我们可以学习一些领域不变的特征。源领域和目标领域的数据都可以进入这个分支,因为我们想在这里进行领域分类,以判断这些特征是来自源领域还是目标领域。
好的,现在我有一个问题。这是领域自适应中对抗训练的一个非常简单的版本。那么,有没有人知道如何在领域泛化设置中使用领域对抗训练?
我们希望我们的对抗器预测什么?对于每张图像,你想预测它对应的领域吗?例如,预测它是否是水域?是的,你想预测它对应的领域。
所以,我们将在这里提到的是,我们有标签预测器和领域分类器。在领域泛化设置中,与领域自适应不同,我们将所有源领域的数据都输入到这个标签预测器中,以预测其对应的标签。类似地,所有源领域的所有数据都将被输入到领域分类器中。与分类是来自源领域还是目标领域不同(因为在领域泛化设置中没有这样的定义),我们将预测每张图像的领域标签。
好的,基于这个定义,我将首先从数学上给出标签预测器和领域分类器对应损失的一些定义。
在标签预测中,我们的目标是进行标签预测。给定输入 X,我们将从 F_θ(x) 中提取一些特征 Z。然后我们将进行标签预测 G(Z) 以获得其预测值。我们将对每个样本求和,最终优化标签预测器和特征提取器的参数。这里损失越小越好,因为我们希望在源领域做出准确的预测。
对于领域预测,我们想预测这些领域,但实际上我们希望最大化损失。所以损失越大越好,因为更大的损失意味着对于平均输入样本,区分领域越困难。当我们无法区分领域时,我们就可以学习到一些领域不变的特征。
然后,我们将从通用公式推导出领域泛化中领域对抗训练的新公式。
领域泛化中的对抗训练损失如下:
总损失 = 标签分类损失 - λ * 领域分类损失
第一项是标签分类损失。第二项是我们设计的一个正则化器,用于学习领域不变的表示。
该算法有四个步骤:
- 随机初始化编码器、标签分类器和领域分类器。
- 尝试使用领域分类器损失
L_D来优化领域分类器D。 - 基于这些结果,通过同时考虑标签分类损失和领域分类损失来更新标签分类器
G和编码器F_θ。 - 重复步骤2和步骤3,直到收敛。
关于第二步的问题:我们是在尝试优化领域分类器使其表现得非常好,还是非常差?因为如果我们有一个非常好的领域分类器,那么它将迫使表示变得领域不变。是的,这意味着我们需要最小化领域分类损失,但在总损失中,我们通过负号 -λ * L_D 来最大化它(即最小化 -L_D)。所以我们需要同时优化这两个目标。
算法示例:CORAL
领域对抗训练利用对抗性优化来学习领域不变的特征。那么你可能会问,还有其他方法可以做到这一点吗?
接下来我将介绍一种称为 CORAL 的替代方法。CORAL 的核心思想是,它可以使用一些相似性度量直接对齐不同领域间的表示。
在 CORAL 中,它被称为“领域相关对齐”,尽管这个名字来自领域自适应,但近年来它也常用于领域泛化。这里我将只展示这个算法的领域泛化版本。
在这个算法中,我假设我们有两个领域。我们希望识别不同的物体。我们有一些共享层,这可以视为特征提取器,然后我们将使用特征输入到某个分类器中,以获得每个领域的分类损失。对于领域1,我们有一个分类损失,领域2有另一个分类损失。然后我们会有 CORAL 损失。在 CORAL 中,我们想直接对齐这两种表示。
在深入 CORAL 损失之前,我将首先给出一些符号表示。
符号 X1 是领域1的表示特征矩阵,维度为 n1 × k,X2 类似,是领域2的 n2 × k 矩阵。k 是特征数量。我们通过公式计算均值向量 μ1(维度 1 × k),类似地计算另一个领域的均值 μ2。然后我们将尝试计算 CORAL 中的协方差矩阵。CORAL 的目标是使这些协方差矩阵尽可能相似,以控制不同协方差矩阵之间的相似性。
在协方差矩阵中,这是我们数学课上学到的东西。为了得到这些协方差矩阵,我们使用公式:
C_i = (X_i^T X_i) / (n_i - 1) - μ_i^T μ_i
最后,定义一个 CORAL 损失,使特征间的协方差矩阵尽可能相同。CORAL 损失定义为两个协方差矩阵之间的 Frobenius 范数差异:
L_coral = || C_1 - C_2 ||_F^2
我们将结合所有不同样本的分类损失作为第一项,并设计一个 CORAL 损失作为显式正则化器来学习领域不变的表示。CORAL 背后的核心思想是使每个领域的协方差矩阵相似。
这可以扩展到两个以上的领域吗?是的,可以扩展,例如,对于领域3、4、5,可以有一个分类损失,并使用成对的 CORAL 损失来实现。
那么,对于不同的领域,我们有单独的编码器吗?通常人们会共享编码器。
正则化方法的结果与总结
对于结果,我展示一些来自 Office-Home、DomainNet 和 iWildCam 数据集的结果。在 Office-Home 中,我们有四个领域,我们将一个领域作为测试集,使用另外三个领域进行训练,然后将一个模型泛化到测试集。我们将重复这个过程四次,以便对每个领域进行评估。对于 iWildCam,如前所述,我们基本上希望将模型泛化到新地点以进行野生动物识别。
我们可以看到,与经验风险最小化相比,性能有时有所提升,但有时甚至损害了性能。我认为这解决了设计合适的正则化器非常重要的问题。
最后,对于这类方法,我将提到一些优缺点。
优点:
- 这些方法可以很好地泛化到各种数据和网络。例如,如果我们想将其更改为图数据或文本数据,我们只需要将共享层(骨干网络)从 CNN 更改为图神经网络或任何其他层。
- 这类方法也有一些理论保证。我不会深入探讨这一点,但如果有人对任何理论结果感兴趣,请给我发邮件,我可以发送一些论文来讨论。
缺点:
正则化器有时对表示的限制过于苛刻或约束性太强,正如我们看到 DANN 在某些数据集上不能很好地工作。

让我们也回顾一下为什么正则化器可能过于苛刻。例如,在这个例子中,我们回到狗与猫的分类。这是损失函数,如果我们直接添加显式正则化器,它会鼓励内部表示只包含关于背景的信息,但有时是混合的,所以我们还需要一些信息来进行分类。如果我们没有任何背景信息,甚至会损害我们学习更好的领域不变表示的能力
15:终身学习 I 🧠


在本节课中,我们将要学习终身学习。这是一个涵盖多种不同场景的领域,其问题定义并不总是非常明确。我们将探讨终身学习的基本方法,思考如何改进这些方法,并从元学习的视角重新审视问题定义,看看如何将元学习的思想应用于终身学习。
课程回顾与问题引入
在之前的课程中,我们讨论了多任务学习和元学习。
- 多任务学习:目标是同时解决一组训练任务,最终模型需要在这组任务上都表现良好。
- 元学习:目标是在一组训练任务上获得经验后,能够快速学习一个新任务。
然而,现实世界中很多场景并非一次性给出所有任务,而是按顺序一个接一个地出现。这与我们之前讨论的问题设置有所不同,因为你无法一开始就获得所有任务的大量数据,而是需要以更序列化的方式利用之前的经验。
以下是几个例子:
- 学生学习:学生按顺序学习学校里的概念,而不是一次性获得所有知识。课程可能由易到难,后面的任务建立在前面任务的基础上。
- 图像分类系统:系统从不同用户持续上传的图像流中学习。新用户在不同时间加入平台并开始上传图片。
- 机器人技能学习:机器人需要在不同环境中学习越来越多的技能,它可能会不断遇到需要学习的新事物或新环境。
- 虚拟助手:助手需要在不同时间帮助不同用户完成不同任务,新用户会不断到来。
- 医疗辅助系统:系统按顺序处理病例,而非一次性获得所有病例。
术语辨析与问题定义的多样性
上一节我们介绍了终身学习的应用场景,本节中我们来看看如何描述这类问题。文献中有很多术语来描述这类序列学习问题,包括在线学习、终身学习、持续学习、增量学习和流数据设置。不幸的是,这些术语并没有非常清晰的定义,经常被互换使用,导致这个领域的概念有些模糊。
需要区分的是:
- 序列学习:指随着数据按顺序到来而进行学习。
- 序列数据:指单个数据点本身具有序列结构(如时间序列)。
- 序列决策:指系统按顺序做出多个决策。
由于“终身学习”的定义缺乏共识,我们将通过一个练习来深入理解。
练习:定义你的终身学习问题
请选择一个示例场景(可以是之前提到的,也可以是你自己设想的),并在小组中讨论以下三点:
- 实验设置:如何设计实验来为该场景开发测试算法?
- 算法属性:对于这个具体问题,算法需要具备哪些期望或必需的属性?
- 系统评估:如何评估这样一个系统?
以下是供参考的示例场景:
- 学生学习课程
- 图像分类系统处理用户图片流
- 机器人学习一系列技能
- 虚拟助手帮助不同用户
- 医疗辅助系统处理病例
(小组讨论与分享环节略)
从各组的分享中,我们可以看到问题定义的多样性:
- 性能关注点:大多数情况下,我们希望模型在过去任务和新任务上都有良好表现。但在某些情况下(如课程学习),我们可能只关心最终任务的性能。
- 模型目标:有时我们希望学习一个能处理所有任务的单一模型;有时(如虚拟助手)我们更关心模型的适应性,因为不同用户可能有不同的目标。
- 任务序列:任务可能是独立同分布的,也可能是随时间可预测的,或者是按课程安排的。甚至可能是对抗性的序列(如垃圾邮件过滤)。
- 任务边界:可能有清晰的离散任务边界(如新用户),也可能是连续渐变的(如季节变化、舆情变化)。
- 资源考量:除了模型性能,我们可能还关心数据效率、计算资源、内存使用(无法存储所有历史数据)、隐私(不能存储敏感数据)、可解释性和公平性等。
这个练习的目的是阐明:根据你面对的具体问题,最重要的考量因素和约束条件会有所不同。因此,某些算法可能只适用于特定的问题设置。
问题形式化与核心概念
上一节我们探讨了问题定义的多样性,本节中我们来看看一个相对通用的形式化描述。一个简单而通用的在线/终身学习问题形式化如下:
在时间步 t,你观察到一个输入 x_t(如图像、病历),目标是预测其标签 y_t。做出预测后,你会观察到真实标签 y_t。这个过程不断重复。
公式表示:
对于 t = 1, 2, ...:
- 接收输入
x_t - 基于当前模型参数
θ_t预测ŷ_t = f_θ_t(x_t) - 接收真实标签
y_t,计算损失l(ŷ_t, y_t) - (可选)根据该数据点更新模型参数
需要注意的变体:
- 标签延迟:可能无法立即获得标签。
- 流式设置:由于数据量过大、计算资源有限或隐私考虑,不允许存储历史数据。
- 任务标识:如果数据来自一系列任务,你可能还会观察到任务标识符
z_t。
评估指标:遗憾
在在线和终身学习文献中,一个常见的评估指标是遗憾。它衡量了算法随时间累积的损失与“事后诸葛亮”最优策略的累积损失之间的差距。
公式:
Regret(T) = Σ_{t=1}^{T} l(f_θ_t(x_t), y_t) - min_θ Σ_{t=1}^{T} l(f_θ(x_t), y_t)
- 第一项:你的算法在所有时间步上的损失总和。
- 第二项:假设我们能纵观所有数据后,选择一个固定的最优参数
θ*,用这个参数在所有数据上计算得到的最小损失总和。
我们希望遗憾 Regret(T) 随时间 T 的增长尽可能慢(次线性增长)。线性增长的遗憾是平凡的(例如,始终输出一个固定预测值就能达到)。次线性增长意味着算法在不断进步,其平均性能在逼近最优固定策略。
迁移的类型
终身学习中一个核心概念是正向和负向迁移,以及前向和后向迁移。
- 正向前向迁移:由于见过先前任务,在未来任务上表现更好(相比从零开始学习)。
- 正向后向迁移:由于见过后续任务,在过去任务上表现更好(相比只见过过去任务时)。例如,当每个任务数据很少时,累积更多任务的数据后,可能对早期任务有更好的理解。
- 负向前向迁移:见过先前任务导致在未来任务上表现更差。
- 负向后向迁移:见过新任务导致在过去任务上表现更差(即遗忘)。这在内存有限、无法重复训练旧数据时非常常见。
迁移的衡量可以针对最终性能,也可以针对学习效率(如达到某个性能所需的数据量)。
基础算法与案例研究
上一节我们介绍了问题形式和评估概念,本节中我们来看看解决终身学习的两种基础方法。
方法一:存储所有数据并训练
在时间步 T,存储所有已见数据 D = ∪_{t=1}^{T} { (x_t, y_t) },然后训练一个模型最小化在该数据上的损失。通常不会每一步都从头训练,而是用上一步的模型参数进行热启动并微调。
- 优点:通常能获得很强的性能。
- 缺点:计算和内存开销大。需要存储所有历史数据。
这常被称为 Follow-the-Leader 算法。
方法二:随机梯度下降
在时间步 t,仅根据当前接收到的数据点 (x_t, y_t) 对模型参数进行一次(或几次)梯度更新。
- 优点:计算代价极低,除模型参数外几乎不需要内存。
- 缺点:容易发生负向后向迁移(遗忘),因为模型没有机会对旧数据重复学习。在非独立同分布的数据流上,这可能很严重。
这本质上就是随机梯度下降,但在这种严格的在线设置下,每个数据点只使用一次。
机器人抓取案例研究
一个实际案例是机器人抓取。首先在一个大型数据集(58万次抓取尝试)上预训练模型,在已知物体上达到86%成功率。但当面对新物体(如玻璃瓶)时,性能显著下降。
简单微调:在新场景数据与部分原始数据混合的数据集上微调预训练模型,能大幅提升新场景下的性能(例如,在透明瓶子上从49%提升到66%)。
序列学习应用:将上述方法应用于序列场景。每遇到一个新条件,就用上一个任务的模型参数初始化,并在新场景数据和原始预训练数据的混合集上微调。这种方法能持续提升在新场景上的性能。
然而,这种方法仍然依赖于保存部分原始数据。如果内存有限,无法保存旧数据,则仍会发生遗忘。
改进算法:梯度情景记忆
上一节我们看到,简单地微调需要存储数据,否则会遗忘。本节中我们探讨一种旨在用极少内存避免负向后向迁移的算法。
我们假设可以为每个任务存储一个非常小的情景记忆(例如,每个任务仅5个样本)。目标是:在学习新任务时,确保更新不会“遗忘”旧任务。
核心思想:
- 最小化新任务上的损失。
- 添加约束:对于所有旧任务
k,更新后的模型在旧任务记忆M_k上的损失,不应比更新前的模型更差。
公式化:
在时间步 t(对应任务 T),我们求解:
min_θ L_T(θ)
约束条件:对于所有 k < T, L_k(θ) ≤ L_k(θ_{t-1})
其中 L_k(θ) 是在任务 k 的记忆 M_k 上计算的损失。
实现挑战:直接施加损失约束很困难。一个实用的方法是施加梯度约束。我们要求,新任务上的更新方向,应该与每个旧任务损失函数的梯度方向尽可能一致或正交(在局部线性假设下)。这样能保证(或至少鼓励)更新不会增加旧任务的损失。
这可以形式化为一个二次规划问题来求解更新方向。
实验结果:
该方法(称为 GEM - Gradient Episodic Memory)在多个序列学习问题上进行了测试:
- 排列MNIST:每个任务是对MNIST图像像素的不同排列。
- 旋转MNIST:每个任务是对MNIST图像的不同旋转。
- 增量CIFAR-100:每个任务引入5个新类别。
在总内存固定(约500个样本)的情况下,GEM能够:
- 保持与训练独立模型或单一模型相当或更高的平均准确率。
- 显著减少负向后向迁移(遗忘),甚至获得少量正向后向迁移。
- 在某些任务上(如旋转MNIST)显示出正向迁移。
在线元学习
到目前为止,我们考虑的评估方式是模型在每个数据点到来时的即时性能。但对于任务序列,更现实的评估可能是:每遇到一个新任务,先给予少量数据用于适应,然后评估其在该任务上的性能。这更接近元学习的评估方式。
形式化:
对于每个到来的任务 T_i:
- 接收该任务的一个小训练集
D_i^{tr}。 - 应用某个更新过程
U(如梯度下降)于当前元参数φ,得到针对该任务的参数θ_i = U(φ, D_i^{tr})。 - 对于该任务的每个测试数据点
(x, y),用θ_i进行预测并计算损失。 - 根据损失更新元参数
φ。
我们可以定义类似遗憾的指标,但这里比较的是“最佳元学习器”与“事后最优元学习器”的累积损失差距。
算法:Follow-the-Meta-Leader
类似于存储所有数据的方法,但这里我们存储所有历史数据用于元训练。在每一步,我们用所有历史数据元训练得到一个更新过程 U,然后将这个 U 应用于新任务。同样,可以用上一步的元参数进行热启动。
优势:如果任务序列是非平稳的,基于优化的元学习器可能表现更好,因为它们能学习适应分布外任务的更新规则。
实验表明,在这种在线元学习设置下,元学习算法能够随着任务数量的增加,持续提升学习效率(需要更少的数据)和最终性能。
总结与要点 🎯
本节课中我们一起学习了终身学习的基础知识。
核心要点如下:
- 终身学习涵盖多种问题:存在许多不同形式的终身学习,但文献中常将它们统称为一个名字。因此,阅读论文时需仔细辨别其具体问题设置。
- 定义问题陈述是关键:定义清晰的问题陈述通常是终身学习中最难的部分之一,需要明确性能指标、约束条件和评估方式。
- 元学习是终身学习的一个子集:元学习关注如何利用先前经验来快速学习新任务,可以看作是终身学习在“快速适应”这一维度上的特例。
- 基础算法与改进:存储所有数据并训练(Follow-the-Leader)和在线SGD是两种基础方法。通过引入情景记忆和梯度约束(如GEM),可以在有限内存下减轻遗忘。
- 在线元学习:将评估方式调整为“先适应,后评估”,并应用元学习算法,可以实现随着经验积累而不断提升学习速度和性能的目标。

终身学习仍然是一个开放且活跃的研究领域,有许多有趣的问题等待探索。
16:前沿与开放挑战 I 🚀


在本节课中,我们将探讨元学习领域的最新研究趋势和激动人心的前沿方向。我们将重点关注如何利用元学习来适应数据分布的变化,以及如何学习比以往更通用的组件,例如优化器和网络架构中的对称性。最后,我们将讨论该领域一些突出的开放性问题与挑战。
课程安排与后勤事项 📅
首先是一些课程安排事项。项目海报展示会将在下周三举行。我们很快会在Ed平台上发布详细信息。由于选课学生众多,展示会将分为两个不同的场次,每位同学将被分配到其中一个场次。更多细节将很快在Ed上公布。
最终项目报告将在两周后的周一截止。
另外,关于之前感恩节假期前的高分辨率反馈,有几点需要说明。反馈主要涉及作业三和作业四的时间安排,我们将在下次开课时重新调整这个时间安排。
另一个多次被提及的问题是希望公布作业的参考答案。我们对此进行了大量讨论。这个问题总是有些棘手,特别是因为我们会在不同学期重复使用作业题目。这样做是为了保持作业的高标准和高质量。但这也意味着,如果我们本学期公布了答案,这些答案可能会流传出去,被未来的学生使用。过去我们曾遇到过学生将自己的答案发布在网上,导致其他学生抄袭的情况。我们不希望助长这种作弊行为。因此,我们决定不公布参考答案,这虽然有些遗憾。但如果你对作业中的错误、评分或其他任何问题有疑问,欢迎在Ed上发帖或参加答疑时间,我们非常乐意与你一起讨论作业的解决方案,希望这能起到与获得参考答案类似的效果。
本节课内容概述 🎯
我今天的计划是讨论一些我认为非常令人兴奋的最新研究趋势。这应该是一堂有趣的课,因为我将谈论一些我认为很酷的、处于研究前沿的东西。这包括用于适应分布变化的元学习,例如使用未标记样本进行适应,以及使用对模型期望修改的局部描述进行适应。
然后,我还将讨论如何元学习比我们过去所见更通用的东西。这包括尝试元学习一个可用于任何不同问题的通用优化器,以及尝试元学习神经网络架构中的对称性。
最后,我将简要谈谈我认为该领域中一些突出的开放性问题与挑战,以及我们可能如何开始着手解决这些挑战。
适应分布变化 🔄
首先,我们来谈谈适应分布变化。为什么这个问题很重要?我认为分布变化是一个非常引人入胜且重要的问题,因为它反映了现实的本质。
当前机器学习研究的范式是:获取数据,在该数据上训练模型,然后在一些保留数据上评估该模型。但在现实中,世界在不断变化。例如,股票、供需关系会变化,或者你的系统被部署到世界不同地区。因此,系统实际部署时遇到的数据,往往与训练时看到的数据不同。
我认为我们需要能够处理世界变化这一事实的算法,而不是仅仅部署一个静态系统。我也认为元学习可能是解决这一挑战的非常有用的工具,因为元学习可以训练出能够快速适应的系统。我们将在接下来的幻灯片中看到这一点。
既然这是当前面临的现实,你可能会问,业界是如何应对的呢?当人们在实践中使用机器学习时,他们如何应对世界不断变化的事实?你可以询问从事机器学习系统工作的Chip Puin,她指出,由于概念漂移,机器学习系统在生产环境中会迅速退化。对于在线机器学习系统,通常你希望尽可能快地更新它们,以应对因概念漂移而迅速退化的问题。
因此,我认为这是一个值得了解的有趣现象。这意味着我们通常开发机器学习系统的方式是基于这种“训练-测试”范式,而实际上它们在实践中的使用方式更像是这种持续训练的场景,这与最初的设想有所不同。所以,也许这意味着,如果我们想构建更好的机器学习系统,并开展与现实世界相关的研究,我们应该考虑到它们需要随时间不断更新这一点。
微调的局限性
微调是一种可靠且性能良好的方法,用于尝试随时间快速更新模型。但它也有一些局限性。
首先,它需要你从数据分布的新部分收集带标签的数据。这可能成本高昂、耗时,甚至可能无法获得。
其次,它可能在计算上很昂贵。尤其是随着模型越来越大,微调模型所需的计算量在某些时候会变得不太实际。
此外,它通常是一个相当生硬的工具。如果你只想对模型进行非常小的更改(例如,你发现了一个错误或某个小细节发生了变化),微调不一定是进行精确、小范围更改的最佳工具。
因此,接下来我将讨论我们如何能够利用元学习来实际解决微调的这些弱点。
领域偏移
首先,我们将关注领域偏移。这是我们在领域适应和领域泛化课程中看到的一种分布变化。在讨论完领域偏移后,我们将讨论一种更普遍的分布变化,称为概念偏移。
回顾一下,在领域偏移中,你有某种分类的领域变量。这可能对应不同的用户、不同的地点、一天中的不同时间等。通常,这种领域信息可以从你训练数据集中已有的元数据中推导出来。
领域偏移的假设是:你的训练数据来自这里的分布,而你的测试数据来自同一分布,但唯一改变的是这个底层领域变量的分布。这种分布变化相当普遍,也是我们在第一部分将要关注的变化,但它也有一些无法捕捉的情况。
分布鲁棒优化
现在,有一种方法。我们在领域适应和领域泛化的课程中看到了一些处理领域偏移的方法。一种我们没怎么讨论的方法是分布鲁棒优化。
这种方法的工作原理是:你尝试在领域变量上形成一个对抗性分布,然后针对最坏情况的分布进行优化。具体来说,你可以制定一种对抗性优化,目标是找到一个在领域的最坏情况分布下表现良好的模型。如果你有一个分类的领域变量,这实际上相当容易评估:你只需选择模型在训练数据集上表现最差的领域,然后针对该领域的性能进行优化,并迭代这个过程。
这种对抗性优化可以实现对不同领域的鲁棒性。它也可能比另一种你可能听说过的鲁棒性——对抗鲁棒性——不那么悲观。但它通常会牺牲平均性能或经验性能,因为它对测试时将看到的数据或领域实际上相当悲观。
自适应风险最小化
因此,我们要尝试做的是制定一种替代范式,它不那么悲观,但仍然允许我们保持相当的鲁棒性。我们将通过以下方式实现:不是针对最坏情况的领域进行优化,而是尝试针对每个给定领域经过少量适应后的领域性能进行优化。
具体来说,这意味着:我们假设我们拥有来自测试领域的未标记数据。这可能是来自新用户、新时间段或新地点的未标记数据。例如,如果你想识别手写体(这是来自联邦扩展MNIST数据集的数据,都来自一个用户),你可能拥有来自该用户的一批未标记数据。
你的目标是利用这些未标记数据,将你的模型适应到该用户,然后推断出该批次中所有样本的标签。
这种方法在几个方面与其他方法不同:
- 与微调不同,它只需要未标记数据来适应模型,而不需要带标签的数据。
- 与领域泛化和领域适应等方法不同,我们不假设在训练时能访问这些未标记数据。我们实际上是在测试时即时适应模型。
这种方法做出的主要假设(实际上是两个主要假设)是:首先,你的训练数据集中有领域标签;其次,在测试时,你一次性获得来自同一组或同一领域的一批测试输入,而不是只有一个样本。这与标准的机器学习设置略有不同,后者通常假设测试时一次只有一个输入。
我们将这个问题设置称为自适应风险最小化,因为你不是直接评估给定样本的风险,而是有机会用少量样本进行适应。
如何实现自适应风险最小化
接下来的问题是,如何优化这个问题,以及如何开发一种方法,让你能够仅用来自分布新部分的未标记数据进行适应。
为此,我们可以实际训练一个模型,使其能够对训练数据集中的不同领域进行小样本适应。这基本上会使用你在课程早期部分看到的相同的元学习算法。
关键的不同之处在于:我们不是进行小样本带标签适应,而是只获得未标记数据。因此,我们希望能够用这些未标记样本进行适应,而不是用几个带标签的样本。
有几种不同的方法可以做到这一点:
- 你可以使用MAML算法,但由于无法计算标准的交叉熵损失函数,你可以元学习一个损失函数,并使用这个元学习的损失函数,使得当你在未标记数据上用该损失函数进行适应时,在训练集的每个领域上都能表现良好。
- 具体来说,你将同时元学习初始参数以及由神经网络表示的某个损失函数的参数。
- 在内部循环中,使用该损失函数从初始参数更新网络,得到一个新网络,然后优化整个系统,使其在训练领域的每个领域上都能获得良好的性能。
- 或者,你也可以使用黑盒方法,简单地将所有未标记样本输入到一个产生某种上下文的神经网络中,然后使用该上下文对你的样本进行预测。这种黑盒方法实际上相当直接,因为要修改黑盒方法使其在没有标签的情况下工作,唯一需要做的就是在将数据作为输入传递时去掉标签。
- 有几种不同的架构可以用于这种黑盒方法。一种是这里显示的架构,你只是预测这个上下文并将其传递到网络中。
- 或者,这个上下文可以用不同的方式计算。一种非常简单的方法是让上下文对应于批归一化统计量。这意味着你将所有样本作为一批输入,不是使用训练数据集的批归一化统计量,而是在测试时使用你所有的样本即时计算它们。
实验结果
论文中有很多不同的实验,这里我只提几个。
第一个是之前展示的联邦扩展MNIST示例。在这个案例中,所有实验都试图适应具有不同笔迹的新用户,测试时只有来自这些用户的未标记数据可用。
实验与多种方法进行了比较,包括标准经验风险最小化、之前提到的组鲁棒性方法、领域对抗训练,以及一种非常简单的上采样方法(对每个用户的数据进行上采样,使其分布均匀,从而等概率地从他们中采样数据)。
然后,我们可以观察在这些新用户上的平均测试性能,以及最差用户的性能。这种最差情况性能很有用,因为它能给你一个公平性的概念(你是否在某些用户上表现极差,而在其他用户上好得多),也能给你一个鲁棒性的概念(如果你的分布更多地转向那些最差情况的用户,你的性能会如何)。
观察数据,首先在平均准确率方面,我们看到领域对抗神经网络实际上比经验风险最小化表现稍好。但通过使用上下文变量进行适应,我们可以获得大约5%的提升。
在最差情况准确率方面,我们也看到了大约5%的提升,超过了现有最佳方法(在这个案例中是上采样或领域对抗训练)。
我们还可以定性地看看它在做什么。这里有一个例子:系统被给定了这张图片。如果你问用经验风险最小化训练的神经网络,它会告诉你这是“2”。同样,如果你问自适应风险最小化(使用上下文变量的元学习模型),给它这两个例子并询问标签,它也会说是“2”。
但是,如果你实际上给它更多上下文,比如所有这些未标记样本,它就能正确判断出这实际上对应的是小写字母“a”。它之所以能做到这一点,是因为它可以查看其他例子(例如这个例子),并意识到这个特定用户经常写不带圈的“2”。因此,这一定是小写字母“a”而不是“2”。本质上,系统正在适应这个特定用户,调整模型以适应该用户,从而能更准确地为该用户做出预测。

我将提到的另一个实验是关于适应不同的图像损坏。这是使用CIFAR-10-C和Tiny ImageNet-C数据集进行的。训练时使用了56种不同的损坏,然后测试其适应在训练中未见过的另外22种损坏的图像的能力。
同样,我们看到领域对抗神经网络方法是先前表现最好的方法之一,尽管它的表现实际上与标准经验风险最小化有些相似。相比之下,通过实际适应并训练快速适应未标记数据的能力,我们能够在平均准确率上获得约2-3%的提升,在最差组准确率上获得7-9%的提升。

概念偏移
现在,我们来看看其他形式的分布变化。具体来说,接下来我们将看一种称为概念漂移或概念偏移的分布变化。这是指基本上整个 P(y|x) 分布可能发生变化。实际上,在我们将要看的大多数例子中,P(x) 不会改变,只有 P(y|x) 会改变。

需要注意的是,当 P(y|x) 发生变化时,你需要某种监督信息来适应这种分布变化,因为 P(y|x) 可能以多种不同的方式变化。
具体来说,在这种情况下,我们将在语言模型的背景下研究如何处理这种分布变化,尽管我们将要看的许多方法也适用于语言模型之外。

作为一个激励性的例子,如果你拿今年早些时候访问过的一个版本的GPT-3,问它“最大的英语欧盟国家是哪个?”,它会告诉你答案是“英国”。但当然,英国已不再是欧盟成员国,所以这个答案不正确,正确答案应该是“爱尔兰”。如果你问它“阿尔及利亚现任总统是谁?”,它也会给出一个过时的答案。同样,如果你问它“梅西效力的俱乐部球队是哪个?”,它也会给出过时的信息。
因此,问题是我们在这个场景下应该做什么?我们应该如何尝试更新像GPT-3这样的模型,使其能够对不断变化的世界做出正确的预测?不幸的是,重新训练甚至微调GPT-3都会非常昂贵。因此,我们希望能够在不需要微调或完全重新训练整个模型的情况下,找出如何保持这些大型模型的最新状态。
模型编辑框架
这就是编辑框架可以发挥作用的地方。理想的情况是,我们可以拿我们的基础模型(如果你问它“英国首相是谁?”,它会告诉你答案是“特蕾莎·梅”,这在以前当然是正确的,但那也是三任首相之前的事了),然后我们可以拿这个例子告诉它答案应该是“里希·苏纳克”,并将其传递给一个模型编辑器,从而得到一个编辑后的模型,该模型可以给我们正确的答案,包括对问题的重新表述或其他在范围内的内容(例如,“里希·苏纳克是英国首相吗?”)。
此外,我们不仅希望它对范围内的输入给出正确答案,还希望我们能够询问范围外且不相关的事情(例如,“梅西为谁效力?”),并仍然得到正确答案。也就是说,我们不希望编辑影响与编辑无关的事情。
具体来说,为了更清晰地界定这个问题,也许你的编辑示例是“英国首相是谁?”。范围是与该输入相关的输入空间,包括问题的重新表述。也有一些超出范围的例子,比如“天空为什么是蓝色的?”。值得一提的是,有些例子既在范围内又超出范围,处理起来会更困难。例如,“里希·苏纳克不是首相的地方是哪里?”这属于范围内,但比简单的重新表述要更远、更困难。同样,有些看似相关但不应在编辑模型时改变的事情,这些实际上是最具挑战性的情况。当我们实际进行一些实验时,我们将重点评估这些例子,而不是像“天空为什么是蓝色的?”这样简单的例子。
将编辑问题构建为元学习问题
我们可以将这个问题构建为一个元学习问题。Cizein等人在2020年发表的一篇很酷的论文,将这个问题构建为元学习问题,试图训练一个能够以非常具体的方式进行编辑的神经网络。不幸的是,这篇ICLR 2020论文中的具体方法不太能扩展到大型语言模型。因此,就我们将要介绍的方法而言,我们将介绍一些更近期的、可扩展性更强的工作,但正是那篇论文引入了在元学习设置中进行这种操作的范式。
为了将其构建为元学习问题,我们假设我们有能力收集一个数据集,该数据集向我们展示应该如何进行编辑的示例。具体来说,这些数据将包含:
- 编辑的描述符。这可以是一个输入-输出对,例如“英国首相是谁?”和“答案是里希·苏纳克”。
- 一个超出范围的示例。这将试图强制模型不应在这些超出范围的示例上发生变化。
- 范围内输入-输出对的示例。具体来说,如果给出一个像“英国首相目前是谁?”这样的例子,它会被告知该问题的新答案应该是什么。
因此,这个编辑数据集本质上是我们用来教导模型编辑器如何编辑模型的东西。收集这个编辑数据将是一项不简单的任务,但一般来说,如果我们收集足够通用的编辑数据,其中包含我们可能想要对模型进行的各种不同类型编辑的示例,那么我们只需要使用它一次、收集一次,就可以训练一个单一的模型编辑器,用于对大型模型进行各种编辑。
模型编辑方法一:修改梯度
一旦我们有了那个编辑数据集,有几种不同的方法可以训练这些模型编辑器之一。
第一种方法试图实际改变梯度并更新模型的权重。具体做法是:它将对应于在该单个编辑示例上微调模型的梯度作为输入,并尝试将该微调梯度转换为对模型更好的更新。
这可以用这张图来概括:如果你有预训练模型并想对其进行编辑,那么你计算如果在该编辑上进行微调会得到的梯度,然后将该梯度传递给这个模型编辑器,模型编辑器将输出一个修改后的梯度,你实际上将使用这个梯度来编辑模型。一旦你将这种修订版的梯度应用到模型上,目标将是让它对这些编辑给出正确答案,当然,也不影响模型在其他示例上的输出。
因此,这里的主要组成部分就是训练中间这个单一的模型编辑器,它以梯度为输入,输出该梯度的修改版本。训练方式是使用编辑数据集:训练它使其在范围内泛化示例上输出正确的预测,并且它应该保持原始模型在给定超出范围示例时的输出分布。所以损失函数中有两项。
关于计算成本:是的,你仍然需要计算梯度。但一个重要点是,我们只对模型应用一次更新。所以我们将输出一个修改后的梯度,使得仅该梯度的一步更新就能得到一个好模型。因此,它比微调需要更少的更新步骤。其次,它也会比微调效果更好,因为通过训练它这样做,它会给你一种更有效地进行针对性编辑而不影响范围外示例的东西。
关于梯度分析:不幸的是,分析起来有点困难。我猜它可能在某种程度上增加了规模,但它肯定不止于此。一般来说,解释神经网络的权重和梯度都很困难。不过,我提到一点:单个示例的梯度实际上是一个秩为1的矩阵。如果你有一个权重矩阵并计算其梯度,它对应于前向激活和从B层反向传播的梯度的外积。因此,它基本上是两个向量的外积,所以实际上是一个秩为1的矩阵。这个名为MEND的模型编辑器做的一件很酷的事情是,它实际上进行了分解:不是传入权重矩阵,而是将两个秩为1的分量传入网络,并输出一个秩为1或低秩的模型更新。结果,这个模型编辑器的输入和输出的维度要小得多。具体来说,如果这是像H和H_B这样的激活大小,那么这个权重矩阵是H乘以H_B,而两个秩为1项的维度是H加H_B。这意味着输入的维度将比输入和输出整个权重矩阵要小得多。
模型编辑方法二:半参数化方法
在介绍一些结果之前,我还要展示第二种模型编辑方法,它试图不更新模型的权重。第二种方法的动机是,第一种方法在扩展到大量编辑时有些困难,因为实际上很难找出如何以能进行此类针对性编辑的方式来改变权重。

因此,第二种方法将尝试采用一种更半参数化的方法。我们将拥有我们的基础语言模型,但不更新这个语言模型的权重,而是将其完全冻结。相反,我们将尝试在该语言模型周围形成一个包装器,使得包装后的语言模型在应用编辑后能给出你想要的行为
17:上下文学习(Percy Liang 客座讲座)🧠


在本节课中,我们将跟随斯坦福大学副教授 Percy Liang 的客座讲座,深入探讨大型语言模型(如 GPT-3)中一个令人着迷的现象——上下文学习。我们将理解其定义、重要性,并通过理论和实验分析其工作原理。
概述
上下文学习是指模型仅通过观察提示中的几个示例,就能学会执行新任务的能力。这挑战了传统机器学习“训练-测试”分布需一致的范式。本节课将分两部分探讨:首先,分析固定模型(如 Transformer)如何实现上下文学习;其次,探讨这种能力如何通过简单的训练目标(如下一个词预测)涌现出来。
第一部分:Transformer 如何执行上下文学习?🔍
上一节我们概述了上下文学习的现象。本节中,我们来看看一个固定的模型架构(如 Transformer)是如何具备这种能力的。
为了严谨地研究这个问题,我们首先需要形式化“学习”的定义。这里,我们借鉴统计学习理论的思想,将上下文学习定义为模型对一个函数类的学习能力。
定义:函数类的上下文学习
- 我们定义一个函数类(例如,所有20维的线性函数)。
- 每次评估时,我们从这个类中采样一个具体的函数
f。 - 然后,我们采样一些输入
x1, x2, ..., xk,并计算对应的输出yi = f(xi)。 - 我们将这些
(xi, yi)对作为上下文示例输入模型,最后给出一个新的查询输入x_query。 - 模型的任务是预测
y_query = f(x_query)。
在这个框架下,我们使用一个经过修改的 Transformer 进行实验:输入是实数向量,输出层直接进行回归(使用平方损失),而不是预测词表分布。
以下是我们在不同函数类上的实验结果:
1. 线性函数
- 观察:随着上下文示例数量增加,Transformer 的预测误差下降曲线与最小二乘法的最优性能几乎重合。
- 对比:简单的基线方法(如平均法、最近邻法)效果很差。
- 结论:Transformer 学会了模仿最小二乘法的行为。
2. 稀疏线性函数(如仅3个非零权重)
- 观察:此时最优算法是 LASSO(L1正则化)。Transformer 学会了模仿 LASSO 的行为,其性能优于普通最小二乘法。
- 关键点:模型需要经过在稀疏函数分布上的训练才能获得此能力,这并非凭空产生。
3. 两层ReLU神经网络
- 观察:Transformer 的表现与梯度下降算法优化该网络的效果相匹配。
4. 决策树
- 观察:在合成的数据分布上,Transformer 的性能甚至超过了 XGBoost 这种手工设计的先进算法。
探究模型的鲁棒性与归纳偏好
仅仅在分布内表现良好还不够,我们还需要测试模型的泛化能力。我们通过改变测试时输入 x 的分布来进行探究:
- 协方差偏移:当测试数据来自不同协方差的高斯分布时,Transformer 性能有所下降,但依然近似遵循最小二乘法的趋势。
- 标签噪声:在测试时加入标签噪声,最小二乘法会出现“双下降”现象。有趣的是,Transformer 也表现出类似的误差峰值,这与其近似实现最小二乘法的观察一致。
- 架构对比:在相同实验设置下,LSTM 模型在分布内表现类似,但在面对协方差偏移时,并未表现出与 Transformer 相同的双下降现象,这表明不同架构具有不同的归纳偏好。
第一部分小结
综上所述,我们可以得出以下结论:
- 我们可以严谨地定义模型对某个函数类的上下文学习能力。
- Transformer 能够通过训练,学会模仿多种经典机器学习算法(如最小二乘、LASSO、梯度下降)。
- 模型大小至关重要,更大的模型通常在分布外泛化中表现更好。
- 模型的归纳偏差影响了其学习的“算法”,Transformer 的架构使其倾向于学习某些类型的算法。
仍然存在许多开放问题:Transformer 内部究竟表示了什么函数?其他架构(如图神经网络)表现如何?能否从这些模型中发现新的算法洞察?
第二部分:上下文学习如何从预训练中涌现?🌱
上一节我们探讨了固定模型如何执行学习。本节中,我们来看看这种能力是如何通过简单的预训练(如下一个词预测)获得的。核心挑战在于分布偏移:预训练数据分布与提示(包含多个任务示例)的分布是不同的。
贝叶斯推断视角
一个理解上下文学习的强大框架是贝叶斯推断。
- 将任务本身视为一个潜在的随机变量
θ(例如,一个线性函数的权重)。 - 每个示例
(xi, yi)都是在给定θ的条件下生成的。 - 在观察到 K 个上下文示例后,我们对
θ的后验分布进行推断。 - 最终对查询
y_query的预测,是综合了所有可能θ的后验预测分布。
公式表示如下:
P(y_query | x_query, D) = ∫ P(y_query | x_query, θ) * P(θ | D) dθ
其中 D = {(x1,y1), ..., (xk,yk)} 是上下文示例集。
上下文学习模型正是在尝试直接近似这个后验预测分布。
分析分布偏移:一个理论模型
为了分析预训练与提示分布不同带来的影响,我们构建了一个简单的理论模型:
- 预训练分布:文档是从一个隐马尔可夫模型的混合中生成的,其中混合成分
θ代表主题(如“维基百科传记”)。 - 提示分布:我们固定一个目标主题
θ*,但生成多个独立的短序列(用分隔符隔开),模拟上下文示例中快速切换但主题相关的文本。
关键点:提示分布中的“分隔符”和主题重置是预训练分布中的低概率事件,这造成了分布偏移。

我们的理论分析表明,如果不同主题 θ 生成的文本分布差异足够大(信号强),能够压倒因分布偏移引入的误差,那么随着上下文示例 K 的增加,模型依然能渐近地正确推断出 θ* 并做出准确预测。

实践启示与实验验证
这个视角带来一些实用提示:
- 提示设计:应使提示格式尽可能接近模型的自然训练数据。例如,使用自然语言描述任务,并使用中立的分隔符(如换行符),而非带有强烈语义的词语。

我们基于混合 HMM 创建了一个小型合成数据集进行实验验证:
- 结果:Transformer 和 LSTM 都能进行上下文学习,且更长的示例(更接近预训练分布)能带来更好的性能。
- 一个有趣现象:增大模型规模能提升上下文学习准确率,即使预训练损失保持不变,这可能意味着模型规模带来了更好的上下文学习归纳偏差。
解释现实中的奇特现象
贝叶斯视角有助于解释一些经验发现:
- 随机标签实验:即使将上下文示例中的标签替换为随机值,GPT-3 的性能下降也远小于完全移除示例。这是因为输入
x本身仍提供了关于任务θ的信息,而随机标签可能被模型部分“忽略”或平均掉。 - 标签重映射实验:如果系统性地将标签重映射(如“体育”->“蔬菜”),GPT-3 能迅速适应新映射并保持一致。这展示了模型强大的变量绑定和上下文依赖推理能力,超出了我们当前简单理论框架的解释范围。
第二部分小结

我们可以总结如下:
- 贝叶斯推断为理解上下文学习提供了一个统一的理论框架,其核心操作“条件化”与上下文学习完全对应。
- 分析预训练分布与提示分布之间的差异是理解能力涌现的关键。
- 即使存在分布偏移,在一定的分离度条件下,上下文学习仍然可以奏效。
- 一些经验性的提示技巧(如使用自然语言、中立分隔符)可以从该框架中得到直观解释。
总结与展望 🚀
本节课中,我们一起深入探索了上下文学习这一现代AI的核心谜题。
- 第一部分 通过合成实验证明,Transformer 架构能够被训练来执行对多种函数类的上下文学习,并模仿经典算法。
- 第二部分 引入了贝叶斯推断视角,将上下文学习视为对后验预测分布的近似,并初步分析了从预训练中涌现该能力所需的条件。
上下文学习不仅仅是一个技巧,它代表了机器学习范式的转变,使得快速任务原型设计成为可能。然而,其可靠性仍需深入理解。

未来的研究方向包括:
- 将合成研究的洞察与融合了先验知识的真实任务联系起来。
- 探索除上下文学习外的其他涌现能力(如思维链、算术推理)。
- 超越传统的“任务”框架,思考语言模型更本质、更复合的能力。


理解上下文学习,不仅是科学探索,也是构建更可靠、更强大AI系统的工程关键。

浙公网安备 33010602011771号