剪枝可以以不同单位进行:
以参数为单位:评估并移除单个权重参数。
以神经元为单位:评估并移除整个神经元。
这两种方式在实践中有显著差异。以参数为单位剪枝会导致网络结构变得不规则,给实现和 GPU 加速带来困难。通常的变通方法是将“剪掉”的参数设为零,但这并未真正减少参数存储。而以神经元为单位剪枝,网络结构保持规则,更易于实现和加速。
大乐透假说
在了解了剪枝的基本操作后,一个自然的问题是:为什么不直接训练一个小型网络,而非要先训练大型网络再剪枝呢?
普遍答案是:大型网络通常更容易训练。直接训练的小型网络往往无法达到“大型网络剪枝后”的小型网络的性能。这引出了著名的“大乐透假说”。
该假说认为,训练神经网络如同抽奖,初始参数的好坏直接影响结果。大型网络可以看作是许多小型子网络的组合。训练大型网络相当于同时训练所有这些子网络。只要其中有一个子网络成功“中奖”(即训练良好),整个大型网络就表现为成功。网络越大,包含的子网络越多,“中奖”几率就越高。
实验上,该假说通过剪枝相关实验得到验证:从训练好的大型网络中剪枝得到的小型网络,如果使用剪枝后对应的原始初始化参数,能够成功训练;但如果对这些参数重新随机初始化,则可能训练失败。这表明,剪枝后保留的参数恰好构成了一个“幸运”的、可训练的子网络初始化状态。
大乐透假说在 ICLR 2019 获得了最佳论文奖,非常知名。后续研究,如Deconstructing Lottery Tickets,进一步发现:
剪枝策略中,某些方法特别有效。
初始化参数中,正负号比绝对值更重要,是决定子网络能否训练成功的关键。
甚至在大型随机初始化的网络中,可能已经存在一个无需训练、剪枝后即可直接使用的有效子网络分类器。
然而,大乐透假说并非没有争议。同期另一篇论文Rethinking the Value of Network Pruning提出了不同观点。其实验表明,如果为直接训练的小型网络设置更多的训练周期(epoch),其性能可以媲美“先训练大再剪枝”得到的小型网络。该文认为,大乐透假说观察到的现象可能只在特定条件下(如学习率较小、非结构化剪枝)成立。因此,这一领域仍需更多研究来厘清。
总结
本节课我们一起学习了神经网络压缩的重要性及其首个关键技术——神经网络剪枝。我们了解了剪枝的基本流程、以不同单位(参数/神经元)剪枝的利弊,并深入探讨了解释“为何要先大后小”的大乐透假说及其相关实验与争议。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/67437bb0dddcc377b9207593e2120900_3.png
神经网络剪枝是模型压缩的有效手段,它帮助我们在资源受限的设备上部署高性能的模型。理解其背后的原理(如大乐透假说)能让我们更好地应用和探索这一技术。
37:L21.2 - 神经网络压缩2:从各种不同的面向来压缩神经网络 🧠
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_1.png
在本节课中,我们将要学习神经网络压缩的多种方法。上一节我们介绍了网络剪枝,本节中我们来看看知识蒸馏、参数量化、网络架构设计以及动态计算等不同面向的压缩技术。
知识蒸馏 (Knowledge Distillation) 🧑🏫
知识蒸馏的核心概念是让一个小的“学生”网络去学习一个大的“教师”网络的输出行为,而不仅仅是学习原始的训练标签。
基本概念与流程
知识蒸馏的过程如下:首先,训练一个大型神经网络,称为教师网络。然后,训练一个较小的神经网络,称为学生网络。学生网络的学习目标不是直接匹配训练数据的真实标签,而是去匹配教师网络对相同输入产生的输出分布。
例如,在手写数字识别任务中,教师网络的输出可能是一个概率分布,如数字“1”的概率是0.7,“7”的概率是0.29,“9”的概率是0.01。学生网络的目标就是让自己的输出分布尽可能接近这个由教师网络产生的“软标签”。
为何有效?
你可能会问,为什么不直接训练一个小网络呢?一个直观的解释是,教师网络为学生网络提供了额外的、更丰富的监督信息。直接告诉学生网络“这是一张‘1’的图片”可能过于困难,因为‘1’可能与‘7’或‘9’有相似之处。而教师网络的软标签(如‘1’: 0.7, ‘7’: 0.29)则揭示了类别之间的相似性,使学生网络更容易学习。
公式描述:学生网络的损失函数通常结合了与教师网络输出的KL散度(或交叉熵)以及与真实标签的交叉熵。
总损失 = α * 蒸馏损失(学生输出 vs 教师软标签) + (1-α) * 学生损失(学生输出 vs 真实硬标签)
技巧:温度参数 (Temperature)
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_3.png
为了使教师网络的输出分布更平滑,从而传递更多类别间关系的信息,常在Softmax函数中引入温度参数T。
代码描述:
# 普通Softmaxoutput=torch.softmax(logits,dim=-1)# 带温度参数的Softmaxtemperature=5soft_targets=torch.softmax(logits/temperature,dim=-1)温度T大于1时,会软化概率分布,使各类别的概率差异变小,从而让学生网络能更好地从教师网络学习到类别间的相对关系。
集成模型作为教师
教师网络不一定是单个大模型,也可以是多个模型的集成。集成模型通常能获得更高的准确率,但推理成本高昂。通过知识蒸馏,可以让单一的学生网络去学习集成模型的输出,从而在保持较高性能的同时大幅降低计算开销。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_5.png
参数量化 (Parameter Quantization) ⚖️
参数量化的目标是通过降低存储每个参数所需的精度来减少模型大小。请注意,此方法在本次作业的评估标准(参数数量)中可能不直接受益,但仍是一种重要的压缩技术。
基本方法
最简单的量化方法是降低参数的数据类型精度,例如从32位浮点数转换为16位甚至8位整数。这通常能在模型性能损失很小的情况下,将模型体积减半或更多。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_7.png
权重聚类 (Weight Clustering)
更进一步的压缩技术是权重聚类。其步骤如下:
对所有网络权重进行聚类(如K-means),将数值相近的权重归为一类。
每个类用一个代表值(如类中心)来表示。
存储时,只需保存聚类中心表和一个记录每个权重属于哪个类的索引表。
以下是权重聚类的操作步骤:
设定聚类数目K(例如4类)。
对所有权重进行聚类分析。
用聚类中心值替代原始权重值。
存储时,保存K个中心值和每个权重对应的聚类索引。
当K值较小时,存储索引所需的比特数远小于存储原始权重值。例如,若K=4,则每个权重只需2个比特来存储其类别索引。
极致压缩:二值化权重 (Binary Weight)
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_9.png
参数量化的终极形式是二值化权重,即每个权重只能是+1或-1。这样每个权重仅需1个比特存储。研究表明,在某些情况下,二值化网络由于引入了极强的正则化,反而可能比全精度网络表现更好,因为它能有效防止过拟合。
网络架构设计 🏗️
通过设计更高效的网络层结构,可以直接减少参数量。本节介绍深度可分离卷积,这是本次作业中突破强基线(strong baseline)的关键方法。
回顾标准卷积
在标准卷积层中,每个滤波器都是一个三维张量(高 x 宽 x 输入通道数)。假设输入特征图有I个通道,使用O个大小为K x K的滤波器,则参数量为:
参数量 = K * K * I * O
深度可分离卷积 (Depthwise Separable Convolution)
深度可分离卷积将标准卷积分解为两个步骤,大幅减少计算量和参数量。
第一步:深度卷积 (Depthwise Convolution)
每个输入通道独立使用一个二维卷积滤波器。
输入有
I个通道,就使用I个滤波器。每个滤波器只与一个输入通道进行卷积,输出
I个通道的特征图。此步骤负责处理空间特征,但通道间无交互。
参数量:
K * K * I
第二步:逐点卷积 (Pointwise Convolution)
使用
1x1大小的标准卷积。其作用是将深度卷积输出的
I个通道的信息进行融合,并变换到指定的输出通道数O。此步骤负责处理通道间的关系。
参数量:
1 * 1 * I * O = I * O
总参数量对比:
标准卷积:
K * K * I * O深度可分离卷积:
K * K * I + I * O
两者比值为1/O + 1/(K*K)。当O较大时,比值约等于1/(K*K)。例如,当K=3时,深度可分离卷积的参数量约为标准卷积的1/9。
原理:低秩近似 (Low-rank Approximation)
深度可分离卷积的本质是将一个全连接层(或卷积层视为一种全连接)分解为两个更薄层的连续操作。这种分解限制了权重矩阵的秩,从而减少了自由度(参数量),但通常能以较小的性能损失换取显著的空间节省。
动态计算 (Dynamic Computation) ⚡
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_11.png
动态计算的目标不是单纯地让网络变小,而是让同一个网络能够根据可用的计算资源(如设备电量、算力)动态调整其计算成本。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_13.png
调整网络深度
一种方法是让网络能在中间层提前输出结果。具体做法是在网络的某些中间层后添加辅助分类器。训练时,要求所有辅助分类器和最终分类器的输出都尽可能接近真实标签。推理时,资源紧张则使用浅层的输出,资源充足则使用深层输出。
调整网络宽度
另一种方法是让网络能选择性地“关闭”一部分神经元(即使用子网络)。在训练时,同时优化多个不同宽度的子网络(共享权重),使它们都能取得良好性能。推理时,根据资源选择激活的神经元比例。
基于输入难度的动态计算
更智能的方法是让网络根据输入样本的难度自行决定需要多少计算。对于简单的样本(如清晰的猫图片),网络可能早期层就能做出准确判断并提前退出;对于困难的样本(如伪装成食物的猫),网络则会使用全部层进行计算。这可以在不牺牲精度的前提下,平均减少计算量。
总结 📚
本节课中我们一起学习了多种神经网络压缩与加速技术:
知识蒸馏:让小模型学习大模型的输出分布,传递暗知识。
参数量化:通过降低权重精度、聚类或二值化来减少存储开销。
网络架构设计:采用如深度可分离卷积等高效结构,从根本上减少参数量。
动态计算:使网络能根据资源或输入难度灵活调整计算成本。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/9979f1055e63e7f5432fa510da72db8c_15.png
这些技术并非互斥,在实际应用中常被组合使用,以在模型大小、速度和精度之间达到最佳平衡。掌握这些方法,将有助于你将强大的深度学习模型部署到资源受限的实际环境中。
38:L22.1 - 元学习1:元学习跟机器学习一样也是三个步骤 🧠
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/737139ede263592daca23d997bccebbc_1.png
在本节课中,我们将要学习元学习的基本概念。元学习,即“学习如何学习”,是机器学习领域的一个高级主题。我们将看到,元学习的基本框架与传统的机器学习非常相似,同样遵循三个核心步骤。
什么是元学习?🤔
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/737139ede263592daca23d997bccebbc_3.png
元学习中的“元”字,通常翻译为“元”,如“一元复始”中的“元”。从字面意思看,元学习是关于“学习的学习”。因此,元学习可以理解为学习如何学习。这与我们之前讨论的机器学习处于不同层次,是迈向更高级领域的一步。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/737139ede263592daca23d997bccebbc_5.png
为什么需要元学习?🔧
在深度学习中,调整超参数(如学习率、网络架构)是一项繁琐且关键的任务。目前,业界常用的方法是使用大量GPU同时训练多个不同超参数的模型,然后选择表现最好的一个。然而,在学术环境中,资源往往有限,通常只能依靠经验和直觉来设定超参数。
既然机器学习可以自动学习模型,那么超参数是否也能通过学习得到呢?这就是元学习可以发挥作用的地方之一。
回顾机器学习 📚
在深入元学习之前,让我们先回顾一下机器学习的基本框架。你会发现,元学习的基本思想与机器学习并无太大差异。
机器学习就是寻找一个函数。例如,构建一个图像识别系统,就是寻找一个输入图片、输出识别结果的函数。机器学习包含三个步骤:
定义一个带有未知参数的函数。在深度学习中,这通常是一个神经网络。我们用F_θ表示这个函数,其中θ代表网络中的权重和偏置等待学习的参数。
定义一个损失函数。损失函数L(θ)用于衡量参数θ的好坏。它基于带有标签的训练数据计算得出,例如,对于分类问题,常计算所有样本的交叉熵之和。
寻找最优参数。目标是找到一个参数θ*,使得损失函数L(θ)最小。我们通常使用梯度下降等优化方法来解决这个问题。找到θ* 后,我们就得到了最终可用的模型F_θ*。
元学习的三个步骤 🚀
学习本身也可以看作一个函数。一个机器学习算法,本质上是一个函数,我们称之为F。它的输入是训练数据集,输出是一个训练好的分类器。目前,这些算法(如梯度下降)都是人工设计的。
元学习的目标,就是学习这个“学习算法”F。我们同样可以通过三个步骤来实现:
第一步:定义带有未知元参数的函数
在元学习中,我们要找的函数F是一个学习算法。这个算法内部有一些我们希望机器自动决定的组件,例如网络架构、初始化参数或学习率策略。我们用φ来表示这些待学习的元参数。因此,学习算法可以表示为F_φ。
不同的元学习方法,主要区别在于学习算法中哪些组件(即φ)被设定为可学习的。
第二步:定义元损失函数
我们需要一个损失函数L(φ)来衡量一个学习算法F_φ的好坏。如何定义这个损失呢?这需要用到“训练任务”。
在元学习中,我们收集的是许多相关的“任务”,而不是单一任务的数据。例如,要训练一个二元分类器,我们就准备许多个二元分类任务(如任务1:区分苹果和橘子;任务2:区分汽车和自行车)。每个任务都包含自己的训练集和测试集。
以下是评估学习算法F_φ的流程:
从第i个任务中取出训练集,输入给学习算法F_φ。
F_φ根据该训练集进行学习(即进行一次“任务内训练”),产出一个针对该任务的分类器F_θ_i*。
使用该任务中的测试集来评估这个分类器F_θ_i* 的性能,计算出一个损失值li**(例如,分类错误率或交叉熵)。**li越小,说明针对此任务学习到的分类器越好,间接反映了学习算法F_φ在此任务上表现越好。
重复以上步骤,在所有N个训练任务上运行学习算法F_φ,得到N个损失值l^1, l^2, …, l^N。
最终,元损失函数L(φ)定义为所有任务损失的平均值:
L(φ) = Σ_{i=1}^{N} l^i / N
请注意:这里的每个l^i是在单个任务的“测试集”上计算的。这与传统机器学习在训练集上计算损失不同。在元学习中,训练的基本单位是“任务”,因此任务内部的测试集可以在元学习训练过程中被合法地用于评估。
第三步:寻找最优元参数
我们的目标是找到一个元参数φ*,使得元损失函数L(φ)最小化:
φ= argmin_φ L(φ)*
如何解决这个优化问题呢?如果我们可以计算L(φ)关于φ的梯度∇L(φ),那么可以直接使用梯度下降法。如果梯度无法计算(例如φ是离散的网络架构选择),则可以考虑使用强化学习或进化算法等黑盒优化方法。
找到φ* 后,我们就得到了一个“学出来的”学习算法F_φ*。
元学习的完整流程与应用 🎯
整个元学习的框架如下:
跨任务训练:使用大量训练任务,通过上述三个步骤,学习出最优的学习算法F_φ*。
跨任务测试:面对一个新的测试任务(例如,区分猫和狗),我们将该任务的训练集输入给学到的算法F_φ*。F_φ* 会针对这个新任务进行学习,产出一个分类器。最后,我们用该任务的测试集来评估这个分类器的性能。
测试任务是我们真正关心的、希望取得好结果的任务。而训练任务则是用于“锻造”学习算法的、与测试任务不同的任务。
元学习的一个著名应用是小样本学习。小样本学习是目标,希望模型只需看少量样本就能学会新任务;而元学习是手段,通过让模型在大量任务上学习“如何学习”,从而获得强大的小样本适应能力。因此,两者紧密关联,但概念上略有区别。
元学习与机器学习的比较 🔄
为了更清晰地理解,我们来系统比较一下机器学习和元学习。
| 方面 | 机器学习 | 元学习 |
| :— | :— | :— |
|目标| 寻找一个函数f_θ(如分类器) | 寻找一个学习算法F_φ(能产出分类器) |
|训练数据| 单个任务的训练集 | 多个训练任务,每个任务包含支持集(训练集)和查询集(测试集) |
|训练过程| 任务内训练 | 跨任务训练 |
|测试过程| 任务内测试 (直接应用模型) | 跨任务测试 (包含:用新任务支持集进行任务内训练 + 用新任务查询集进行任务内测试) |
|损失函数|L(θ),对单个任务训练集求和 |L(φ),对多个任务的查询集损失l^i求和/平均 |
|过拟合| 在训练集上表现好,在测试集上差 | 在训练任务上表现好,在新测试任务上差 |
|缓解过拟合| 收集更多训练数据、数据增强 | 收集更多训练任务、任务增强 |
术语澄清:
跨任务训练/测试:涉及多个任务的学习和评估过程。
任务内训练/测试:在单个任务内部,用其支持集学习模型,或用其查询集评估模型。
支持集/查询集:为避免与“元学习的训练集”混淆,文献中常将任务内的训练集称为支持集,测试集称为查询集。
外层循环/内层循环:在某些元学习方法(如学习初始化参数)中,跨任务训练被称为外层循环,而任务内训练被称为内层循环。
元学习的实践细节与挑战 ⚙️
元学习训练的计算量通常很大。因为每计算一次元损失L(φ),都需要对每个任务完整执行一次任务内训练和测试(即一个回合)。
与传统机器学习一样,元学习也需要调参(如优化φ时使用的学习率)。这似乎陷入了“为减少调参而引入更多调参”的循环。但元学习的理想目标是:花费一次大力气调参,找到一个强大的通用学习算法F_φ*,之后将其应用于任何新任务时,都无需或只需极少调参。
此外,元学习也应有验证环节。合理的流程是:拥有训练任务、验证任务和测试任务。用验证任务来选择元学习过程中的超参数,最终在测试任务上报告性能。目前并非所有文献都严格遵循此流程,但这应是未来标准。
总结 📝
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/737139ede263592daca23d997bccebbc_7.png
本节课中,我们一起学习了元学习的基础知识:
元学习的核心是学习如何学习,旨在让机器自动发现高效的学习算法。
其框架与机器学习一脉相承,都包含定义函数、定义损失、优化参数三个步骤,只是操作对象从“模型参数θ”提升到了“学习算法元参数φ”。
元学习在“任务”的层面上进行学习和评估,需要准备大量的训练任务。
元学习与机器学习在目标、数据形式、流程上既有相似之处,也有关键区别,理解这些区别对于掌握元学习至关重要。
元学习是小样本学习等前沿方向的重要实现手段,尽管在实践中面临计算量大和自身需要调参等挑战,但其前景是让AI获得更强大、更通用的学习能力。
39:L22.2 - 元学习2:万物皆可Meta 🧠
在本节课中,我们将学习元学习(Meta Learning)的具体应用实例,探讨在元学习框架下,哪些组件可以被学习。我们将从梯度下降算法出发,逐一分析可学习的部分,并介绍相关的经典方法与研究。
概述
上一节我们介绍了元学习的基本概念。本节中,我们将通过具体实例,详细说明在元学习框架中,哪些组件可以被学习。我们将从最常见的梯度下降算法开始,分析其各个部分,并介绍如何通过元学习来优化这些部分。
梯度下降算法中的可学习组件
最常用的学习算法是梯度下降(Gradient Descent)。在梯度下降中,我们首先需要一个神经网络架构。接着,我们初始化参数,这个初始化的参数通常记作θ₀。然后,我们从训练数据中采样一个批次(Batch),计算梯度,并用这个梯度来更新参数。这个过程反复进行,直到达到满意的训练次数,最终输出训练得到的参数θ。
在这个完整的过程中,以下部分是可以被学习的:
1. 初始化的参数(θ₀)
初始化的参数θ₀是可以学习的。通常,θ₀是随机初始化的,从一个固定的分布中采样出来。然而,初始化的好坏对最终结果有显著影响。好的初始化参数可以带来更好的训练效果,而差的初始化则可能导致结果天差地别。因此,我们可以通过元学习,利用一系列训练任务来找到一个对训练特别有帮助的初始化参数。
以下是学习初始化参数的代表性方法:
MAML(Model-Agnostic Meta-Learning):这是元学习领域中最知名的方法之一。它的目标是学习一个通用的初始化参数,使其能够通过少量梯度更新快速适应新任务。
Reptile:这是 MAML 的一个变体,其名称与爬行动物相关。它通过一种更简单的方式学习初始化参数。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/c3d897f20dd9d3ab1dff7e10fee531fe_1.png
这些方法的细节因时间有限不在此详述,但相关参考文献已列在课程材料中供大家深入阅读。在作业中,我们也会涉及更多与 MAML 相关的细节问题。
需要注意的是,训练 MAML 本身也需要调整超参数。原始的 MAML 版本效果并不总是非常稳定。有一篇名为《How to Train Your MAML》的论文专门研究了如何更好地训练 MAML,并提出了改进版本MAML++。有关 MAML++ 的更多细节,建议大家自行阅读这篇论文。
讲到学习好的初始化参数,这让我们联想到课程中的另一个主题:自监督学习(Self-Supervised Learning)。在自监督学习中,我们利用大量无标签数据,通过预训练任务(例如 BERT 中的填空题,或图像中的对比学习)来获得一个好的初始化参数,然后将其用于下游任务。
那么,MAML 和自监督学习的预训练有何不同呢?最明显的区别在于,MAML 在训练任务中使用了标注数据,而自监督学习完全不需要标注数据。自监督学习虽然有效,但其背后的原理并不完全清晰。而 MAML 的有效性则更直观:它在训练任务上找到了一组好的初始化参数,因此有望迁移到测试任务上。
在自监督学习这个概念流行之前,另一种常见的做法是将多个任务的数据混合在一起,当作一个任务进行训练,以获得一个好的初始化参数。这种方法被称为多任务学习(Multi-Task Learning)。在元学习研究中,多任务学习常被用作比较的基线(Baseline),因为两者使用的数据相同,只是组织方式不同。
2. 优化器(Optimizer)
在更新参数时,我们需要决定学习率(Learning Rate)、动量(Momentum)等超参数。这些超参数能否通过元学习自动学习出来呢?答案是肯定的。
早在 2016 年,就有一篇名为《Learning to Learn by Gradient Descent by Gradient Descent》的论文提出了这种方法。该论文直接学习优化器(如 Adam)内部的参数,并将其方法类比为训练一个 LSTM,因此直接命名为LSTM Optimizer。
该研究首先在 MNIST 数据集上训练并测试,取得了不错的结果。更重要的是,它早期就具备了“训练任务与测试任务应不同”的概念。例如,训练时使用一层神经网络,测试时使用两层神经网络,模型依然有效。但如果改变激活函数(例如从 Sigmoid 改为 ReLU),学习到的优化器就可能失效。这表明了元学习泛化能力面临的挑战。
3. 神经网络架构(Neural Architecture)
我们能否学习神经网络架构本身呢?当然可以。这一系列的研究就是鼎鼎大名的神经网络架构搜索(Neural Architecture Search, NAS)。在元学习框架中,如果我们将神经网络架构本身视为要学习的函数f,那么我们就是在进行 NAS。
在 NAS 中,f是网络架构,我们的目标是找到一个f来最小化损失函数L(f)。由于f是离散的架构选择,无法直接计算梯度。这时,我们可以运用本课程反复强调的思路:当遇到无法计算梯度的问题时,强化学习(Reinforcement Learning)是一个可行的解决方案。
如何用强化学习实现 NAS呢?我们可以将f视为一个智能体(Agent)的参数。这个智能体的输出就是与网络架构相关的超参数(例如,每一层的滤波器大小、数量、步长等)。然后,我们训练这个智能体去最大化一个奖励(Reward)。这里的奖励可以直接设置为损失函数L(f)的负值,即最小化L(f)等价于最大化负的L(f)。通过策略梯度等强化学习算法,我们就可以训练出能设计出好架构的智能体。
除了强化学习,使用进化算法(Evolutionary Algorithm)也是可行的。此外,还有一种经典方法叫做可微分架构搜索(Differentiable Architecture Search, DARTS),它通过巧妙的参数化,使得架构选择变得可微分,从而可以直接使用梯度下降来优化。
4. 数据处理(Data Processing)
在训练神经网络时,我们通常需要进行数据增强(Data Augmentation)。目前,数据增强的方法大多是通过试错(Trial and Error)来选择的。那么,能否通过元学习自动学习出最佳的数据增强策略呢?这也是可以的。已有一些论文致力于学习自动化的数据增强方法。
此外,在训练时,我们有时需要为不同的数据样本赋予不同的权重。例如,有的策略认为接近决策边界的困难样本应给予更大权重,以便模型重点学习;也有相反的观点认为,这些样本可能标签噪声较大,应给予较小权重。如何决定样本权重的策略呢?我们可以通过元学习,根据数据的特性自动学习出样本权重的分配策略。
超越梯度下降:学习全新的算法
到目前为止,我们看到的方法都是在梯度下降的基础上进行改进。但我们是否可以完全抛弃梯度下降,让机器发明全新的学习算法呢?
1. 学习一个“元网络”
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/c3d897f20dd9d3ab1dff7e10fee531fe_3.png
我们有可能直接学习一个神经网络,该网络的参数就是f。这个网络以训练数据作为输入,直接输出训练好的模型参数。如果真有这样一个网络,我们就可以说机器发明了新的学习算法。这方面已有一些研究论文进行了探索。
2. 端到端的“学习与推理”
更进一步,我们能否不再区分训练和测试两个阶段,而是用一个神经网络把整个“训练+测试”的过程一次性搞定呢?这是有可能的。这类方法通常被称为基于度量的方法(Metric-Based Approaches)或学习比较(Learning to Compare)。
在这类方法中,一个神经网络同时读取支持集(训练数据)和查询集(测试数据),直接输出查询集样本的预测结果。整个过程中没有显式的参数更新步骤。如果你想了解更多关于这类方法的内容,可以参考课程中过去讲解少样本学习(Few-Shot Learning)的相关部分。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/c3d897f20dd9d3ab1dff7e10fee531fe_5.png
元学习的实际应用与评测
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/c3d897f20dd9d3ab1dff7e10fee531fe_7.png
你可能会好奇,元学习这种听起来有些科幻的技术,真的有实际应用吗?
少样本图像分类(Few-Shot Image Classification)
目前,元学习技术最常用来测试的任务是少样本图像分类。在这类任务中,每个分类任务只有极少数量的图片。例如,一个N-way K-shot分类任务,表示任务中有 N 个类别,每个类别只有 K 个样本。
为了进行元学习训练,我们需要准备大量这样的 N-way K-shot 任务。在学术界,最常用的基准数据集是Omniglot数据集。它包含 1623 个不同的手写字符,每个字符有 20 个样本。研究人员可以从中采样字符来构造大量的训练任务和测试任务,从而评估元学习算法的泛化能力。
更广泛的应用
元学习并非只能用于简单的 Omniglot 任务。下表列举了元学习在语音和自然语言处理等更复杂任务上的应用:
| 方法类型 | 语音检测 | 关键词识别 | 语音转换 | 序列标注 | 机器翻译 | 语音识别 |
| :— | :— | :— | :— | :— | :— | :— |
|学习初始化 (e.g., MAML)| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|基于度量的方法| ✓ | ✓ | | ✓ | | |
|其他 (e.g., NAS)| | ✓ | | | ✓ | |
这表明,元学习已经开始被推向更复杂的现实任务。我们可以期待未来元学习技术能够在实际应用中走得更远。
总结
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/c3d897f20dd9d3ab1dff7e10fee531fe_9.png
本节课中,我们一起深入探讨了元学习的各种可能应用。我们从梯度下降的各个组件(初始化参数、优化器、网络架构、数据处理策略)出发,分析了如何通过元学习来优化它们。接着,我们展望了超越梯度下降、让机器学习全新算法的可能性。最后,我们了解了元学习在少样本分类等任务上的评测方式及其在更复杂领域的应用前景。元学习作为一个充满潜力的方向,正在不断拓展机器学习的边界。
40:回顾、总结与展望 🎓
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/2951fb6cfa39bb2b31c5fdd374a96967_1.png
在本节课中,我们将回顾整个机器学习课程的核心内容,总结所学知识,并对未来的学习与应用进行展望。
课程内容回顾 📚
在这门课程中,我们学习了机器学习的核心概念与技术。课程伊始,我们明确了机器学习的本质:寻找一个函数。
上半学期:深度学习基础与核心模型
上一节我们介绍了机器学习的基本目标,本节中我们来看看课程前半部分的核心内容。
我们首先指出,简单的线性模型(linear model)能力有限。因此,课程直接进入深度学习领域,讲解了深度学习(deep learning)的基本原理。
以下是上半学期涵盖的核心模型:
卷积神经网络:用于处理图像等具有矩阵结构的输入数据。
自注意力机制:用于处理序列数据,如声音或文字。
Transformer模型:其输入与输出的长度可以不同。
掌握了这些模型,便足以处理大多数常见的应用场景。
下半学期:进阶主题与应用
在掌握了基础模型后,我们进入了一系列机器学习的进阶主题。
以下是下半学期探讨的关键技术:
生成模型:让机器学会创造,例如介绍了GAN技术。
自监督学习:利用无标注数据进行学习,例如BERT模型。
领域自适应:处理训练与测试数据分布不匹配的问题。
强化学习:以通俗易懂的方式介绍了Reinforcement Learning。
对抗攻击与防御:应对针对模型的恶意攻击。
可解释机器学习:解释模型的学习结果与决策。
网络压缩:在资源有限的设备上进行模型部署。
终身学习:探讨模型持续学习新知识的能力。
元学习:学习如何学习,实现超越传统学习框架的目标。
技术应用实例展示 🛠️
课程中,我们通过大量实例展示了机器学习技术的广泛应用可能性。
以下是课程中涉及的部分应用领域:
影像处理:不仅包括基础的影像分类,还涉及影像生成、对抗攻击、模型调试、压缩、解释以及异常检测。
自然语言处理:实现了机器翻译与问答系统。
语音处理:完成了语音转文字(语音辨识)和说话人辨识任务。
强化学习应用:让机器学会了玩小游戏。
这些应用旨在说明,深度学习技术可以应用于各行各业。你可以思考自己关注的问题是否能用这些技术来解决。
课程定位与未来学习建议 🧭
这门漫长的学习旅程现已接近尾声,但这并非终点,而是另一段探索的开始。
本课程的核心目标并非深入钻研某个特定问题,而是像“深度学习一日游”一样,带领大家概览该领域的关键技术与景点,为大家打开一扇扇门。真正的深入探索,需要依靠各位未来的持续努力。
课程结束后,你可以从以下几个方面继续前进:
尝试解决实际问题:结合课程作业中的概念,尝试解决你研究或感兴趣的问题。
阅读学术论文:如果你已掌握课程多数内容,便已具备阅读顶尖机器学习会议论文的基础能力。
参与进阶学习:例如关注并参与像MLSS这样的机器学习暑期学校,继续深入学习。
关于课程设计与挑战的说明 💡
本学期课程开放给所有感兴趣的同学,这带来了多元的背景,也对课程设计提出了挑战。为此,我们重新设计了教材与作业,并提供了范例程式,旨在让尽可能多的同学理解课程内容。
我们理解同学们可能遇到的一些挑战,例如模型训练时间长、运算资源有限等。需要说明的是:
这些挑战是深度学习实践中本质存在的困难,并非课程刻意设置。
课程选择不隐藏这些困难,是为了呈现深度学习真实、完整的样貌,避免产生“深度学习非常简单”的误解。
这种体验或许像疫苗,可能带来短暂不适,但能帮助你未来更好地应对实际应用中更大的挑战。
无论你未来是否继续深入研究深度学习,本课程都希望为你提供客观、全面的认识,由你自己做出选择。
结语与勉励 🌟
最后,想对坚持修完这门课,尤其是那些在资源有限条件下克服困难的同学,表达勉励之意。这让人联想到改编自《为学一首示子侄》的故事:
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/2951fb6cfa39bb2b31c5fdd374a96967_3.png
台湾大学有二生,其一贫,其一富。贫者语于富者曰:“吾欲修李宏毅机器学习,何如?”富者曰:“子何恃而训?”曰:“吾 Colab 足矣。”富者曰:“吾数年来欲买 V100 而修,犹未能也。子何恃而训!”越一学期,贫者完成不止十个作业,以告富者。富者有惭色。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/2951fb6cfa39bb2b31c5fdd374a96967_4.png
感谢大家这学期的参与。在座的各位来自不同科系,未来将步入各行各业。你们之中,或许有人会运用深度学习创造出今日难以想象的成就。
本学期的课程到此结束。请为坚持到最后的自己,献上热烈的掌声。
https://github.com/OpenDocCN/dsai-notes-pt3-zh/raw/master/docs/leemldl/img/2951fb6cfa39bb2b31c5fdd374a96967_6.png
本节课中我们一起学习了:对整个机器学习课程的知识体系进行了全面回顾,总结了从基础模型到进阶技术的核心内容,探讨了课程的设计理念与面临的挑战,并对未来的学习与应用方向给予了建议和勉励。