第二章:元学习

摘要

元学习(即学习如何学习)是一门系统地观察不同的机器学习方法如何在各种学习任务上执行的科学,然后从这种经验或元数据中学习,以比其他方式更快的速度学习新任务的科学。这不仅极大地加速和改善了机器学习管道或神经体系结构的设计,而且还使我们能够用以数据驱动方式学习的新颖方法来代替手工设计的算法。在本章中,我们概述了这个引人入胜且不断发展的领域中的最新技术。

简介

当我们学习新技能时,我们很少(如果有的话)从头开始。我们从之前在相关任务中学习的技能开始,再使用以前有效的方法,并基于经验[82]专注于可能值得尝试的东西。通过学习所有技能,学习新技能变得更加容易,需要更少的示例和更少的反复试验。简而言之,我们学习如何跨任务学习。同样,在为特定任务构建机器学习模型时,我们通常会基于相关任务的经验,或者使用我们对机器学习技术行为的理解(通常是隐性的)来帮助做出正确的选择。

元学习的挑战在于以系统的,数据驱动的方式从先前的经验中学习。首先,我们需要收集描述先前学习任务和先前学习模型的元数据。它们包括用于训练模型的精确算法配置,包括超参数设置,管线组成和/或网络架构,结果模型评估(例如准确性和训练时间),学习到的模型参数(例如神经网络的训练权重)以及任务本身的可测量属性,也称为元特征。其次,我们需要从该先前的元数据中学习,以提取和转换知识,这些知识将指导新任务的最佳模型的搜索。本章简要概述了有效执行此操作的各种元学习方法。

术语“ 元学习” 涵盖了基于先前其他任务的经验的任何类型的学习。先前的任务越相似,我们可以利用的元数据类型就越多,并且定义任务相似性将是一个主要的总体挑战。也许不用说,没有免费的午餐[57,188]。当新任务代表完全不相关的现象或随机噪音时,利用先前的经验将无效。幸运的是,在现实世界中的任务中,有很多机会可以从以前的经验中学到东西。

在本章的其余部分,我们将根据元数据学习所利用的元数据类型对元学习技术进行分类,从最一般的到最具体的任务。首先,在第 2.2 节中,我们讨论了如何仅从模型评估中学习,这些技术可用于推荐通常有用的配置和配置搜索空间,以及从经验相似的任务中转换知识。在第 2.3 节中,我们讨论了如何表征任务以更明确地表达任务相似性并建立元模型来学习数据特征与学习性能之间的关系。最后,第 2.4 节介绍了我们如何在固有相似的任务之间传递训练好的模型参数,例如,共享相同的输入特征,从而可以进行迁移学习[111]和小样本学习[126]等。

请注意,尽管多任务学习[25](同时学习多个相关任务)和集成学习[35](在同一任务上构建多个模型)通常可以与元学习系统有意义地结合,但它们本身并不涉及学习以前在其他任务上的经验。

本章基于一个非常新的综述文章[176] 。

从模型评估中学习

考虑我们可以利用先前任务 tj∈Tt_j \in Ttj​∈T ,所有已知任务的集合,同样也是一组学习算法的集合,这些学习算法完全由它们的配置 θi∈Θ\theta_i \in \Thetaθi​∈Θ 定义;这里 Θ\ThetaΘ 表示离散,连续或混合的配置空间,可以覆盖超参数设置,管道组件和/或神经体系结构组件。PPP 是所有先前配置 θi\theta_iθi​ 在任务 tjt_jtj​ 上的评估标量 Pi,j=P(θi,tj)P_{i, j} = P(\theta_i, t_j)Pi,j​=P(θi​,tj​) 的集合,根据预先定义的评估方法(例如准确性)和模型评估技术 (例如交叉验证) 生成。 PnewP_{new}Pnew​ 是在新任务 tnewt_{new}tnew​ 上的已知评估 Pi,newP_{i,new}Pi,new​ 的集合。我们现在要训练一个元学习器 LLL ,它预测用于新任务 tnewt_{new}tnew​ 的推荐配置 Θnew∗\Theta_{new}^*Θnew∗​ 。元学习器在元数据 P∪PnewP \cup P_{new}P∪Pnew​ 上进行训练。PPP 通常是事先收集的,或者是从元数据库中提取的[174,177]。PnewP_{new}Pnew​ 是以迭代的方式通过元学习技术本身学习到的,有时也通过另一种方法生成的初始 PnewP_{new}Pnew​ 热启动。

与任务无关的推荐

首先,想象一下无法访问任何 tnewt_{new}tnew​ 上的评估,因此 Pnew=∅P_{new} = \emptyPnew​=∅ 。然后我们仍然可以学习一个函数 f:Θ×T→{θk∗},k=1,…,Kf: \Theta \times T \to \{\theta_k^*\}, k = 1, \ldots, Kf:Θ×T→{θk∗​},k=1,…,K ,产生一组独立于 tnewt_{new}tnew​ 的推荐配置。然后可以在 tnewt_{new}tnew​ 上评估这些 θk∗\theta_k^*θk∗​,以选择最佳的一个,或热启动进一步的优化方法,这些方法在第 2.2.3 节中讨论。

此类方法通常会产生排名,即有序集 θk∗\theta_k^*θk∗​ 。通常通过将 Θ\ThetaΘ 离散化为一组候选配置 θi\theta_iθi​(也称为组合)来完成此任务,该配置对大量任务 tjt_jtj​ 进行了评估。然后,我们可以建立每个任务的排名,例如使用成功率,AUC 或显著获胜[21,34,85]。但是,通常希望将同样好但速度更快的算法排名更高,并提出了多种方法来权衡准确性 和训练时间[21,134]。接下来,我们可以将这些单任务排名汇总为全局排名,例如通过计算所有任务的平均排名[1,91]。当没有足够的数据来建立全局排名时,可以基于每个已知任务的最佳配置推荐配置子集[70,173],或者返回 “准线性排名“ [30]。

为了找到从未见过的新任务 tnewt_{new}tnew​ 的最佳 θ∗\theta^*θ∗ ,一种简单的随时方法是选择前 KKK 个配置[21],从列表中向下选择并依次评估每个配置。在预定义的K值,时间预算耗尽或找到足够准确的模型后,可以停止此评估。在时间受限的环境中,已经显示出多目标排名(包括训练时间)更快地收敛到接近最优的模型[1,134],并且这为算法比较提供了强有力的基线[1,85]。

与上述方法非常不同的另一方法是,首先将可微分函数 fj(θj)=Pi,jf_j(\theta_j) = P_{i, j}fj​(θj​)=Pi,j​ 拟合到特定任务 tjt_jtj​ 的所有先前评估,然后使用梯度下降为每个先前任务找到优化的配置 θj∗\theta_j^*θj∗​ [186]。假设某些任务 tjt_jtj​ 与新任务相似,则这些任务对于热启动贝叶斯优化方法很有用。

配置空间设计

先前的评估也可以用来学习更好的配置空间 Θ∗\Theta^*Θ∗ 。 尽管还是独立于 tnewt_{new}tnew​ ,但是由于只探索配置空间中更相关的区域,因此可以从根本上加快对最佳模型的搜索。这在计算资源有限的情况下至关重要,并且已被证明是 AutoML 系统实际比较中的重要因素[ 33]。

首先,在实用的 ANOVA 方法[67]中,如果超参数解释了给定任务的算法性能的大部分差异,则它们被认为是重要的。在[136]中,使用 100 个数据集上的 3 种算法的250,000 个 OpenML 实验对此进行了探索。

一种替代方法是首先学习最佳超参数默认设置,然后将超参数重要性定义为通过调整超参数而不是将其保持在该默认值可以实现的性能增益。的确,即使超参数可能会导致很大的差异,但它也可能具有一个始终会产生良好性能的特定设置。在[120]中,这是通过对 6 种算法和 38 个数据集进行的大约 500,000 个 OpenML 实验来完成的。首先通过训练该算法针对大量任务的替代模型来共同学习算法的所有超参数的默认值。接下来,对许多配置进行采样,并且建议将最小化所有任务上平均风险的配置作为默认配置。最终,通过观察对其进行调整获得多少改进,来估计每个超参数的重要性(或可调性)。

在[183]中,默认值是从其他超参数中独立学得的,并定义为每个任务的前 KKK 个配置中最频繁出现的配置。在最佳默认值取决于元特征(例如训练实例或特征的数量)的情况下,学得的简单函数包含这些元特征。接下来,统计测试基于在不调整一个超参数(或一组超参数),同时调整所有其他参数时观察到的性能损失,定义是否可以安全地将超参数保留为默认值。这使用 59 个数据集上的 2 种算法(SVM 和随机森林) 118,000 个 OpenML 实验进行了评估。

配置转换

如果我们要为特定任务 tnewt_{new}tnew​ 提供建议,我们需要其他信息以了解 tnewt_{new}tnew​ 与先前任务 tjt_jtj​ 的相似程度。一种方法是在 tnewt_{new}tnew​ 上评估许多推荐的(或可能是随机的)配置,从而产生新的证据 PnewP_{new}Pnew​ 。如果随后我们发现,Pi,newP_{i, new}Pi,new​ 与 Pi,jP_{i, j}Pi,j​ 相似,根据经验证据,可以认为 tjt_jtj​ 和 tnewt_{new}tnew​ 本质上相似。我们可以包括此知识,以训练一个为 tnewt_{new}tnew​ 预测一组推荐的配置集 Θnew∗\Theta_{new}^*Θnew∗​ 的元学习器。此外,每个选定的 θnew∗\theta_{new}^*θnew∗​ 都可以进行评估并包含在 PnewP_{new}Pnew​ 中,重复该循环并收集更多的经验证据,以了解哪些任务彼此相似。

相对界标

任务相似性的第一个度量考虑了在特定任务 tjt_jtj​ 上的两个配置 θa\theta_aθa​ 和 θn\theta_nθn​ 之间[53]相对性能(成对)的差异,也称为相对界标, RLa,b,j=Pa,j−Pb,jRL_{a,b,j} = P_{a, j} - P_{b, j}RLa,b,j​=Pa,j​−Pb,j​ 。主动测试[85]通过以下方式利用这些:以全局最佳配置热启动(请参阅第2.2.1节),将其称为 θbest\theta_{best}θbest​,然后以锦标赛风格进行。在每个回合中,它都会选择最有说服力地胜过相似任务上的 θbest\theta_{best}θbest​ 的 “优胜者” θc\theta_cθc​ 。如果所有评估配置的相对界标都相似,则认为任务是相似的,即如果配置在 tjt_jtj​ 和 tnewt_{new}tnew​ 上性能相似,则认为任务相似。接下来,它评估优胜者 θc\theta_cθc​,产生 Pc,newP_{c, new}Pc,new​ ,更新任务相似性并重复。该方法的局限性在于它只能考虑在许多先前任务中评估过的配置 θi\theta_iθi​ 。

代理模型

一种更灵活的信息传递方式是为所有先前的任务 tjt_jtj​ 建立代理模型 sj(θi)=Pi,js_j(\theta_i) = P_{i, j}sj​(θi​)=Pi,j​ ,并使用所有可用的 PPP 进行训练。 然后可以根据 sj(θj)s_j(\theta_j)sj​(θj​) 和 Pi,newP_{i, new}Pi,new​ 之间的误差来定义任务相似性:如果 tjt_jtj​ 的替代模型可以为 tnewt_{new}tnew​ 生成准确预测,则这些任务本质上是相似的。该方法通常将其与贝叶斯优化(参见第1章)结合使用以确定下一个 θi\theta_iθi​ 。

Wistuba 等[187]基于先前每个任务的高斯过程(GPs),加上 tnewt_{new}tnew​ 的高斯过程,并将它们组合为加权归一化总和,其中(新的)预测均值 μ\muμ 定义为各个 μj\mu_jμj​ 的加权和(从先前任务 tjt_jtj​ 获得)。使用 Nadaraya-Watson 核加权平均值计算 μj\mu_jμj​ 的权重,其中每个任务均表示为相对界标的向量,Epanechnikov 二次核[104]用于测量 tjt_jtj​ 和 tnewt_{new}tnew​ 的相对界标向量之间的相似性。tjt_jtj​ 与 tnewt_{new}tnew​ 越相近,权重 sjs_jsj​ 越大,从而增加了 tjt_jtj​ 的代理模型的影响力。

Feurer 等[45]提出将各个高斯过程的预测分布进行合并,从而使合并后的模型再次成为高斯过程。权重是根据 Lacoste 等的不可知贝叶斯联合来计算的[81],其权重预测器根据它们泛化性能的估计预测权重。

元数据也可以在采集函数中转换,而不是代理模型[187]。代理模型仅在 Pi,newP_{i, new}Pi,new​ 上训练,但是接下来要评估的 θi\theta_iθi​ 由采集函数提供,该函数是 Pi,newP_{i, new}Pi,new​ 上的预期改进[69]和所有先前 Pi,jP_{i, j}Pi,j​ 的预测改进的加权平均值。先前任务的权重可以再次通过代理模型的准确性或相对界标来定义。随着收集更多的证据 Pi,newP_{i, new}Pi,new​ ,预期改进组件的权重会随着每次迭代而逐渐增加。

热启动多任务学习

关联先前任务 tjt_jtj​ 的另一种方法是使用先前的评估 PPP 来学习联合任务表示。在[114]中,特定任务的贝叶斯线性回归[20]代理模型 sj(θiz)s_j(\theta_i^z)sj​(θiz​) 通过由前馈神经网络 NN(θi)NN(\theta_i)NN(θi​) 学到的一种新颖的配置 θz\theta^zθz 训练,该模型学习了原始配置 θ\thetaθ 的合适基础展开 θz\theta^zθz ,其中线性代理模型可以准确地预测 Pi,newP_{i, new}Pi,new​ 。代理模型已在 OpenML 元数据上进行了预训练,从而为在多任务学习环境中优化 NN(θi)NN(\theta_i)NN(θi​) 提供了良好开端。早期关于多任务学习的研究[166]假设我们已经有一组“相似”源任务 tjt_jtj​ 。它通过建立贝叶斯优化联合 GP 模型来学习和利用任务之间的确切关系,从而在 tjt_jtj​ 和 tnewt_{new}tnew​ 之间传递信息。但是,学习联合 GP 的可扩展性往往不及每个任务构建一个 GP。 Springenberg 等[161]也假设任务是相关的和相似的,但是在使用贝叶斯神经网络的优化过程中学习了任务之间的关系。这样,他们的方法在某种程度上是前两种方法的混合。Golovin等[58]假设了任务的顺序(例如时间)。它建立一个 GP 回归器的栈,每个任务一个对应一个 GP 回归器,基于其相对于其下方回归器的残差训练每个 GP 。因此,每个任务使用其之前的任务来定义其先验条件。

其他技术

多臂赌博机 (Multi-armed bandits) [139]提供了另一种方法来查找与 tnewt_{new}tnew​ 最相关的源任务 tjt_jtj​ [125]。在这个类比中,每个 tjt_jtj​ 是一个臂,并且选择(拉动)特定先前任务(臂)的(随机)奖励是根据基于 GP 的贝叶斯优化器的预测误差来定义的,该预测器将 tjt_jtj​ 的先验评估建模为噪声测量并将它们与 tnewt_{new}tnew​ 现有评估结合起来。尽管 GP 的三次方放大使此方法的可扩展性较差。

定义任务相似性的另一种方法是采用现有的评估值 Pi,jP_{i, j}Pi,j​ ,使用汤普森采样[167]来获得最佳分布 ρmaxj\rho_{max}^{j}ρmaxj​ ,然后测量 ρmaxj\rho_{max}^jρmaxj​ 和 ρmaxnew\rho_{max}^{new}ρmaxnew​ [124]之间的 KL-散度[80]。然后根据相似性将这些分布结合为混合分布,并用于构建采集函数,该函数预测要评估的下一个最有前景的配置。到目前为止,该方法仅评估了使用 5 个任务来调整 2 个 SVM 的超参数。

最后,一种利用 PPP 的补充方式是推荐不应使用的配置。在训练完每个任务的代理模型后,我们可以查找哪个 tjt_jtj​ 与 tnewt_{new}tnew​ 最相似,然后使用 sj(θi)s_j(\theta_i)sj​(θi​) 来发现 Θ\ThetaΘ 中预测性能较差的区域。排除这些区域可以加快对性能更好的区域的搜索。Wistuba等[185]使用分别基于 Pi,jP_{i,j}Pi,j​ 和 Pi,newP_{i, new}Pi,new​ 获得的 θi\theta_iθi​ 的排名之间的Kendall tau 等级相关系数[73]的任务相似性度量来完成此任务。

学习曲线

我们还可以提取有关训练过程本身的元数据,例如随着添加更多训练数据,模型的性能提高的多快。如果将训练划分为步骤 sts_tst​ ,通常每步添加固定数量的训练示例,则可以测量在步骤 sts_tst​ 之后配置 θi\theta_iθi​ 在任务 tjt_jtj​ 上的性能 P(θi,tj,st)=Pi,j,tP(\theta_i, t_j, s_t) = P_{i, j, t}P(θi​,tj​,st​)=Pi,j,t​ ,在时间步骤 sts_tst​ 上生成学习曲线。正如第 1 章中讨论的那样,学习曲线还用于加速给定任务的超参数优化。在元学习中,学习曲线信息在任务之间传递。

在新任务 tnewt_{new}tnew​ 上评估配置时,我们可以在一定数量的迭代次数 r<tr<tr<t 之后停止训练,并使用部分观察到的学习曲线根据其他任务的先验经验来预测配置在整个数据集上的性能如何,并决定是否继续训练。这可以显着加快寻找良好配置的速度。

一种方法是假设相似的任务会产生相似的学习曲线。首先,根据部分学习曲线的相似程度来定义任务之间的距离: dist(ta,tb)=f(Pi,a,t,Pi,b,t),t=1,…,rdist(t_a, t_b) = f(P_{i, a, t}, P_{i, b, t}), t = 1, \ldots, rdist(ta​,tb​)=f(Pi,a,t​,Pi,b,t​),t=1,…,r 。 接下来,找到最相似的 K 个任务 t1…kt_{1 \ldots k}t1…k​ ,并使用其完整的学习曲线来预测配置在新的完整数据集上的执行情况。可以通过比较所有尝试的配置中的局部曲线的形状来衡量任务的相似性,并通过将“最近的”完整曲线与新的局部曲线相匹配来进行预测[83,84]。这种方法与主动测试相结合也很成功[86],可以通过使用包括训练时间在内的多目标评估方法来进一步加速[134]。

有趣的是,尽管有几种方法旨在预测神经体系结构搜索过程中的学习曲线(请参见第3章),但到目前为止,这些工作都没有利用先前在其他任务上观察到的学习曲线。

从任务特性中学习

元数据的另一个丰富来源是手头任务的特征(元特征)。每一个任务 tj∈Tt_j \in Ttj​∈T 都可用一个 KKK 个元特征组成的向量 m(tj)=(mj,1,…,mj,k)m(t_j) = (m_{j,1}, \ldots, m_{j, k})m(tj​)=(mj,1​,…,mj,k​) 描述, 其中 mj,k∈Mm_{j,k} \in Mmj,k​∈M 为所有已知元特征的集合。这可用于相似度度量,基于(例如) m(ti)m(t_i)m(ti​) 和 m(tj)m(t_j)m(tj​) 之间的欧式距离来定义任务相似性度量,以便我们可以将信息从最相似的任务转移到新任务 tnewt_{new}tnew​ 。 此外,与先前的评估 PPP 一起,我们可以训练一个元学习器 LLL 以预测配置 θi\theta_iθi​ 在新任务 tnewt_{new}tnew​ 上的性能 Pi,newP_{i, new}Pi,new​ 。

元特征

表 2.1 简要概述了最常用的元特征,并简要说明了为什么它们能指示模型性能。在可能的情况下,我们还展示了用于计算它们的公式。更多完整的综述可以在文献中找到[26,98,130,138,175]。

为了建立一个元特征向量 m(tj)m(t_j)m(tj​) ,需要选择并进一步处理这些元特征。对 OpenML 元数据的研究表明,最佳的元特征集取决于应用[17]。许多元特征是根据单个特征或特征组合计算的,需要通过汇总统计量(max,min,μ\muμ,σ\sigmaσ,quartiles, q1…4q_{1 \ldots 4}q1…4​)或直方图进行汇总[72]。人们需要系统地提取和汇总它们[117]。在计算任务相似度时,标准化所有元特征[9],执行特征选择[172]或采用降维技术(例如 PCA)[17]也很重要。 学习元模型时,也可以使用关系元学习器[173]或基于案例的推理方法[63,71,92]。

除了这些通用的元特征之外,还制定了许多更具体的元特征。对于流数据,可以使用流界标 (landmarks)[135,137],对于时间序列数据,可以计算自相关系数或回归模型的斜率[7,121,147],对于无监督问题,可以以不同方式对数据进行聚类并提取这些聚类的特性[159]。在许多应用中,也可以利用特定领域的信息[109, 156]。

学习元特征

除了手动定义元特征,我们还可以学得一个对任务组的联合表示。一种方法是建立元模型,该元模型在给定其他任务元特征 MMM 的情况下,通过性能元数据 PPP 或 f:M→M′f: M \to M'f:M→M′ 上训练,生成类似于界标的元特征表示 M′M'M′ 。 Sun 和 Pfahringer [165] 通过评估所有先前任务 tjt_jtj​ 上的一组预定义配置 θi\theta_iθi​ ,并为配置 θa\theta_aθa​ 和 θb\theta_bθb​ 的每对成对组合的生成二元元特征 mj,a,b∈M′m_{j, a, b} \in M'mj,a,b​∈M′ 来完成此操作,表示 θa\theta_aθa​ 的性能是否优于 θb\theta_bθb​ ,因此 m′(tj)=(mj,a,b,mj,a,c,mj,b,c,…)m'(t_j) = (m_{j, a, b}, m_{j, a, c}, m_{j, b, c}, \ldots)m′(tj​)=(mj,a,b​,mj,a,c​,mj,b,c​,…) 。为了计算 mnew,a,bm_{new, a, b}mnew,a,b​ ,元规则从每个成对组合 (a,b)(a, b)(a,b) 学得,每个在任务 tjt_jtj​ 上 θa\theta_aθa​ 是否优于 θb\theta_bθb​ 的预测,都会给出其另外的元特征 m(tj)m(t_j)m(tj​) 。

我们还可以完全基于可用的元数据 PPP 学得一个联合表示,即 f:P×Θ→M′f: P \times \Theta \to M'f:P×Θ→M′ 。我们先前在 2.2.3 节中讨论了如何使用前馈神经网络[114]来实现此目的。如果任务共享相同的输入空间,例如,它们是相同分辨率的图像,则也可以使用深度度量学习来学习一种元特征表示,例如,使用暹罗 (Siamese) 网络[75]。通过将两个不同任务的数据馈送到两个孪生网络,并利用预测性能和观测性能 Pi,newP_{i, new}Pi,new​ 之间的差异作为误差信号进行训练。由于两个网络之间的模型参数绑定在一个暹罗网络中,因此两个非常相似的任务被映射到潜在特征空间中的相同区域。它们可用于热启动贝叶斯超参数优化[75]和神经体系结构搜索[2]。

相似任务的热启动优化

元特征是一种非常自然的方法,可以根据相似任务的优秀配置来估计任务相似性并初始化优化过程。这与人类专家如何开始手动搜索好的模型相似,通过相关任务上得到的经验。

首先,在有前景的解决方案所在的搜索空间的区域中启动遗传搜索算法可以显着加快收敛到一个好的解决方案的速度。Gomes 等[59]通过基于向量 m(tj)m(t_j)m(tj​) 和 m(tnew)m(t_{new})m(tnew​) 之间的 L1L1L1 距离找到最相似的 kkk 个先前任务 tjt_jtj​ 来推荐初始配置,其中每个 m(tj)m(t_j)m(tj​) 包括 171717 个简单的统计元特征。对于每个最相似的任务,都会在 tnewt_{new}tnew​ 上评估最佳配置,并将其用于初始化遗传搜索算法(粒子群优化)以及禁忌 (Tabu) 搜索。Reif 等[129]遵循非常相似的方法,使用了 15 个简单的,统计的和具有界标的元特征。他们使用前向选择技术查找最有用的元特征,并通过修改后的高斯变异操作热启动标准遗传算法(GAlib)。也尝试了使用元特征的主动测试的变体(请参见第 2.2.3 节)[85,100],但其表现并不比基于相对界标的方法更好。

同样,基于模型的优化方法也可以从有前景的配置的初始设置中受益匪浅。SCoT [9] 训练单个代理排名模型 f:M×Θ→Rf: M \times \Theta \to Rf:M×Θ→R ,预测任务 tjt_jtj​ 上 θi\theta_iθi​ 的排名。MMM 包含 4 个元特征(3 个简单特征和一个基于 PCA 的特征)。代理模型基于所有排名(包括 tnewt_{new}tnew​ 上的排名)训练。之所以使用排名,是因为任务之间的评估值规模可能会有很大差异。GP (高斯过程) 回归将排名转换为概率进行贝叶斯优化,并且每个新的 Pi,newP_{i, new}Pi,new​ 用于在每一步之后重新训练代理模型。

Schilling等[148] 使用改良的多层感知器作为代理模型,其形式为 sj(θi,m(tj),b(tj))=Pi,js_j(\theta_i, m(t_j), b(t_j)) = P_{i, j}sj​(θi​,m(tj​),b(tj​))=Pi,j​ ,其中 m(tj)m(t_j)m(tj​) 是元特征, b(tj)b(t_j)b(tj​) 是 jjj 的二元指示的向量如果元用例来自 tjt_jtj​ 则为 1,否则为 0 。多层感知器在第一层中使用修改后的基于分解机[132]的激活函数,旨在学习每个任务的潜在表示以对任务相似性进行建模。由于此模型无法表示不确定性,因此训练了 100 个多层感知器的集合,以获取预测平均值并模拟方差。

在所有先前的元数据上训练单个代理模型的可扩展性通常较差。Yogatama 和 Mann[190] 还建立了单个贝叶斯代理模型,但仅包括与 tnewt_{new}tnew​ 相似的任务,其中任务相似性定义为由 3 个简单的元特征组成的向量的欧式距离。Pi,jP_{i, j}Pi,j​ 的值被标准化以克服每个 tjt_jtj​ 的不同比例的问题。代理模型在所有实例上学习具有特定内核组合的高斯过程。

Feurer 等[48] 提供了一种更简单,可扩展性更高的方法,该方法可通过对所有先前任务 tjt_jtj​ 进行排序来热启动贝叶斯优化,类似于[59],但包括 46 个简单,统计和界标元特征以及 H(C)H(C)H(C) 。ddd 个最相似任务上的 ttt 个最佳配置被用于热启动代理模型。 他们搜索的超参数比以前的工作要多得多,包括预处理步骤。此热启动方法也用于以后的工作中 [46],在第 6 章详细讨论。

最后,还可以使用协同过滤来推荐有前景的配置[162]。以此类推,任务 tjt_jtj​ (用户)为配置 θi\theta_iθi​ (条目)提供评级 (Pi,j)(P_{i, j})(Pi,j​) ,矩阵分解技术用于预测未知的 Pi,jP_{i, j}Pi,j​ 值并为任何任务推荐最佳配置。这里一个重要的问题是冷启动问题,因为矩阵分解至少需要一些 tnewt_{new}tnew​ 上的评估。Yang等[189] 使用 D 最优实验设计采样和初始化了一组评估 Pi,newP_{i, new}Pi,new​ 。他们预测了预测性能和运行时间,以推荐一组准确而快速的热启动配置。Misir 和 Sebag [102,103] 利用元特征来解决冷启动问题。Fus i等[54] 也按照与[46]相同的步骤使用元特征,并使用概率矩阵分解方法,使他们能够执行贝叶斯优化以进一步优化其管道配置 θi\theta_iθi​ 。这种方法产生了任务和配置的有用的潜在嵌入,使贝叶斯优化可以更有效地执行。

元模型

我们还可以通过构建一个元模型 LLL 来学习任务的元特征和特定配置的实用性之间的复杂关系,该模型给定任务 tnewt_{new}tnew​ 的元特征 MMM 推荐最有用的配置 Θnew∗\Theta_{new}^*Θnew∗​ 。在建立用于算法选择[15,19,70,115]和超参数推荐[4,79,108,158]的元模型方面,存在大量的早期工作[22,56, 87,94]。实验表明,增强的和打包的树通常可以产生最好的预测,虽然非常依赖于抽取元特征的使用[72,76]。

排名

元模型还可以生成最有前景的前 KKK 个配置的排名。一种方法是建立一个 k 最近邻(kNN)元模型,以预测哪些任务相似,然后在这些相似任务上对最佳配置进行排名[23,147]。这与第 2.3.3 节中讨论的工作类似,但与后续优化方法无关。元模型还可以专门用于排名,例如预测聚类树[171]和标签排名树[29]都可以很好地工作。近似排名树森林(ART Forests)[165]是快速排名树的集合,被证明是特别有效的,因为它们具有“内置”元特征选择,即使很少可用的先前任务也能很好地工作,并且集成特性也使得该方法更加鲁棒。autoBagging [116] 使用基于 XGBoost 的排序器在 140 个 OpenML 数据集和 146 个元特征上进行训练,对包含四个不同的 Bagging 超参数的 Bagging 工作流进行排序。Lorena等[93] 使用一个 kNN 元模型和基于数据复杂性的一组新元特征为针对回归问题的 SVM 推荐了一组配置。

性能预测

元模型还可以直接预测性能,例如给定任务的元特征,可以确定给定任务的配置的准确度或训练时间。 这使我们能够估计配置是否足够有吸引力,可以在任何优化过程中进行评估。早期的工作使用线性回归或基于规则的回归器来预测一组离散配置的性能,然后对其进行相应排名[14,77]。Guerra等[61] 训练了一种 SVM 元回归器,为每个分类算法在默认设置下根据其元特征为新任务 tnewt_{new}tnew​ 预测准确度。Reif等[130] 在更多元数据上训练类似的元回归器,以预测其优化性能。Davis等[32] 使用基于多层感知机的元学习器来预测特定算法配置的性能。

除了预测 "“预测性能” "之外,还可以训练元回归器来预测算法训练/预测时间,例如使用通过元特征训练的 SVM 回归器[128],其本身通过遗传算法进行调整[119]。 Yang等[189] 仅基于实例和特征的数量,使用多项式回归预测配置运行时间。Hutter等[68] 在各种领域中提供了关于预测算法运行时间的一般性论述。

这些元模型中的大多数会生成有前景的配置,但实际上并不会为 tnewt_{new}tnew​ 自动调整这些配置。反而,这些预测可用于热启动或指导任何其他优化技术,从而可以使用各种元模型和优化技术的组合。实际上,在第 2.3.3 节中讨论的某些工作可以看作是使用基于距离的元模型热启动贝叶斯优化[48,54]或进化算法[59,129]。原则上,其他元模型也可以在这里使用。

除了学习任务的元功能和配置性能之间的关系以外,还可以构建代理模型来预测特定任务上的配置性能[40]。然后,可以研究如何将这些每个任务的预测结合起来,以热启动或指导新任务 tnewt_{new}tnew​ 的优化技术[45,114,161,187],如第 2.2.3 节中所述。虽然元特征也可以用于基于任务相似性来组合每个任务的预测,但最终更有效的方法是收集新的观测值 Pi,newP_{i, new}Pi,new​ ,因为它们允许我们利用每个新观测值来改进任务相似性的估计[47,85,187]。

管道合成

当创建整个机器学习管道时[153],配置选项的数量急剧增加,这使得利用先验经验变得更加重要。可以通过在管道上施加固定的结构来控制搜索空间,该结构可以由一组超参数充分描述。然后,人们可以在最相似的任务上使用最有前景的管道来热启动贝叶斯优化[46,54]。

其他方法为某些管道的步骤提供了推荐[118,163],并且可以在较大的管道构建方法中加以利用,例如计划[55,74,105,184]或进化技术[110,164]。Nguyen 等[105]使用束搜索 (beam search) 来构建新的管道,重点关注是由元学习器推荐的组件,并且元学习器本身就根据的先前成功管道的示例进行了训练。Bilalliet等[18] 预测对于给定的分类算法推荐使用哪种预处理技术。他们针对每个目标分类算法建立了一个元模型,给定了 tnewt_{new}tnew​ 的元特征,预测了管道中应包含的预处理技术。同样,Schoenfeld等[152] 建立元模型,预测预处理算法何时可以改善特定分类器的准确性或运行时间。

AlphaD3M[38] 使用自强化学习方法,其中用当前管道表示当前状态,动作包括添加,删除或替换管道组件。通过蒙特卡洛树搜索(MCTS)生成管道,对管道进行评估,以训练可以预测管道性能的循环神经网络(LSTM),从而产生在下一轮中 MCTS 的动作概率。 状态描述还包括当前任务的元特征,允许神经网络跨任务学习。Mosaic[123] 也使用 MCTS 生成管道,但是使用基于赌博机的方法来选择有前景的管道。

调整还是不调整

为了减少要优化的配置参数的数量,并在时间受限的设置中节省宝贵的优化时间,还提出了元模型来预测是否有必要根据手头任务的元特征调整给定的算法[133] ,以及通过调整特定算法我们期望得到多少改进 vs. 额外的时间投入[144]。对特定学习算法的更集中研究产生了元模型,这些元模型预测何时需要调整 SVM[96] ,给定任务(包括可解释的元模型)的 SVM 好的默认超参数是什么[97],以及如何调整决策树[95]。

从先前模型中学习

我们可以从中学习的最后一个元数据的类型是先前的机器学习模型本身,即它们的结构和学习到的模型参数。简而言之,我们要训练一个元学习器 LLL ,它学习如何为新任务 tnewt_{new}tnew​ 训练一个(基本)学习器 lnewl_{new}lnew​ ,给定相似的任务 tj∈Tt_j \in Ttj​∈T 和相应的优化模型 lj∈Ll_j \in \mathcal{L}lj​∈L ,其中 L\mathcal{L}L 是所有可能模型的空间。学习器 ljl_jlj​ 通常由其模型参数 W={wk},k=1…KW = \{w_k\}, k = 1 \ldots KW={wk​},k=1…K 和/或其配置 θi∈Θ\theta_i \in \Thetaθi​∈Θ 定义。

迁移学习

在迁移学习[170]中,我们使用在一个或多个源任务上训练过的模型,并将它们用作在类似目标任务上创建模型的起点。这可以通过强制目标模型在结构上或其他方面与源模型相似的方式来完成。 这是一个普遍适用的想法,并且已经针对核方法[41,42],参数贝叶斯模型[8,122,140],贝叶斯网络[107],聚类[168]和强化学习[36,62]提出了迁移学习方法。但是,神经网络非常适合进行迁移学习,因为源模型的结构和模型参数都可以用作目标模型的良好初始化,从而产生预训练模型,然后可以使用 tnewt_{new}tnew​ 上可用的训练数据对其进行进一步的微调[11,13,24,169]。在某些情况下,在迁移源网络之前可能需要对其进行修改[155]。在本节的其余部分中,我们将重点介绍神经网络。

特别对于大型图像数据集,例如 ImageNet [78],已显示出可以很好地迁移到其他任务的预训练模型[37,154]。但是,也有研究表明,当目标任务不太相似时,这种方法效果不佳[191]。与其希望预训练模型“偶然地”很好地转移到新问题上,不如让我们对元学习者施加归纳偏好(从许多类似的任务中学习),从而使他们更快地学习新任务,正如我们将在下面讨论的那样。

神经网络中的元学习

早期的元学习方法是创建能够修改自身权重的循环神经网络(RNN)[149,150]。在训练期间,他们使用自己的权重作为其他输入数据,并观察自己的错误,以学习如何根据手头的新任务修改这些权重。权重的更新是以参数形式定义的,该参数形式是端到端可区分的,并且可以使用梯度下降来共同优化网络和训练算法,但也很难训练。后来的工作使用跨任务的强化学习来使搜索策略[151]或梯度下降的学习率[31]适应当前任务。

受到反向传播不太可能是我们大脑的学习机制这一感觉的启发。 Bengio等[12] 用简单生物学启发的参数规则(或进化的规则[27])代替反向传播,以更新突触权重。参数被优化,例如,在一组输入任务中使用梯度下降或进化。 Runarsson 和 Jonsson [142] 用单层神经网络替换了这些参数规则。Santoro等[146]使用记忆增强神经网络来学习如何存储和检索先前分类任务的“记忆”。Hochreiter等[65] 使用 LSTM [66] 作为元学习器来训练多层感知器。

Andrychowicz等[6] 还替换了优化程序,例如将随机梯度下降替换为在多项先前任务上训练过的 LSTM 。元学习器(优化器)的损失定义为基本学习器(优化器)的损失之和,并使用梯度下降进行优化。在每个步骤中,元学习器都会根据上一步所学的模型权重 {wk}\{w_k\}{wk​} 以及当前的性能梯度,来选择估算的权重更新以最大程度地减少优化程序的损失。后来的工作通过使用梯度下降训练综合函数的优化器来推广这种方法[28]。即使元学习无法使用梯度,这也可以对其优化。

同时,Li 和 Malik [89] 提出了从强化学习的角度学习优化算法的框架。它将任何特定的优化算法表示为策略,然后通过指导性策略搜索来学习该策略。后续工作[90]显示了如何利用这种方法来学习(浅)神经网络的优化算法。

神经网络架构搜索领域包括许多其他方法,这些方法可以为特定任务构建神经网络性能模型,例如使用贝叶斯优化或强化学习。在第 3 章中进行了深入的讨论。但是,这些方法中的大多数(尚未)在各个任务之间进行归纳,因此这里不再讨论。

小样本学习

一个特别具有挑战性的元学习问题是在给定以往非常类似的任务经验 (对此我们拥有大量可用的训练集) 的情况下,仅使用几个训练示例来训练准确的深度学习模型。 这被称为“小样本学习”。人类对此具有与生俱来的能力,我们希望构建能够做到这一点的机器学习代理[82]。这样的一个特定示例是“K-shot N-way” 分类,在该分类中,我们给出了某些类(例如对象)的许多示例(例如,图像),并且想要学习一个可以仅使用每个分类 KKK 个示例的情况下对 NNN 个新类别分类的分类器 lnewl_{new}lnew​ 。

例如,利用先前的经验,我们可以学习所有任务的通用特征表示,通过更好的模型参数初始化值 WinitW_{init}Winit​ 开始训练 lnewl_{new}lnew​ ,并获得归纳偏好,以帮助指导模型参数的优化,因此 lnewl_{new}lnew​ 可以比其他可能方法更快地训练。

早期在小样本学习上的工作主要是基于手工设计的特征[10,43,44,50]。但是,通过元学习,我们希望以端到端的方式学习所有任务的通用特征表示。

Vinyals等[181] 指出,要从很少的数据中学习,应该寻找非参数模型(例如 k 近邻),该模型使用记忆组件而不是学习许多模型参数。他们的元学习器是一个匹配网络,该网络应用了神经网络中记忆组件的概念。它为标记的示例学习通用表示,并使用余弦相似度将每个新的示例与存储的示例进行匹配。该网络在小型批次上进行训练,每个批次仅包含几个特定任务的示例。

Snell等[157] 提出了原型网络,该网络将示例映射到 p 维向量空间,以使给定输出类别的示例相互靠近。然后,它为每个类计算一个原型(均值向量)。新的测试实例被映射到相同的向量空间,并且距离度量用于在所有可能的类上创建 softmax 。 Ren等[131] 将这种方法扩展到半监督学习。

Ravi 和 Larochelle [126] 使用基于 LSTM 的元学习器来学习用于训练神经网络学习器的更新规则。对于每个新示例,学习器都会将当前的梯度和损失返回给 LSTM 元学习器,然后 LSTM 元学习器会更新学习器的模型参数 {wk}\{w_k\}{wk​} 。元学习器通过所有先前任务训练。

另一方面,模型无关的元学习(Model-Agnostic Meta-Learning MAML)[51]并不尝试学习更新规则,而是学习模型参数初始化值 WinitW_{init}Winit​ ,该参数可以更好地概括类似任务。从一个随机 {wk}\{w_k\}{wk​} 开始,它迭代地选择一批先前的任务,并针对每个任务在 KKK 个示例上训练学习器,以计算梯度和损失(在测试集上)。然后向后传播元梯度以将权重 wk{w_k}wk​ 朝更容易更新的方向更新。换句话说,在每次迭代之后,权重 wk{w_k}wk​ 成为更好的 WinitW_{init}Winit​ 来开始对任何任务进行微调。Finn 和 Levine [52] 也认为,当使用足够深的全连接 ReLU 网络和某些损失函数时,MAML 能够近似任何学习算法。他们还得出结论,MAML 初始化对于小样本的过度拟合更具弹性,并且比基于 LSTM 的元学习方法更通用。

REPTILE [106] 是 MAML 的近似,它对给定任务执行 KKK 轮的随机梯度下降,然后逐渐将初始化权重朝着在 K 轮迭代之后获得的权重的方向移动。直觉是每个任务都可能具有一组以上的最优权重 {wi∗}\{w_i^*\}{wi∗​} ,目标为每个任务是找到一个至少接近其中一个 {wi∗}\{w_i^*\}{wi∗​} 的 WinitW_{init}Winit​ 。

最后,我们还可以从黑盒神经网络派生一个元学习器。Santoro等[145] 提出了记忆增强神经网络(Memory-Augmented Neural Networks MANN),它训练了一个神经图灵机(Neural Turing Machine NTM)[60],这是一种具有增强记忆功能的神经网络,也作为一种元学习器。然后,该元学习器可以记住有关先前任务的信息,并利用它来学习学习器 lnewl_{new}lnew​ 。SNAIL[101] 是一种通用的元学习器架构,由交错的时域卷积和因果注意力层组成。卷积网络为训练实例(图像)学习一个通用特征向量,以汇总过去的经验信息。因果注意层可从收集的经验中学习选择哪些信息,以推广到新任务。

总体而言,深度学习和元学习的交叉被证明是开创性新思想的沃土,我们希望随着时间的流逝,这一领域将变得越来越重要。

超越监督学习

元学习当然不限于(半)监督任务,并且已经成功地应用于解决诸如强化学习,主动学习,密度估计和项目推荐之类的任务。基本学习器可以是非监督的,而元学习器则是监督的,但是其他组合当然也可以

Duan等[39] 提出了一种由特定任务的快速 RL 算法组成的端到端强化学习(RL)方法,该方法由通用的慢元 RL 算法指导。这些任务是相互关联的马尔可夫决策过程(MDP)。元 RL 算法被建模为 RNN,它接收观测值,动作,奖励和终止标志。RNN 的激活存储了快速 RL 学习器的状态,并且通过观察快速学习器在任务之间的表现来学习 RNN 的权重。

同时,Wang等[182] 还提出使用深度 RL 算法来训练 RNN ,接收先前间隔的动作和奖励,以便为特定任务学习基本级别的 RL 算法。他们没有使用诸如随机马尔可夫过程 (MDP) 之类的相对非结构化的任务,而是专注于结构化任务分布(例如依赖赌博机),其中 元-RL 算法可以利用任务固有的结构。

Pang等[112] 提出了一种主动学习(AL)的元学习方法。基本学习器可以是任何二分类器,而元学习器则是一个深度 RL 网络,它由学习跨任务的 AL 问题表示的深层神经网络和学习最佳策略的策略网络组成,该策略被参数化为网络中的权重 。元学习器接收当前状态(未标记的点集和基分类器状态)和奖励(基分类器的性能),并输出查询概率,即指向未标记的集合中的下一个要查询的位置。

Reed等[127]提出了密度估计(DE)的几种方法。目标是学习某个概念(例如手写字母)的少量图像上的概率分布,该概率分布可用于生成该概念的图像,或计算图像显示该概念的概率。该方法使用自回归图像模型,该模型将联合分布分解为每个像素因子。通常,这些因子取决于目标概念的许多示例。 而,基于 MAML 的小样本学习器,在许多其他(相似)概念的示例上进行训练。

最后,Vartak等[178] 解决了矩阵分解中的冷启动问题。他们提出了一种深度神经网络体系结构,该体系结构学习一个(基础)神经网络,该神经网络的偏置可以根据任务信息进行调整。在神经网络推荐器的结构和权重保持固定的同时,元学习器将学习如何根据每个用户的历史记录来调整偏置。

所有这些最近的新发展都表明,通过元学习的镜头看问题并找到新的、数据驱动的方法来代替手工设计的基础学习器通常是成果丰富的。

结论

元学习机会以许多不同的方式展现出来,并且可以使用多种学习技术。每当我们尝试学习某个任务时,无论成功与否,我们都会获得有益的经验,可以利用这些经验来学习新任务。我们永远不必完全从头开始。相反,我们应该系统地收集 “学习经验” 并从中学习,以构建随时间不断改进的 AutoML 系统,从而帮助我们更加有效地解决新的学习问题。我们遇到的新任务越多,这些新任务越相似,我们就可以更多地利用先前的经验,以至于大多数必需的学习已经事先完成。计算机系统能够存储几乎无限量的以前的学习经验(以元数据的形式)的能力为以全新的方式使用这些经验提供了广泛的机会,而我们才刚刚开始学习如何有效地从先前的经验中学习。然而,这是一个值得努力的目标:学习如何学习任何任务,给与我们的远不止了解如何学习任何特定的任务。

AutoML-第二章-元学习相关推荐

  1. 一文弄懂元学习 (Meta Learing)(附代码实战)《繁凡的深度学习笔记》第 15 章 元学习详解 (上)万字中文综述

    <繁凡的深度学习笔记>第 15 章 元学习详解 (上)万字中文综述(DL笔记整理系列) 3043331995@qq.com https://fanfansann.blog.csdn.net ...

  2. 知识图谱文献综述(第二章 知识表示学习)

    第二章 知识表示学习 1. 任务定义.目标和研究意义 知识表示是知识获取与应用的基础,因此知识表示学习问题,是贯穿知识库 的构建与应用全过程的关键问题.人们通常以网络的形式组织知识库中的知识, 网络中 ...

  3. C++PrimerPlus 第二章 开始学习C++

    C++PrimerPlus 第二章 开始学习C++ 2.1 进入C++ 2.1.1 main()函数 2.1.1.1 作为接口的函数头 2.1.1.2 为什么main( )不能使用其他名称 2.1.2 ...

  4. Foundations of Machine Learning 2nd——第二章 PAC学习框架 后记

    Foundations of Machine Learning 2nd--第二章 PAC学习框架后记 前言 Generalities 一般性 可确定性 VS 随机场景 定义1 Agnostic PAC ...

  5. 第二章 oceanbase学习之手动部署

    系列文章目录 第一章 oceanbase学习之docker方式部署 第二章 oceanbase学习之手动部署 第三章 oceanbase学习之迁移MySQL数据到oceanbase 第四章 ocean ...

  6. Foundations of Machine Learning 2nd——第二章 PAC学习框架

    Foundations of Machine Learning 2nd--第二章 PAC学习框架 前言 定义介绍 Generalization error Empirical error 定理1 PA ...

  7. 计算机网络(第五版 作者:AndrewS.Tanenbaum David J.Wetherall 清华大学出版社)读书笔记----第二章的学习

    计算机网络第二章--物理层读书笔记 1.物理层是网络的技术设置,物理层的材质和带宽决定了最大的传输速率. 2.传输介质的分类:引导性(有线介质)和非引导性(无线介质). (1)有线介质:磁介质.双绞线 ...

  8. 第二章 如何学习Linux(鸟哥的Linux私房菜基础学习篇)

    在这个章节中,鸟哥说:"1,从头学习:2,选择工具书:3,实践再实践:等等."我认为:实践再实践,不断的重复练习,讲给别人听,写出来,然后应用于工作中,就是好方法.学习的最后目的就 ...

  9. C++ Primer第六版程序清单与习题详解【第二章 开始学习 C++】

    一.程序清单 程序清单 2.1 m yfirst.cpp 程序清单2.1中的示例非常简单,只包含一个名为main()的函数.myfirst.cpp示例包含下述元素. •  注释,由前缀//标识. • ...

最新文章

  1. 说实话,DataGrip真得牛逼,只是你不会用而已~
  2. python:字典的操作
  3. PMcaff-培训 | 活动报名结束,押金和邮件须知的那些事儿
  4. php使用supervisor管理进程脚本
  5. ‘ascii‘ codec can‘t encode characters in position
  6. AndroidLinux gdb用法
  7. Java中的random
  8. LLDP协议编写要点
  9. 一个微信关联管理多个腾讯云账号
  10. 【python】之字符串格式化
  11. 人工神经网络的训练步骤,神经网络训练过程图解
  12. 一顿操作猛如虎,细说MySQL索引的区别
  13. pccs色卡_PCCS色卡RGBCMYK對照表.PDF
  14. flink sql 如何upsert 到一张hologres表中
  15. 用户标签体系的应用——精准营销
  16. 美创科技与您一同回顾2022年一季度网络与数据安全政策
  17. 论文阅读笔记(五)CLIP4Clip: An Empirical Study of CLIP for End to End Video Clip Retrieval
  18. Nobleman__ ACM 比赛模板 (C++ Java)个人总结 (不断更新) (自用)
  19. 温故而知新CentOS宝塔
  20. 4 步搞定 Hive 增量更新

热门文章

  1. 宝塔php7.4通用拓展需要安装_bt宝塔面板php7.3、php7.4不支持ZipArchive解决方法
  2. 高防服务器稳定性原因,企业租用高防服务器有什么原因呢?
  3. 南邮计算机学院张晓霞,南京邮电大学第四届海内外青年学者云论坛通信与信息工程学院分论坛成功举办...
  4. 轻松获取布局截图 或友盟分享截图
  5. 最全的C#图片处理类ImageHelper.cs(个人保留)
  6. svg图编码成base64实现图片效果
  7. python小游戏合集-9个Python编程小游戏,有趣又好玩,简直太棒了
  8. 电脑桌面上做工作计划的便签软件是啥?
  9. Dynamic Selective Network for RGB-D Salient Object Detection
  10. 实现recycleView页面的跳转设计(移动开发第二次作业)