随着机器学习(ML)在过去几年的快速发展,开始ML实验变得非常容易。多亏了像scikit-learn和Keras这样的库,用几行代码就可以创建模型。
但是,将数据科学项目转化为有意义的应用程序比以往任何时候都更加困难,比如将模型转化为团队决策或成为产品的一部分。典型的ML项目涉及到许多不同的技能集,对于任何一个人来说,如果不是完全不可能的话,那也是一种挑战——如此困难,少有的同时还能开发高质量软件和游戏工程师的数据科学家被称为独角兽!
随着这一领域的成熟,很多工作将需要软件、工程和数学技能的结合,有些人说他们已经这么做了。
引用一位无与伦比的数据科学家/工程师/评论家Vicki Boykis在她的博客data science is different now里的话:
越来越清楚的是,在炒作周期的后期阶段,数据科学正逐渐接近工程,数据科学家需要的技能不再是可视化和基于统计的,而是与传统的计算机科学课程更加一致。
为什么数据科学家需要了解DevOps
那么,在众多的工程和软件技能中,数据科学家应该学习哪一种呢?我的钱花在DevOps上了。
DevOps是development和operations的合成词,于2009年在比利时的一次会议上正式诞生。这次会议的召开是为了应对科技公司在历史上经历过深刻分歧的两个方面之间的紧张关系。软件开发人员需要快速行动并经常进行试验,而运维团队则优先考虑服务的稳定性和可用性(这些人让服务器每天都在运行)。他们的目标不仅是对立,而且是竞争。
这听起来很像今天的数据科学。数据科学家通过实验创造价值:数据建模、组合和转换的新方法。与此同时,雇佣数据科学家的组织受到稳定的激励。
这种划分的后果是深远的:在最新的Anaconda数据科学状态”报告中,“不到一半(48%)的受访者认为他们可以证明数据科学对他们的组织的影响”。据估计,绝大多数由数据科学家创建的模型最终都被束之高阁。我们还没有强大的实践来在创建模型的团队和部署模型的团队之间传递模型。数据科学家和实现他们工作的开发人员和工程师拥有完全不同的工具、约束条件和技能集。
DevOps的出现就是为了解决软件中的这种僵局,就像开发人员vs运维一样。它取得了巨大的成功:许多团队已经从每几个月部署一次新代码发展到一天部署几次。既然我们已经有了机器学习和操作,那么现在就该考虑MLOps了——来自DevOps的用于数据科学的原则。
引入持续集成
DevOps既是一种哲学,也是一套实践,包括:
- 自动化你所能做到的一切
- 快速获得对新想法的反馈
- 减少工作流程中的手工交接
在一个典型的数据科学项目中,我们可以看到一些应用:
- 自动化你所能做到的一切。自动化部分重复和可预测的数据处理、模型训练和模型测试。
- 快速获得对新想法的反馈。当你的数据、代码或软件环境发生变化时,立即在类似生产的环境(即具有预期在生产中具有的依赖关系和约束的机器)中进行测试。
- 减少工作流程中的手工交接。为数据科学家寻找机会,尽可能多地测试他们自己的模型。不要等到有开发人员时才查看模型在类似生产环境中的行为。
实现这些目标的标准DevOps方法是一种称为持续集成(CI)的方法。
要点是,当你更改项目的源代码时(通常通过Git提交注册更改),你的软件将被自动构建和测试。每个动作都会引发反馈。CI通常与Git-flow一起使用,Git-flow是一种开发架构,其中的新特性构建在Git分支上。当一个特性分支通过自动化测试时,它就成为了一个候选分支,可以合并到主分支中。
通过这种设置,我们有了自动化——代码更改触发一个自动构建,然后进行测试。我们有快速的反馈,因为我们可以快速得到测试结果,所以开发人员可以不断迭代他们的代码。而且因为所有这些都是自动发生的,你不需要等待其他人得到反馈——少了一个切换!
那么我们为什么不在ML中使用持续集成呢?一些原因是文化上的,比如数据科学和软件工程社区之间的低交叉。其他的则是技术性的——例如,为了理解模型的性能,你需要查看诸如准确性、特异性和敏感性等指标。数据可视化可能会帮助你,比如混淆矩阵或损失图。所以通过/失败的测试不会减少反馈。理解一个模型是否得到了改进需要一些关于手头问题的领域知识,因此测试结果需要以一种有效的和可理解的方式进行报告。
CI系统是如何工作的?
现在我们要更实际一些,让我们看看典型的CI系统是如何工作的。对于学习者来说,幸运的是,由于GitHub Actions和GitLab CI等工具的出现,障碍从来没有降低过——它们有清晰的图形界面和为首次用户准备的优秀文档。由于GitHub操作对于公共项目是完全免费的,所以我们将在本例中使用它。
它是这样工作的:
你创建了一个GitHub存储库。你创建了一个名为.github/workflows的目录,并在其中放置了一个特殊的.yaml文件,其中包含你想要运行的脚本。
- $ python train.py
你可以以某种方式更改项目存储库中的文件,然后Git提交更改。然后,推到GitHub存储库。
- # Create a new git branch for experimenting
- $ git checkout -b "experiment"
- $ edit train.py
- # git add, commit, and push your changes
- $ git add . && commit -m "Normalized features"
- $ git push origin experiment
一旦GitHub检测到push,GitHub就会部署他们的一台计算机来运行.yaml中的函数。
如果函数运行成功或失败,GitHub会返回一个通知。
就是这样!真正奇妙的是,你正在使用GitHub的计算机来运行你的代码。你所要做的就是更新代码并将更改推送到存储库中,工作流就会自动发生。
回到我在第1步中提到的特殊的.yaml文件——让我们快速查看一个。它可以有任何你喜欢的名称,只要文件扩展名是.yaml,并且它存储在.github/workflows目录中。这里有一个:
- # .github/workflows/ci.yaml
- name: train-my-model
- on: [push]
- jobs:
- run:
- runs-on: [ubuntu-latest]
- steps:
- - uses: actions/checkout@v2
- - name: training
- run: |
- pip install -r requirements.txt
- python train.py
有很多操作在进行,但大多数操作都是相同的——你可以复制粘贴这个标准的GitHub动作模板,但在“运行”字段中填写你的工作流。
如果这个文件在你的项目repo中,每当GitHub检测到对你的代码的更改(通过push注册),GitHub Actions就会部署一个Ubuntu运行程序,并尝试执行你的命令来安装需求并运行Python脚本。请注意,你必须在项目repo中包含你的工作流所需的文件——这里是requirementes .txt和train.py。
得到更好的反馈
正如我们之前提到的,自动训练是非常酷的,但重要的是要有一个容易理解的形式的结果。目前,GitHub操作允许你访问运行的纯文本日志。
但是理解你的模型的性能是很棘手的。模型和数据是高维的,并且通常是非线性的——如果没有图片,这两件事是特别难以理解的。
我可以向你展示一种将数据viz放入CI循环的方法。在过去的几个月里,我的团队在Iterative.ai(我们做数据版本控制)正在开发一个工具包,帮助在机器学习项目中使用GitHub动作和GitLab CI。它被称为持续机器学习(简称CML),并且是开源免费的。
从“让我们使用GitHub动作来训练ML模型”的基本思想出发,我们构建了一些函数来提供比通过/失败通知更详细的报告。CML帮助你在报告中放入图像和表格,就像这个由SciKit-learn生成的混淆矩阵:
为了制作这个报告,我们的GitHub操作执行了一个Python模型训练脚本,然后使用CML函数将我们的模型准确性和混淆矩阵写入一个markdown文档。然后CML将减价文档传递给GitHub。
我们修改后的.yaml文件包含以下工作流(新添加的行被加粗以示强调):
- name: train-my-model
- on: [push]
- jobs:
- run:
- runs-on: [ubuntu-latest]
- container: docker://dvcorg/cml-py3:latest
- steps:
- - uses: actions/checkout@v2
- - name: training
- env:
- repo_token: ${{ secrets.GITHUB_TOKEN }}
- run: |
-
- # train.py outputs metrics.txt and confusion_matrix.png
- pip3 install -r requirements.txt
- python train.py
-
- # copy the contents of metrics.txt to our markdown report
- cat metrics.txt >> report.md
- # add our confusion matrix to report.md
- cml-publish confusion_matrix.png --md >> report.md
- # send the report to GitHub for display
- cml-send-comment report.md
你可以在这里看到整个项目存储库。注意,我们的.yaml现在包含更多的配置细节,比如一个特殊的Docker容器和一个环境变量,以及一些要运行的新代码。容器和环境变量细节在每个CML项目中都是标准的,而不是用户需要操作的东西,所以请关注代码。
在工作流中添加了这些CML功能后,我们在CI系统中创建了一个更完整的反馈循环:
- 创建一个Git分支并更改该分支上的代码。
- 自动训练模型并产生度量(准确性)和可视化(混淆矩阵)。
- 将这些结果嵌入到Pull请求的可视报告中。
现在,当你和你的团队成员决定你的变更是否对你的建模目标有积极的影响时,你就有了一个可以检查的仪表板。另外,Git还将此报告链接到你的确切项目版本(数据和代码)、用于训练的跑步器以及那次运行的日志。很彻底,不再有那些很久以前就失去了与代码的任何连接的图形在你的工作空间中浮动。
这就是数据科学项目中CI的基本思想。明确地说,这个示例是使用CI的最简单方法之一。在现实生活中,你可能会遇到相当复杂的场景。CML还有一些功能可以帮助你使用存储在GitHub存储库之外的大型数据集(使用DVC),并在云实例上进行训练,而不是使用默认的GitHub动作运行器。这意味着你可以使用GPU和其他专门的设置。
例如,我做了一个使用GitHub Actions部署EC2 GPU的项目,然后训练一个神经类型的传输模型。以下是我的CML报告:
你还可以使用自己的Docker容器,这样就可以在生产中紧密地模拟模型的环境。以后我将更多地介绍这些高级用例。
关于ML的CI的最后思考
总结一下我们到目前为止所说的:
DevOps不是一种特定的技术,而是一种哲学、一套原则和实践,用于从根本上重构创建软件的过程。它之所以有效,是因为它解决了团队如何工作和试验新代码的系统瓶颈。
随着数据科学在未来几年的成熟,懂得如何将DevOps原则应用到他们的机器学习项目中的人将成为一种有价值的商品——无论是从薪水还是从组织影响的角度。持续集成是DevOps的主要内容,也是构建具有可靠自动化、快速测试和团队自治的文化的最有效的已知方法之一。
CI可以通过GitHub Actions或GitLab CI等系统实现,你可以使用这些服务来构建自动模型培训系统。好处很多:
- 你的代码、数据、模型和培训基础设施(硬件和软件环境)都是Git版本化的。
- 你正在自动化工作,频繁地进行测试并获得快速的反馈(如果使用CML,则使用可视化的报告)。从长远来看,这几乎肯定会加速项目的开发。
- CI系统使你的工作对团队中的每个人都可见。没有人需要非常费力地搜索你的最佳运行的代码、数据和模型。
我保证,一旦你进入最佳状态,通过一个Git提交自动启动你的模型训练、记录和报告是非常有趣的。
你会觉得很酷。