建模,也被称为训练(Training)模型。包括了两个主要部分,一是数据科学家进行试验,找到解决问题的最佳方案,本节称之为模型试验;二是计算机训练模型的过程,本节在平台支持中介绍。
建模是数据科学家的核心工作之一。建模过程涉及到很多数据工作,称为特征工程,主要是调整、转换数据。数据科学家的主要任务是要让数据发挥出最大的价值,解决业务需求,或发现未知的问题,从而提升业务。建设机器学习平台时,要对数据科学家的工作有一定理解,才能建设出真正能帮助数据科学家的平台。
特征工程与超参调整是建模过程中的核心工作。
特征工程是指对数据进行预处理,使处理后输入模型的数据能更好的表达信息,并提升输出结果的质量。特征工程是机器学习中非常重要的一环。数据和特征工程决定了模型质量的上限,而算法和超参只是逼近了这个上限。
超参调整包括选择算法、网络结构、初始参数等工作。这些工作不仅需要丰富的经验,也需要不断地试验来测试效果。
特征工程与超参调整不是独立的过程。做完特征工程后,即要开始通过超参的组合来试验模型的效果。如果结果不够理想,就要从特征工程、超参两方面来思索、改进,经过一次次迭代,才能达到理想的效果。
特征工程的内涵非常丰富,在输入模型前的所有数据处理过程都可以归到特征工程的范畴。通过特征工程,将人的知识(通常称为先验知识)加入到数据中,并降维来减小计算规模,从而提高模型性能和计算效率。
特征工程的数据处理过程大部分都可以在数据转换阶段进行。可以将常见的特征工程的处理函数抽象为数据转换组件,方便重用。
特征工程的主要内容有:
数据清洗。在数据部分已介绍过,即处理异常数据,或对数据进行修正。
纠正数据偏离(bias)。
在一些应用中,虽然有大量的数据,但数据分布并不均衡。如,在流水线检测缺陷产品的场景下,如果缺陷率为千分之一,那么原始数据里99.9%都是正常产品的图片,只有0.1%是缺陷数据。这种情况下,训练出来的模型质量不会太高。
还有些情况下,数据偏离很难被发现。比如,互联网新闻图片下训练的分类模型,在用于手机摄像头照片分类时,效果会差很多。原因是新闻图片通常选择了颜色饱满丰富,构图优美的图片,和用户自己拍摄照片的色彩构图上有不小的差异。
这种情况下,一旦发现了数据偏离就要从数据和算法两方面来调整。有的机器学习算法能够自动将小量数据的作用放大。但大部分情况下,需要人工对数据比重进行调整,并引入接近真实情况的数据集。
数值变换。机器学习需要的数据都是数值,如果是浮点数,一般要调整到0~1之间。枚举值要拆成一组布尔值。不同来源的数据还要做计量单位的统一。
输入先验知识。即根据人的判断,将一些数据中难以直接学习到的信息抽取成特征,从而减小学习难度。如,自然语言的评价分类问题中,可以建词表,将正面词语和负面词语总结出来,对每句话的正负面词计数,并作为单独的特征列。这样对正面负面的分类判断会有较大的帮助。虽然数据维度会增加,但模型有了更多的人类先验知识,会判断得更准确。
数据降维。是在尽量不丢失信息的情况下,减小单条数据的大小,从而减小计算量。比较直观的降维方式就是把图片缩小到一定的尺寸,减小像素数量。深度学习是在多层网络里,保留信息的同时,逐步给数据降维。机器学习算法中的主成分分析(Primary Component Analysis, PCA)和线性判别分析(Linear Discriminant Analysis,LDA)是经典的降维方法,用线代的矩阵特征分解的算法,找出数据中区分度最大的特征,然后省略一些作用不大的特征。
在机器学习中,模型能够自己学习改变的权重等数据,叫做参数。而不能通过机器学习改变,需要提前人为指定的参数叫做超参数(hyperparameter,简称超参)。这些参数会直接影响最终模型的效果,超参调整过程非常依靠数据科学家的经验。
常见的超参如下:
算法与网络结构。机器学习从经典算法到最近流行的深度学习算法,以及各种各样的深度学习网络结构。虽然每个算法的适用范围比较清晰,但同一个问题仍然有很多可选的算法来实现。每个算法还会有自己独有的超参需要调整。还有的算法还能改动网络深度,每层神经元数量,或者采用不同的方法来进行非线性化,误差传递,提高泛化性能。算法中能调整的超参非常多,有些超参值也是连续的。所有超参的排列组合数量可认为是无限的。
批数据量大小,即每批数据的数量。如,每次取100条数据的平均值来更新模型。批数据量太小,会造成每批数据缺乏代表性,模型结果收敛时波动较大。而批数据量过大,会减少一些偏差很大特征的差异,无法学习到一些细节的信息。
学习率,即每次迭代时对数值的修改幅度。早期的机器学习方法都是固定的学习率,调整起来比较复杂。现在一般都是动态的学习率,但仍然要调整一些学习幅度、用什么算法等。学习率过大,会造成结果震荡,无法很好的收敛。而学习率过小,会让收敛很慢,浪费计算资源。
每组超参的效果,需要通过一定时间的训练之后才知道。因此,超参的调整过程非常耗时,数据科学家需要通过超参的各种组合来研究它们之间的关系,找到较好的搭配。
平台可通过可视化界面,提交一组超参配置,并对数据结果进行比较,提高调参效率。
自动化建模(AutoML),主要是通过对超参的自动化选择,来提升建模工作的效率。超参调整问题,实际上是研究 什么样的超参组合下会得到最好的模型效果。
对某个具体问题,需要试验的超参组合可能有无穷多种。数据科学家其实就是在这个组合空间里找到效果较好的组合。通过自动化建模的方式,可部分、甚至全自动的寻找超参组合。寻找超参的方法包括穷尽法,随机搜索,通过概率模型发现超参关联,遗传算法,梯度优化,或组合前述方法等等。
有的自动化建模方法可完全自动。只需要输入数据,即可探索从算法到网络结构等所有超参的组合。这种方法不需要有任何机器学习经验,但搜索过程较长,也用不上人的一些先验知识。
有的自动化建模方法是半自动的。除了输入数据,还需要输入一些算法、参数限定的组合,即可自动找出这些组合中的较佳组合。这种方法需要一定的机器学习建模经验,但搜索时间较上者短,同时能结合人的先验知识,在较小的组合范围内搜索。
在实际应用中,经常组合多个模型,以及规则代码才能完成整个功能。比如,在手写体识别时,需要先用目标检测模型将文本部分找出来,然后分割字符,最后通过分类模型识别单个字符。实际上,还会涉及到文本旋转、连笔等问题。这样的应用中,不能依靠一个单一的模型,输入了图片就期待这个强大的模型输出结果,而需要多个模型再加上一些算法才能得出结果。因此,机器学习平台需要有流水线的处理能力来支持模型、规则组合的应用。在建模阶段,多个模型可以分拆来处理,但在部署后的应用推理阶段,一般需要近实时的输出结果。
有些情况下,组合模型与通用规则还不够,还需要对推理结果进行基于数据的特殊规则。如,在搜索引擎中,当结果中含有某些关键词时,会增加或降低其权重,从而达到人工调整搜索结果的效果。
总之,模型试验时,不应考虑依靠一个模型就能达到最好的效果。要灵活的组合模型、自动规则以及人工调整的方法来获得最终的效果。
模型实验阶段对平台支持有较多要求。好的工具能够提高生产力,减少人为错误,还能充分利用资源,让算力尽可能产生价值。
平台除了本节提到的功能外,还需要扩展能力、运维支持、易用性、安全性等方面的功能,这些与部署后的平台功能有所重叠,在随后的章节中集中讨论。
机器学习平台一般是计算密集型的平台。管理好算力才能提高生产力,节约成本。算力管理的基本思路是将所有计算资源集中起来,按需分配,让资源使用率尽量接近100%。
算力管理几乎对任何规模的资源都是有价值的。比如,一个用户,只有一个计算节点(如一块GPU)有多条计算任务时,算力管理通过队列可减少任务轮换间的空闲时间,比手工启动每条计算任务要高效很多。多计算节点的情况,算力管理能自动规划任务和节点的分配,让计算节点尽量都在使用中,而不需要人为规划资源,并启动任务。多用户的情况下,算力管理可以根据负载情况,合理利用其它用户的空闲资源。在节点数量上百甚至上千时,运维管理也是必不可少的功能。
虚拟化。是将实际物理资源与运行时的逻辑物理资源进行隔离的技术。资源虚拟化后,能将一台性能很高的计算机拆分给多个不需要整台机器算力的任务使用,互不干扰。这样,在搭建机器学习平台的时候,按照性价比或最高性能的要求进行硬件采购即可,不必考虑实际任务的资源使用规模。在使用时,可灵活适配低资源要求的任务,而不会造成资源的闲置。Docker是目前比较流行的操作系统级的虚拟化方案,启动速度很快,还能将模型直接发布到部署环境。
任务队列。任务队列的管理是算力管理中的重要方法。在一些小型团队中,成员们独自使用服务器,算力不能得到很好的规划。如果将计算机集中起来,通过提交任务的方式来申请计算资源,运行训练任务。一旦任务完成后就释放计算资源,这样能达到最高的使用效率。
在计算任务较多时,还涉及到优化资源分配的问题。可按照比例为不同团队保障一定的资源。如,给团队A分配50%的资源,如果团队A没有使用到50%的资源,则空闲资源可分配给其它团队使用。若团队A有了更多的任务后,可立刻将其它团队的任务终止,或等任务完成后将团队A的任务优先执行。也可以按照任务优先级调度,保障某类任务的优先执行。训练任务在终止时,如果使用的框架支持保存点,下次启动时可以从保存点接着运行。如果不支持保存点,就要从头运行,这时候,终止任务会损失一定的算力。
任务队列在分配资源时,还要注意到大小资源任务的抢占问题。如,某任务需要多个GPU来运行,但其它任务都只需要1个GPU运行。如果要保证100%的计算资源利用率,势必在每次释放出1个GPU后,立刻指派下一个只需要1个GPU的任务。这样会造成需要多个GPU的任务很难获得足够的资源开始执行。平台对物理资源的调度方式要能够解决这种问题,将某台满足条件计算机的空闲资源留存下来不分配,保障多GPU的任务的运行。
代码集成。如果试验的模型输入输出比较固定后,可考虑进一步提高效率。在代码、配置提交后立刻执行配置好的训练任务,不需要手工配置任务模板并提交。代码集成带来的不仅是执行速度的提高,对于同样的输入输出更容易横向比较历史数据,获得更多的信息。
分布式训练。一些训练任务花费的时间很长,即使最高性能的单台设备也无法快速完成训练,这时需要分布式训练来进一步提升速度。分布式训练通常由机器学习框架来具体实现。平台要做的是保留足够的资源,并通过参数等方式将IP、端口等信息传入到代码中,然后启动分布式训练任务。
批量任务。在试验超参的过程中,经常需要对一组参数组合进行试验。批量提交任务能节约使用者时间。平台也可以将这组结果直接进行比较,提供更友好的界面。
交互试验体验。在脚本开发中,不少用户习惯于在交互式工具中进行试验、开发,如:Jupyter 笔记本。交互式开发可以对某一段代码提供所见即所得的交互式体验,对调试代码的过程非常方便。
虽然任务调度的方法对平台算力的利用率是最高的,但交互式开发在代码变化很大的时候,会提高人的开发效率。在交互试验的场景下,需要独占计算资源。机器学习平台需要提供能为用户保留计算资源的功能。如果计算资源有限,可对每个用户申请的计算资源总量进行限制,并设定超时时间。例如,若一周内用户没有申请延长时间, 就收回保留资源。在收回资源后,可继续保留用户的数据。重新申请资源后,能够还原上次的工作内容。
在小团队中,虽然每人保留一台机器自己决定如何使用更方便,但是用机器学习平台来统一管理,资源的利用率可以更高。团队可以聚焦于解决业务问题,不必处理计算机的操作系统、硬件等出现的与业务无关的问题。
平台要通过标准化数据接口来提高试验的速度,也能横向比较试验的结果。如果团队的试验比较多,需要经常研究公开数据集、算法实现等。可以根据开源数据集来实现统一的数据处理接口,这样可以加快算法与数据集的对接,方便组合不同的数据集和算法。数据接口标准化后,可以通过在新算法上运行多个公开数据,或在新数据集上运行经典的算法,从而对新算法、新数据集进行自动的试验和评估。
另外,考虑到数据的保密或减小计算规模,可以保留好几份不同规模生产数据。小数据集用于本地调试代码,中等规模的数据集用于评估模型效果,大规模数据集用于正式训练模型。当某种候选算法准备好后,能够快速切换到生产数据进行评估。
可视化也是机器学习领域的热点问题。包括结果分布、训练进度、训练效果对比等各方面的可视化。呈现出好的可视化效果,能让人直观的获得信息和经验,更容易理解信息。
数据分布。经典的机器学习方法可以选择最主要的两三个特征,通过二维或三维坐标来展示数据的分布。通过数据分布的可视化,可以让人了解到数据聚类的效果、直接的看到数据的规律。
训练进度。通过在模型中埋点(Telemetry),能够将模型的错误率、进度等信息保存下来。再绘制出图表,就能直观的看到模型错误率的收敛速度等信息。还可以对比多个模型的训练历史,对模型的效果和收敛速度的关系有更深的认识。
可解释性。在深度学习模型中,可解释性是研究的重点,即为什么模型会得出这样的推理结果,这个结果受哪些神经元节点影响最大?通过高亮出相关的神经元,并对不同的推理结果、模型进行对比,能洞察出更多信息,帮助更快的调整超参。
如果团队有一定的规模,甚至有多个小团队时,平台需要支持团队协作相关的功能。团队的分工上可能会横向根据工作内容分,如将数据预处理与建模团队分开;也可能根据垂直的模型来划分,如根据应用将调试不同模型的团队分开。平台建设时,要根据需求来决定团队合作相关的功能如何实现。
团队协作时,主要需求是沟通和数据交换。沟通可通过邮件、消息平台来进行,本文不再讨论。而交换的数据包括样本数据、代码、脚本、训练好的模型以及一些配置文件等等,这些需要机器学习平台来实现。团队协作时,要防止数据误操作和丢失,并要方便共享、查找。
分布式文件系统需要避免硬件问题造成数据意外丢失。另外,还要利用定期备份来防止数据被误删,如果改动比较频繁,可考虑每日备份。如果备份数据量较大,可通过差异备份来节约空间。有了数据备份,还要提供方便的搜索功能。除了要能够按照日期、相关人等方式来搜索外,按照机器学习模型对应的数据版本、效果、配置等来查找也是很重要的搜索方式。如果是代码、脚本等文本内容,可利用源代码管理工具获得更强的版本管理功能。
有了统一的存储和搜索功能,团队能方便的共享资源。上下游团队约定好具体的流程后,可以大大加快诊断问题,协作的速度,就能将各自最新的成果尽快集成到业务系统中。