随着机器学习(ML)成为每个行业的重要组成部分,对机器学习工程师(MLE)的需求急剧增长。MLE将机器学习技能与软件工程专业知识相结合,为给定应用程序找到高性能模型,并应对实现过程中遇到的挑战 - 从构建训练的基础架构到准备部署模型。新的在线资源如雨后春笋般冒出,培训工程师构建ML模型,并解决遇到的各种软件挑战。然而,新ML团队最常见的难题之一是保持工程师习惯于传统软件工程的进展水平。
这一难题的原因在于开发新ML模型的过程在一开始就非常不确定。毕竟,很难知道模型在给定的训练运行结束时的表现如何,更不用说通过广泛的调优或不同的建模假设可以实现什么性能了。
许多类型的专业人员都面临着类似的情况:软件和商业开发人员,寻找适合产品市场的初创公司,或者在信息有限情况进行操作的飞行员。这些职业中的每一个都采用了一个共同的框架,以帮助他们的团队通过不确定性高效地工作:软件开发的agile和 scrum,初创公司“lean”和美国空军的OODA循环理论。MLE可以遵循类似的框架来应对不确定性并快速提供优质产品。
在本文中,我们将描述我们对ML版本的“OODA循环”的概念:机器学习工程循环(ML Engineering Loop,MLE循环),其中ML工程师循环:
这样就可以快速有效地发现最佳模型并适应未知。此外,我们将为每个阶段提供具体的建议,并对整个过程进行了优化。
MLE循环
ML工程循环的目的是围绕开发过程设置一个钉死的思维框架,简化决策过程,只专注于最重要的后续步骤。随着从业者在经验方面的进步,这个过程成为第二本能,不断增长的专业知识使你可以毫不犹豫的在分析和实现之间的快速转换。也就是说,当不确定性增加时,即使对于最有经验的工程师,这个框架仍然非常有价值。这些不确定性包括:当模型意外地无法满足要求时,团队的目标突然改变(例如,测试集被修改以反映餐品本身的变化),或者当团队进展没有达到目标等。
要进行下面描述的循环,你应该从一个包含很少的不确定性的最小实现开始。通常我们希望尽快“get a number” - 建立够用的系统,以便我们可以评估其性能并开始迭代。这通常意味着:
例如,假设我们正在构建一个树木探测器来测量一个地区的树木种群,我们可能会使用类似的Kaggle竞赛中的现成训练集,以及来自目标区域的手工收集的一组照片用于开发并作为测试集。然后我们可以对原始像素进行逻辑回归,或者在训练图像上运行预训练网络(如ResNet)。我们这里的目标不是一次性解决项目,而是开始我们的迭代周期。以下是一些帮助你做到这一点的提示。
要做一个好的测试集:
关于开发和训练集:
获得初始模型后,应检查其在训练,开发和测试集上的性能。这标志着第一次循环结束了。评估测试性能和有用产品所需性能之间的差距。现在是时候开始迭代了!
分析阶段就像医疗诊断一样:你拥有一套可以执行的诊断,你的目标是针对是什么限制模型性能提出最可能的诊断。在实践中,可能会有许多不同的问题交叠导致当前的结果,但你的目标是首先找到最明显的问题,以便你可以快速解决它们。不要陷入对每个缺点的完全理解的泥沼中 - 而是要了解最重要的因素,因为许多小问题会随着你的模型改进而改变甚至消失。
下面,我们列出了一组常用的诊断方法。选择要运行的诊断需要一些技巧,但是当你绕着ML工程循环工作时,你会逐渐获得要先用哪种方法进行尝试的直觉。
想要进行分析,比较好的起点是查看你的训练,开发和测试性能。我们建议在每次实验结束时使用代码执行这个操作,以使自己习惯于每次查看这些数字。通常,我们认为:训练错误<=开发集错误<=测试集错误(如果每个集合中的数据遵循相同的分布)。使用上一次实验的训练,开发和测试错误率,你可以快速查看这些因素中的哪些是当前的限制。例如,当训练错误和开发设置错误之间存在差距较小时,你的训练错误就是提高性能的瓶颈。
权重直方图
如果训练集错误是当前限制因素,则可能会出现以下问题:
如果开发集错误是当前限制因素,这可能是与上述问题类似的问题引起的:
如果测试集错误是当前限制因素,这通常是由于开发集太小或者团队在多次实验过程中过拟合开发集。
对于上述任何一种情况,你可以通过手动检查模型出错的一组随机实例来了解模型的失败(对于测试集,通常不这样做,以避免在这些测试实例中“训练”你的系统。) 。
请注意,上述多数诊断都有直接而明显的对策。例如,如果训练数据太少,那么只需获取更多训练数据!我们发现在心理上将分析阶段和选择阶段(下面会有)分开是有用的,因为在没有真正深入研究根本问题的情况下,很容易陷入尝试随机方法的泥潭。此外,以开放的心态努力回归错误分析中通常会发现什么,这可以改善你做出的决定。
卫星数据是出了名的嘈杂,经常需要检查
以Insight为例当AI研究员Jack Kwok正在建立一个帮助灾难恢复的分割系统时,他注意到,虽然他的分割模型在他的卫星图像训练集上表现良好,但在包含飓风泛滥城市的开发集上表现不佳。原因是飓风图像的质量较低,比训练数据更模糊。向训练管道添加额外的增强步骤,对图像应用模糊处理有助于缩小训练和开发性能之间的差距。
对于语音识别系统,对开发集的深入错误分析可能会发现有与大多数用户非常不同的浓重口音的说话者,他们导致了很多错误。然后,我们可以检查训练集以查看类似的口音是否被正确的标记了,如果没有,正确标记并且通过训练算法成功拟合。在机器学习中,某些用户组的不充分表示或错误标记导致偏差的原因之一。因此,谷歌的语音系统使用的一个解决方案是积极获取具有浓重口音用户的额外训练数据。
在进行分析之后,你会很好地了解模型所出现的错误类型以及阻碍性能的因素。对于给定的诊断结果,可能存在几种可能的解决方案,下一步是枚举并给出优先级。
上面的一些诊断直接决定潜在的解决方案。例如,如果你的优化器似乎被错误调优,你可以尝试不同的步长,或者甚至换个优化算法。如果训练数据集太小,收集更多训练数据可能是一个快速而简单的解决方案。
我们建议ML工程师和他们的团队列举尽可能多的可行方案,然后尽可能选择比较简单,快速的解决方案。如果解决方案有效(例如,使用工具包中已实现的其他优化算法),那么就从这个开始。虽然更复杂的方法看起来可能会在一次性完成更多的工作,但我们经常发现,许多快速迭代的改进抵消了修订最先进的或者定制解决方案所带来的收益,而这些解决方案需要更长的时间才能完成。如果你的选项是标记1000个数据点或研究尖端的无监督学习方法,我们认为你应该收集并标记数据。如果你可以使用简单的探索式的方法开始,那就动手做吧。
根据你的诊断,以下是一些常见的解决方案。
如果需要调整优化器以更好地拟合数据:
如果模型无法很好地拟合训练数据:
如果模型没有泛化到开发集:
你知道该尝试什么,你已经让它变得简单了,现在只需实现即可。这个阶段的目标是快速构建原型,以便你可以度量结果,从中学习,并快速回到循环。因此,我们建议你专注于构建当前实验所需的内容。请注意,虽然你的目标是快速学习而不是完善所有内容,但你的工作仍需要正确,因因此你应该经常检查代码是否按照预期工作。
收集和标记数据时:
编写新模型时,请从类似的现有实现开始。许多研究论文现在都有免费提供的代码 - 所以在重新从论文中实现一个想法之前,尝试获得代码,因为论文通常没有说明过多的细节。这将节省你几个小时甚至几天的工作时间如果可能,对于任何问题,我们建议你执行以下步骤:
编写测试以检查你的梯度,张量值,输入数据和标签是否格式正确。在你最初设置模型时执行此操作,这样你捕获错误一次就够了。
打印出你的测试结果和你决定是否准备交付的任何其他指标。(例如,生产限制因素)。
如果性能有所改善,你可能就在正确的轨道上了。在这种情况下,现在可能是清理已知运行良好的任何组件的好时候,并且你要确保你团队中的其他人可以复制你的尝试。
另一方面,如果性能变差或没有足够的改善,你要决定是再次尝试(回到分析阶段)还是放弃当前的想法。如果ML循环的每个循环都相对省力,那么这些决定更容易做出:你没有投入太多精力来使你的代码完美,而下一次尝试不会花费太长时间 - 所以你可以根据想法的风险和价值来决定做什么,而不是根据沉没成本。
任务肯定会有不确定性,但上面的ML工程循环会帮助你朝着更好的模型方向前进。但很遗憾的是,它并不魔法 - 你仍然需要培养你在每个阶段做出正确选择的能力,比如确定性能瓶颈,决定尝试哪些解决方案,如何正确实现它们,以及如何度量你应用的性能。你还需要快速、熟练地迭代。因此,你还应该花时间考虑提高迭代的质量和速度,以便你可以在每个周期中取得最大进展,并且可以快速完成多次迭代。
与其他决策一样,只有当这些决策能够解决当前的痛点时,才能对它们进行处理。很多团队花费太多时间构建所谓“完美的”框架,却发现真正令人头疼的事情不在于此。
由于ML项目具有固有的不确定性,我们上面推荐的方法相当于为你提供了一个扶手。虽然当实验不确定时,很难让自己对达到特定准确性的目标负责,但至少可以让自己负责完成错误分析,制定想法列表,编写代码并查看其工作原理。在Emmanuel和Adam的经历中,拒绝光鲜事物的呼唤,不懈地专注于循序渐进的进步,可以在研究和应用方面产生非凡的成果。这会改变团队,并使无数的研究员提供最前沿的项目。