Press "Enter" to skip to content

构建更好的机器学习系统 —— 第三章:建模让乐趣开始

关于基准、实验跟踪、适当的测试集和度量标准。关于让算法正常工作。

图片来源

你好。很高兴再次见到你。我真的很欣赏你想要成为一个更好的专业人士,做出更好的工作,并构建更好的ML系统的愿望。你很棒,继续努力!

在这个系列中,我尽力帮助你掌握设计和构建机器学习系统的艺术、科学和(有时候)魔力。我们在这里讨论业务价值和需求、数据收集和标记、模型开发、实验跟踪、在线和离线评估、部署、监控、重新训练等等诸多内容。

这是第三章,专门讲述模型开发。 一个ML算法只是ML系统的一小部分。一个完全准确的算法如果没有一个设计良好的系统,将无法为您的客户提供服务,也无法为您的公司赚钱。在本文中,我不会给你提供关于ML算法的概述,而是向你展示一个不同的视角:如何在选择、开发和评估算法时牢记算法的主要目标是为业务带来价值。到最后,无论您是使用线性回归还是最先进的神经网络来解决业务问题,都并不重要。

ML算法(黑盒子在中间)只是ML系统的一小部分。图片来源

在我们继续之前,让我们快速回顾一下我们已经学到的内容。

第一章是关于规划的。我们了解到每个项目都必须从一个计划开始,因为ML系统太复杂了,无法以临时的方式来实施。我们回顾了ML项目的生命周期,讨论了为什么以及如何估算项目的商业价值,如何收集需求,然后再冷静地重新评估一下是否真正需要ML。我们学会了如何从小开始,快速失败,使用“PoC”和“MVP”等概念。最后,我们谈到了在规划阶段制定设计文档的重要性。

第二章是关于数据的。我们讨论了行业中的一个新趋势——以数据为中心的人工智能,这是一种构建ML系统的方法,它认为干净的数据比先进的ML算法更重要。我们谈到了数据流水线,这些流水线旨在组织混乱和非结构化的数据流,以便将数据用于分析。我们了解到训练数据应该是相关、统一、代表性和全面的,因为模型是基于这些数据来建立对世界的理解的。我们回顾了人工和自然两种类型的标签,并介绍了获取人工标签的复杂、缓慢和昂贵的过程,并讨论了使这个过程更加轻松的最佳实践。最后,我们谈论了真实数据和人工标注的替代方案:合成数据。

如果你不小心错过了之前的文章,我鼓励你在继续之前先阅读它们。我会在这里等你。

现在,让我们开始吧。

如何选择一个ML算法

没有一种算法适用于所有问题。你需要尝试几种方法,并对你的数据和领域有深入的了解,直到你找到一个有效的方法。

思考、集思广益、与同事交流、询问ChatGPT,然后写下你打算尝试的三种方法:1)一些非常简单的方法;2)一些非常流行的方法;3)一些新颖和有创意的方法。

  1. 一些非常简单的方法。算法中引入的每种复杂性都必须有充分的理由。从一个简单的方法(甚至可能不是ML方法)开始,评估它,并将其作为基准与其他所有模型进行比较。
  2. 一些非常流行的方法。如果你看到、听到和读到许多人正在使用特定算法解决相同的业务问题,确保将其添加到你的实验列表中。利用集体智慧!我对流行方法的期望总是很高的,在大多数情况下,它们的效果都非常好。
  3. 一些新颖和有创意的方法。试试看。如果你能通过击败典型的流行方法来建立竞争优势,你的老板和公司会很高兴。

谨慎行事:不要重复造轮子。有数百个开源库和存储库已经实现了大多数算法、数据采样策略或训练循环。不要自己编写定制的K-means聚类算法——使用scikit-learn中的算法。不要从头开始编写ResNet50——使用PyTorch中的算法。在实施最新的论文之前,查看PapersWithCode,我敢打赌有人已经做过了。

进行研究并发明新事物是令人兴奋的。从头开始实现算法,理解每一行代码,是很诱人的。然而,研究只适用于大学和大型科技公司。对于初创公司来说,每一美元都很重要,因此他们无法承担投资低成功率项目的成本(研究通常需要进行100次试验才能获得1次成功)。

对“最先进”要谨慎。想象一下,你正在使用YOLOv7进行目标检测,然后听说YOLOv8发布了,预计会更好。这是否意味着你需要升级所有生产流程以支持YOLOv8?不一定。

在大多数情况下,“更好”意味着在静态基准数据集(如COCO)上提高1-2%的性能。您的数据模型可能会更好,也可能会稍微好一些,甚至可能更差,因为您的数据和业务问题在各个方面都不同。此外,从系列文章的第二章中您应该记住:改进数据比改进算法对提高模型准确性有更大的影响。想办法清洗训练数据——您将看到5-10%的准确性提升。

如何开发机器学习算法

首先,获取一个基线。基线是您将要与之竞争的模型。基线有两个逻辑选择:

  1. 来自生产环境中的现有模型(如果有的话)。我们希望改进现有模型,所以需要与其进行比较。
  2. 一个易于部署的非常简单的模型。如果业务任务可以通过简单的方式解决,为什么要费心训练复杂的模型呢?花几天时间寻找简单解决方案并实施它。

接下来是实验。您构建所有实验以改进基线。找到一个有希望的算法?很好,评估并将其与基线比较。您的模型更好吗?恭喜,现在它就是您的新基线,考虑一些实验来进一步改进它。

算法开发是一个迭代的过程。图片由作者提供

算法开发是一个迭代的过程。要么当您找到一个足够适用于生产的算法,要么当您没有时间继续时,您就可以结束。这两种情况都是可能的。

自然地,您尝试的大多数想法都会失败。所以不要为此感到沮丧,也不要把它当成个人问题。我们都是这样工作的:找到一个好主意,尝试一下,发现这个想法实际上是不好的,然后提出一个新的、希望好一点的想法,再试一下,发现它也不起作用,寻找一个新的想法,…

我在这里的建议是:为单个想法投入的时间设定一个时间框架。如果您无法在N天内使想法起作用(提前选择您的N),请结束它并转向另一个想法。如果您真的想要成功,您需要尝试许多不同的想法,因为,如我之前所说,您尝试的大多数想法都会失败。

深入了解您的数据。可视化样本和标签,绘制特征分布图,确保您理解特征的含义,探索每个类别的样本,了解数据收集策略,阅读给注释员的数据标记说明,…训练自己来预测模型的预期预测结果。如果您想创建一个好的算法,开始像一个算法一样思考(我不是在开玩笑)。所有这些都将帮助您发现数据问题,调试模型,并提出实验想法。

将数据分为训练、验证和测试部分。在训练集上训练,在验证集上选择超参数,在测试集上评估。确保拆分之间没有重叠或数据泄漏。关于这方面的更多信息,请参考Jacob Solawetz的文章:用于机器学习的训练、验证、测试拆分。

加油:拿一个开源模型,用默认参数运行,然后进行超参数调优。使用来自机器学习库(如scikit-learn、PyTorch、OpenCV)或GitHub存储库的算法,这些存储库有很多星标,有良好的自述文件,并且使用许可证允许商业用途。使用默认超参数在您的数据上进行训练和评估。算法的默认超参数是为了在基准数据集(ImageNet、COCO)上最大化准确性,所以在大多数情况下,它们并不适合您的数据和任务。彻底了解每个超参数的含义以及它对训练/推断的影响,这样您就可以进行超参数优化。超参数优化的典型方法包括Grad Student Descent、随机/网格/贝叶斯搜索和进化算法。在进行超参数优化之前,不要说算法不起作用。要了解更多信息,请参阅Pier Paolo Ippolito的文章:超参数优化。

更多地使用您的数据:进行特征工程和数据增强。特征工程是指对现有特征进行转换和创建新特征。特征工程是一项关键技能,所以我向您推荐两篇很棒的文章,您可以在其中获得这项技能:- Emre Rençberoğlu的《机器学习特征工程的基本技术》- Maarten Grootendorst的《高级特征工程和预处理的4个提示》

数据增强是一种从现有数据创建新的训练样本的技术,因此在训练过程中模型能够“看到”更多样本。增加训练集是提高模型准确性的最简单方法,因此您应该尽可能进行数据增强。例如,在计算机视觉领域,几乎没有人在训练模型时不进行基本的图像增强,如旋转、缩放、裁剪、翻转等。有关更多详细信息,请查看我的文章:计算机视觉数据增强完全指南。

如果您想了解自然语言处理中如何进行数据增强,请阅读Shahul ES的文章《自然语言处理中的数据增强:来自Kaggle大师的最佳实践》。

迁移学习是您的朋友。零样本学习是您最好的朋友。迁移学习是一种提高模型准确性的流行技术。实际上,它意味着您采用在某个数据集上预训练的模型,并使用您的数据继续对其进行训练(“转移知识”)。即使来自COCO或ImageNet数据集的权重也可以改善您的模型,尽管您的数据可能与COCO/ImageNet图像看起来相差很大。

零样本学习是一种在不进行训练的情况下在您的数据上工作的算法。如何做到的呢?通常,它是在一个包含数十亿样本的庞大数据集上预训练的模型。您的数据可能与该模型已经训练过的某些内容相似,而且该模型“看到”的样本如此之多,以至于可以很好地对新数据进行泛化。零样本学习可能听起来像一个梦想,但是有一些超级模型已经实现了:Segment Anything、大多数词嵌入模型、ChatGPT等。

Model Development Checklist for your convenience. Image by Author

关于模型开发还有很多要说的,但我们需要结束,留出一些时间来讨论实验跟踪和评估主题。如果您还对知识感到饥渴,可以查看Andrej Karpathy的文章《训练神经网络的配方》。

实验跟踪

实验跟踪是将实验信息保存到某个仪表板或文件中,以便将来进行回顾的过程。它类似于软件开发中的日志记录。训练和测试数据集的链接、超参数、Git哈希值、测试数据上的指标等都是您可能要跟踪的示例。

您必须跟踪您运行的所有实验。如果出于某种原因您的团队没有这样做,请立即组织一个团队会议,讨论其重要性。您以后会对此感激不尽 🙂

那么,为什么我们要进行实验跟踪呢?

  • 比较不同实验之间的差异。当您开发模型时,您会训练和评估许多不同的算法,尝试不同的数据预处理技术,使用不同的超参数,并采用各种创造性的技巧。最终,您希望看到您尝试过什么、什么有效,以及什么给出了最佳准确性。也许以后您想回顾某个实验并用新的思路重新审视其结果。模型开发可能需要几周甚至几个月的时间,因此如果没有适当的实验跟踪,您将简单地忘记您所做的,并且必须重新进行实验。
  • 重现实验。如果无法重现它,那就不算数。自问一下:您能否返回到最成功的实验,重新运行它并得到相同的准确性?如果答案是否定的,可能是因为您没有对代码和数据进行版本控制,没有保存所有超参数,或者没有设置随机种子。设置随机种子的重要性在Cecelia Shao的文章《机器学习实验中正确设置随机种子:没有您想象的那么简单》中有很好的解释。
  • 调试实验。有时实验不起作用:算法不收敛,预测看起来奇怪,准确性接近随机。如果没有保存有关实验的信息,就无法理解它失败的原因。保存的超参数列表、样本和增强的可视化、损失图等可能会给您一些线索,让您知道问题出在哪里。

现在你已经意识到实验追踪的重要性了,让我们来谈谈如何实际进行追踪。

市面上有数十种免费和付费的实验追踪工具,选择适合你需求和预算的工具。可能最流行的是Weights&Biases;我用过它很多次,感觉不错。如果想了解其他工具的评测,可以参考Patrycja Jenkner的《15个最佳机器学习实验追踪和管理工具》。

机器学习实验由数据、代码和超参数组成。确保你使用代码版本控制工具,比如Github或Gitlab,在开发过程中提交所有的修改。能够还原旧版本的代码以重新运行旧实验非常重要。对数据进行版本控制。最简单和最流行的方式是为每个新版本的数据集创建一个新的文件夹或新文件(最好在云存储,比如Amazon S3或Google Cloud Storage上)。有些人使用一个叫做Data Version Control(DVC)的工具。

机器学习实验由数据、代码和超参数组成。图片由作者提供

那么,究竟应该追踪实验的哪些内容呢?嗯,追踪所有你能追踪到的东西都不是坏主意 🙂 大部分时间你可能不会使用所有那些信息,除非一个实验失败得非常彻底。

以下是一些你可能要考虑追踪的内容:

  • 代码的Git哈希
  • 训练、验证和测试数据集的链接
  • 超参数及其随时间的变化(模型架构、学习率、批大小、数据增强等)
  • 训练和验证集上的损失曲线
  • 训练和验证集上的指标曲线
  • 测试集上的指标
  • 带标签的训练样本可视化(应用增强和未应用增强的情况下)
  • 测试集上的错误可视化
  • 环境信息(操作系统、CUDA版本、包版本、环境变量)
  • 训练速度、内存使用、CPU/GPU利用率

设置一次实验追踪,享受它带来的好处。

模型评估

在模型部署到生产环境之前,必须进行彻底的评估。这个评估被称为“离线”评估。相反,“在线”评估是关于检查正在生产环境中运行的模型。在线评估将在本系列的下一章中讨论,今天我们仅专注于离线评估。

进行离线评估需要一个度量指标和一个数据集。

模型在测试数据集上进行评估,这是在训练和调整超参数时放置一边的数据集。假设:1)测试集足够大且非常干净;2)模型从未见过测试数据;3)测试数据代表生产数据。如果上述任一假设被违反,评估将被执行错误,并且存在高风险部署一个糟糕的模型并得到一个过于乐观的度量指标。

在一个小的测试集上进行评估可能仅仅是偶然的好结果。在脏数据上进行评估无法展示真实的模型性能。尽管训练集中存在错误是可以容忍的(可以使用干净的标签、脏标签或者甚至没有标签进行训练),但在测试集中存在错误可能是有害的。重要提示:无监督模型也需要一个带标签的测试集。否则,你怎么知道你的模型是否好?

确保你的模型没有“看到”测试数据。始终过滤掉重复数据,这样同一个样本就不会同时出现在训练集和测试集中。不要随机划分数据,而是使用基于时间或用户的划分。基于时间的划分意味着将较旧的数据放入训练集中,较新的数据放入测试集中。基于用户的划分意味着将同一用户的所有数据放入同一划分中。并且在数据泄露方面要非常小心,Prerna Singh在《机器学习中的数据泄露:如何检测和最小化风险》中有更多详细信息。

度量指标是一个被认为与模型真实性能相关的数字:数字越高,模型越好。你可以选择一个或几个度量指标。例如,对于分类任务的典型指标有准确率、精确率、召回率和F1分数。选择一些简单且理想情况下可解释的指标,这样非技术的经理和客户也能理解。

以下是Shervin Minaee关于各种任务和领域的优秀文章:

  • 20个热门机器学习指标。第1部分:分类和回归评估指标
  • 20个热门机器学习指标。第2部分:排名和统计指标

使用基于切片的指标,评估您的模型在您能想到的每个数据分段上的表现(除非您想陷入“Zoom的虚拟背景功能不适合黑人面孔”之类的丑闻)。例如,面部检测系统必须针对不同种族、性别和年龄的人分别进行评估。值得评估的电子商务模型包括桌面与移动设备、不同国家和浏览器。请确保每个分段在测试集中得到良好的代表。基于切片的指标还有助于处理类别不平衡问题:分别查看每个类别的精确度和召回率比查看总体精确度/召回率更有帮助。

另一种避免丑闻的方法(这次是“ABC银行的新信用评分系统歧视未婚女性”),是使用行为测试。一篇很棒的论文《超越准确性:使用CheckList对NLP模型进行行为测试》,建议除了使用数值指标外,还可以使用最小功能性测试、不变性测试和方向性期望测试。尽管该论文主要关注自然语言处理,但这些测试类型也可以轻松应用于表格数据和图像。

在“ABC银行的新信用评分系统歧视未婚女性”的例子中,不变性行为测试可能会有很大帮助。保持所有特征不变,但改变婚姻状况和性别,并检查模型的预测是否发生了变化。如果在预测中看到显著差异(当应该是“不变”的时候),可能是因为您的模型吸收了训练数据中的偏见;这需要进行修正,例如完全从模型输入中删除敏感(容易导致歧视)的特征。

最后,可视化错误。找出测试集中模型出错的样本;将它们可视化并分析为什么会发生错误。是因为测试集仍然存在问题吗?在训练集中有足够相似的样本吗?模型错误是否存在任何模式?这种分析有助于发现测试集中可能存在的标注错误以及训练过程中的错误,并提出进一步改进模型性能的想法。

Model Evaluation Checklist for your convenience. Image by Author

结论

在本章中,我们学习了如何开发模型时要记住,机器学习算法只是机器学习系统的一部分。模型开发始于创建一个简单的基准模型,并在此基础上进行迭代改进。我们找到了最有效的方法:采用开源模型,并围绕它构建实验,而不是重复造轮子或陷入研究的兔子洞。我们讨论了“最先进”算法的陷阱以及数据增强和迁移学习的好处。我们一致认为实验跟踪的重要性,并学习如何设置它。最后,我们讨论了离线评估——指标选择、适当的测试集、基于切片的评估和行为测试。

我们几乎完成了,只剩下最后一章。在下一篇(最后一篇)文章中,您将学习关于部署、监控、在线评估和重新训练的知识——这是帮助您构建更好的机器学习系统的最后一块拼图。

即将推出大结局,订阅以保持关注。

Leave a Reply

Your email address will not be published. Required fields are marked *